[BETA] YAMA (Yet Another MQTT App)

WHAT IS IT:
I wanted to make a SUPER SIMPLE MQTT client app/driver that would support publishing any Hubitat device with any command/attribute (even custom ones) to MQTT without any custom work needed by the end user.

This app only allows you to select Hubitat devices to publish to MQTT.

  • You can not select specific commands/attributes - it is all or none on a device basis (on purpose).
  • You can not control which commands on a device are controllable via MQTT - it is all or none on a device basis (on purpose).
    Keep this in mind for perimeter security devices like locks and garage door openers!!!!

With a very specific goal in mind, and less optionality, the code is very small and light.

I run this on my dev and production hubs (80+ devices each) with no issue. That said, it is marked as a BETA for a reason, and I fully expect some device/attribute/command types I haven't tested may throw errors/break it.

All of that said, if you want to try it a link to the code is below. I'm open to error/bug reports, but as a side project issues may not get fixed immediately.

DRIVER

  1. Install driver code
  2. Create virtual device, specify YAMA driver for the type then click SAVE DEVICE.
  3. Edit this new device, entering MQTT broker info and then click SAVE PREFERENCES

APP

  1. Install user app code
  2. Create new user app (of type YAMA of course)
  3. Edit the app and select driver created above for the "MQTT Driver" entry
  4. Then select the devices you want to publish to MQTT in the next selection box
  5. Click Save and the app will start populating the MQTT data on the broker, and subscribe to the command topics

Initialization is throttled (no throttling once init is complete). So if you add a ton of devices, each with a lot of commands/attributes then it will take a while to initialize!!!! On my production hubs it takes ~90 seconds for the app to complete initialization.

Use -

  • All attribute values should show up, and automatically update, in the MQTT topic structure:

    • hubitat/[hubname]/[device name]/[attribute name]/value
  • All commands on devices are controlled by publishing values to the MQTT topic structure:

    • hubitat/[hubname]/[device name]/[command name]/set
      Note 1: For commands that do not need parameters (like 'on' and 'off'), you can publish anything as the value for the /set topic (the value is ignored by the app).
      Note 2: For commands that take multiple parameters, separate the parameters with a comma (like 80, 25)

No guarantees of the quality of the code. It is BETA, and I'm not a professional programmer. Use at your own risk.

That said, it hasn't destroyed my dev or production hubs, so there is that. :slight_smile:

CODE:

Driver setup screen. Yup, that's all of it:


App setup screen. Yup, that's all of it:

Example of what it looks like on the MQTT side via the MQTT Explorer app:

3 Likes

Reserve one more for To-Do / known issues

TO-DO:

  1. Consider caching command type/parameter lists to improve performance when writing commands to hub from MQTT.

KNOWN ISSUES:

  1. ISSUE: Jason - Your code looks like a 5 year old with dyslexia wrote it, and made my eyes bleed. How can I sue you for my medical bills?
    • You can't. See comment above about me not being a profressional programmer, and "use at your own risk" disclaimer.
  2. ISSUE: Jason - it didn't work for device XYZ - your app sucks!
    • First, screw you for saying my sucky app sucks. I already know that, and don't need to hear it from you.
    • Second, let me know the device type and copy the error message and I'll try to fix it.
  3. ISSUE: I looked on the "Runtime Stats" logs and this thing is taking A LOT of runtime!!!!
    • Both the app and driver run any time an event fires for any device you have added to the app. When you have a lot of devices it will run OFTEN - that's expected.
    • Also note that the long initialization time for the app (especially if you have added a lot of devices to the app) skews the runtime data as well - it uses up a LOT of runtime while initializing, so right after installation or a hub reboot the stats will be HIGH - that's expected.
    • If you are on hub version 2.2.5 or higher you can watch the average runtime data. After it has settled in, I normally see the app and driver taking <50ms per execution. If it is taking something much greater than that, there may be an issue.
  4. ISSUE: I changed a device type/driver/etc after I already had it in your app. Now it won't publish anything correctly!?!!!
    • Yes, if you change the driver structure for a device you have previously added to the app, you may (likely WILL) have to go in the YAMA app and re-save it to rebuild the MQTT structure.
  5. ISSUE: Sometimes the MQTT driver disconnects from the broker for unknown reasons - why?
    • I have seen this a few times, too. Don't know why it does that right now. The times I have seen this happen, it automatically reconnects after a while.
  6. ISSUE: This seems slow!!!!
    • While every hub, and its loading, are different. Based on limited testing my data showed it takes 60-250ms round trip on normal operation. So yup, it can be slower than directly using Maker API, or a native app. But still pretty zippy.
