MQTT Switch

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?

From MQTT Tutorial: An Easy Guide to Getting Started with MQTT

Each message can be published with one of three quality of service levels (QoS). These levels are associated with different guarantees. A message send with level 0 doesn’t have a guarantee at all, it implies fire and forget. Level 1 guarantees that the message will at least arrive once, but can arrive more than once. Level 2 is the most sophisticated choice, which guarantees that the message arrives at the destination exactly once. The choice of QoS is a trade-off, between protocol overhead and the guarantee that the message arrives, because ensuring QoS 2 is using more bandwidth than QoS 0.

1 Like

Hi there,

I am testing controlling a gate (open/close) with Home Assistant and a Sonoff/Tasmota in an industrial environment in a large industry.

I use a MQTT switch with a button on the front end, no physical switch. Tasmota is configured to turn on the relay for 1,5 sec every time the button is pressed.

Our WiFi coverage reaches the whole industry (around 50 access points to give an idea of size) and there will be like 15 people who will be authorized to command the gate. Most of them are older managers from a generation that doesn’t feel very comfortable operating a smartphone.

So there is a safety concern here, I fear they may inadvertently click on the shortcut and command open/close the gate without being close to it when operating their smartphones with other purposes in mind.

I plan to use a BLE beacon to increase security, thus demanding the user to be close to the gate, but what I would like to do immediately is to setup an ON-DELAY timer somewhere (Tasmota or MQTT Switch or automation) that would force the user to keep the button pressed for a given time before the command is issued.

Something like a long press that tasmota already has, but on a virtual button on the front end. Is that possible?

Thank you in advance for any help.

Tales