UPB lighting

@gwww awesome. I would say if its not possible to rename in hass, then allow some naming scheme. Right now I’m using light.upb_* . I’m also parsing the upe file and find/replacing - with _ when converting the names to entities.

Also brightness, blinking, and link support if you don’t already have it.

I don’t recall how I made links work. I think it was something like switch.upb_link_<id> or something.

I might try spinning up yours at some point in a test environment.

I saw some discussion about polling. I’m not sure what good it is. I haven’t done it and have had no issues.

Thanks for doing this. I’ve been wanting a python UPB integration for years.

I was looking at how other lighting integrations support the concept of links/scenes/groups. I examined the Lutron and Lutron Caseta inegrations and they define it as a scene:

However, I may be mistaken about this, I only see a means of activating a scene whereas a UPB link can be activated/deactivated. Therefore it may make more sense to follow bbrendon’s approach and model links as switches. The only caveat being that, as I understand it, links are stateless; UPB doesn’t keep track of a link’s state. Deactivating a link is just “undoing” whatever activating a link does.

My US2-40 universal dimmers have four buttons and each one can activate/deactivate a scene. However, they are not really “switches” in the classic sense; they’re just pushbuttons like on a remote-control (momentary booleans, if you will).

I dug around in my mess. I hacked links into HASS as events. I guess I wasn’t trying to make it user friendly. Oops. :slight_smile:

What I did was if I wanted to use a link outside of UPB and in HASS I made it trigger an event in HASS like event: upb_link_99. I see in my code I have something where I attempted to make upb links switches but maybe it didn’t work because links aren’t on/off. They are activate/deactivate. I’m pretty sure in my setup I never deactivate links, I only activate them.

I have a Morning scene (UPB link) that is activated early in the morning but only if the ambient light level is low (like at this time of the year, when the days are short). Various lights leading from the bedroom to the kitchen are turned on to a low level of brightness. Later in the morning, when the ambient light level increases, the Morning scene (link) is deactivated (the lights turn off).

I believe the way to model a UPB link in Home Assistant is to use a scene. The scene itself is stateless (there’s a scene.turn_on but no scene.turn_off). To model a UPB link, one scene would be “Link 01 Activate” another would be “Link 01 Deactivate”.

The reason I did not use Scene in HASS is because a UPB Scene is different. The similarity is that a UPB Scene (Link) can be activated and deactivated. What HASS Scene does not have is the ability to set a scene to a specific dim level, such as what you can do with a light. So, right or wrong that’s what I chose – for now. I’m not anchored to any one way to do it, I’m looking for the best way so suggestions gladly accepted.

For similar reasons I did not use switch. It does not has the concept of dimming.

PS: not sure if you are aware, a UPB Link can set all lights to a specific dim level in addition to setting them to the dim level defined by the link.

1 Like

Yes, but there’s still justification for modeling them as scenes.

Your point is that both Link Packet and Direct Packet can use the same commands so a scene falls short of supporting the full range of available commands.

From page 26 of UPB Technology Description:

Controlling Linked Device Components

The UPB Device Control Command Set (refer to the section entitled “The Device Control Command Set”) contains many commands that can be used to control both individual devices as well as “linked” Device Components. There are commands to request that the receiving device(s) go to specified states or levels at specified rates. There are also commands that request the receiving device(s) to start and stop fading, start blinking, store their current states, etc. Whenever these commands are packaged in a Direct Packet they will affect only an individual device. Whenever these commands are packaged in a Link Packet they will affect all of the “linked” Device Components associated with that Link ID. A single Link Packet command can therefore request a set of “linked” lighting channels on separate devices to start fading to 100% at a specified fade rate. Then, with another Link Packet command they can be requested to stop fading.

One could argue that a group of linked devices effectively operate like a single “virtual device”. You can command this virtual device to Goto level 50 and all linked devices will change their state to level 50. Therefore you could model it as a light in Home Assistant.

So let’s say we have an entity called light.link_03. If you change its brightness, that will correspond to sending a Link Packet for link 3 with a Goto command. Similarly, if you set its transition, it would correspond to a Link Packet with a FadeRate command. So far, the model works.

Where the model falls short is its lack of supporting Activate/Deactivate. If I turn on light.link_03, it corresponds to sending a Link Packet with a Goto level 100. That will turn on all linked devices and that’s not what Activate would do. Activate tells a linked device to assume its programmed state for link 3. Home Assistant’s scene handles that neatly.

To summarize, to model all of a link’s capabilities, it could be done using both a scene and a light.

light.link_03
scene.link_03

Or the integration could use the link’s (UPB scene’s) friendly name:

light.morning_scene
scene.morning_scene

If I want to run Morning Scene (i.e. make all linked devices set themselves to their pre-programmed state) then I just turn on the scene:

  action:
  - service: scene.turn_on
    entity_id: light.morning_scene

On the other hand, if I want to control all linked devices in Morning Scene, let’s say to set them all to 50%, then I would turn on the light:

  action:
  - service: light.turn_on
    entity_id: light.morning_scene
    brightness_pct: 50

