Event System

A vital component of MudPi is the underlying event system. This system is used to allow all internal components to communicate. MudPi offers support for redis and MQTT to utilize their Pub/Sub capabilities since they also work across multiple languages (Python, PHP, and Javascript in our case).

Events

MudPi will publish events for all of its internal operations. Events are the main way MudPi systems interact with one another. Examples of when events are emitted include state update, user input, time changes etc. Each event will return a JSON payload with an event and its data. Depending on your configurations MudPi will broadcast events on both Redis and MQTT.

Topics

A topic is a communication line that MudPi will broadcast data on. Only clients listening on a topic can receive its events and event data. Events are not rebroadcast so if a listener misses an event it's gone.

Subscribe to Events

You can subscribe to events in MudPi through the mudpi core instance which has the event system available through its events attribute. Here is how you would subscribe to an event on the state topic.

def display_data(event_data):
    print(event_data)

mudpi.events.subscribe('state', display_data)

Events Emitted by MudPi

MudPi emits several events throughout its operations. It can be useful to know these events to add features and hook in additional functionality.

State Events

topic: state

State Changed

Fired anytime new state is detected. Data will be an object with its state.

{
    "event": "StateUpdated",
    "new_state": {...},
    "component_id": "example_1",
    "previous_state": {...},
    "updated_at": "2021-03-13 12:15:11"
}

Core Events

topic: core

Loaded

Fired when core is prepared. Useful for hooks. Data will be Null.

{
    "event": "Loaded",
    "data": None
}

Starting

Fired when core is starting. Useful for hooks. Data will be Null.

{
    "event": "Starting",
    "data": None
}

Started

Fired after core is started. Useful for hooks. Data will be Null.

{
    "event": "Started",
    "data": None
}

Stopping

Fired when core is stopping. Useful for hooks. Data will be Null.

{
    "event": "Stopping",
    "data": None
}

Stopped

Fired when core is stopped. Useful for hooks. Data will be Null.

{
    "event": "Stopped",
    "data": None
}

Shutting Down

Fired when core is shutting down. Useful for hooks. Data will be Null.

{
    "event": "ShuttingDown",
    "data": None
}

Shutdown

Fired just before core is fully shutdown. Useful for hooks. Data will be Null.

{
    "event": "Shutdown",
    "data": None
}

Action Called

Fired when an action is called. Data will be an object of all your action data.

{
    "event": "ActionCall",
    "data": {...},
    "action": 'example_1.action',
    "namespace": None
}

Action Registered

Fired when an action is registered to the core. Data will be an object of all your action data.

{
    "event": "ActionRegistered",
    "action": 'example_1.action',
    "namespace": None
}

Component Registered

Fired when a component is registered to the core. Data will be an object of all your component data.

{
    "event": "ComponentRegistered",
    "component": 'component_key',
    "namespace": None
}

Extension Registered

Fired when a extension is registered to the core. Data will be an object of your extension namespace.

{
    "event": "ExtensionRegistered",
    "namespace": 'extension_namespace'
}

Extension Events

Extensions also work on the event system. The rule for extensions is that they must only emit events on a topic the same as their namespace. They are allowed to subscribe to any topic though. Extensions often emit events when their components are updated or some change has taken place i.e. a toggle turned on.

Extension Events

topic: Based on value set for "namespace" option in extension configuration

Below is an example of an event that is emit by the toggle extension.

Example Toggle Event

{
    "event": "ToggleUpdated",
    "component_id": "example_toggle_1",
    "state": {...},
    "invert_state": False,
    "updated_at": "2021-03-13 12:15:11"
}

Using Multiple Event Systems

MudPi supports multiple event systems to broadcast events on. Since you could possibly enable multiple systems at once there is going to be duplicate events listened for. For example if you have both redis and mqtt configured MudPi will send and listen for events on both. This means now each listener is getting the same message once on each bus. To prevent duplicate events across channels MudPi will insert a uuid on all events it broadcasts. You can provide one manually but this is taken care of for you.

Most extensions that interact with events are encouraged to cache the previous event handled and check that that same event is not being handled again just from a different bus. Only the last event is cached so if another event get handled in between it is likely a duplicate event could still occur. However, because these events are sent microseconds between one another when they do occur its highly unlikely another event will squeeze in between during this time.