Creating Components

A component is created by either an extension or interfaces through an extension. Each component requires a unique id that comes from a key set in configurations. MudPi has a components registry that keeps each component registered under its id.

Component Structure

A component at minimum needs to define an id property and extend from the base Component class. There are additional properties and methods available but these are the minimal requirements. Below is an example of a basic component that just sets it state to 10.

from mudpi.extensions import Component


class ExampleComponent(Component):

    @property
    def id(self):
        return 'example_component'
    
    @property
    def state(self):
        return self._state


    def update(self):
        self._state = 10

As you can see this example component also defined a state property and an update() method. The state property is where a component should return its state from memory. Its important to not perform operations here that could take process time or block. This is where the update() method is used. update() is called on the component based on a configured update_interval. The update() method is where the logic and operations to get state updates should happen. This allows components to be responsive when gathering data.

Not all components require updates and you are not required to provide the update() method. If your component does not need update requests then you can also set the property should_update to False.

@property
def should_update(self):
    return False

Components have a few other methods in addition to update() you should be aware of.

def init(self):
    """ Called at end if __init__ and
        used for additional setup tasks
    """
    pass

def reload(self):
    """ Reload the component if supported """
    pass

def unload(self):
    """ Unload the component and cleanup """
    pass

As the names suggest they offer the ability to add functionality for additional setup, reloading and unloading.

Component Lifecycle

A component is loaded in one of two ways, either from an extension or from an interface through an extension. The component gets initialized with a reference to the core MudPi instance and a copy of the config dict. Components should not overwrite the __init__() method of components. Instead an init() method is provided that gets called at the end of initialization for additional setup. Once setup the component gets registered in the component registry and added to a worker.

The worker will manage components and request updates during each update cycle. In each update cycle the component update() method is called which performs its operations. In the update method this is where all state should be updated instead of the state property. The state property should just be pulling from memory to avoid blocking while trying to fetch multiple component states.

When the system is shutting down the last thing that happens is cleanup operations. Components sometimes have cleanup operations that need to happen as well like closing connections and releasing resources. A component has an unload() method for this purpose. During the MudPi shutdown phase each component will have its unload method called.

Additional Options

There are a few other properties components have you should use to your advantage.

@property
def name(self):
    """ Return the display name of the component """
    return None

@property
def metadata(self):
    """ Returns a dict of additonal info about the component 
        This is mainly used by the dashboard / frontend
    """
    return {}

@property
def classifier(self):
    """ Classification further describing it, effects the data formatting """
    return None

The name property is a friendly display version of the id they usually is set by a key in configs. You are free to put anything you like here as this is mainly used for human readable output. The id is what is used for all the important internal operations.

metadata is a dict of additional information that describes the component and its state. This is where data like prefixes, units of measurements and descriptions go. This is not used internally by the core but instead for the frontend and supporting resources.

Lastly the classifier is useful for component formatting and display. It will change the icon and display format on the dashboard. Below is a list of available classifiers.

ClassifierPrefix
battery%
currentmA
electrical_conductivityµS
flowmetergal/m
humidity%
illuminancelux
temperature°
timestampNone
moisture%
phph
voltageV

You are encouraged to checkout the base Component class in mudpi/extensions/__init__.py for all the properties and methods available.

Core components

MudPi provides a set of base components that support interfaces for you. The current supported component interfaces are: sensors, controls, cameras, triggers, character displays and toggles. These core components are designed be extended through interfaces making it easier to add support for new features. Read the developer interface docs if you are interested in adding a new component interface.

If you would like to add another core component that supports interfaces contact the developer team.