OH3 - MQTT - Subscribe to an array/upper topic

Hello people,

I contact you because I’ve an issue to subscribe on an “array” of a MQTT item, or I should say to browse the topics under the root topic.
I try to do this to create an item with the list of all entries coresponding to the sub topics and display it with a repeater component.

Current MQTT organisation

  • Topic: ESP/xx/users = no message
  • Sub topic:
    • ESP/xx/users/a = {…}
    • ESP/xx/users/b = {…}

Any idea on how to proceed?

Thanks in advance and take care :wink:

Guillain

If you want to show anything on the UI, you must get it into Item(s).

There are no ‘array’ like Item types.
You can have a number of related individual Items, though this doesn’t work very well if you don’t know how many to expect.
Or you can encode a set of related information into a single String type Item, comma separated text perhaps.
A custom UI widget could I think recover from that, and create a visible “list”.

On the MQTT side, you can subscribe with wildcard # in the topic.
You have the limitation that you can only direct the message to a single Item, which would normally overwrite the old Item state with new as each different topic arrives.
One way to work round that might be to have the MQTT channel issue a command instead of the usual state update. Then a rule can intercept the command and “append” it to Item state.
Without more detail, you’ll have to think about how you will clear or manage this list so that it doesn’t keep growing.

An alternative without using channels is to subscribe (with wildcards) directly on the broker bridge Thing, so you get events instead of Item updates. Again, a rule can manage building a list from incoming events.

Thanks @rossko57 for your reply.

I think I’ll try the second approch and enrich a list (I should be able to identify the “start of the sync” so the list initialization should be ok) as I already have some assets running on a node-red for some post-treatment.

Thanks again and enjoy :slight_smile:

Hi @rossko57, hello all

I’ve migrated all my NodeRED workflows on OH3 rules (easy way to automate the deployment and the provisioning: GitHub - guillain/Domo: Domotic solution that include all requirements (instead the hardware :) to deploy and use it rapidly!) but I’m facing an issue with your proposition.

In fact even if I saw all incoming events on the listenning item/queue where I should grab the entries to concatenate that in one list, it’s like the item update doesn’t raised the rule for all of them but only the last one., making the concatenation ko.

This should not come from the msg QoS (the msg are really delivered).
So I can only presumed it’s due to speed (but I don’t like to think like this ^^), any other idea?

FYI, with the code bellow (lovely Python :slight_smile: you don’t need to take care of the start of sync to flush the list, instead for deletion cmd:


            data = json.loads(str(ir.getItem("my_item")))

            uid = str(data['uid'])
            usr = {
              "uid": uid,
              "username": str(data['user']),
              "acctype": str(data['acctype']),
              "validuntil": str(data['validuntil']),
              "time": int(event_time)
            }
            
            usrs = json.loads(str(ir.getItem("14_Entry_Users").state))
            usrs[uid] = usr
            
            actions.get("mqtt", "mqtt:broker:Domo").publishMQTT("ESP/xx/users", json.dumps(usrs))
            actions.get("mqtt", "mqtt:broker:Domo").publishMQTT("ESP/xx/users/{}".format(uid), json.dumps(usr))

Thanks in advance for your support!

Take care & Enjoy :slight_smile:
Guillain

It’s working.
My issue was to grab the item state with the ir.getItem fct, now I’m using directly itemState and it’s ok.

        import json

        import time

        event_time = int(time.time())

        data = json.loads(str(event.itemState))

        uid = str(data['uid'])
        usr = {
              "uid": uid,
              "username": str(data['user']),
              "acctype": str(data['acctype']),
              "validuntil": str(data['validuntil']),
              "time": int(event_time)
        }
            
        usrs = json.loads(str(ir.getItem("14_Entry_Users").state))
        usrs[uid] = usr
            
        actions.get("mqtt", "mqtt:broker:Domo").publishMQTT("ESP/xx/users", json.dumps(usrs))
        actions.get("mqtt", "mqtt:broker:Domo").publishMQTT("ESP/xx/users/{}".format(uid), json.dumps(usr))

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.