MQTT interface... time for some testing. Where are my experts?
-
xAPPOreplied to toggledbits on Jan 8, 2022, 2:36 AM last edited by xAPPO Jan 7, 2022, 9:37 PM
All working well. However in the topic structure for echoed devices (from Hubitat anyway) the <entity-id> is used. Is it possible to instead or even better as well as, include the entity-name ?
reactor/<mqtt-id>/<ctrl-id>/<entity-id>/state/<capability-name>
perhaps
reactor/<mqtt-id>/<ctrl-id>/<entity-name>/<entity-id>/state/<capability-name>
-
The entity name can be changed or duplicated and is not an appropriate unique identifier for a device.
-
Topic hierarchy segments don't have to be unique - in fact I would say most aren't. Keeping the <entity-id> then within the hierarchy would ensure the topic remains unique. Having no easily human identifiable topic is not helpful to other integrations.
-
@xappo OK. And what about receiving messages for inbound action requests? Same
entity-name/entity-id
construction? If you know the correct entity ID to form that message, what value is the name? If you don't know the ID and only use the name, how do you specify that, and what if the name isn't unique then? And what if the name and ID conflict, or an entity can be found for one but not the other (i.e. they don't match)? I'm not opposed to what you're proposing, but I want you to help me think through the consequences of it.@xappo said in MQTT interface... time for some testing. Where are my experts?:
Having no easily human identifiable topic is not helpful to other integrations.
I think that's a bit of a reach. The whole MQTT environment is so unstructured and freeform, with so many inconsistencies between players, that things like unique IDs (or MAC addresses or other cryptic and "hard to read" identifiers) are a regular occurrence, and anybody who uses MQTT a lot is used to it.
-
The incoming action request message to a topic must be complete with all segments as you can't wildcard a publish command. So the <entity-id> will always be unique and present there. You could should you wish subscribe to the topic from your code ignoring any <entity-name> segment with a + wildcard as you don't process it. So that should work fine.
Human readability.. I agree it's a bit of a reach but my whole system is MQTT based with over 10K topics and 1K+ devices - remembering what they all are and linking to or from those topics from other controllers requires some hints as to what those devices are. Later examination of logic requires understanding what devices are related. Having to refer back to Reactor config each time to identify a device isn't practical (or user friendly).
-
Good stuff. Let me see what I can cook up.
-
toggledbitswrote on Jan 8, 2022, 9:50 PM last edited by toggledbits Jan 8, 2022, 4:52 PM
OK. Version 22008 of MQTTController is up on the downloads site (under extras).
New configuration key that you can put in the
echo
section: setentity_identifier
tocombined
and the telemetry topics will include the entity name; it adds another level to the topic as you suggested. This has no effect on received messages for entity actions; those still require the ID (but it's a secret/undocumented feature--you can give it the name instead of an ID and it will work if the name is unique), and the structure of the topic is the same (i.e. same number of levels, not changed). Online docs are updated as well. -
This is working well - thank you for the prompt update.
For me having the <entity-name> before <entity-id> in the topic hierarchy would have been more informative as you can then see a list of names rather than numbers in expanded topics with say MQTT explorer rather than having to drill down in each one, but I totally understand why it is so much easier in terms of your existing implementation to position it afterwards and this is very workable too.
Thank you again.
Kevin -
No worries. Version 22009 now. You can now set
entity_identifier
toid/name
(as a synonym forcombined
) orname/id
. I'll fix up the documentation later. -
It's like having my own on site developer team Many thanks for that
-
I notice in the MQTT code you subscribe to the root level with a wildcard which means you receive every payload update. On my (untypical) broker this will produce 10’s of message per second. The good thing is Reactor seems to handle it but obviously it’s resource wasteful. Did you do this with a view to implementing discovery across the broker perhaps?
Currently it might seem better to just pull the necessary topics from the MQTTController section of reactor.yaml even though this may result in lots of individual subscribes?
Also just to mention I’ve got my first CBusController half written. It discovers and creates entities for all the 100+ lights I have on my Schneider C-Bus lighting but needs some refining. Learning as I go. Having the MQTT code as an example has been invaluable to me.
Would you be up to releasing the Hubitat and HomeAssistant controller code as examples? I think that would help people in authoring new controllers, as might a minimal code template that does nothing really.
-
When I started writing MQTTController I didn't quite know where it was going to end up or how it was going to get there. It moved a lot from its starting point. I can definitely "tune up" the subscriptions, but discovery is in the mix (it captures certain discovery messages to debug currently but doesn't do much else with them -- still under consideration).
Did you find the probably dated but maybe marginally helpful docs here? https://reactor.toggledbits.com/docs/Building-Controllers/
I've been really busy this week, and suffered a long Internet outage that just recovered a couple of hours ago, but when I'm caught up I'll quickly update some key points and concepts in there.HubitatController and HassController are very complex pieces of machinery that I don't think would make good examples. Now that I have a few done, one of my tasks is go back and boil out some of the work into common methods or helper classes. I have a lot of work to do on the server API side.
-
@toggledbits said in MQTT interface... time for some testing. Where are my experts?:
Did you find the probably dated but maybe marginally helpful docs here?
Yes I did .. a quick Q - how do I delete an entity ?
The bit I'm adding currently is
If the process may be protracted and lengthy, the Promise should resolve earlier and the entities by published as discovered.
and trying to avoid having to loop through them all on restarts to see if they already exist. This is an aspect that you must have encountered with Hubitat and Hass.
Making good progress and enjoying it .. great application.
-
@xappo said in MQTT interface... time for some testing. Where are my experts?:
how do I delete an entity ?
controller.removeEntity( entity )
-- pass the entity, not just the ID.@xappo said in MQTT interface... time for some testing. Where are my experts?:
trying to avoid having to loop through them all on restarts to see if they already exist
Define restarts in this context. If you mean restart of Reactor, no entities exist in the version you are running when Reactor starts up. That's about to change, though... entity persistence is coming. If you mean when the connection to the hub is re-established, that's entirely implementation-dependent for your Controller subclass. My subclasses generally reinventory everything, because you don't know how long the hub has been unavailable, and what may have happened to it while it was down.
I just posted a ton of updates to the doc.
-
I am trying to install this in Docker and getting the following error:
$ docker exec -it reactorjs /bin/sh cd /home/pi/reactor/ext/MQTTController ./install.sh exit
/bin/sh: can't open 'cd': No such file or directoryNot enough of a linux gut to know what the issue is. Anyone have any hints?
Roger
-
toggledbitswrote on Mar 1, 2022, 12:26 AM last edited by toggledbits Feb 28, 2022, 7:35 PM
You're reading the wrong direction, I think. See the docs.
Edit 2: OK, getting in sync here again... you've given the wrong pathname to
cd
. Give it what the documentation says. You're working inside the container -- gotta follow its rules. -
This is the part I used from the instructions:
"docker exec -it <container-name> /bin/sh cd /var/reactor/ext/MQTTController ./install.sh exit"Results:
pi@RedBMWDeb:/home $ docker exec -it reactorjs /bin/sh cd /var/reactor/ext/MQTTController ./install.sh exit
/bin/sh: can't open 'cd': No such file or directoryThen I tried to determine why the command wouldn't run and determined that maybe the path was wrong on my machine so ran the one in the previous message pointing to the path where MQTTController files were.
pi@RedBMWDeb:~/reactor/ext/MQTTController $ ls
0-README.txt COPYRIGHT MQTTController.js
buildstamp install.sh mqtt_devices.yaml
CHANGELOG.md mqtt_capabilities.yaml package.json -
It looks like you're trying to do all of those commands on one line. That's not right. You do them one at a time.
-
Installing line my line removed that issue. Still running into errors.
Is there a way to determine if the dependencies get installed correctly. I see this on the screen but once I restart reactor it fails.
Installing dependencies...
[..................] \ idealTree:MQTTController: sill idealTree buildDeps.
It sits here for a minute or 2 and then exits. When I modify the reactor.yaml file- id: mqtt name: MQTT enabled: true implementation: MQTTController config: source: "mqtt://192.168.0.16:1883/"
Then I get these error messages in the container logs when ReactorJS starts up
Require stack:-
/var/reactor/ext/MQTTController/MQTTController.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/var/reactor/ext/MQTTController/MQTTController.js:22:14)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:168:29)
[zwavejs-22058]2022-03-01T20:12:27.189Z Controller:CRIT Error: Cannot find module 'mqtt'
-
-
Dependencies didn't get installed properly. Try running the install script again.