MQTT Light/Templating Help

Didn’t get a ton of help on the Discord, hoping someone can help here. I’ve literally been pulling hair over getting MQTT Lights to work nicely. I got them finally to work/be controlled by my 2nd instance but I get getting a ton of errors. Normally I would keep trying but I’ve been at this for hours and just feel like giving up.

The errors i get are: Invalid brightness value received, Error parsing value: ‘value_json’ is undefined (value: off, template: {{ value_json.state }}), and Error parsing value: ‘value_json’ is undefined (value: on, template: {{ value_json.brightness }})

Here is an example light:

  - platform: mqtt
    schema: template
    name: Office Level
    command_topic: "homeassistant/light/office_level/set"
    state_topic: "homeassistant/light/office_level/state"
    command_on_template: >
      {"state": "on"
      {%- if brightness is defined -%}
      , "brightness": "{{ brightness }}"
      {%- endif -%}
      {%- if transition is defined -%}
      , "transition": "{{ transition }}"
      {%- endif -%}
      }
    command_off_template: >
      {"state": "off"
      {%- if transition is defined -%}
      , "transition": "{{ transition }}"
      {%- endif -%}
      }
    state_template: "{{ value_json.state }}"
    brightness_template: "{{ value_json.brightness }}"

Also, I had to create a ton of automations to control all the varies situations involving brightness and transitions. Can anybody help shrink this down? I suck at templating.

- alias: "MQTT Light On No Brightness No Transition"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
  - condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  - condition: template
    value_template:  "{{ trigger.payload_json.state | lower == 'on' }}"
  - condition: template
    value_template:  "{% if trigger.payload_json.brightness is defined  %}False{% else %}True{% endif %}"
  - condition: template
    value_template:  "{% if trigger.payload_json.transition is defined  %}False{% else %}True{% endif %}"
  action:
    - service_template: "light.turn_{{ trigger.payload_json.state | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"

- alias: "MQTT Light Yes Brightness Yes Transition"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
  - condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  - condition: template
    value_template:  "{{ trigger.payload_json.state | lower == 'on' }}"
  - condition: template
    value_template:  "{% if trigger.payload_json.brightness is defined  %}True{% else %}False{% endif %}"
  - condition: template
    value_template:  "{% if trigger.payload_json.transition is defined  %}True{% else %}False{% endif %}"
  action:
    - service_template: "light.turn_{{ trigger.payload_json.state | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"
        brightness: "{{ trigger.payload_json.brightness }}"
        transition: "{{ trigger.payload_json.transition }}"

- alias: "MQTT Light Yes Brightness No Transition"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
  - condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  - condition: template
    value_template:  "{{ trigger.payload_json.state | lower == 'on' }}"
  - condition: template
    value_template:  "{% if trigger.payload_json.brightness is defined  %}True{% else %}False{% endif %}"
  - condition: template
    value_template:  "{% if trigger.payload_json.transition is defined  %}False{% else %}True{% endif %}"
  action:
    - service_template: "light.turn_{{ trigger.payload_json.state | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"
        brightness: "{{ trigger.payload_json.brightness }}"

- alias: "MQTT Light Off No Transition"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
  - condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  - condition: template
    value_template:  "{{ trigger.payload_json.state | lower == 'off' }}"
  - condition: template
    value_template:  "{% if trigger.payload_json.brightness is defined  %}False{% else %}True{% endif %}"
  - condition: template
    value_template:  "{% if trigger.payload_json.transition is defined  %}False{% else %}True{% endif %}"
  action:
    - service_template: "light.turn_{{ trigger.payload_json.state | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"

- alias: "MQTT Light Off Yes Transition"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
  - condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  - condition: template
    value_template:  "{{ trigger.payload_json.state | lower == 'off' }}"
  - condition: template
    value_template:  "{% if trigger.payload_json.brightness is defined  %}False{% else %}True{% endif %}"
  - condition: template
    value_template:  "{% if trigger.payload_json.transition is defined  %}True{% else %}False{% endif %}"
  action:
    - service_template: "light.turn_{{ trigger.payload_json.state | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"
        transition: "{{ trigger.payload_json.transition }}"
"brightness": "{{ brightness }}"

I’m guessing this is supposed to be something like:

"brightness": "{{ states('input_number.brightness') | int }}"

Where are you actually storing the brightness value in HA?

Likewise for transition.

No. It’s pulling from the mqtt payload. I think you may be right but what’s weird is the automations work. I just get an error. I pulled that straight out of the example on the mqtt light page.

Also, the brightness settings get published to a different mqtt topic. I’m not seeing a way to pull that topic instead of I’m guessing the state topic. I’m finding the fact that the different varieties of mqtt light are missing some features very annoying.

Not for command_on_template it’s not. You have to supply the entity or attribute that holds the value in the template so it can be published. “brightness” as a value here means nothing. Hence your error

 Error parsing value: ‘value_json’ is undefined (value: on, template: {{ value_json.brightness }})

Try this in the developer tools template editor:

    command_on_template: >-
      {"state": "on"
        , "brightness": "{{ state_attr('light.office_level', 'brightness') | int }}"
        , "transition": "{{ state_attr('light.office_level', 'transition') | int }}"
      }

Also you have no else case for your if statements so leave them out or supply a default value in an else statement (128 or something).

      {%- if state_attr('light.office_level', 'brightness') is defined -%}
        , "brightness": "{{ state_attr('light.office_level', 'brightness') }}"
      {% else %]
        , "brightness":"128"
      {%- endif -%}

