openHASP icon indicating copy to clipboard operation
openHASP copied to clipboard

Add "guid" to each page, allowing commands regardless of page order

Open Humancell opened this issue 1 year ago • 11 comments

We now have numerous OpenHASP devices installed for our demonstration and testing. Each of them has different pages, and the pages are in different orders. For example, in one room the order might be:

  • Room Controls
  • Room Climate
  • Outside Weather
  • Emergency Services

The next room might be:

  • Room Controls
  • Emergency Services
  • Music Controls
  • Outside Weather
  • Water Controls

In the current design, we have to keep track of the order of the pages to update the Weather Page - for example - across numerous devices.

If the Weather Page had a "guid" associated with it, and commands could be sent using that guid, then page updates could be done regardless of the page order.

For example, if I used:

{"page":2, "guid":"00B0D063C226", "comment":"---------- Page 2 ----------"}
{"id":14,"obj":"gauge","x":10,"y":65,"w":150,"h":150,"label_count":7,"line_count":25,"text_font":16,"val":10}

Then I could update the gauge maybe using the command:

p[00B0D063C226]b14.val=100

And this command would work on any device to update the gauge on the page with that guid, no matter what the order of pages was.

If my Weather Page in the example above had that same guid on both devices, then I can update the Weather Page on either device without having to keep track of the page order.

In addition, if in my management portal I assign the guids to pages, then whether they were my pages or shared pages they could be updated regardless of which devices had them and in what page order.

This also would not be a breaking change ... unless I missed something.

And maybe there is another way to do this that I missed?

Humancell avatar Jul 28 '22 02:07 Humancell

This also would not be a breaking change ... unless I missed something.

One issue I see is the way that events post their data. Now there is a standard pXbY message posted to the state topic.

Events would become ambiguous as there will be multiple ways to name an object. One way to handle it would be to use the guid in events too if present and page number of not...

And maybe there is another way to do this that I missed?

Not really, currently we expect the automation system to keep track of the pages and object IDs. There have been requests to have a page name though. This would probably be similar, where the guid/name would be the same thing.

fvanroie avatar Jul 30 '22 10:07 fvanroie

Another complication is switching pages which should also be possible by name or id. e.g. page light_switches or page 4. The resulting state message could be hasp/plate01/state/page {"id":4, "name":"light_switches"} which is a breaking change.

fvanroie avatar Aug 18 '22 19:08 fvanroie

I've started to implement a pagename to see which parts would be affected:

[15:56:19.096][90100/95304  5][49912/51072  3] MSGR: p1b0.name=my_page_name
[15:56:24.045][88052/93456  5][49912/50968  3] MQTT PUB: my_page_name.b8 => {"event":"down","val":0}
[15:56:24.187][88052/93456  5][50476/50864  1] MQTT PUB: my_page_name.b8 => {"event":"up","val":1}
[15:56:32.203][90100/95304  5][49912/51072  3] MSGR: p1b0.name
[15:56:32.230][88052/93456  5][49912/51072  3] MQTT PUB: my_page_name.b0 => {"name":"my_page_name"}

fvanroie avatar Aug 19 '22 13:08 fvanroie

My thoughts would be to implement a guid in this manner (hopefully easiest way).

Device 1 {"page": 1, "id": 8, "gid": "1", "obj": "text", blah blah}

Device 2 {"page":2, "id": 12, "gid": "1", "obj": "text", blah blah}

Then if you send a command, perhaps you make a special call to make easier to identify its for a global object like hasp/group_topic/guid/command/g1.text

or likely easier to implement, only accept JSON commands. hasp/group_topic/command/guid payload {"gid": 1, "text": "new text"}

The goal here would be to update the same information, on different devices that may have the information placed differently between them. I.e. Outside Temp, Wind Speed, Forecast data, etc. I have one larger screen on my desk, and one smaller on my bedside table. Both have different layouts, but share some data. Right now I just have Node-Red send out two MQTT messages, one to each. But when I add a 3rd display, I'll have to change my automation, whereas, if we had this, I could simply include the correct "gid"

marc-gist avatar Jan 20 '23 23:01 marc-gist

Sorry that I've let this fall without replying for so long. :-( I got caught up in so many work projects things slowed on my research here. The message above peaked my interest in this again.

I've started to implement a pagename to see which parts would be affected:

[15:56:19.096][90100/95304  5][49912/51072  3] MSGR: p1b0.name=my_page_name
[15:56:24.045][88052/93456  5][49912/50968  3] MQTT PUB: my_page_name.b8 => {"event":"down","val":0}
[15:56:24.187][88052/93456  5][50476/50864  1] MQTT PUB: my_page_name.b8 => {"event":"up","val":1}
[15:56:32.203][90100/95304  5][49912/51072  3] MSGR: p1b0.name
[15:56:32.230][88052/93456  5][49912/51072  3] MQTT PUB: my_page_name.b0 => {"name":"my_page_name"}

How did this research turn out? The page_name - if always unique - could serve the same purpose as the guid. My goal was simply to remove the number identifier as pages on different devices could be in different orders.

The most recent post above seems to bring up a completely different use case where @marc-gist seems to want to have the ability to update controls on any page using a similar quid concept?

Humancell avatar Jan 23 '23 04:01 Humancell

@Humancell I believe my idea solves both use cases at the same time, whereas your idea only works if you have the exact same screen on a device (which means likely same screen size, etc, etc).

Creating a unique id for an object, rather than a page, allows that object to be anywhere on the device. If you have a page full of objects with GUID, shouldn't matter to this method.

my 2c

marc-gist avatar Jan 23 '23 11:01 marc-gist

I also refer to my work here: https://github.com/HASwitchPlate/openHASP/pull/689

At the moment only a hash of the alias is stored. Therefore sending information to the plate works fine but the alias text cannot be returned. I would like to extend this and also save the alias text. Then the plate sends an MQTT message when a button is pressed, for example, as follows:

Topic : hasp/plate/state/p1b16 Payload : {"event":"up","val":1,"alias":"cover_down"}

marsman7 avatar Mar 28 '24 16:03 marsman7

One question: Do you see it as a problem if two buttons have the same alias, that they also work synchronously?

For example: On page 1 there is a button with the alias "foor_light" and another one on page 2 with the same alias. When one of the two buttons is pressed, the light switches. If an MQTT command is sent to this alias, both buttons react to it.

Another possibility is to assign an alias that already exists to a second object, in which case the alias is discarded.

Two questions come to mind about multiple aliases: What if the objects have a different type (for example button and label)? For example, if there are two switches on the plate and one is toggled, the other should toggle synchronously.

marsman7 avatar Mar 28 '24 18:03 marsman7

I have continued to work on the alias feature.

To be able to use alias, USE_OBJ_ALIAS must be greater than zero when compiling.

#define USE_OBJ_ALIAS 1

It is now also allowed to use an alias multiple times

For example

{"page":3,"id":10,"obj":"switch","x":20,"y":10,"w":60,"h":30,"radius":25,"radius20":25,"alias":"Alpha"}
{"page":5,"id":35,"obj":"switch","x":220,"y":10,"w":60,"h":30,"radius":25,"radius20":25,"alias":"Alpha"}

on touch on the first switch the second switch also assumes the status of the first switch and, the plate sends the following MQTT message :

Topic : hasp/plate/state/p3b10
Payload : {"event": "up", "val":1, "alias": "Alpha"}

On touch on the second switch the first switch assumes the status of the second switch and the following message is sent:

Topic : hasp/plate/state/p5b35
Payload : {"event": "up", "val":1, "alias": "Alpha"}

The synchronous behavior of the objects is similar to the "groupid" property. However, aliases cannot be used to interact with the GPIOs and the user must be careful when using both.

Example :

{"page":1,"id":15,"obj":"btn","x":10,"y":20,"w":150,"h":50,"toggle":true,"text":"test","alias":"Bravo","groupid":4}
{"page":1,"id":16,"obj":"btn","x":10,"y":80,"w":150,"h":50,"toggle":true,"text":"foo","alias":"Bravo"}
{"page":1,"id":17,"obj":"btn","x":10,"y":140,"w":150,"h":50,"toggle":true,"text":"bar","alias":"Charlie","groupid":4}

on touch of the "Test" button synchronizes the status of the "foo" button (alias match) and the "bar" button (groupid match) on touch of the "foo" button only synchronizes the status of the "test" button (alias match) on touch of the "bar" button only synchronizes the status of the "test" button (groupid match)

The GPIOs only interact with the two buttons with the "groupid" property.

When sending an MQTT message to the plate, the alias must be preceded by the '@' character.

For example:

Topic : hasp/plates/command/@delta.bg_color
Payload : #888800

As a result, all objects with the alias "Delta" that support "bg-color" change their background color.

Another example:

Topic : hasp/plates/command/@foxtrot.val
Payload : 1

All objects with the alias "foxtrot" change their value. For example, the status of toggle buttons and switches is set to on.

An alias can also be used for an "action" property or in a batch script:

{"page":1,"id":18,"obj":"btn","x":10,"y":10,"w":75,"h":70,"toggle":false,"text":"run","alias":"Golf","action":{"down": "@india.text foobar"}}

Sets the text of all objects with the alias "india" to "foobar". The same happens with the following batch script "testscript.cmd" and MQTT command. Batch script :

@india.text foobar

and MQTT command

Topic : hasp/plates/command/run
Payload : /testscript.cmd

marsman7 avatar Apr 06 '24 07:04 marsman7

Interesting, at the moment if I have two buttons controlling the same thing, I create a lookup table with the common topic and the button ids, that need to be synced. Would your proposal work if the common topic were added to the alias e.g. {"page":3,"id":16,"obj":"btn","x":10,"y":80,"w":150,"h":50,"toggle":true,"text":"foo","alias":"/some/topic/value"} {"page":1,"id":66,"obj":"btn","x":10,"y":80,"w":150,"h":50,"toggle":true,"text":"foo","alias":"/some/topic/value"}

smcgann99 avatar Apr 17 '24 02:04 smcgann99

Should work. A hash is calculated and when a button is pressed, the status is transmitted to all objects with the same hash.

Why don't you try it out ;)

marsman7 avatar Apr 17 '24 15:04 marsman7