MQTT with relay driver and controller

Hi guys,

I have Relay Driver and Light Switch controller, just have a simple question about MQTT.

So far I have:

  • MQTT broker (running on Home Assistant)
  • Controller, which just publishes a value every time when the button is pressed
    (e.g. topic=home/switch/relay/relay5 value=1)
  • Relay driver which subscribes to the relay topics

Relay driver works fine - if it receives 1 it turns the relay on and if receives 0 it turns it off. Where I stuck a bit is how by pressing the button change the value, right now I can only publish the same value every time which can only turn the relay on (or turn it off if I change the code)

I can see two ways how to solve it, but not sure what would be the better option:

  1. Subscribe the controller to the relay topics so it reads current status and if it’s 0 send 1
  2. Always publish the same value to the topics (e.g. topic=home/switch/relay/relay5 value=5) but on the relay driver trigger different actions depending on the current status after another relay message arrived.

Or maybe I am overcomplicating things and there is even easier way? How do you do that?

Thank you.

I’m not sure what relay driver you’re using… You mention “topic=home/switch/relay/relay5 value=5”… is 5 supposed to be a made up value for “toggle”, or is that a message to turn on relays 1 and 4 on the fifth board?

In any case, you’re using Home Assistant. So do it there:

  1. An MQTT Switch, have it Retain the current state. MQTT will remember whether the switch should be on or off. The switch publishes on/off commands to the relay.

  2. An Automation listening to your button. When the button is pressed. the Automation does a switch.toggle to swap it’s state.

If your sending a byte that maps to multiple relays being on or off, HA can do that too, you just have to get a little more fancy. One straightforward way, is using an MQTT backed (Retain) numeric input in place of the MQTT Switch, and then a bunch of template switches with a little bitwise math magic to break those bits out for your HA view, and the rest continues as above. You could also go the other way, having separate MQTT switches, and an Automation that puts them together and send it to the light (probably the simpler of the two). Whichever method you prefer… do both and then choose the one that makes the most sense. But it’s probably easier to just have the relay board accept individual relay on/off commands, as well. Or, if you’re me, do all of the above, coz it’s FUN!

In either case, relays, lights, whatever, I always add a toggle option; check if it’s an ON command — I usually accept any of “on”, “true”, “yes”, “1” or “+”, plus abbreviations thereof (strncmp is a lovely function). If not, check if it’s an OFF command, if still not, then toggle the current state. When you’re doing it that way, the, “uh, it was neither, guess I’ll just flip it” falls out as a natural consequence.

In the bitmapped case, either a second “toggle” command that XORs the bits with the current state, or me being me, simply if it receives two numbers instead of one, they form an ON/OFF mask pair (think JK flipflops — I kinda fell in love with them as a kid). OR/XOR pairs also work, but the typical function in bitmaps tends to be either “set them to these states”, or “turn these ones on/off”, so those should be the simple cases — I find when toggle happens, it’s generally a single “toggle THAT one”, so it makes sense to shove that on a separate command that takes a single bit index (of course, there’s no reason you can’t just accept a string of bit indexes, either, with optional prefix flag to set the bit twiddling mode… and another flag to set indexed or bitmapped mode, and this would be why I have so many unfinished projects…).

1 Like

I am using Relay Driver based on Arduino board - SuperHouse version :slight_smile:

It’s easy to do that with Home Assistant and I still keep it in mind but the main problem here is that I am playing a lot with HA (new automations, updates, etc.) and reboot it at least once a week, sometimes 5 times a day. I just cannot afford putting the whole house light switches offline that often, so thinking of moving mosquito to a dedicated Raspberry. That means HA (if it’s powered off) is not an option with lights on/off, but not 100% sure yet.

Thinking of adding some logic to the relay driver itself - when message arrives if relay status is off - turn it on, if relay on - turn it off. Or maybe similar logic to the controller - so it subscribes to the relay status and depending on that sends different value.

Still testing and playing.

