If then else in configuration.yaml for serial data

Can someone please help me a little with some YAML. I have been trying all day and not getting anywhere!
I have a serial sensor and the following YAML works in configuration.yaml.

sensor:

  • platform: serial
    serial_port: /dev/ttyUSB0
    baudrate: 4800

I now I want to process the data from this serial sensor. It comes as coma delimited text lines like this:

$IIVHW,T,121,M,00.03,N,00.05,K61
$IIDBT,010.5,f,003.2,M,001.7,F
12
$IIVWR,008,L,00.0,N,00.0,M,000.0,K41
$IIMTW,020,C
3F
$IIHDM,121,M*3E

I want to define different sensors depending on the value of the first field of each line. And then set the state to one of the other fields in the line. Here is pseudo code for what I want to do:

if $IIDBT then
sensor:
name: Water Depth
state: “{{ states(‘sensor.serial_sensor’).split(’,’)[3] | float(default=0) }}”
else if $IIVHW then
sensor:
name: Compass Heading
state: “{{ states(‘sensor.serial_sensor’).split(’,’)[3] | float(default=0) }}”
else if $IIMTW then
sensor:
name: Water Temperature
state: “{{ states(‘sensor.serial_sensor’).split(’,’)[1] | float(default=0) }}”

In the serial help guide of HA there is this example:
template:
sensor:
- name: Temperature
unit_of_measurement: “°C”
state: “{{ states(‘sensor.serial_sensor’).split(’,’)[1] | float(default=0) }}”
- name: Humidity
unit_of_measurement: “%”
state: “{{ states(‘sensor.serial_sensor’).split(’,’)[2] | float(default=0) }}”

But I need the if then else included.
Thanks in advance.

Hi, can’t help you with your problem but maybe format your code properly for making it easier for others to help you.

1 Like

I suggest you consider using Trigger-based Template Sensors.

Based on your pseudo-code example, here’s how to configure three Trigger-based Template Sensors (add two more to handle $IIVWR and $IIHDM, if needed).

template:
  - trigger:
      - platform: state
        entity_id: sensor.serial_sensor
    sensor:
      - name: Water Depth
        state: >
          {% set d = trigger.to_state.state.split(',') %}
          {{ d[3] if d | count > 3 and d[0] == '$IIDBT' else this.state }}
      - name: Compass Heading
        state: >-
          {% set d = trigger.to_state.state.split(',') %}
          {{ d[3] if d | count > 3 and d[0] == '$IIVHW' else this.state }}
      - name: Water Temperature
        state: >-
          {% set d = trigger.to_state.state.split(',') %}
          {{ d[1] if d | count > 1 and d[0] == '$IIMTW' else this.state }}

How it works

Whenever the state value of sensor.serial_sensor changes it causes each one of the three Template Sensors to evaluate their respective templates.

The following line converts the received value into a list and assigns it to a variable name d.

{% set d = trigger.to_state.state.split(',') %}

The following line checks if the list contains a sufficient number of items and the first item in the list is the string $IIDBT.

  • If both conditions are met then it reports the fourth item in the list (i.e. d[3]).
  • If the first or second condition is not met, it reports the Template Sensor’s existing state value.
{{ d[3] if d | count > 3 and d[0] == '$IIDBT' else this.state }}

Initially, the value of all three sensors will be unknown. They will report proper values only after they receive data from the Serial Sensor. These values will survive a restart of Home Assistant.

2 Likes

It works!!!
Thank you so so so much.
Much appreciated.
I spent 5 hours yesterday trying different solutions.
Your trigger suggestion is brilliant.

You’re welcome!

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. This helps users find answers to similar questions.

For more information about the Solution tag, refer to guideline 21 in the FAQ.