Suggestion for Openhab 4.3 Home Assistant MQTT scene's in single channel

I’ve just tested the new Mqtt Homeassistant scene channels in OpenHab 4.3 with zigbee2mqtt and I have suggestions on how this could be improved.

Currently the binding creates a separate channel for every scene like this:


When I link an item to this channel the item gets the following state options:
image
To call a scene from a rule I have to set it like this:

ST_ZIGBEE_Group_Kitchen_Scene0.sendCommand("{ \"scene_recall\": 0 }")

Or like this:

ST_ZIGBEE_Group_Kitchen_Scene0.sendCommand(ST_ZIGBEE_Group_Kitchen_Scene0.getStateDescription().getOptions().get(0).getValue())

Here are my suggestions on how this could be improved:

  1. Ability to call the scene by it’s name instead of the “scene_recall” text like this:
ST_ZIGBEE_Group_Kitchen_Scene0.sendCommand("DefaultWhite")
  1. Create a single channel for all the lamp scene’s with multiple possible state an command options, so I only have to create a single item for all scene’s with all the possible scene values.

For a comparison this is how zigbee2mqtt scene’s look in Home Assistant:
image

Would something like this be possible to implement in OpenHab?

Typically the state description is not something that is used in rules. But I think you can get to where you want to through a transformation profile and the Map transformation.

