Control a light plugged into Siemens LOGO! 8.4 with MQTT

Hello,

I’m quite new to Home Assistant and to LOGO! Siemens, and I’m trying to figure out how to control a light with both of them.

LOGO! side setup

  • Several push buttons in the house are connected in parallel to one LOGO! input (I1)
  • The light is connected to a LOGO! output (Q1)
  • The LOGO! program is as follow:
  • The LOGO! is publishing on Logo_Pub topic on MQTT and subscribed to Logo_Sub
  • Q1 is published on changes and M1 is set to writable

This means that I can still control the light with the physical push buttons even if HA is down.

What I'm trying to achieve

I’m trying to add a light entity in HA with these properties:

  1. The on/off state of the light entity is updated according to the actual on/off state of the physical light, by listening on changes of the Q1 value on the Logo_Pub topic.
  2. Toggling the light should push a message on the Logo_Sub topic with a message telling the LOGO! to change the state of M1.

So far, I can achieve point 2 with this mqtt light:

mqtt:
  - light:
      command_topic: "Logo_Sub"
      payload_on: '{"state": {"M1": {"value": [1]}}}'
      payload_off: '{"state": {"M1": {"value": [0]}}}'
      state_topic: "Logo_Pub"
      state_value_template: "{{ value_json['state']['reported']['Q1']['value'][0]}}"
      unique_id: "my_unique_id"

With that, when I click the “on” or “off” part of the light, the payload_on/off is correctly send to MQTT, the LOGO! reads it and the physical light turns on/off.

The problem is the feedback. The light is always on the “unknown” state and I can’t figure out why it does not read the values published by the LOGO!.

However, this sensor is working, receiving value 1 or 0 depending on the state of Q1:

mqtt:
  sensor:
    - name: "LOGO Q1"
      state_topic: "Logo_Pub"
      value_template: "{{ value_json['state']['reported']['Q1']['value'][0]}}"

Any help would be greatly appreciated :slight_smile:

What’s the actual payload on the “Logo_Pub” topic?

Thanks you for your interest.

The payload sent by the LOGO! on Logo_Pub is:

{"state":{"reported":{"Q1":{"desc":"Q-bit-1-1","value":[0]}}}}

Note that if I want to do it for several lights, the message will be:

{"state":{"reported":{"Q1":{"desc":"Q-bit-1-1","value":[1]},"Q2":{"desc":"Q-bit-2-1","value":[0]},"$logotime":1729527696}}}

So both values are published on an array when they are both changed (here, Q1 turned on and Q2 turned off), but the message contains only Q1 if Q2 hasn’t changed.

The logotime value is published every 10 seconds and unfortunately this cannot be silenced.
So when there are no changes in neither Q1 or Q2, the message is:

{"state":{"reported":{"$logotime":1729527897}}}

Then maybe:

value_template: >
  {% if value_json['state']['reported']['Q1'] != null %}
    {{ value_json['state']['reported']['Q1']['value'][0]}}      
  {% else %}
    {{ states("sensor.logo_q1") }}
  {% endif %}

I just tried it, no luck.

Would it be because the sensor has a 0 or 1 value, but the light is expecting “on” or “off”. I have no idea how to translate it.

I was able to define a mqtt.binary_sensor which reflect correctly the state of Q1:

- binary_sensor:
    - name: logo_q1
      state_topic: "Logo_Pub"
      value_template: "{{ value_json['state']['reported']['Q1']['value']}}"
      payload_on: "[1]"
      payload_off: "[0]"

And I can define a mqtt.light that has the correct status feedback:

- light:
    state_topic: "Logo_Pub"
    state_value_template: "{{ value_json['state']['reported']['Q1']['value']}}"
    payload_on: "[1]"
    payload_off: "[0]"
    command_topic: "Logo_Sub"
    unique_id: "my_unique_id"

But unfortunately, the mqtt.light cannot command the physical light since the message sent to Logo_Sub is now “[0]” or [“1”] instead of:

{"state": {"M10": {"value": [1]}}}

So basically, the problem is that the payload_on/off is used both for the state feedback (Logo_Pub topic) and the command (Logo_Sub topic) :confused:

Unless the json you showed is not the actual one, I don’t quite get it

{% set value_json = {
  "state": {
    "reported": {
      "Q1": {
        "desc": "Q-bit-1-1",
        "value": [
          1
        ]
      },
      "Q2": {
        "desc": "Q-bit-2-1",
        "value": [
          0
        ]
      },
      "$logotime": 1729527696
    }
  }
}
%}

{{ value_json['state']['reported']['Q1']['value'][0] == 1 }}  // True
{{ value_json['state']['reported']['Q1']['value'] == "[1]" }}  // False

You can use state_value_template to “build” the payload to find out the state

Hi There,

I have done it like this:

light:
  - name: "Light 1"
    command_topic: "LOGO_Sub"
    state_topic: "LOGO_Pub"
    state_value_template: '{{ {"state": {"M1": {"value": value_json["state"]["reported"]["M10001"]["value"]}}} | tojson }}'
    payload_on: '{"state": {"M1": {"value": [1]}}}'
    payload_off: '{"state": {"M1": {"value": [0]}}}'
    retain: false
    unique_id: 10001

I have used the same network input as output with some loopback mechanism, but you could use a different network output than input. For me it was the “| tojson” that was the final key in making it work.