MQTT Switch

Hello, I discovered HomeAssistant recently.
with HA, I build interface to monitor lamp from ESP8266 (truned into ESPduino) via MQTT platform.
But, I’m facing a problem with switch that automatically “turn off” after switch to “turn on”.
This is my script

switch 1:
  platform: mqtt
  name: "Lampu 1"
  state_topic: "/test/confirm"
  command_topic: "/test/light1"
  payload_on: "1"
  payload_off: "0"
  qos: 0
  retain: true

after adding optimistic value to the script, the problem solved. But, I want to keep switch like a toggle,
not like a push button (in optimistic mode) :

switch 1:
  platform: mqtt
  name: "Lampu 1"
  state_topic: "/test/confirm"
  command_topic: "/test/light1"
  payload_on: "1"
  payload_off: "0"
  qos: 0
  retain: true
  optimistic : true

Any solution for this problem?

You should use “optimistic : false” and confirm the state of your switch to HA with the “state_topic”. Without the confirmation, the switch (in HA) turns in its previous state. I’ve made a simple example with an esp8266.

configuration.yaml :

switch:
  platform: mqtt
  name: 'Office Switch'
  state_topic: 'office/switch1/status'
  command_topic: 'office/switch1/set'
  optimistic: false

Thanks for reply, as you can see I’ve describe confirm status to HA.

state_topic: “/test/confirm”
command_topic: “/test/light1”

But the problem still exist (I’ve changed optimistic to false), toggle automatically turn off.
any other possible solution?

*btw, what exactly the function of “optimistic” value for HA?

Is it possible to look at your code? Did you try to capture the traffic with Wireshark or to use a MQTT client (MQTTfx for example) to subscribe to these two topics?

It is ok, I tried to build it from ItKindaWorks project. (Github)
This is the code I customized for HA :

homeassistant:
name: Home

temperature_unit: F
time_zone: EST

http:
api_password: ####

mqtt:
broker: 127.0.0.1
port: 1883
client_id: home-assistant-1
keepalive: 60

sensor 1:

  • platform: mqtt
    state_topic: “/house/temp1”
    unit_of_measurement: “°F”
    name: “Temperature”

binary_sensor 1:
platform: mqtt
state_topic: “/house/door1”
name: “Door Sensor”
qos: 0
payload_on: “1”
payload_off: “0”

switch 1:
platform: mqtt
name: “Outlet 1”
state_topic: “/test/confirm”
command_topic: “/test/light1”
payload_on: “1”
payload_off: “0”
qos: 0
retain: true
optimistic : false

group:
Home Sensors:

  • binary_sensor.door_sensor
  • sensor.temperature
  • switch.outlet_1

I’m sorry I cant capture image for publish/subscribe process using mosquitto now, because I left my project in the office. But I tried to check it last week, publish/subscribe process was going well in mosquitto command. When I published (send “1” to payload), the subscribed monitor gave me “Light On”/“Light Off” status.

I had this as HA was not getting a payload (0 or 1) back on that state_topic. If it does not, the switch will turn on then 1 second later, off again. Install MQTT.fx and subscribe to your topic /test/confirm to ensure the payload is coming back and exactly what it is then modify your yaml to match. Here my working code using a Sonoff and ESPEasy (R121).

switch 4:
  platform: mqtt
  name: "Sonoff3"
  state_topic: "/sonoff3/relay/state"
  command_topic: "/sonoff3/gpio/12"
  payload_on: "1"
  payload_off: "0"
  qos: 1
  retain: true

Furthermore, if you add the following to the top of your yaml just under ‘homeassistant’ as I’ve shown, the switch will look so much better.

homeassistant:

  # Add this to your existing configuration
  # Only the `entity_id` is required.  All other options are optional.
  customize:
    switch.sonoff3:
      friendly_name: Sonoff 03 (floor)
      icon: mdi:lightbulb-outline  
      assumed_state: false

If your payload coming back on the subscribed topic is as above, you need to modify your payload settings for your switch 1 to reflect these values.

Thanks for your big help xbmcnut, now I have change payload_on : “1” & payload_off : “0” and its working.
But I’m facing new problem, if I make more than one switch, how to handle it?
Is it possible to share your code in HA and esp? I want to know about topic arrangement to handle more than one switch.
Thanks before.

That part is actually pretty easy. Simply name your switches uniquely or follow the guide here for defining the best layout approach. As my yaml is small at the moment, I’m using the following:

switch 4:
  platform: mqtt
  name: "Sonoff4"
  state_topic: "/sonoff4/relay/state"
  command_topic: "/sonoff4/gpio/12"
  payload_on: "1"
  payload_off: "0"
  qos: 1
  retain: true

switch 5:
  platform: mqtt
  name: "Sonoff5"
  state_topic: "/sonoff5/relay/state"
  command_topic: "/sonoff5/gpio/12"
  payload_on: "1"
  payload_off: "0"
  qos: 1
  retain: true

