Software Designt

Software framework

Software Design Diagram

image-20250205105239936

Business system startup process

image-20250205112309962

Code Explanation

Event management

Collaboration between various modules is achieved through the EventMet event management class EventMeth event management class provides publishing and subscribing of events, as well as synchronous and asynchronous sending of messages. The framework is shown in the figure:

The definition of event management class is as follows:

class EventStore(object):
def __init__(self):
        self.map = dict()
        self.log = None

    def append(self, event, cb):
        self.map[event] = cb

    def fire_async(self, event, msg):
        if event in self.map:
            _thread.start_new_thread(self.map[event], (event, msg))
            if self.log:
                self.log.info("ASYNC executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, None))

    def fire_sync(self, event, msg):
        res = None
        try:
            if event in self.map:
                res = self.map[event](event, msg)
        except Exception as e:
            usys.print_exception(e)
        if self.log:
            self.log.info("SYNC executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, res))
        return res

event_store = EventStore()

def subscribe(event, cb):
    """
    subscribe event and cb
    """
    return event_store.append(event, cb)

def publish(event, msg=None):
    """
    publish event and msg
    """
    return publish_sync(event, msg)

def publish_async(event, msg=None):
    """
    异步发送
    """
    return event_store.fire_async(event, msg)

def publish_sync(event, msg=None):
    """
    同步发送
    """
    return event_store.fire_sync(event, msg)
  1. EventMesh is an application framework based on subscription and publish mechanisms, where users can subscribe to any topic of interest, which represents an event.
  2. At the same time as subscribing to the topic, it is also necessary to register a callback (event_cb) function to handle the generated events.
  3. Users can post the event anywhere it occurs and carry the message content. At this point, the callback function registered by the subscriber will be called and the event will be processed.

Principle of screen switching implementation

In every screen interface script code generated by a touch event with a control, theadd_event_cb()method of the control is called to register a callback function for the corresponding event. The interface switching implementation is relatively simple. When the lvgl thread detects a touch event, it will issue the required operation to EventMeth through the callback function corresponding to the control.

example:

class MainScreen(Screen):
    # Some code is omitted here
    def create(self):
    	# Some code is omitted here
    	self.weather_btn.add_event_cb(lambda e: self.__weather_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.alarm_btn.add_event_cb(lambda e: self.__alarm_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.monitor_btn.add_event_cb(lambda e: self.__monitor_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.monitor_btn_2.add_event_cb(lambda e: self.__monitor_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.dev_btn.add_event_cb(lambda e: self.__dev_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.setting_btn.add_event_cb(lambda e: self.__setting_btn_event_cb(e), lv.EVENT.PRESSED, None)

    def __weather_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("The click event occurs")
        EventMesh.publish("load_screen", "WeatherScreen")

    def __monitor_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("The click event occurs")
        EventMesh.publish("load_screen", "MonitorScreen")

    def __alarm_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("The click event occurs")
        EventMesh.publish("load_screen", "AlarmScreen")

    def __dev_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("The click event occurs")
        EventMesh.publish("load_screen", "Dev1Screen")

    def __setting_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("The click event occurs")
        EventMesh.publish("load_screen", "SettingScreen")

Taking the switching weather screen in the above example code as an example:

self.weather_btn.add_event_cb(lambda e: self.__weather_btn_event_cb(e), lv.EVENT.PRESSED, None)

Bind callback function __weather_btn_event_cb() for weather control

    def __weather_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("The click event occurs")
        EventMesh.publish("load_screen", "WeatherScreen")

ExecuteEventMesh.publish("load_screen", "WeatherScreen") in the callback function, and publish theload_streen event to EventMeth, meaning to load the screen, carrying the message WeatherScreen, indicating to load the WeatherScreen interface.

Screen module

screen.py defines a Screen class as the base class for all interfaces, which is defined as follows:

class Screen(object):
    """Abstract class of screen"""

    def __init__(self):
        super().__init__()
        self.style_siyuan_14_red = None
        self.style_siyuan_16_blue = None
        self.style_opa_btn = None
        self.style_siyuan_26 = None
        # Some code is omitted here
    def create_style(self):
        """
        create style
        """
        # Interface style, background color: 3a5283
        style_screen = lv.style_t()
        style_screen.init()
        style_screen.set_bg_color(lv.color_make(0x3a, 0x52, 0x83))
        style_screen.set_bg_opa(255)
        self.style_screen = style_screen

        # The style of the left menu bar
        style_cont_menu = lv.style_t()
        style_cont_menu.init()
        style_cont_menu.set_radius(0)
        style_cont_menu.set_bg_color(lv.color_make(0x28, 0x39, 0x5c))
        style_cont_menu.set_bg_grad_color(lv.color_make(0x28, 0x39, 0x5c))
        style_cont_menu.set_bg_grad_dir(lv.GRAD_DIR.VER)
        style_cont_menu.set_bg_opa(255)
        style_cont_menu.set_border_color(lv.color_make(0x21, 0x95, 0xf6))
        style_cont_menu.set_border_width(0)
        style_cont_menu.set_border_opa(0)
        style_cont_menu.set_pad_left(0)
        style_cont_menu.set_pad_right(0)
        style_cont_menu.set_pad_top(0)
        style_cont_menu.set_pad_bottom(0)
        self.style_cont_menu = style_cont_menu
        # Some code is omitted here

The Screen class provides common methods required for all screen objects, such as creating screens and displaying status bar information (operator name, signal strength, system time, battery level, etc.). QuecPython uses NXP's GUI Guider as a graphical interface design tool, generates the style code for this section.
All script files ending with _screen. py implement a class inherited from class Screen(), which is the code implementation corresponding to the screen that needs to be displayed. The main content of the interface code is provided by the GUI Guider tool is automatically generated and then slightly modified, mainly by modifying the object initialization method __init__() and the control event handling callback function __xxx_event_cb().

GUI startup

The load_screen event is subscribed to in the start() method of the class AgriUi (object) class in the Agri_ui.py script file.

example:

class AgriUi(object):

    # Some code is omitted here

    def __create(self):
        for screen in self.screens:
            screen.create()

    def start(self):
        self.__create()
        EventMesh.subscribe("load_screen", self.__route)
        EventMesh.publish("load_screen", "WelcomeScreen")
        utime.sleep(2)
        EventMesh.publish("load_screen", "MainScreen")

    def __route(self, topic, meta):
        for screen in self.screens:
            if screen.name == meta:
                lv.scr_load(screen.screen)

Thestart() method in the above code is used to launch the graphical interface of the smart agriculture control panel, and its workflow is as follows:

  • Call the __create() method to create metadata for each screen interface.

  • Call the EventMesh. subscribe() method to subscribe to an event named load_screen. When the event occurs, call the __route() method to process it.

    The route() method matches the corresponding interface object based on the message carried when publishing the event, that is, the name of the screen interface, and calls lvgl's lv. scr_load()method to load the new interface.
    Observant readers will notice that in every class implemented in the screen interface script file, there will be statements similar to self. name=" MainScreen" in its object initialization method __init__(). This statement records the name of the screen interface.

  • The EventMesh.publish("load_screen", "WelcomeScreen") statement is used to trigger the first interface display, which is the welcome interface. Then wait for the welcome interface to display for 2 seconds, creating a good visual experience.

  • After the welcome interface ends, use the EventMesh.publish("load_screen", "MainScreen") statement to trigger the display of the main interface.

At this point, the graphical interface of the smart agriculture control panel has been launched, and the subsequent interface switching is controlled by the user's touch.

In summaryAgri_ui.py performs all initialization work for the smart agriculture control panel, including lvgl initialization and MIPI LCD initialization; At the same time, it provides a graphical interface for adding screen objects and a GUI launcher. The screen object adder is used to add all possible screen objects that may need to be displayed in the application, and the GUI launcher is used to launch graphical interface functionality.

Graphic interface design

As mentioned earlier, QuecPython uses NXP's GUI Guider as a graphical interface design tool, GUIDER not only enables interface layout design, but also automatically generates QuecPython code. Click here to view the tutorial on using the GUI Guider tool.

Layout and background settings

Create a smart agriculture project and choose a suitable layout template and background design. This stage will start with a blank layout design, selecting a blank template and setting the resolution to 854 * 480.

Draw screen

This section will start drawing the various modules in the homepage.

1.Left navigation bar

  • component: imgbtn。
  • icon: Use easily recognizable icons as shortcuts to access homepage, display data, settings, controls, and other functions.
  • layout: The icon is vertically aligned and placed on the left side of the interface for easy use.
  • interactivity: Add a selection effect to the icon to enhance the interactive experience.

When using the imgbtn component in GUI Guider software to create the left shortcut bar in the graphical interface of smart agriculture, you will need to pay attention to several key design elements:

  1. Icon selection:
  • Each imgbtn should select an intuitive icon representing its function, such as a home shaped icon representing the homepage and a gear shaped icon representing the settings.
  • Icon design should be concise and clear, so that users can recognize its function at a glance.
  1. Size and spacing:
  • The size of each imgbtn should be large enough for users to easily click, especially on touchscreen devices.
  • There should be appropriate spacing between shortcut keys to prevent accidental touches and make the interface look neater.
  1. Icon status:
  • Design icons in different states, such as default state, floating state, and click state, to provide visual feedback and enhance user interaction experience.
  • The 'imgbtn' component should support state switching so that users can see the interface response caused by their cross cloud actions.
  1. Functionality:
  • Each imgbtn should be configured with the correct event handler to ensure that the user can trigger the correct action or navigate to the corresponding interface when clicking.
  • If the function represented by imgbtn is currently activated or located on the current page, it should be displayed in different visual styles to indicate its activity status.

2.Top Information Display Bar

  • component: label、image.
  • Operator information: Display the mobile operator or network status on the top left side of the interface.
  • Time display: Display the current time in the middle position at the top of the interface.
  • Signal strength and battery level indication: Display icons for Wi Fi or network signal strength and current battery level on the top right side of the interface.

When using GUI Guider software to design the top information display bar of the smart agriculture control panel, combine the label and image components to create an informative and visually recognizable status bar. Here are the detailed steps on how to use these components to design the top information display bar:

  1. Operator information:
    • Use the label component to display operator information. Choose clear and easy to read fonts and sizes to ensure easy reading on different devices.
    • Place the label component on the left side of the top information bar and set an appropriate alignment, usually left aligned.
  2. Time display:
    • Another label component is used to display time. You can set a timer to ensure that the time is always updated.
    • The time label is usually located on the right side of the information bar and should have sufficient recognition, which can be achieved by increasing the font size and bolding.
  3. Signal strength:
    • Signal strength can be represented by a series of predefined signal icons. These icons can display different images based on the strength of the signal.
    • Use the image component to place the signal strength icon and place it on the right side of the top information bar.
  4. Battery Indicator:
    • The battery level indicator is also displayed using the image component, and you can prepare a set of battery level icons to reflect different battery levels.
    • Place the battery icon on the far right side of the top information bar, adjacent to the signal strength icon.

3.Weather module:

  • component: label、container、image。
  • Current Weather: Display the current weather conditions and temperature.
  • Future weather forecast: Provide horizontal scrolling or small grids next to or below the current weather to display the weather forecast for the next few days.
  1. When designing the weather information module on the upper left side in GUI Guider, you can combine label , image and container components to create an intuitive and informative weather display area. Here are the steps on how to use these components to design a weather information module:

    • Basic container settings:

    • Place a container component in the upper left corner of the interface as the basis for the weather module. This container will contain all weather related subcomponents.

    • Adjust the size of the container to ensure it can accommodate all sub components without appearing crowded.

  2. Position display:

    • Use a label component to display the current geographic location or farm name at the top of the container.
    • This label can use larger fonts and bold effects so that users can clearly identify location information.
  3. Current temperature and weather:

    • Use two label components to describe the current temperature and weather. These should use clear and easy to read fonts, and be appropriately sized for clarity at a glance.
    • The label for the current temperature should be the most prominent and may require larger font size and prominent colors.
  4. Weather icon:

    • Use the image component to display icons of current weather conditions, such as sunny, cloudy, rainy, etc.
    • The weather icon should be adjacent to the label of the current temperature, providing a visual representation of the weather.
  5. Weather forecast:

    • Use multiple label and image components below or next to the container to display the weather forecast for the next 5 days.
    • The daily forecast can be displayed using a small image component to show the weather icon, followed by a label component to show the date.
  6. Adaptive Design

    • When designing, it is important to ensure that the weather information area can adapt to different screen sizes and resolutions, especially on responsive interfaces.
    • The sub component should be able to automatically adjust its size and position when the size of the container changes.

4.Historical curve of temperature and humidity:

  • component: container,chart ,label。
  • Chart Style: Use a line graph to display historical data trends of temperature and humidity.
  • Timing: Provide options to view data from different time periods, such as day, week, and month.
  • Interactivity : Allow users to hover or click on points on the chart to view specific data points.

When using GUI Guider to design the temperature history curve on the lower left side of the smart agriculture graphical interface, layout the label` Chart and container components. These components will collectively form a chart area displaying temperature trends. The following are specific design instructions:

  1. Container Layout:
    • Place a container component on the lower left side of the interface to serve as the background and framework for the temperature history curve. This container will contain charts and related labels.
    • Set the width and height of the container to meet the display requirements of the curve graph, while maintaining coordination with other interface elements.
  2. Curve chart:
    • Add a chart component inside thecontainer to draw a historical temperature data curve.
    • Configure the chart component to display temperature data of time series, such as setting the x-axis as the time axis and the y-axis as the temperature values, to ensure that the data points are clear and visible.
    • Define curve styles, such as curve color, thickness, and whether to display markers for data points.
  3. Title tag
    • Use the label component above the graph or at the top of the container to display the title, such as Historical Curve.
    • Choose the appropriate font size and style to ensure that the title is clear and consistent with the overall design style.
  4. Responsive design
    • For responsive interfaces, ensure that the container and its chart and label components can be appropriately scaled according to different screen sizes.
    • Test the display effect of charts on different resolutions and devices to ensure that the data is always clear and visible.

5.Common environmental parameters display:

  • component: container,label。
  • Data display block: Display key parameters in the form of independent "blocks" or "cards", such as current readings of soil pH, soil temperature, oxygen and carbon dioxide concentrations, etc.

When designing the environmental parameter display on the upper right side of the smart agriculture graphical interface in GUI Guider software, the 'label' and 'container' components can be used to clearly display key information such as soil pH value, oxygen concentration, soil moisture, and carbon dioxide concentration. The following are detailed design steps:

  1. Environment parameter container:
    • Place a container component on the upper right side of the interface as a wrapping element for all environment parameters. This container will help organize and separate different parameter displays.
  2. Parameter label:
    • For each environmental parameter, use a separate label component to display the parameter name and value. For example, one label displays "Soil pH value: 7.1", another label displays "Oxygen concentration: 50%", and so on.
    • The label of parameter names can use smaller fonts, while the label of numerical values can use larger or bolded fonts to highlight numerical information.
  3. Parameter update mechanism:
    • If possible, design a data update mechanism to periodically refresh the displayed environmental parameter values. This can be done by binding the 'label' component to the data source and setting a timer to update the values.

6.Alarm Information Area:

  • component: container,label,table。
  • list view: Display recent alerts and warnings in the form of a list or log.
  • priority indication: Use color coding or icons to indicate the priority or severity of alarms.
  • interactivity : Allow users to click on the alarm to obtain more details or confirm and clear notifications.

When using GUI Guider software to design the lower right alarm information area of the smart agriculture graphical interface, you can use label container and table components are used to effectively display alarm titles and specific alarm information. This area will provide users with critical security and system status updates. The following is a detailed design process:

  1. Alarm information container:
    • Place a container component on the bottom right side of the interface as the main framework for the alarm information area. This container will contain the title and specific content of the alarm information.
    • Set the size of the container to ensure sufficient space to display alarm information while maintaining coordination with other elements on the interface.
  2. Alarm Information Title:
    • Use a label component to display a title at the top of the container, such as Alarm Information.
    • Choose eye-catching and easy to read fonts and sizes to ensure that users can clearly identify the functionality of this area.
  3. Alarm Information Table:
    • Use the table component below the container to list specific alarm information. This can include columns such as alarm time, type, status, etc.
    • Adjust the column width and row height of the table to ensure that all information is clearly visible.
  4. Alarm information style:
    • Set appropriate background, border, and font colors for the table component to maintain consistency with the overall interface style.
    • Consider using different colors or icons to represent different levels of alerts, such as red for emergency alerts and yellow for warnings.
  5. Alarm information update mechanism:
    • Design a data update mechanism that allows thetable component to dynamically display the latest alarm information. This may require binding the table component to the backend data source and setting a scheduled refresh.
  6. Responsive design:
    • Ensure that the container and its table and label components can be appropriately scaled at different screen sizes and resolutions.
    • On a small screen, it may be necessary to adjust the layout of the table to ensure the readability of information.

When placing these elements in the GUI Guider, ensure that each component is placed according to a grid or flexible layout system to accommodate different screen sizes and resolutions. The interface design should be concise, with sufficient blank space to avoid crowding. The color scheme used should highlight important information but not be glaring. Interactive elements should provide instant feedback, such as floating or changing appearance when clicked. In addition, the design should be tested on different devices to ensure its availability and performance.

If the system is to be used under various lighting conditions, such as direct sunlight, it should be able to adjust contrast and brightness to enhance visibility. Finally, interface design should be intuitive, allowing new users to navigate without extensive training, reflecting good user experience (UX) design principles.