I run my MQTT on a separate R.Pi, but only because it was there (along with my original Python script based automations) before I started playing with HA… Was planning on migrating it onto the HA Pi so I’d have one spare for experimenting on… Until the 4’s came out, and I got one of those, of course.

So get two… or three… or five… Then, you have your main system, and your development system. You do your experimenting on the development system (could also set it up as a satellite system, I believe), and if you mess it up, just restore it from the main one. Then when you’ve got it how you like, go the other way, replacing the main one from the development one. rsync works well there. I Git my main config, but that doesn’t work so well for passwords and stuff, if you ever might possibly plan to make it public (or if Microsoft one day decides you want to make it public)…

You reboot your HA? Why? What image are you running? Restart the HA image every so often, sure… Takes it offline for a minute or two, which is a pain, so do it while people are out, or asleep, and won’t get annoyed at you (unless all the lights turn themselves on, or something, in which case wait till people are out).

But my HA Pi’s current uptime (actually, both of them, since it was a blackout that last caused them to be restarted) is 263.5 days. I run, and the HA itself gets restarted anywhere between when I feel like the latest updates are worth trying out, and several times an hour while I’m tinkering, but the other containers keep on running, so MQTT should too. Linux isn’t Windows. When I used to run Linux as my sole system, I was less than a month short of a full year uptime a couple times, and that’s with everything updated regularly except the kernel (which I’d upgrade, often several times, before the next restart — usually by blackout). Seriously, Linux isn’t Windows.

But even then, a HA restart takes all of a minute or two. And if you have split main/dev systems (I believe with Docker — what uses — it should actually be possible to run them both on the SAME system, though it could get tricky and/or confusing), then that’s a minute or two downtime only when you feel confident with your new setup to apply it to the main system. And a duel system like that, you can even do things like bridge the two MQTT servers only one way (so dev gets updated from changes in the house, but the lights don’t go crazy if you screw up your automation), and then you can selectively bridge back the other way, too, so, like, only the lights in that one room are actually being controlled by the dev system. You can do all those things.

But, if you’re comfortable putting the logic on the nodes, then that’s just as good. Teach the relay driver board to toggle individual relays, and have the switches send toggle messages, and you’re all sweet. As I said before, I did that, but I don’t use it, it’s just there in case I feel like it at some point. I’d probably use the MQTT as the data store, though, because otherwise you’ll be wanting to fiddle with the controllers EEPROM and all that, and then there’s the question of what state should they come up in after a blackout. Some devices you might want to default ON, or OFF, others you might want to remember their previous state. Easiest way to do that, is with the MQTT retain flag. Retain will make it resume it’s previous state, where not using retain on individual messages lets you retain the initial state you want them to be in — just have to be consistent with a given device. That too, is easy to do if your switch messages come into HA, and get sent back out to your relays on a different topic, then the HA logic that binds them can decide whether to retain or not.

But definitely get a second HA instance for experimentation, either way.

1 Like

Oh, and I think in one of Jon’s videos, he shows having two R.Pi’s driving his setup too… Main and Dev systems, just like that. The real world calls that staging, or some such, I think. I just call it common sense.

1 Like

What you’re asking is the classic question of “where should state be maintained?”

There are a few ways to solve this, and different people will have different opinions. Personally, I prefer that devices which publish events (such as button presses) should only publish that event. It’s not their job to decide if pressing the button now is to turn something on, or turn it off. That logic should be elsewhere.

So I think you’re doing the right thing with the controller publishing a value when the button is pressed.

That leaves you with 2 other places you can put the logic.

First, you could put it in the relay driver. Instead of going explicitly to either on or off, it could toggle each time it receives a command. Or it could accept 3 commands: on, off, or toggle. However, without having a feedback mechanism, putting this logic in the relay driver could be asking for trouble because you can’t determine what state it’s currently in.

Secondly, you could put it into a third element of the system that acts as an intermediary between the switch controller and the relay output. This is my preferred option. It could be Home Assistant, OpenHAB, Node-RED, or many other home automation controllers. It’s the job of the controller to act like a gatekeeper between all the other devices, coordinate messages, and keep track of the current state of all devices.

