MQTT Shims plugin Release 2023.0.2

User avatar
FlyingDiver
Posts: 7830
Joined: Sat Jun 07, 2014 10:36 am
Location: Southwest Florida, USA

MQTT Shims plugin Release 2023.0.2

Post by FlyingDiver »

In the plugin store. Additional value sensor subtypes were added in pre-release 2022.1.1 which I forgot to release. Oops.

New feature: You can now write a custom Decoder that will be run for a device, to parse out complicated or encoded payloads and create additional custom states. There's an example Decoder included with the plugin that expands nested dicts in a JSON payload. Instructions in the next post.

The plugin now copies Decoders and Templates to subfolders of Python3-includes. This is now the only place these files are searched for. Plugin config dialog has been updated to remove the option to set the Templates folder. Users of the Template feature will need to move their existing templates to the new folder. This was done to make sure these files persist between Indigo updates.
joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177
User avatar
FlyingDiver
Posts: 7830
Joined: Sat Jun 07, 2014 10:36 am
Location: Southwest Florida, USA

How to use a Decoder

Post by FlyingDiver »

After installing the 2023.0.2 release (or later, in the Python3-includes folder, there is a sub-folder named "MQTT Shims Decoders". Make a copy of the "Expand.py" file with an appropriate name.

Edit that file, and change the class name to the same as the file name. See comments in file.

Edit the code per your requirements. The input is the entire payload. The output is a dict with one or more key/value pairs. Make sure the key names don't conflict with any existing states.

Edit (or create new) the Shim device definition to specify the decoder you just wrote.

Here's the code for the example Decoder:

Code: Select all

class Expand(object):
    def __init__(self, name):
        self.name = name

    def recurse(self, payload, new_states, prefix):
        for key in payload:
            if type(payload[key]) is dict:
                self.recurse(payload[key], new_states, f"{prefix}_{key}")
            else:
                new_states[f"{prefix}_{key}"] = payload[key]

    def decode(self, payload):

        if type(payload) is not dict:
            return payload

        new_states = {}
        for key in payload:
            if type(payload[key]) is dict:
                self.recurse(payload[key], new_states, key)

        if len(new_states):
            return new_states
        else:
            return None
The only required function is decode(), which is called by the Shims plugin after loading this class file.

The self.name isn't used in the Decoder, it's used by the Shims plugin for debugging.

The code just loops through the payload dict, and everywhere it finds a dict, it recurses on it to create new states (key names and values). Those are returned to the plugin and converted to custom states for the device.
joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177
Post Reply

Return to “MQTT”