How get an Hardware/Physical Abstraction Layer?

Hi there,

That’s a bit more that 2 years that I deal with HA. I have a pretty wide type of use cases and technologies at home, managed by HA.

With time, I tried some component (hw and Sw), then replace with others (because of depreciation, reliability, price whatever)

The pain is that when you have done a good scenario with a specific hardware (scene, automation,… other tools…) and you change the hw, you have to change the whole config !

If there is no way to abstract the device, I think we should consider it ! We see many industry (automotive, automation,…) doing such concept to help in a better interoperability and to decrease device supplier hard dependency.

3 Likes

I use Node Red for all of my automations, and do it there, but I think I’m mainly using HA capability. So maybe you could do something similar.

In NR I have a mapping of entities stored in global context (imaginatively called entities). This way I can map “laundry” to “switch.tp_link_114”. Then whenever I want to control the laundry, rather than specifying the entity name directly, I use

      {{ global.entities.laundry }}

and it substitutes the switch entity in. If I replace the switch with another, I just need to update the mapping once.

I only do this with devices that I might move around, not everything. For example, I haven’t done it for LED lights that should last at least 10 years in the same spot.

This is a cut-down version of the entities global context variable:

{
    "back_lights": "switch.xiaomi_2",
    "laundry": "switch.tp_link_114",
    "laundry_power": "sensor.tp_link_114_power",
    etc
}
1 Like

I didn’t know much about Node Red, but I will have a look on it. It’s seems to be able to do the job, but that would delegate the whole hw abstraction to a dependency.

Adding such component to the HA system is significant, especially if it does abstract every hw I have on HA (> 50).

Is the main usecase for NR to handle such abstraction ? It could be from the very quick look I had on the main page.

Do other HA big config handler work the same way ?
Is NR taken as a main component for HomeAssistant ? with LTS ?

I mean I would like to get a bit of background from others, and getting some words from people involved in roadmap would be awesome ! @balloob @frenck

I agree, this would be very handy.
A simple “virtual” device to which you could assign a real device.
That virtual device would assume/expose the physical attributes/functions of the assigned device and may be extendable to offer compound attributes made up of original device attributes modified by code.
Groups almost do this but do not expose enough function for the contained devices. At least in my limited experience.

1 Like

It does seems that unfortunately there is no much interest by this concept ! This is strange, because on other industry mature software, it is a very huge step to successfully un-correlate functional behaviour from hw, with a so call hardware abstraction layer !

I’m not everyday on ha, but this is almost 3 years I’m playing with it, and hw is weekly changing, in addition to news protocol / or sdk that you can be used to better work with devices ! What I do not want to, is having to update my automation, local calculation or whatever, because I changed the sensor protocol or the sensor itself !

Please, reader of this post, just comment !

Is Blue print may help a bit ? I will look about it.

Hi again @michaelblight. I’m not use to NR, could you please provide a screenshot of your explanation ?

Because, right now, I only succeed by get state, filtering the state and then starting a service. So this is a huge effort.

I agree with you 100%.

Lots of manufacturers are making all sorts of devices which basically do the same thing (open/close window/blinds/curtains, set light bulb brightness/colour, report movement/temperature etc). … and they can communication in any of a number of protocols.

There are more benefits to having an abstract device layer. For example, I have Z-Wave-controlled curtains, not blinds, and my windows are hinged, not sash. An abstraction layer would allow me to have a ‘curtain’ type (with specific icons for when opened and closed, and buttons that point sideways instead of vertically) that could be instantiated for each specific curtain.

This would also assist interconnections. For example, HomeKit sees my windows as covers and shows blinds icons.

At this level, you could deal with the entities more abstractly: for a numerical setting of 0 or 100, a bulb would be off or on, a window closed or open, curtains open or closed.

Note that this is almost implemented with command line -covers -switches and -sensors (https://www.home-assistant.io/integrations/#search/command%20line). These could be merged into the abstraction layer for providing default communicatiion with the hardware, or when custom-built entities are needed.

Wouldn’t it be great to say that the Living Room has a “Window” covered by a “Curtain” in Lovelace, and you would say these were operated by Z-Wave, Zigbee, WiFi, or Thread etc etc devices?

1 Like

Superb idea, going to try this on my setup. New HA user (~3 months), but Ive been on node red since day 1.

Having had this setup for some time, my experience has been pretty good. What I’ve found:

  • It’s useful to have the entity_id indicate the physical device so you know what ‘other app’ to go into. In the example I used, rather than having “switch.laundry” I called the physical device “switch.tp_link_114”. If I need to use the app it’s registered with, because the name includes TP Link, I know I need to use their Kasa app. I’m tempted to call it “tp_link_kasa_114” because I struggle to remember the app, but then they’d go and change the name on me.

  • I also put a Dymo label on each device with its entity_id. And the “114” above is the static IP address (ie. 192.168.0.114), because it seemed like a good idea.

  • The events: state node does not support templates for the entity (or at least it didn’t at the time). However, the trigger: state node does. I’m not sure if there’s any use case where the first can’t be done with the second, but you can always look for substrings or regex - for example have an events: state looking for a substring of “switch.” (ie. all switches) and followed by a switch node looking for the one you’re interested in. I have one such code instance, but I’m not really sure why. Everywhere else I’m using trigger: state using a template in the entity_id like

    {{ global.entities.laundry }}
  • The HA friendly name should represent something useful, so in my example, the entity_id is “switch.tp_link_114” but the friendly name is “Laundry”. If things move about, the friendly name can be changed in one place, whereas entity_id is used multiple times and places.

  • I do my own logging of everything that happens in Node Red, so in these cases where I would list the entity_id, I also include the logical name. There’s probably a better way, but I use the following JSONata for this:

    $keys($sift($globalContext('entities'), function($v) {
        $v = payload.entity_id
    }))
1 Like

Thank you for these extra insights - invaluable!

By complete chance I started renaming devices (and thereby, entities) using a similar schema (i.e. indicating the integration in the name). The IP part is a nice add-on too.

Are you by chance using the node-red-contrib-config node to set the global variable? If not, how do you ensure it is set on startup?

That config node might have been a good idea, but I’m just using a change node that is initiated by an inject node that has the “inject once” checkbox set. So I guess it would be possible for something to be needed before the global has been set, but it’s unlikely and would only be a possibility when I re-deploy at which time I’m watching it anyway.