MQTT trigger toggling light state

Related to another thread I have going, I’m looking to set up a simple button for my daughter to be able to press to turn her light on or off. Since there is essentially nothing out there that is wireless and battery powered that’ll fit the bill (they all seem to have issues that make them ‘not great’ for a toddler), I’ve taken to wiring up a first gen Raspberry pi that I have sitting around with a button and scripts to interpret that button press and then publish a mqtt event.

I’ve made remarkable headway (for me, lol), but I’m not sure it’s the best or really proper way to do it.

I’ve got the pi that has the button publishing to itself, and I have mqtt in HA set up to point to that pi with the topic and payload, and I have a trigger set to activate a scene and amazingly (again, for me) it works. BUT. I’m not sure this is the best (or even right) way to do the mqtt messages, and I don’t want to activate a scene, but instead toggle a light state (If it’s off, turn it on, it’s on, turn it off). The only possible challenge with that requirement (toggling the state) is most of my switches are the Leviton DZMX1-1LZ, which do not send the instant status updates back to the controller if activated manually. I’ve read that they eventually do, but my experience has been that HA has no clue if they have been turned on or off manually and the status never updates. I have not figured out how to make HA poll the status of the devices to update them if they’ve changed. I have a few of the Vizia RF line of z-wave switches that DO send the instant status update when operated manually, so if I have to get one of those to make this work how I want, so be it (I do want to eventually replace the DZM switches with the Vizia RF switches).

I would THINK the better approach with the mqtt messages would be to have HA set up to look to itself, and have the pi publish it’s messages to HA. It seems like setting HA to point to the pi with the button would be pigeon-holing it to not be able to interface with other mqtt sources, such as my Open Energy Monitor setup, if I wanted it to get data from that, for example.

One other part, which I’m no sure where the best place to address it would be, is since this is for my Toddler daughter, It would be a good idea to have some kind if ‘sleep’, where if you press the button, subsequent presses will be ignored for a period of time (say 15 seconds), so she can’t be turning her light on and off 50 times a minute. Is this something that could be handled by HA, or should it be done on the button side?

Does anyone have any advice on how to best set up the mqtt messaging, and how to get the button press to toggle a dimmer state, or if need be, have HA poll the switch, and activate the opposite scene, so if the status is ‘off’, it activates the ‘Turn light on’ scene, and if the status is ‘on’, it activates the ‘Turn light off’ scene?

Edit: Probably wouldn’t hurt to include my relevant config settings.

configuration.yaml:

mqtt:
  broker: 192.168.1.17
  port: 1883
  client_id: home-assistant-1

automation.yaml:

- alias: 'Toggle Room Light'
  trigger:
    platform: mqtt
    topic: hass/light/Room
    # Optional
    payload: 'Toggle'
  action:
      service: scene.turn_on
      entity_id: scene.Office_Lights_Off

I’m using my office lights for testing since that’s where I’m working and my daughter is sleeping :).

You could run the MQTT broker on the other PI, but that would make you reliant on that PI being active. If its around a toddler, I wouldn’t think that is going to be very reliable.

I suggest you run the broker on the same machine as HA and publish MQTT messages from the PI to this, so when your daughter spills milk over the PI, only that stops working.

Yes, but how would I do that? I pointed the ‘ButtonPi’ at HA and had HA looking to itself like it’s set up by default, and with the trigger still in place, nothing happened. I had read another post where it seems the person was doing something similar and was only able to make it work with the ‘ButtonPi’ publishing to itself, but I don’t know he had HA subscribe to it.

I guess you should maybe simply start with a toggle of the switch/light your using:

automation:
  - alias: Toggle lamp
    initial_state: True
    hide_entity: False
    trigger:
      platform: mqtt
      topic: home/433toMQTT
      payload: 13210193
    action:
      service: switch.toggle
      entity_id: switch.column_lamp

For that I use a 433MHz wall switch, they are inexpensive, between 8 and 10€ and can control from 1 to 3 automation: VHome switch
They also have the advantage to run on a small battery, so no need of cabling and no danger of modifying some existing wall switch.

