UPB lighting

Update here…

The pull request to put the lights into hass should be approved today. Since pull requests are to be broken up, scenes are next up.

There is a breaking change for lights (perhaps more than one, I can remember one). That is update_status is removed. It is replaced with homeassistant.update_entity.

There will be breaking changes for scenes. upb.activate is removed in favour of scene.activate. The second breaking change, so far, is that event will no longer be used. They are not allowed by integrations any longer. Events will be replaced with device_triggers – which I know nothing about yet. All that said, scenes may get done first and then a subsequent change will contain the device_trigger work.

Right now, lights should make the 0.110 release. Scenes should too. I’m hoping to figure out triggers to get them done too, just a warning they may miss the 0.110 cut.

This is much more work than I hoped for! However, through some excellent help by @bdraco he has helped me through this. I already said it to him on the pull request thread, but let me say where more will see it: Thank you Nick! I really appreciate the help. Gold standard on collaboration!

2 Likes

Thank you for the update. The changes all seem reasonable to me.

Ditto. I look forward to learning more about it because detecting when a link is activated/deactivated is important to my automations.

That’s an interesting development. Integrations like zigbee and zwave generate all kinds of events so I imagine those integrations will eventually be overhauled? Talk about a breaking change!

YiKES. Okay, it sounds like we should stick with the custom_component for a bit then? I can’t say I’ve ever heard about device_trigger. Doesn’t ring a bell.

1 Like

Both the light and the scene UPB integrations merged into the dev branch. They are scheduled to show up in 0.110.

I’m working the the trigger code now. If anyone can share wisdom, my supply is low at the moment :open_mouth:

I suspected a device_trigger is part of Device Automations and the Developer Docs appear to confirm that.

I believe this mean the only way to detect link activation/deactivation will be via a Device Automation. They’re designed to be created via the UI, not via YAML. If anyone has ever looked at the YAML version of a Device Automation’s trigger they’ll understand what I mean. Getting the device’s identifier value would mean exploring core.device_registry.

The Developer Docs surprised me when it used ZHA and Deconz as examples. I believe they also support events. So the new directive is effectively grandfathering events in existing integrations in favor of device_triggers for all new integrations. Is that your impression as well?

Finally got around to playing around with this a bit more, been super busy with work in general so I’ve had limited time to look into this. I have a tool I started writing called upbshark which is a decoder proxy that sites between upstart and ser2net attached to a PIM.

The idea is that it can be used to do logic traces for upstart and any other UPB compatible software to verify the command/decoder logic is correct before actually building out a library that is capable of handling pulse mode properly.

Take a look: https://github.com/jameshilliard/upbshark

So apparently pcs open sourced upstart or at least part of upstart here. At first glance this code is not at all easy to read, especially due to the widespread use of magic constants throughout the codebase, the premise source is much cleaner IMO but this may fill in some missing feature gaps for things that premise doesn’t implement.

I’ve made a number of updates to my upbshark utility, I think for the most part I’ve got pulse mode decoding figured out(I still need to finish building out some parsers for all the features but they generally seem to follow the same pattern), I’m currently reading out buffered data from pulse mode for commands generated by upstart such as MDID_CORE_COMMAND_GETREGISTERVALUES. Next I’ll probably work on writing a parser for the register maps but that should be relatively straight forward.

1 Like

Latest update: not using device triggers. Using events again. However, events are not allowed from entities, so event cannot have entity_id in it. Don’t ask me why, cause every time I try to understand I get shut down. You can see the discussion that happened on this topic on Sunday afternoon on the Discord chat server in the #dev channel.

So, if I understand, and that’s a big if, I will be generating events from the integration level. Event type is something such as upb.link_changed (name not final yet) and the contents being:

  • Type of change (e.g.: activated, goto, etc.)
  • Address of link in the form <upb_network_number>_<upb_link_number> (e.g.: 42_6 for link 6 on network 42)
  • Brightness, -1 if default or does not apply
  • Rate, -1 if default or does not apply

I plan to submit the PR tonight.

I also plan to open an architectural issue around creating events out of entities.

1 Like

Its not very complicated; an entity belong in hass state machine and should focus on describing one thing. An event is stateless and thus doesn’t belong in the state machine and is only relevant in the moment. A device can be a combination of entities and events. This is also why device triggers exist, to combine entities and events when writing automations. Which is nice, device automations really improves the simplicity in creating automations, when you want it.

If I create a Device Automation, the device_trigger contains a device_id. This is a unique identifier assigned to the device at the time the integration created it.

If I uninstall the integration and then re-install it, the device will be assigned a new unique device_id.

