Skip to content

Entities not present at driver start won't work anymore #51

@yoctopuce

Description

@yoctopuce

As far as I understand, the integration driver's backbone are the available_entities and the configured_entities list. The integration driver is in charge of populating the available_entities list and the first thing the remote will do when connecting to the driver is subscribing to driver's entities, i.e. looking for its own configured entities in the available_entities list and place a copy in the configured_entities list. If the remote cannot find the entity in the available_entities it won't bother with it any more and you'll get a "resource not found" when trying to interact with this entity from the remote.

Well, this doesn't account for a scenario where the driver is based on dynamic discovery and remote controlled devices can easily be plugged/unplugged or switched on/off:

  1. a device is controlled from the remote, everything works
  2. the driver is stopped
  3. the device is switched off
  4. the driver is restarted
  5. the remote connect to the driver, figures out the device isn't there and "bans" it
  6. the device is switched back on
  7. the driver discovers its, and add it the available_entities list
  8. the remote doesn't care.

I believe there are several ways to fix this

  • Make sure the driver saves the available_entities list, but I don't like it, I'd like my driver to be as state-less as possible.
  • The proper way: notify the remote when a entity is back in the available_entities list, not sure how difficult this would be
  • The quick and dirty way: add the possibly the have a call back right when the remote is about to subscribe to an entity, so the driver can, if needed, quietly create an matching one with the attribute STATE set to UNAVAILABLE and add it to the available_entities list. Actually this takes only a few lines in the ucapi/api.py file
    # added by Yoctopuce
    _subscribeCallback :  Callable[[ str],Awaitable[None]] =None
    def setSubscribeCallBack(self,fct:Callable[[ str],Awaitable[None]]):
       self._subscribeCallback = fct
    # end of added by Yoctopuce	

    async def _subscribe_events(self, websocket: Any, msg_data: dict[str, Any] | None) -> None:
        if msg_data is None:
            _LOG.warning("Ignoring _subscribe_events: called with empty msg_data")
            return
        for entity_id in msg_data["entity_ids"]:
            # added by Yoctopuce
            if self._subscribeCallback is not None: await self._subscribeCallback(entity_id)
            # end of added by Yoctopuce

What do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions