Trouble with custom MQTT switch

Ive been struggling trying to figure out how to make a simple MQTT switch.

I have a Cambridge Audio receiver that accepts RS232. With the help of this project
https://github.com/elvenpath/CambridgeAudioAzur351R-RS232toMqtt
I am able to control my amp using the publish.mqtt service.

How do I start to integrate basic mqtt switches? I’ve tried using the example in the docs, but I’m unsure on what i need to alter? obviously the topics will be different but I’m a little stumped on what to do next.

These are the commands available.

This is what I’ve been trying and changing the payloads around with different commands. The switch shows up in Dev Tools but wont switch on.

- platform: mqtt
  unique_id: ca_amp_power
  name: "Cambridge Audio Power"
  state_topic: "receiver/stat"
  command_topic: "receiver/cmnd"
  payload_on: "on"
  payload_off: "off"
  state_on: "ON"
  state_off: "OFF"
  optimistic: false
  qos: 0
  retain: true

According to the documentation link you provided, the state and command data isn’t simply on/off (nor ON/OFF). The data is in JSON format.

Try this version:

- platform: mqtt
  unique_id: ca_amp_power
  name: "Cambridge Audio Power"
  state_topic: "receiver/stat"
  value_template: "{{ value_json.status }}"
  command_topic: "receiver/cmnd"
  payload_on: '{"status": "on"}'
  payload_off: '{"status": "off"}'
  state_on: 'on'
  state_off: 'off'
  optimistic: false
  qos: 0
  retain: false

So I tried your version and I get the same result. The switch turn on for a second then off.

Using the MQTT integration and listening to the receiver/stat topic I can see that no traffic is being sent

That’s an important bit of information. I assumed communication was functional when you stated:

The implication is that the device is not publishing anything to the topic receiver/stat in response to Home Assistant publishing to receiver/cmnd.

Do you have access to another MQTT client like MQTT Explorer? It’s a very useful tool for debugging MQTT communication problems. Use it to confirm payload format is correct and payloads are published to proper topics. You can use Home Assistant to do that but MQTT Explorer is more convenient.

Sorry for not being clear. When I manually send a command using the publish.mqtt service or an external MQTT client the amp behaves as expected and the traffic all looks correct.

Im not in front of the amp at the moment so I cant actually see what is physically happening. :crazy_face:

I have enable syslog and it appears to be sending the correct commands

But the switch in HA turns its self back off

That’s standard behavior in Home Assistant when it fails to receive a reply from the device after sending it a command to turn on (i.e. it reverts to off).

  • We may be sending the wrong “turn on” command to the device.
  • If it’s the correct command, the device is not responding with an acknowledgement in a timely manner.

What about escaping the inner quotes?

payload_on: '{\"status\": \"on\"}'
payload_off: '{\"status\": \"off\"}'

That’s a possibility because Home Assistant’s native typing might be altering the JSON syntax. It would also support what I wrote in my previous post that we might be sending the wrong command to the device (and so it fails to reply and the switch’s state reverts to off). In this case the command is mostly correct but the double-quotes might be getting messed up.

@IamDan
If you use an MQTT client, you can observe what Home Assistant is publishing to receiver/cmnd. If the payload’s double-quotes aren’t correct then apply duceduc’s suggestion and escape the meaning of all the double-quotes with a backslash.


EDIT

I used mqtt.publish to publish {"status": "on"} to topic xyz and it was done correctly (i.e. there was no misrepresentation of the double-quotes).

Screenshot from 2021-07-01 22-03-23

Screenshot from MQTT Explorer:
Screenshot from 2021-07-01 22-01-35

The question remains is if this also true for payload_on in an MQTT Switch.

Follow-up:

I just confirmed there’s no need to escape the double-quotes in {"status": "on"}.

I tested the MQTT Switch configuration (that I posted above) and confirmed it works correctly.

Lovelace UI:
Screenshot from 2021-07-01 22-11-42

MQTT Explorer:
Screenshot from 2021-07-01 22-11-57

  • Turning on the MQTT Switch publishes {"status": "on"} to receiver/cmnd.
  • I can emulate the device by using MQTT Explorer to manually publish {"status": "on"} to receiver/stat to acknowledge receipt of the “turn on” command. As a result, the MQTT Switch remains on and doesn’t revert to off.
  • Manually publishing {"status": "off"} to receiver/stat changes the MQTT Switch’s state to off (as it should).

Based on my results, the suggested MQTT Switch configuration appears to be fine. The issue now is for you to confirm if:

  1. Turning on the MQTT Switch publishes {"status": "on"} to receiver/cmnd.
  2. The amplifier replies by publishing {"status": "on"} to receiver/stat.

Unfortunately I’m not at home at the moment to actually read the traffic. (Any suggestions for an Android app I can use over VPN). Ill have to check it in a few hours

hmm im not getting the on reply.
Screenshot from 2021-07-02 16-49-13

The timestamps indicate the reply to the command comes 11 seconds later? Even if it did reply with {"status": "on"} eleven seconds is a long time and the switch would initially revert to off and then, several seconds later, flip back to on.

However, the fact is it’s actually replying off not on so that needs to be rectified first.

Yeah that 11 secs is the amp booting up. Is there a way to make the switch assume its on?
Over serial its very reliable

EDIT: I changed optimistic to false and it worked!!!

That’s surprising because optimistic: true means it won’t wait for an acknowledgement and assumes all transmitted commands are received.

The default is optimistic: false where an acknowledgement is expected and required.

BTW, your original MQTT Switch configuration included this:

retain: true

That is not recommended for a switch. The reason is because the MQTT Switch’s published command is stored on the broker. If the broker is restarted or the amplifier reconnects to the broker, the amplifier will receive the last published command. This may seem to be desirable but there is a scenario where it can cause the amplifier to be turned on unexpectedly (amplifier is turned off manually and then the broker restarts and the amplifier receives the stored {"status": "on"} payload).

Changing retain: true to retain: false is insufficient to change the broker’s handling of the payload. You must purge the topic of any retained message first. If you are using MQTT Explorer, it allows you to easily delete a retained message. Otherwise the traditional way is to publish an empty payload (i.e. empty string) as a retained message to the topic.

1 Like

Perhaps it may or may not be helpful for me to point out that I believe I have seen a mqtt media player somewhere around here. It was possibly a custom component, although I can’t see it in HACS.

Edit: AAHAA found it GitHub - TroyFernandes/hass-mqtt-mediaplayer: Fill out your Media Player Entity with MQTT Topics

yeah i saw that thanks! It is missing a few things but might work for now :+1:

If the configuration I posted above is working correctly, please consider marking my post (above) with the Solution tag. It will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. It will also place a link below your first post that leads to the solution. All of this helps users find answers to similar questions.

1 Like

Thanks for all the help guy!!