That means the Device Automation I created will have an invalid device_trigger because its device_id is still the original one, not the new one. Is what I’ve described correct?

In contrast, an automation using an event trigger isn’t so tightly integrated with its device. So if a device_id changes it makes no difference to the event trigger. It’s only affected if the actual event name changes.

1 Like

Both statements are correct

Hmm, I wonder how this would work if we have home-assistant fully manage the UPB device configuration like premise does, in premise how do you set a uniquely identify UPB devices?

Thank you. I was kind of sorry to hear I got that right because there’s no simple way of fixing the broken device automation.

Sure, you only have to replace its device_id with the newest value but getting that value is (currently) not a straightforward process (and to be fair, it was never meant to be handled manually). You find it in core.device_registry or make a new device automation, examine it in YAML form, copy the new device_id, then paste it in the broken device automation.

It can be improved. There was no plan for device automations when I wrote the device registry. A lot has happened since then

Good question and the short answer is the device driver assigns each device a sequential “USQ” number (USQ, USQ1, USQ2, USQ3, etc).

If I add a new device with UPStart, the UPB driver discovers it and assigns it the next available number. That typically means the next highest number (USQ4, USQ5, etc).

If I use UPStart to remove a device, the UPB driver also removes it, leaving a gap in the USQ sequence. The next device I add will be assigned that ‘gap value’.

I imagine that, under the hood, whenever the driver performs a discovery, it compares the discovered device to what it already has on record (my guess is by creating a hash key using a combination of device attributes) to ensure that it doesn’t create a duplicate.


BTW, if the naming sequence sounds simplistic it’s because there’s an important architectural difference between Premise and Home Assistant.

Premise has an additional abstraction layer where you define virtual objects, representing lights, appliances, media_players, etc. The automation logic works with these virtual objects. These virtual objects have names, properties, etc but have no association with real-world devices. It’s a virtual model of your home’s devices but with no connection to physical devices. That’s a separate step.

When you install a driver, like the UPB driver, it creates device objects representing real-world devices like UPB light switches. You then ‘soft-link’ or, in Premise parlance, bind a virtual light object to a UPB device object.

If you remove one device object or even the entire driver, you simply break the bindings between itself and the bound virtual objects. All your virtual objects retain their names and properties and no automations are invalidated.

That’s why the name assigned to device objects can be so simplistic.


I added this diagram from Premise to highlight the separation between virtual and device objects.

Screenshot from 2020-05-11 18-56-03

Hardware ports are on the left, device objects are in the center, and virtual objects are on the right.

  • I have a UPB PIM connected to COM5 and its very first device object, designated USQ, is bound to the virtual object named FoyerLight.

  • Similarly, I have an ELK M1_Panel connected to a network port and it has a Zone device object called Doorbell that is bound to a virtual object with the same name.

If I no longer wished to use the M1_Panel to detect the doorbell, and use some other means, I would un-bind the virtual Doorbell from the M1_Panel and re-bind it to the new device object (whatever that might be). Any automations involving the virtual Doorbell continue to work without modification.

Thank you for replying @Robban. It has been quite frustrating over the last couple of day trying to understand so many changes that are happening so fast. I appreciate your contributions, here and in general!

What we are trying to accomplish is that the UPB equivalent of a HASS Scene, called UPB Links, generates events such as activated, fade_start, etc. These events are associated with a specific UPB Link. The idea of the events is to trigger an automation when one of these async events is received. Associating the events with the entity seems to make the most sense, since the entity directly maps to a UPB link and the event is from the UPB link.

Since events are not allowed to be generated from an entity I’ve put the event generation code on the at the integration level and include the id of the UPB link in the event (i.e.: no entity_id).

@123 does all that sound right? (I tend to lean towards developer perspective while @123 is great at making user requirements clear).

Sounds right to me.

I had hoped to find another integration to serve as a comparison. I thought Insteon would be suitable but apparently not. It has commands to turn scenes on and off (UPB link activate and deactivate) but not events to report when a scene is turned on or off.

Instean has events and they are used to report when a button is pressed. In UPB, pressing a button can generate a link so an event would be a suitable model for that. However, a link isn’t limited to being generated by a button-press so it would not be accurate to say it’s always the product of a physical action.

Associating the events with the entity seems to make the most sense, since the entity directly maps to a UPB link and the event is from the UPB link.

That doesn’t sound right to me, an entity would represent a specific switch or other UPB device right? So if I’m understanding how this all works correctly a link event triggers a state change in multiple entities and can also come from multiple entities.

Thats the way to do it :+1:, I’d still look into adding to the device registry and build device triggers for this

1 Like