Open pfink opened 6 years ago
First of all I think this is a nice feature to have!
Unfortunately we have the problem that we do not want to mix the physical layer (i.e. things) with the functional layer (i.e. items). So when introducing such a feature we have to be careful to not fully mix up the two layers.
The ThingStatus
is available in our "admin user interface", i.e. Paper UI, so an admin user knows which things are reachable and which are not. In our user interfaces for "users of the system" we only show the functional layer, i.e. the items. In a lot of cases the ordinary user happens to be the admin user as well so we could argue that he could look into the admin interface and find out whether a Thing
is online or offline. However in reality this is not necessarily the case!
I would therefore propose a sketch of a solution for this problem:
Right now we have two events: ThingStatusInfoChangedEvent
and ThingUpdatedEvent
, both carrying information about the state of a Thing
. We could therefore create a service that subscribes itself to these events and creates a new ItemLinkStatusEvent
containing the information for a specific Item
whether its linked Channel
s point to an online or offline Thing
. The service will also cache all these calculated state information (to send it out only if something changes) and can be asked "what is the link status of item xyz?".
This new ItemLinkStatusEvent
can be send out via SSE also to UIs like Basic UI, etc. For Basic UI we also need to take care of its SitemapWidgetEvent
s so they also contain this information.
In addition the REST interface should be extended so the ItemResource
returns DTO objects containing the link information, i.e. whether the Item
is linked to something that is online or offline.
If UIs have the information about the ThingStatus
of the Thing
which is behind the Channel
of an Item
it can render a hint saying "Careful when interacting with this control, it might not work" or something. Or they even could disable the controls of that particular ´Item` completely.
This also addresses #5122. If one defines a ´Thingvia a
.thingsfile and the
GenericItemProviderwants to create an ´Item
which has a Channel
pointing to a Thing
whose ThingUID
resides in a non-installed binding it delays the creating of such a Thing
, so it creates the Item
with a Channel
that points to "nowhere". We could treat this the same way as if the Thing
is offline.
Rules can ask the new service for the "link status" of an Item
too.
Problems that need to be discussed:
What if the Item
is linked to multiple Channel
s of different Thing
s of possibly different bindings?
ItemLinkStatusEvent
with the information that the Thing
behind one of its Channel
s is offline. We could say the "link status" of the Item
is offline if one Thing
is offline, or if all Things
are offline.Users that wish to have more control over the default behavior above could create a GroupItem
with Item
s that each have only one Channel
, instead of multiple Channel
s on one Item
. For these GroupItem
s in sitemaps we could have a configuration parameter that allows changing the behavior which we have defined for Items
with multiple Channel
s, i.e. we can have a function that calculates the Group
state based on the online/offline information.
Sounds like an good approach.
I would also suggests an error for
Thing whose ThingUID resides in a non-installed
There just has to be an option to choose how the ui behaves when the item is offline.
Item will be offline as soon as one channel is oflline, UI will will represent that.
Any progress?
Personally I don't think it make sense to mix the Thing's status and the items.
An item could be linked to 0, 1, ... (0..n) channels of a thing.
It could be wired to a things channel by rules and so not by a link.
The detection of online / offline of a thing depends on the binding and the connection to that things. Perhaps the offline / online detection can also be identified on interaction with the real device (e.g. only on sending a command and receive or not receiving a reply but no change to send something without user interaction because it will trigger a change on the device)...
IMHO the suggestion above will fit for some cases but not for others. I don't think it should be added to the framework that way.
@kaikreuzer, @sjka, @htreu WDYT?
I second @maggu2810's opinion. Especially the 0..n relationship between items and channels makes it impossible to provide a consistent solution. I suggest to work around this issue by using thing based tiggers as stated in the openHAB docs:
With
Thing <thingUID> received update [<status>]
Thing <thingUID> changed [from <status>] [to <status>]
it should be possible to modify synthetic items and react to thing status changes.
The real thing that is wanted, for me, is an easy mechanism to access the things OFFLINE status. I'm working on the Homekit binding and I want to report if a LeakSensor is unreachable, so this notification can be surfaced appropriately, for example.
EDIT
It looks like ItemChannelLinkRegistry
has the method I want: getBoundThings
. Neat.
Other idea: Each thing provides a predefined online
channel (type: Switch) without the need of any implementation by the binding developer. Easy to implement and less complicated for users compared to the other approaches as it does not require the knowledge of any new mechanisms or syntax. Many use cases could be covered very nicely with our existing features (e.g. Multi-Channel linking, Group functions, ...).
That's an interesting idea. I was wondering if it'd be a bad idea to make online/offline an inherent property of channels.
Really, as one working on an addon, I'm mostly interested in an efficient way to get the thing(s) from which an item's status is derived. ItemChannelLinkRegistry is a way, but it's not efficient. If Items could just keep track of associated things and update their list as bindings are removed / added, that would be pretty helpful. Then there could be a method call on Item such as .getBoundThings()
.
EDIT
On second thought I over estimated the complexity of ItemChannelLinkRegistry.getBoundThings
; I had the impression there was a scan or two involved in finding bound things, but it looks like it's a few Map lookups and a few Set instantiations. It's probably fine.
It'd still be convenient to have a getBoundThings
method on Item, but still, this is fine.
EDITED AGAIN
Well, I'm feeling sheepish. I had assumed all along (I'm not sure what gave me this impression) that a Thing could be offline while the linked item state is defined (IE not UNDEF), but upon further experimentation I've realized that items values are automatically translated to UNDEF when their associated thing is offline.
Perhaps this can be called out better in the docs? It'd be nice to have a warm cozy assertion that we can rely on this behavior.
a warm cozy assertion that we can rely on this behavior
Sorry, but this can not be taken for granted. The state of an item can not be used to derive the status of a thing.
Your approach using ItemChannelLinkRegistry.getBoundThings
sounds okay to me though.
Sorry, but this can not be taken for granted. The state of an item can not be used to derive the status of a thing.
And, corollary, the state of an item can not be derived from the state of a thing. IE the expire binding combined with MQTT generic items. :/
There are different use cases that require obtaining the ThingStatus from an item within sitemaps or rules (e.g. here or here). I open this issue as a further base of discussing how we can extend ESH so that these use cases can be solved better in the future.