unixorn/ha-mqtt-discoverable

Make the `hmd` cli scripts less awkward

unixorn opened this issue · 7 comments

The hmd scripts started out as something I was using strictly for creating test sensors that I could check with my Home Assistant test instance.

They're painful to use since they require JSON arguments for each metric on a device - I didn't care about that while I was testing, but is not really end-user friendly.

This issue is to discuss better ways to handle creating devices/sensors from the command line. The new hmd scripts should also run easily inside docker containers.

Should we store state of command runs in something like ~/.hmd_state.yaml to make it easier to add another metric to an existing device?

@mion00, you brought up using Click or Typer instead of argparse in #15, we should decide on that too before doing much more work on the hmd commands.

In the last weeks I spent some time digging around the (messy) world of packaging Python applications, and I think I have a found a clean solution to use additional libraries like Click and Typer without forcing them on our downstream dependencies: defining our CLI as a Python extra.

This approach is used for instance by httpx. The end user could import our library as usual, pulling only the MQTT dependencies.
If however they are interested in the CLI, they can just do a

$ pip install 'ha-mqtt-discoverable[cli]'

This will install automatically the additional dependencies they need to run our cli (either Click or Typer).

This issue is to discuss better ways to handle creating devices/sensors from the command line. The new hmd scripts should also run easily inside docker containers.

Should we store state of command runs in something like ~/.hmd_state.yaml to make it easier to add another metric to an existing device?

I think these two requirements seems a bit conflicting with each other: if we assume the user starts our script various times via a docker run, it will inevitably create a new container at each run, losing track of the "state file".
The solution could be bind-mounting a folder from the host system, but to me it seems a bit cumbersome, and we loose the advantage of having one-off containers.

Our approach I think depends on what we consider a "device". In HA it is simply a "virtual container" for various entities referencing the same device ID. Do we want to abstract this for our end-users by introducing the device as an target they can manipulate (doing CRUD operations on it)?

I was thinking of having a second module that only has the cli tools that imports ha_mqtt_discoverable.

Having everything in the same repo would definitely be cleaner, we'll just have to figure out how to package the extras with poetry. I've only been using it for the simple case of one module per repository, so I'll have to dig a bit to figure out how to do the packaging.

Worst case, we make two top level directories in the repo, move the existing module into a ha_mqtt_discoverable_core subdirectory and the new cli tools into ha_mqtt_discoverable_cli.

I have an idea: what if we use the broker as our "state storage"? Since all the entities are strictly correlated with a config message inside the HA topic tree, and those are retained, we could read them on startup, and for each device in the "device" field we create this "virtual device" that the user interacts with.
It might seems a bit cumbersome, but this way we don't depend on a local state file and in addition any device deleted by the user in HA will not show up for us, avoiding sync problems.

I like that idea a lot. We only work if we have write access to an MQTT broker anyway, we might as well take advantage of it.

The more I think about it, the less I want to try and kluge up the poetry configuration to have multiple modules in the same repository. I think it will just make the poetry configuration brittle and cause follow-on contortions in the package publisher action.

Instead, I think we should strip out the entire [tool.poetry.scripts] section from pyproject.toml in this repository and create a new module, ha-mqtt-discoverable-cli that is basically just the [tool.poetry.scripts] section with a dependency on ha-mqtt-discoverable.

The code would all stay in ha-mqtt-discoverable, ha-mqtt-discoverable-cli will exist solely to create entrypoint scripts.

I'm going to break the cli tools into ha-mqtt-discoverable-cli tonight.

Closing in favor of unixorn/ha-mqtt-discoverable-cli#4 now that the cli scripts have been broken out.