I see what you’re saying but that literally is what is here: https://www.home-assistant.io/components/light.mqtt/#json-payload, and the docs says brightness and transition are allowed variables: https://www.home-assistant.io/components/light.mqtt/#command_on_template. Your example isn’t going to work because it’s a chicken and egg problem.

Again, pulling straight from the docs for this. I thought about an else statement but for brightness, in order for a light to be turned off brightness can’t be defined. For transition i wouldn’t mind a default value, but brightness was the issue.

Yeah ok I did not realise it had this:

Available variables: state, brightness, red, green, blue, white_value, flash, transition and effect.

I think I see what i need to do, i just am not quite sure how to do it. I need to set state_template and brightness_template based on an MQTT topic. IE this is what is in MQTT:

homeassistant/light/office_level/brightness 255
homeassistant/light/office_level/state on

Not sure how I use a template to extract that.

I’m having trouble understanding why this MQTT Light requires automations. I thought the purpose of the template schema is to provide complete flexibility to process received and transmitted payloads (without relying on automations).

Can you post a sample of the payload that is received (and, if not the same, the payload that is transmitted back to the light).

1 Like

I’m running two instances of HASS. One runs my Zwave network and the other is my “main” instance. (I’ve looked at zwave2mqtt but it won’t work for what i need). I’m basing my work off this thread: Automating the sharing of sensors and switches between HA's using MQTT Discovery and Statestream

And here is a copy/paste from MQTT-Explorer that shows all the values in MQTT. Includes the payload (what I want it to be).

last_updated = 2019-07-16T11:29:24.263374+00:00
brightness = 255
node_id = 50
value_index = 0
value_instance = 1
value_id = "72057594881605633"
friendly_name = "Office"
supported_features = 33
last_changed = 2019-07-16T11:29:24.263374+00:00
state = on
set = {"state": "on", "brightness": "255", "transition": "2"}

Edit: Maybe the issue is this. I’m trying to set the light based on the MQTT topics, which don’t have JSON values, and the light doesn’t pass the MQTT value in JSON (ie it uses the state and brightness topics, not what is in the set topic. So maybe I need to be using the json schema for lights instead? I just couldn’t get that working.

Thanks for the clarification. So those automations are based on RobDYI’s strategy to make entities discoverable (via MQTT Discovery) by another instance of Home Assistant.

In lieu of RobDYI’s strategy, you may wish to consider the following custom component:

Full disclosure: I have not tried it. However, others have and reported their success in this thread.

Sort of, i gave up trying to make them auto-discoverable (at least for lights, everything else I got working). I manually defined the lights to try and get them working.

Says it requires api_password which is going to be deprecated soon, right?

He added support for access tokens.

Ooo. Well I’m gonna hate throwing out literally tens of hours of work on the MQTT part (and I feel like I’m frustratingly close but not at the same time) but I just don’t know what else to do. I’ll maybe give it a try.

@123 I actually made some progress based on your posts here: Mqtt value template

This is now working:

state_template: "{{ 'on' if value == 'on' else 'off' }}"

Now just to get brightness_template working and i THINK i’m set. Could use some help. is it possible to template something like “if brightness is between 1 and 100 use {{brightness}} otherwise nothing?” Below is my stab at what I was thinking.

brightness_template: "{{ '{{brightness}}' if (value <=1 OR >= 100) else '' }}"

Not sure I understand the purpose of your state_template. It’s saying this:

If the received value is on then the state is on, otherwise it’s off.

If the received payload can be either on or off then there’s no need for the state_template.

You can create a template like that but that doesn’t mean it will work the way you expect. The purpose of the brightness_template is to supply a valid brightness level. An empty string ('') isn’t a valid brightness level.

The larger question is: If the payload doesn’t contain a value between 1 and 100, what does it contain? Zero? A number greater than 100 or less than zero?

I’m not 100% sure either. I may be able to remove it and test again, just not at the moment.

EDIT: Nope, it’s necessary. I get this error when i remove:

Exception in state_received when handling msg on 'homeassistant/light/office_level/state': 'off'
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/components/mqtt/light/schema_template.py", line 186, in state_received
    state = self._templates[CONF_STATE_TEMPLATE].\
AttributeError: 'NoneType' object has no attribute 'async_render_with_possible_json_value'

I think what I need to do is create an automation on the zwave HASS side that pushes a single payload with the information I need (particularly state and brightness). Right now i have 3 topics (set, state, and brightness) and it looks like i need 2 (set and state/brightness). I think i’ve figured out a way to push a change to MQTT when the brightness is changed so I’ll give that a shot.

I’ll keep messing around, but i appreciate your help. I’ll post an update if I figure out a work around

According to the documentation for MQTT Light using the JSON schema, state_template is optional. That means Home Assistant won’t complain if the state_template option is omitted. It will complain if you defined a blank state_template.

I think maybe it’s because of the way I defined my on/off commands. Idk, my solution seems to work so I’m not seeing a reason to stop using it unless there’s a bigger issue i’m not seeing.

I can’t comment because I haven’t seen what you’re working on. The only MQTT Light configuration you’ve shared is in the first post and that version uses a different state_template. In fact, that version appears to be handling a JSON-formatted payload whereas your most recent state_template isn’t.

:man_shrugging:

What i’m working on is exactly what I posted initially other than the recent change to state_template and removing brightness_template. And yea, only thing I can think of is the on/off command creates a json value to parse.