For many years I used OpenHAB as my main controller, but right now I’m using Node-RED. In either case, you can have your switch controller publish to one topic, and your relay controller subscribed to a totally different topic. They don’t need to know anything about each other.

It’s the job of the home automation controller to see the events published by the switch controller, and then decide what to do about them. Internally, it can maintain a record of the current state of the relay driver, and send alternate “on” and “off” messages each time it sees a button press event.

1 Like

Thank you Fredderic and Jon, you have changed my mind :slight_smile:
One more advantage in putting the logic into the brain - if you need to do any changes to the automations - you don’t have to upload the code to arduino every time, you just change it in one place.

Fredderic, I had my HA downtime for about a week one time and then for 2 days again. PI just stopped responding and reimaging or restore from backup didn’t help, took a week to get my second PI. It worked for a month and then stopped responding as the previous one. The problem was in a bad power supply unit. But I also have regular ones when I need to reboot it and it hangs, if I didn’t check config and there are some errors or typos. Happens sometimes, quick to restore, but still takes 5-10 minutes.

It’s all getting better of course and I don’t really have those long downtimes anymore. Will see how it goes and if it becomes annoying I will setup a dev system.

Yeah, both of mine were running continuously about a month, before they started their duty controlling my system. I also made a point of getting slightly over-spec’d (and non-cheapo) power supplies — you need the right voltage, but there’s no harm throwing in an extra amp or two. Plus, a more capable power supply will often run cooler, because it’s just breezing along rather than having to struggle to keep up. Also, backups and fallbacks, and test them once in a while.

My main backup test, will be when I migrate to the new Pi 4… I’ll set it up normally first, give it something simple to do for a month, and then when I’m ready, pull out it’s SD card, and whack in a new one “restored from backups”. Another thing to keep in mind with Pi’s, is that SD card will fail at some point, so right from the start, I’ve planned accordingly.

And the absolute last fallback; I’ve tested running my original scripts on my PC, with a bridged MQTT server. My PC is also running a Python script I put together just recently (my first foray into Windows programming with Python) to let me lock it and turn off the monitors from the HA, plus lets my HA query to see if it’s presently locked as well (though unfortunately it’s not able to tell the difference between locked, and that Ctrl-Alt-Del screen). So I dropped a couple watchdog tasks into that script too, and if one of the things it’s checking up on with both the Pi’s shows bad, it’ll pop up a message on my main PC, hopefully before the lights stop working. :smiley:

All up, so far in just over a year now that I’ve being messing with automations, I’ve not had any real issues, except a few stupids early on, and I’ve put things into play to prevent them from happening again. I am, however, keeping those original scripts around; they lack the bells and whistles, but worst-case, they’ll keep the basics going in a pinch.

For HA, especially until you’ve got a dev system to mess with safely, remember to always check your configs before you apply them; a good command to know is hassio ha check && hassio ha restart, which will check your configs, and only if they pass, try to restart HA to load them. And when you’ve made a significant change, and you’re happy it’s all working, back it up (I use Git for the main configs, and then scp my secrets file and a couple others into the Dropbox folder of my PC as needed). But at the end of the day, it’s an important system, so just treat it that way, and don’t cut too many corners.

1 Like

Have a read of my post from a few months back.

Might help you out

Could you do a video on the topic of where to put, and how to implement, state control? I’m very confused by it…
My current setup is Node-RED, Amazon Alexa, Sonoffs and a few ESP8266 buttons with DHT22 temperature and humidity sensors attached. The Sonoffs and ESPs are running Tasmota.
I can see why I’d want the state stored in Node-RED but Alexa operates directly on the Tasmota devices, independently from Node-RED (though I make use of the status messages to toggle the dashboard switches) and doesn’t seem capable of outputting a ‘toggle’ command - meaning that the state is inherently stored on the device (Sonoff or ESP).
This does mean that, if the Node-RED/MQTT goes down, I still have Alexa control but that seems to be the only upside…