The firmware I’m running is version R121 of ESPEasy.

Very very big thanks, I’ve tried & it works.
Now I want to add timer in HA, I found many example about it, but till now automation script like didnt work well. This is the script :

> switch 1:
>   platform: mqtt
>   name: "Outlet 1"
>   state_topic: "instalasi/status1"
>   command_topic: "instalasi/lampu1"
>   payload_on: "1"
>   payload_off: "0"
>   qos: 0
>   retain: true
>   optimistic : false
>   
> switch 2:
>   platform: mqtt
>   name: "Outlet 2"
>   state_topic: "instalasi/status2"
>   command_topic: "instalasi/lampu2"
>   payload_on: "1"
>   payload_off: "0"
>   qos: 0
>   retain: true
>   optimistic : false
>   
> switch 3:
>   platform: mqtt
>   name: "Outlet 3"
>   state_topic: "instalasi/status3"
>   command_topic: "instalasi/lampu3"
>   payload_on: "1"
>   payload_off: "0"
>   qos: 0
>   retain: true
>   optimistic : false
>   
> switch 4:
>   platform: mqtt
>   name: "Outlet 4"
>   state_topic: "instalasi/status4"
>   command_topic: "instalasi/lampu4"
>   payload_on: "1"
>   payload_off: "0"
>   qos: 0
>   retain: true
>   optimistic : false
>   
> group:
>   Switch Group: 
>    - switch.outlet_1
>    - switch.outlet_2
>    - switch.outlet_3
>    - switch.outlet_4
>   
> automation:
>     trigger:
>         platform: time
>         after: "10:15:00"
>     action:
>         service: group.switch.outlet_1.turn_on

Whats wrong with the code? Switch.outlet_1 should be turn on at 10:15:01, isn’t it?

Sorry man, I’ve not done any automation as yet as I’m slowing building my assets and working on creating different files for everything as my house is a live install. Migrating from Vera so I have to be careful not to break anything or the wife will break me! :wink:

oke, never mind. thanks for reply.

- service: switch.turn_on
  data:
    entity_id:
      - switch.outlet_1

If you use service I think you need something like that.

Hmm just noticed the time, you probably solved it by now :slight_smile:

I read over this thread, and still didn’t have the solution I was looking for. I was having the same issue @xbmcnut was having, where when i loaded homeassistant, i was getting the state set on the mqtt topic, but the switch would not stay in the state I set.

What i found was that I need to have the state_topic and the command_topic the same. When i did that, it was able to read the state correctly, as well as setting. I only found this by SSHing into by Pi running HA, and subscribed to the topic, so i could monitor what going on.

my config yaml for the switch:

switch:
    platform: mqtt
    name: 'Notify Washer Switch'
    state_topic: 'sensor/notify/washer/set'
    command_topic: 'sensor/notify/washer/set'
    retain: true
    optimistic: false   
    payload_on: "1"
    payload_off: "0"    

And for making the switch look prettier as @xbmcnut suggested (i am using this as a switch for turning on or off notifications for my washing machine - project notes soon to come as i finish) here is the code under the customize in main HA root:

switch.notify_washer_switch:
    friendly_name: Notify Washer Switch
    icon: mdi:washing-machine

So when the switch is on

and when the switch is off

I am using a Sonoff device with the firmware provided by arendst/Sonoff-Tasmota project. Thanks to the tips I got from this topic I finally got the MQTT switch to work properly. I just wanted to share with you the steps I followed and I hope it helps.

  • platform: mqtt
    name: “Sonoff”
    state_topic: “stat/sonoff_1/POWER”
    command_topic: “cmnd/sonoff_1/POWER”
    optimistic: false
    payload_on: “ON”
    payload_off: “OFF”
    qos: 1
    retain: true
  1. Set optimistic to false, since you have a state_topic to tell you the actual state of the switch. The firmware allows you to set PowerRetain to “1” so the last state info will always be available.

  2. In my case I realized the state_topic is case-sensitive - the command_topic is not. If you do not set the topic properly, you will not receive a valid status and the switch will keep turning off after you turn it on.

  3. Set the payload_on and payload_off to be the exact value you receive when you subscribe to the state_topic. I used mosquitto_sub to check what I was receiving. Even though the command works with either “on” or “1”, the state_topic always sends “ON” as a response.

3 Likes

Thanks for the post! That worked for me the first time… I appreciate your posting the working solution.

I am glad it helped.

@dparaujo can you post also a photo with
Sonoff-Tasmota Mqtt configuration for sonoff? Thanks!

The MQTT configuration at the web interface should be similar to this:

MQTT parameters

Host (192.168.1.XXX)
192.168.1.XXX

Port (1883)
1883

Client (DVES_972F7D)
DVES_%06X

User (sonoff_1)
sonoff_1

Password
••••••••

Topic = %topic% (sonoff)
sonoff_1

Full Topic (%prefix%/%topic%/)
%prefix%/%topic%/

What
qos: 0/1
stands for?