To receive the 433MHz signal I use a [MQTT enable RF receiver] (https://1technophile.blogspot.de/2016/11/433nIRtomqttto433nIR-bidirectional-esp8266.html)

I’m not sure which bit you don’t understand, so I’ll go through the whole procedure.

  1. You set up the mqtt broker on the same machine as HA. You did this on the Pi, so its the same procedure as that, but for whatever operating system you are using for HA.

  2. You send the MQTT messages from the Pi to the broker on the HA machine. To do this you send them to the IP address of the MQTT machine, instead of the PI, so the address in mqtt_publish will change.

  3. Check that the broker on the HA machine is receiving the messages. I use mosquitto, so I normally use mosquitto_sub to do this, but there are other mqtt clients that will do the job.

$ mosquitto_sub -h <HA machine address> -t "hass/light/Room" -v 
  1. Set up HA to use the broker on the local machine by changing the ip address in the mqtt section to 'localhost`
mqtt:
  broker: localhost

And all should work the same as it is now. But if you lose your daughter’s Pi, MQTT messages will still be processed by HA.

After a bunch of trial and error and digging around, I finally got the ButtonPi to send the messages to HA. I had to add an ‘auth’ section to it so it sends credentials over, and now when I pressed the button, it turned my office lights off.

With some more trial and error, I got it to do what I want with this automation:

- alias: 'Toggle Room Light'
  initial_state: True
  trigger:
    platform: mqtt
    topic: hass/light/Room
    # Optional
    payload: 'Toggle'
  action:
      service: light.toggle
      entity_id: light.leviton_unknown_type1b03_id0334_level_18_0

The only ‘gotcha’, as I stated earlier, may be that these DZM switches don’t update their status to the controller, so if the controller thinks the switch is on, but it’s off, my guess is the controller will send an ‘off’ command. We’ll see how it goes - if need be, I’ll order a new dimmer for her room.

Definitely going to need to do something different for the button presses though - if you hold the button, it keeps turning the light on and off, and if you press it 64 times in a row, it tries to keep turning the light on and off.

Thanks for the help.

The simplest solution I can think of for this is to make the script conditional on an input_boolean. Then turn this on in the script, delay for a length of time, and then switch the input boolean back after the delay.

The input_boolean could also be used to stop the script being used, if you ever needed to do that.

The simplest solution is still to forbid the kid to do so ^^ a mechanical switch can also be pressed 120 times per minutes.

Another possibility is to create a second automation triggered by the switch, which role is to turn off the main automation “toggle_room_light” and turn in back on after the desired time.
So the switch trigger won’t have any effect as long as the first automation is off.

I guess to achieve that you can inspire yourself from this automation:

I’m trying to work on getting this taken care of on the Pi/Button side, so that the scripts that run the button input handle this logic and if the button is held, the MQTT message is only sent once, and if the button is pressed 20 times in 10 seconds, only the first press is registered.

Although, at the end of the day, this entire exercise may be a moot point: http://z-uno.z-wave.me/

I have their Razberry as my Z-Wave interface and it’s always worked well. That Z-Uno looks REAL neat and promising. Some people have made some real neat examples.

I got the multiple button press issue handled on the ButtonPi side with help on the Raspberry Pi forums - if the button is pressed 10 times in 5 seconds (I currently have a delay of 10 seconds after press set), only the first press sends a MQTT message and it it’s held, it only sends one message until the button is pressed and released again…

Sounds like a good design. Far better to cut these things off at source.

The z-uno looked interesting until I saw the price. Its more than the ready made sensors.

To be honest, I haven’t seen a price - that could potentially be a dealbreaker. But it does seem to have a lot of potential, and unlike the ready made devices, you should be able to make it do anything.

Edit: Just looked around some more ad found it for sale apparently in the UK - £58.00 ($72.39) YIKES. I was figuring they’d be like $20-30.

Edit2: In case anyone’s interested, these are the scripts on the ButtonPi that make it work.

I have a python file containing the following script, which was set up in crontab to run at boot:

import RPi.GPIO as GPIO
import time
import os


GPIO.setmode(GPIO.BCM)

GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

while True:
    input_state = True
    while input_state == True:
        input_state = GPIO.input(18)
        time.sleep(.01)
    os.system('python /home/pi/mqttbutton.py')
    time.sleep(10)
    input_state = False
    while input_state == False:
        input_state = GPIO.input(18)
        time.sleep(0.01)

As you can see, that calls the python script ‘mqttbutton.py’ when the button is pressed:

import paho.mqtt.publish as publish
auth = {
  'username':"username",
  'password':"password"
}
publish.single("hass/light/Room", "Toggle", hostname="HASS_IP", auth=auth)
1 Like