4 Likes

Driver updated to v0.0.5 to fix weird atomicState issue I can't explain, but could work around.

Mandatory upgrade for anyone using this app/driver! Serious issue found in prior version causing code loop/queue exhaustion/hub crash/bad things!!!

DRIVER
V0.0.6 - 01/20/21 - Fixed looping issue when broker disconnected from calling PublishLWT. Added subscribe to +/+/set and SendAll on connected status. Added periodic reconnect setting option.

APP
V0.0.5 - 01/20/21 - Added check for driver connection status. NOTE if driver can not connect/is not connected, the app will not initialize.

Jason:

Trying to learn from your driver code to fix a mqtt driver I'm using that doesn't auto-reconnect

If I read it correctly your driver publishes a periodic heartbeat to the broker to ensure that your driver is connected and if its not then it attempts to reconnect based on the frequency of the heartbeat.

The driver I'm using only receives mqtt messages from a button device that is not natively supported by hubitat but is by zigbee2mqtt.

Do you mind if I lift a few pieces of your code to try to fix mine?

Mike

Not exactly...

The heartbeat helps keep the driver connected to the broker after it has already connected - it doesn't connect it or re-connect to the broker if disconnected. In the code you'll see that the heartbeat method checks if the broker is connected, if not it does nothing and doesn't run again until the broker is connected.

In the latest version of the driver (released yesterday) there is an option for auto-reconnect though. That does (1x/minute) retry the connection to the broker if it is disconnected (by scheduling connect to run once a minute).

Help yourself!

I see that now. Thanks

I have another question assuming normal operations.

Within initialize(), you schedule the heartbeat to run in 5 secs. then within mqttConnectionAttempt(), the 3rd "if" statement will schedule another heartbeat in 5 secs, and finally connected() will schedule a 3rd instance of heartbeat in 5 secs.

So is there 3 separate instances of the heartbeat scheduled or does each successive runInMillis replace the previous so only the last is actually scheduled?

By default runIn and runInMillis replaces the previous schedule.

https://docs.hubitat.com/index.php?title=Common_Methods_Object#runIn

Thanks

1 Like

No worries.

With better planning maybe I wouldn't need it all the places - but each time I thought of a different place that could trigger it, I just added it since it doesn't really hurt anything.

APP
V0.0.6 - 01/23/21 - Added check for driver connection status before sending events to MQTT to avoid potential hub DOS if MQTT broker is disconnected/unavailable post app initialization.

Created 2 pull requests for driver ( hopefully correctly, first time using github) to handle broker failure and disconnect command not updating driver connection status.

DRIVER

  • V0.0.7 - 01/24/21 - Added in PRs from kuzenkohome fixing disconnect and mqttstatus

I just installed this. I have a broker running on another computer. I can use a mqtt explorer on that machine and see it ok.

I can't get your driver to connect. It just says in the logs:
dev:22812021-01-27 03:02:04.622 pm infoIn disconnected: Disconnected from broker

dev:22812021-01-27 03:02:04.610 pm errorIn mqttConnectionAttempt: Error initializing.

Not sure I have any bright ideas. All of the connection code is built in to Hubitat, so I can't dig in too deep.

You can turn on debug logging and see the error it is giving back in the logs though.

I've tested it with 3 different brokers, and it connects for me.

That said, none of my brokers use login security, so I haven't tested that at all. Does your broker use a login?

Also double check what you entered for the broker ip address and port.

I don't have any security on the broker at this time. I am using Mosquitto.

I ran the MQTT Explorer on another machine and it won't connect either. So it's not HE stuff.

I have verified the IP and Port.

Will have to work on it some more.

Thanks for the help.

No worries! I use mosquitto as my primary broker, too. So happy to help.

I will say that there will be another version of the driver in the next few days. The "periodically try to reconnect" doesn't always get scheduled/work when the broker disconnects.

I need to fix that.

What I can’t understand I can run the mqtt explorer on the same machine as the broker and it connects fine. So I know the broker is running. But for some reason it’s not letting in remote connections. Don’t know if there is some settings I missed or some network settings or what. Enough for one day. I’ll play with it tomorrow when my brain is fresh.