MQTT turning a message into an entity

Hi all, Ive just installed HA and am brand new to it so still getting my head around things. Ive had a long term set up on nodered but wanted to try HA so Im gradually porting things over. Im starting to get the MQTT based items (read only at this point) into HA but Im confused about the configuration.

I used IOTstack to set everything up so its running inside a container and on the current pi OS version.

Im using the method of publishing the config to HA via MQTT and this is working. But after this, Im confused about where the configuration actually lives inside the file system. But this isnt the main issue.

I have a few sensors reading fine but some others not so much. I have two examples, and analogue sensor and a binary status. there are multiple and all not working.

This is the MQTT message im trying to pick up (its a custom device I programmed a long time ago)
This is the content of the ‘home/PIV/state’ object, so dont be confused about the state object inside here as well!

{
  "state": {
    "enable": true,
    "speed": false
  },
  "freshAirSensor": {
    "temp": 9.111444,
    "pres": 1022.437,
    "hum": 83.67773
  },
  "supplyAirSensor": {
    "temp": 9.3053,
    "pres": 1024.119,
    "hum": 61.59961
  },
  "shower": {
    "demand": false
  },
  "wifi": {
    "rssi": -63
  }
}

Analogue sensor first.
I sent this as the config

{
  "device_class": "temperature",
  "name": "PIV Fresh Air Temperature",
  "state_topic": "home/PIV/state/freshAirSensor",
  "unit_of_measurement": "°C",
  "value_template": "{{ value.temp }}",
  "unique_id": "PIVFreshAirTemperature"
}

and the binary sensor

{
  "name": "PIV Fan Enable",
  "state_topic": "home/PIV/state/state/enable",
  "payload_on": "true",
  "payload_off": "false",
  "device_class": "moving",
  "unique_id": "PIVFanEnable"
}

All items that I sent a config for have appeared in the entity list inside the MQTT integration.
Im not sure why the analogue sensor isnt reading, because I followed the same setup config as a previous sensor, although from a different MQTT message. And the binary sensor, I know the /enable, should be .enable in the JSON format but Ive tried a few ways that I couldnt get my head around. But Im aware this is wrong, I dont know what to try next. For the analogue sensor I tried value_json.temp first but this didnt work so tried value.temp instead. I dont know if there is an equivalent for the binary sensor. I feel thats what I need.

Thanks!!

also cant work out how to format the code blocks!

To format the code blocks put 3 back-ticks (```) on the line before and line after the code. You can also highlight the code and click Preformatted Text (</>) in the toolbar.

There are a couple of problems:

  • You can’t use topic to drill into the content of the message. Topic and content are completely separate. So if you’re publishing “home/PIV/state”, you have to subscribe to that same topic (incl possible wildcards). Therefore there is no message “home/PIV/state/freshAirSensor” or “home/PIV/state/state/enable”.
  • The “value_template” should use “value_json”, not “value”. It is then the whole message, so your sensors would use the following:
"value_template": "{{ value_json.freshAirSensor.temp }}"
      and
"value_template": "{{ value_json.state.enable }}"

EDIT: When I copy/pasted your code I got weird MS Word quotes (“”) rather than simple keyboard ones. If you’ve got them in your config it probably won’t work either, but I would expect you’d get a more severe error.

Thanks, what you say here makes sense and Ive got all analogue items now reading fine. However the binary sensors points are showing as unknown. I did read about this being a default state but Ive defined the on and off payloads and on the binary sensor page is the following text in the value_template option.

value_template string (optional)

Defines a template that returns a string to be compared to payload_on/payload_off or an empty string, in which case the MQTT message will be removed. Remove this option when payload_on and payload_off are sufficient to match your payloads (i.e no pre-processing of original message is required).

I dont understand this, if I remove the value_template then there is no reference to the json object I need to get the value from. I saw there was an example using an if/else statement but I dont know how that would apply to my scenario as I dont know what ‘is_state’ means in this context.

# Example configuration.yaml entry
mqtt:
  binary_sensor:
    - state_topic: "lab_button/cmnd/POWER"
      value_template: "{%if is_state(entity_id,\"on\")-%}OFF{%-else-%}ON{%-endif%}"

thanks for you help

I agree that the wording on the MQTT Binary Sensor page is confusing. I think what they’re trying to say is, if the MQTT message contains a string that matches ‘payload_on/payload_off’, then you don’t need to specify a ‘value_template’. So if ‘payload_on’ is set to ‘yes it is on’, and this is what you send in the message, you don’t need ‘value_template’. And if the message sends ‘on/off’ or ‘true/false’ then you don’t need ‘value_template’ or ‘payload_on/payload_off’.

But if you do specify ‘value_template’, that is what sets the state - it’s a pity they didn’t call it ‘state_template’ instead. That’s probably why referring to “is_state(entity_id, ‘on’)” doesn’t work - you’re trying to set the state using the value of the state.

I guess it’s possible that if you’re sending simple JSON you could omit ‘value_template’ and, for example:

"payload_on": "{ \"ison\": true }"

I don’t know that this would necessarily work, but state gets converted to a string, so that’s what it would look like if you sent that JSON without specifying ‘value_template’. However, in your case with more complex JSON, you’re always going to have to specify ‘value_json’, and will therefore always need ‘value_template’.

You could try this, and then omit payload_on/payload_off:

"value_template": "{{ 'on' if value_json.state.enable else 'off' }}"

I think the case might matter - I’ve read somewhere what HA considers as ‘true’, and it includes ‘on’ and ‘True’ etc., but I’m not sure about ‘ON’ vs ‘on’.