How to Determine if mqtt.homeassistant Thing is Online or Offline as an Item?

Running:

  • Openhab 5.0.1, installed with openHabian v1.10.5

  • Raspberry PI 5, Model B, Rev 1.0

Openhab mqtt.homeassistant discovery works very well, except for the little challenge last week when Things went to Unknown state, which was solved by @ccutrer (Thanks again). My current challenge is that I cannot determine how to have an Item that reflects the Online/Offline state of the Thing that mqtt.homeassistant creates.

In those cases where I manually create mqtt Things (Bridge = MQTT Broker, Thing Type = Generic MQTT Thing), the Thing configuration (Show Advanced) would include the Availability topic (typically the device’s Last Will and Testament (LWT) mqtt topic) and the Device’s Availability and Unavailability Payloads. I would then create a channel for each data item that I wanted to use in Openhab as well as a channel for the device’s availability or LWT topic. Thereafter Items would be created and linked to each of the channels including the LWT channel. I could then use this item (LWT) to indicate its status.

How do I accomplish the same with Things created with the mqtt.homeassistant binding? (Other than manually creating an mqtt Thing for just the LWT topic)

After much searching, including this forum, I have not been able to find something that would help me solve this issue.

You can create rules that trigger on the thing status. For DSL rules it’s documented at Textual Rules | openHAB. UI based rules can be similarly set up. If you want to display the current status in a UI you could make an item that you update in a rule.

If it’s just this one thing you’re interested in then you can add a thing event directly in the GUI.

Maybe check the (deprecated) rule template from @rlkoshak here: template offline things. You can still use it or use a similar trigger in your code tab of your rule.

Not deprecated. Still working and actively maintained. though I’m going through some edits to deal with the new wrapper and event Object coming in OH 5.1 so that the templates remain backwards comparable.

Note that rule template will trigger on all ThingStatusEvents.

But you’ll need to create some sort of mapping between the Thing UID and the status Item. I use the following rule coupled with the rule tempalte.

configuration: {}
triggers: []
conditions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/javascript
      script: >
        console.debug('Processing a Thing status change ' + ruleUID);

        const key = ruleUID+'_thingToItem';


        if(!cache.shared.exists(key)) {
          console.info('Creating Thing to Status Item map');
          cache.shared.put(key, { 'zwave:serial_zstick:zw_controller'      : 'Zwave_Status',
                                  'zigbee:coordinator_ember:zg_coordinator': 'Zigbee_Status',
                                  'ipcamera:generic:garage_camera'         : 'GarageCamera_Raw',
                                  'mqtt:topic:broker:family'               : 'FamilyRoomWaveplus_Status',
                                  'mqtt:topic:broker:basement_waveplus'    : 'BasementAirthingsWavePlus_Status'
                                });
        }


        const rval = cache.shared.get(key)[thingID] !== undefined;


        console.debug('Run the actions? ' + rval);


        return rval;
    type: script.ScriptCondition
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: >
        console.debug('Thing process change running...');

        console.debug('Thing ' + thingID + ' changed from ' + oldStatus + ' (' +
        oldDetail + ') to ' 
                      + newStatus + '(' + newDetail + ')');

        const itemName = cache.shared.get(ruleUID+'_thingToItem')[thingID];

        const newState = (newStatus == 'ONLINE') ? 'ON' : 'OFF';


        console.debug(cache.shared.get(ruleUID+'_thingToItem'));

        console.debug('Thing status update: ' + itemName + ' ' + newState);

        items[itemName].postUpdate(newState);
    type: script.ScriptAction

In the condition I create a mapping between the Thing ID and the status Item and only proceed if the event comes from one of the Things I care about.

It is possible to be a bit more clever about this but I only had a few that I cared about so this approach was sufficient for me.

@KUnger, if you used this approach you might consider matching on all the Things with “homeassistant” in the UI and possibly use some other mapping approach which is a bit more flexible (Item names, tags, metadata, querying the ItemChannelLinkRegistry, etc).

As per @ccutrer’s advice, here’s a JRuby example script that would create the tracker items for you and keep them up to date against the Thing’s status:

ha_things = things.select { |thing| thing.uid.to_s.start_with?("mqtt:homeassistant:") }

def tracker_id(thing)
  thing.uid.id.gsub(/[^a-zA-Z_]+/, "")
end

items.build do
  ha_things.each do |thing|
    id = tracker_id(thing)
    switch_item "HA_Status_#{id}", "#{thing.label} Status", state: thing.online?
  end
end

rule "Dynamically add new tracker items for newly created Things" do
  thing_added "mqtt:homeassistant:*"
  run do |event|
    id = tracker_id(event.thing)
    items.build do
      switch_item "HA_Status_#{id}", "#{event.thing.label} Status", state: event.thing.online?
    end
  end
end

rule "Keep track of HA Thing Status" do
  changed "mqtt:homeassistant:*"
  run do |event|
    id = tracker_id(event.thing)
    items["HA_Status_#{id}"]&.update(event.thing.online?)
  end
end

it was from the first sentence of your template description.

https://community.openhab.org/t/thing-status-reporting-4-0-0-0-5-9-9-9/143180

Thank you for your responses and apologies for the lack of mine. Had an unexpected road trip, will be back later today.
I can see that there is a rule based solution to determining the status of a Thing. I will take a look at them when I get home.
In the case of mqtt messages the LWT topic is used to determine the status of a Thing. I’m wondering why the mqtt.homeassistant binding doesn’t provide a way of directly linking an item to that topic? Just wondering if I’m missing something regarding mqtt messaging.

Oh,I forgot we cna do wild card Thing triggers now. Indeed, the template is not really needed any more since we can do wild card subscriptions.

However, UI users will need to manually edit the Thing ID with wild cards on the code tab. I don’t see a way to do a wild card subscription from the UI itself.

I can’t say why, but that LWT message is used to control the ONLINE/OFFLINE status of the Thing. And the status of the Thing is the more standard way to monitor and report the online status for all the other bindings. For example, there’s no status Channel for Things in the Zwave, Zigbee, nor Matter bindings.

But you could create a Generic MQTT Thing and subscribed to any topic and link it to any Item if that’s really the way you want to to do it. But having this status in a Channel that can be linked to an Item is kind of unique to MQTT and it doesn’t surprise me that the autodiscovered Things are made to work more like all the other Things.