Your map transformation would map between the scene_recall stuff to the name you want to use and back (i.e. two entries, one for { "scene_recall": 0 }=DefaultWhite and the opposite DefaultWhite={ "scene_recall": 0 }.
You’d link the Channel to a String Item (which I think is already the case) and on the link set a transform and choose map and this transformation from the list (if managed) or enter the .map file for both the channel to Item and Item to channel directions.

Then the scene_recall stuff will be mapped to the friendly name that you want to use.

You could also use the transform action in a rule with the map transformation to convert the scene_recall to a friendly name and vise versa.

Thanks for the hint. I know that this will be possible using transformations, but my suggestion would be that this mapping happens automatically. This way it would also handle new scenes that will be added later without changing anything in the transformation.

To my knowlege this would just work if the “label” of the state and command description would be set to the scene name instead of the value that has to be sent to zigbee2mqtt.

Also using a single item for the scene’s per lamp instead of one item per scene would be much simpler and would “just work” if a new scene is added later on.

Actually it wouldn’t “just work” because the stateDescription options and command options are only pushed to the Item at link time (i.e. when you link the Item to the Channel). If things change later on the HA side, those changes wont get pushed to the Item unless you manually remove the link and add it back again.

Ok, but as far as I’ve seen it would be there after an Openhab restart or just by restarting the binding. Or at least it’s what I’ve seen with the wled addon.

I think that would only work under the following circumstances:

  1. you haven’t manually added any stateDescription metadata to the Item
  2. you are using .items files

If you add your own stateDescription metadata that takes precidence over the metadata pushed from the binding.

When you are using .items files, every time the file is loaded the Item is created anew and therefore the links are recreated anew. For managed Items, that’s not the case. Even restarting OH won’t recreate the Links. The Links continue to exist even through the restart.

I’ve just tested this in OpenHab 4.3 with an item in .items file and one from the json database.

To test this I just checked the current state configuration of both items using the api explorer. Then I changed the value “{ "scene_recall": 1 }” to “{ "scene_recall": 99 }” directly with MQTT Explorer and checked both items again and they now had the new value:
image

This all happend even without an OpenHab restart or restarting the binding. After restarting zigbee2mqtt the state configuration also again automatically reverted back to “{ "scene_recall": 1 }”.

@ccutrer @Lolodomo Could you maybe take a look at my suggestion? (See first message)

Would somethink like this be possible and make sense for the MQTT HomeAssistant scenes?

It’s an interesting suggestion, and not without precedent. You are correct that state (and also in this case, command) descriptions get “pushed” to items from the binding. That’s because it’s not actually setting the state/command description on the item, but instead core asks all state description providers (one of which is a metadata based provider, which is what @rlkoshak is thinking of, and another of which is one from the MQTT binding), and aggregates them. I can’t remember for sure, but I believe they also have priorities so that the metadata based provider will overwrite anything the binding is suggesting. (There is also a generic provider for file-based items, that parses the "[%s]" for example as a state pattern from the item name.)

So, the precedent: the device_trigger component type maps to an openHAB trigger channel, and it will provide a single value per component. This component typically represents a button on the device a person presses, and then notifies the automation hub so that some action can be taken. The binding takes multiple device_automation components and aggregates them by “button” into a single channel, so that for example you would have a “button 1” channel, and on it you would get events button_short_press, button_double_press, button_triple_press, etc. Not all device_automations aggregate into a single channel - they’re still broken up to have one channel per button (subtype, in Home Assistant parlance).

And now, two corollaries:

  • Home Assistant actually has a lot of places that MQTT discovery allows mapping specific strings as states or commands, instead of the well-known string. For example, on a switch, payload_on defaults to ON, and payload_off defaults to OFF (mapping perfectly to openHAB!). For switch, this isn’t a problem because the MQTT binding doesn’t present a String channel, but instead a Switch channel, and internally does the transformation for you. (This is further complicated with command and state/value templates, allowing very complex transformations). But for other component types, the MQTT binding presents a more advanced string channel, with the mapped payload and/or state values being passed through to the item (but NOT the template, which is still processed internally by the binding). For example, the cover component presents both a Rollershutter channel (which can accept aPercentType value, or UP/DOWN/STOP commands - the former going to a set_position_topic for commands, and the latter going to the main command_topic (which might be the same topic, depending on the device)). But the state topic might also have “opening”, “closing”, or “stopped” values (in addition to “open” or “closed”). So the MQTT binding presents a String state channel, and if the discovery JSON maps any of these values to a different string, those strings are used instead. Should the binding instead always present open, opening, closed, closing, stopped values (and OPEN, CLOSE, STOP commands), so the user doesn’t have to know or care about device specifics? Seems reasonable, but was not done initially both because the internal MQTT binding structure (mqtt.homeassistant on top of mqtt.generic, and a single transformation that could be used, and was already used for the command template, if provided), and because the UI should generally show up decently as is, because we have the state descriptions. It’s just difficult to use from rules. Note that for scene, the payload_on value defaults to ON.
  • There are other components that only have one possible action you could take on them. button being the one that comes to mind (with a default payload_press of PRESS). Should they also be aggregated into a single String button channel, presenting a command description with all possible buttons for that device?

So we’re discussing two changes here. DON’T expose the internal device mapping for default values in general. And aggregating single-action components into a single channel (per component). I’m pretty sure the former is a requirement for the latter (since otherwise you could have two scenes, with different command topics, but the same payload_on, which it would be impossible to tell which topic to send a command to). But then what values do you use for that channel to tell which component it’s sent to? Your example makes it clear we don’t want to use the payload_on. But perhaps the object_id (which is either the second-to-final component in the topic of a node-nested component, like homeassistant/scene/device1/DefaultWhite/config, or can be explicitly specified in the JSON)?

Btw, can you post the full discovery JSON for your components? It would be helpful for me to build more context.

Do you mean the JSON values from the homeassitant MQTT topic? I’ve already sent you the whole config in this GitHub issue: [mqtt.homeassistant] Fix components with an empty name by ccutrer · Pull Request #17933 · openhab/openhab-addons · GitHub

Regarding the scene topics. The command topic for the lamp scenes is always the same in zigbe2mqtt, just the name, object_id, payload_on and unique_id are different. Here is a diff of the scene_0 and scene_1 topic of one of my lamps:

Maybe the solution would be to group scenes that have the same command topic into one channel?

@ccutrer I just noticed another problem with the scene channels. For some reason the channel names change somtimes when OpenHab is running for a longer time.

For example the channel name
mqtt:homeassistant:4ce1d806:zigbee2mqtt_5F0x001788010cbcbeb6:scene_0
got renamed to
mqtt:homeassistant:4ce1d806:zigbee2mqtt_5F0x001788010cbcbeb6:scene_0_scene

After this the scene commands do not work anymore because the items are not linked to the channel anymore. I noticed this 3 times already. After an OpenHab restart the channel name is back to :scene_0. Do you have an idea what could cause this problem?

Also have you seen my last post?

The problem you’re seeing is known: Problem with new MQTT/Home Assistent channel naming - #3 by Elsing. I’m almost certain you can just disable and re-enable the thing to fix it, instead of restarting all of openHAB. Unfortunately I have had very little time for openHAB since the holidays. I really can’t commit to any specific timing in the short term future.