That covers the full range of what Link Packet supports.

Bottom line, I don’t what the right answer is, yet.

UPB Links are like nothing else I’ve seen modelled in hass. You’re right, they are kind of like a virtual device and in many ways that is true. The big thing that links don’t have is state, such as on or off. This is important for a hass light as a light can’t be turned off that is not turned on. A virtual “on” state could be created but that doesn’t work well either.

For example say link1 is activated and it is marked as turned “on”. Then another link, link2, is activated that, say, turns off all the lights in the link1 activate. First, link1 would show as on. Second, link2 would show as on, even though the activation of link2 turns off all the lights.

Modelling a link as both a light and a scene doesn’t buy much, since a hass scene only offers activate.

Modelling a link as a “virtual device”, i.e.: a hass light makes the most sense so far. However that has problems. Since a link doesn’t have state (i.e…: on or off) there’s no way of turning a link off, since it is never turned “on”.

See the library code here: https://github.com/gwww/upb-lib/blob/77a6954ffbababfb6e53ec40a2cfa533593bfa27/upb_lib/links.py#L42-L54.

No matter which way this goes, there’s more work to do. And no easy perfect solution for links. Perhaps a question to the integrations forum to see what others have to say.

I suggest asking in the Discord developers channel.

I’m in the middle of typing something up for the dev channel.

Here’s a thought. Don’t model links as a Light. Model links as a Hass Scene. Add services for the missing bits. Thoughts?

I’m in the middle of testing your code. No entities are created in HASS. I’m running as root to avoid permission problems while testing.

upb:
  #url: serial:///dev/cu.KeySerial1:4800
  url: serial:///dev/ttyS1:4800
  file_path: ./upb.upe

2020-01-27 16:03:40 ERROR (MainThread) [homeassistant.components.light] Error while setting up platform upb
Traceback (most recent call last):
  File "/opt/python-venvs/hass/lib/python3.7/site-packages/homeassistant/helpers/entity_platform.py", line 158, in _async_setup_
platform
    await asyncio.wait_for(asyncio.shield(task), SLOW_SETUP_MAX_WAIT)
  File "/usr/lib/python3.7/asyncio/tasks.py", line 416, in wait_for
    return fut.result()
  File "/opt/hass-upb/custom_components/upb/light.py", line 27, in async_setup_platform
    async_add_entities(UpbLight(upb.lights[light], upb) for light in upb.lights)
AttributeError: 'UpbPim' object has no attribute 'lights'

I think I like this because a the definition of a scene in HASS and a link in UPB seems more closely related. Let us know how the gods vote :slight_smile:

Nuts, while suggesting to model a link as a light (and a scene), I overlooked the glaringly obvious issue that a light must show state but a link is stateless. Duh. Scratch that idea (and it appears to be the same advice from developers on Discord).

A given link can be represented by two scenes, one to activate it and the other to deactivate it.

A scene can’t support a Link Packet’s ability to send Goto, FadeRate, etc to linked devices. Nevertheless, at least it provides an easy way to activate/deactivate a link (heck, even UPStart refers to them as scenes).

FWIW, this is modeled differently in Premise. Premise supports the concept of a button (think of it as a “momentary input_boolean”). I can make a single-press of a button activate a link and a double-press deactivate it. That’s the same way UPStart allows you to configure the physical buttons of a UPB device. Therefore Premise models it exactly as its done in the real world. Easy-peasy.

On the other hand, Premise does not model a Link Packet’s ability to send other commands. The olive branch it offers is that its UPB driver can accept a raw UPB command:
{nid}{link}{mdid}{data}
and then it appends the required checksum prior to sending it. I don’t know if such a thing would is permissible in Home Assistant. I believe integrations are supposed to maintain their distance from the “bare metal”.

Certainly a bug to fix. However, the cause is that the upb.upe cannot be found. If it can be found then my setup is working well. I push a small change that prints the error to the log (right now its not a log call just a simple print). Here’s the message I get when it can’t find my UPE file:

Cannot open UPStart file './upb.upe': [Errno 2] No such file or directory: './upb.upe'

Where did you put the file? What are you running on? Is it a Raspberry Pi? If so you could try changing the path to /config/upb.upe

One more idea. I run hass when my current directory is in the config directory. I’m pretty sure that you are not doing that. So whatever the path is to your config directory put that in the config.

I can add custom services to a Scene for deactivate, goto, etc. So a scene could do some of those things. The question is, does that make the most sense – to have a Scene with custom services?

The hass Scene sounds similar to a Premise button.

I started hass with : /opt/python-venvs/hass/bin/hass -c /opt/hass-upb
So I’m guessing that means the file should be in /opt/hass-upb ?

Once I put the full path to the file it worked. Maybe ./upb.upe needs to be in quotes? I don’t know.

Thoughts…

  1. Awesome.
  2. Confusion. I was wondering what all these additional lights were. Then I realized they are links. I haven’t looked in upstart in a long time :slight_smile:
  3. The additional information (attributes) on the UPB modules is excellent! Not sure what I’d need it for but I’ve been so crippled, who knows. I’ll probably find a use for it.
  4. The dimmable attribute on each device based on real data is great. Mine just listed everything dimmable no matter what.
  5. The links exposed as lights is weird but it seemed to work. Having links show “on” in the GUI is definitely weird mostly because once the devices associated to the link go on to other states, it still shows on (which makes sense).

The only thing I didn’t like is the default naming of entity IDs. Its not light.upb_*. I’m not sure if upstream HASS allows what I want but maybe you could make it a configuration option? I’m not looking forward to renaming everything manually.

I couldn’t find any bugs. I think I’ll try switching over to it once the link stuff is sorted out.

This is super exciting though. I’ve been wanting this for soooo long.

Thanks for all the work you’ve done on this.

That sounds … unusual. I suspect this might cause balloob to squint.

The hass Scene sounds similar to a Premise button.

Mmm, sort of. Buttons (in Premise) also have button-actions (press, hold, release, etc) whereas a scene is just turn_on.

To be fair, it really shouldn’t ‘show on’ because UPB doesn’t track the state of a link. That’s why modeling it as a light (or even a switch) is problematic. Like you said, the linked devices may go to other states (like all are off) yet the ‘light link’ continues to report on. It even feels weirder when it comes times to activate that scene again. The light link is still reporting its state is on and now you want to turn it on again. Weird.

It needs to be a stateless entity. Something that can be triggered but never reports it has changed state. It’s like “do it” and “undo it”. One scene to activate a link and another to deactivate it.

scene.link_03_activate
scene.link_03_deactivate
  action:
  - service: scene.turn_on
    entity_id: scene.link_03_activate

Added this to the development channel… UPB (Universal Powerline Bus) integration

I’ve intentionally left out as many details as I thought I could to keep the focus on the modelling issue rather than on how UPB works. I tried to keep the UPB details as slim as I could.

Wow, I was gone a few days and this forum thread went crazy. Looks like a lot of work going on.

I wanted to comment that being a UPB provider, I would consider you guys - Glenn, 123Taras, JamesHilliard, and bbrendon - UPB experts. It’s been years since I got down into these low level details and it’s been a long time since I’ve talked with anyone who has as well. In fact, in many respects, you’re probably more up to date than I am, as it’s been so long since I’ve dived this deep. So, don’t discount your level of expertise - it’s much greater than almost anyone else out there.

A couple of things, then I’m going to shut up and stay out of your way (I’ll be happy to help out with documentation and can try to answer any questions I can, but you guys are already pretty advanced - and if anyone needs help with products to test with, let me know). There’s another System document you guys might want to look at, if you haven’t already. This is the PIM System Description document. This is where you can find the detailed description of Pulse and Message modes, plus lots more information. For example, there is a way to get signal level and noise information even when in Message mode. You can download from the PCS website or I can get you a copy - just let me know.

I know there is a desire by some to use Pulse mode, in order to simplify device discovery - a very laudable goal. However, using Pulse mode adds a lot of overhead to the code and project - I would suggest at least starting in Message mode and get something workable, which appears to be the way Glenn is approaching it with his implementation, and then later move to Pulse mode to simplify operation, if so desired.

There was some discussion about reading device registers on individual devices in order to get more detailed information, for example which devices belong to which links (scenes - we used the terms links for so long, it’s hard to break). A big issue with this would be determining what registers to read for this information. The main registers for NID, MID, PID, Firmware Version, Network name, network password, etc - will have good consistency between products and manufacturers, but once you get past those, the registers are going to be different depending on the type of unit, the manufacturer of the unit, whether it is single or multichannel, etc. So, you would need to read the MID and PID, then have a table showing what registers to read for those devices. It’s going to get complicated and trying to get that information from most of the manufacturers is going to be problematic for multiple reasons. It could be reverse engineered but that’s going to take quite a bit of time and effort, plus you would need sample units of all desired units.

And, all of this information is already included in the Upstart UPE file. So, again, I would encourage an initial faster development that pulls that information from the UPE file then enhance it later if so desired as part of a discovery process.

I know practically nothing about HASS. I did just bring up a RPi4 with HASS and will integrate Glenn’s implementation shortly so I can play with it. bbrendon has been a huge help - thanks so much. I won’t be able to contribute, but at least I can start playing with HASS and UPB.

Now, I’ll get out of your way and try to shut up. If I can help any, let me know. Also, as this comes together, I’ll work on offering a special product discount code for HASS users to purchase product at a nice discount. bbrendon asked the moderators about this and they seem to be fine with it.

1 Like

New release up on github. Links are now represented as hass Scenes. I started using the github Releases so you can see them there with changes and do compares. You will have to cleanup your old entities. FYI… as I’m testing I use a custom configuration that can be easily deleted or recreated.

While perusing the LIFX integration, I couldn’t help but notice it has custom services:

lifx.set_state
lifx.effect_pulse
lifx.effect_color_loop
lifx.effect_stop

If the LIFX integration is permitted to have custom services (allowing it to talk directly to the underlying LIFX library versus through an existing Home Assistant light) then it opens the door to allowing the UPB integration to have its own custom service for a UPB link.