How to debug a binary sensor

Hi all,

As I’m having a dynamic energy-contract, I’ve configured HA to switch on a few devices during the cheapest hour of the day.

For this, I use two helpers and three binary sensors. Naming is self-explanatory, I have split my yaml up for ease of use and readability:

config/binary_sensors/smartenergy.yaml:

- platform: template
  sensors:
    smartelec_lowest_hour:
      friendly_name: "Lowest hour"
      value_template: "{{ states('sensor.smartelec_current_marketprice') == states('sensor.smartelec_lowest_today_marketprice') }}"

- platform: template
  sensors:
    smartelec_below_treshold:
      friendly_name: "Price below treshold"
      value_template: "{{ states('sensor.smartelec_current_marketprice') < states('input_number.smartelec_treshold_marketprice') }}"

- platform: template
  sensors:
    smartelec_active:
      friendly_name: "Smart active"
      value_template: >
        {%- if is_state('input_boolean.smartelec_both', 'on') -%}
        {{- is_state('binary_sensor.smartelec_below_treshold','on') and is_state('binary_sensor.smartelec_lowest_hour', 'on') -}}
        {%- else -%}
        {{- is_state('binary_sensor.smartelec_below_treshold','on')  or is_state('binary_sensor.smartelec_lowest_hour', 'on') -}}
        {%- endif -%}

smartelec_both is off, smart_elec_treshold_marketprice is set to 0. This will cause the smartelec_active to be on if the current hour has the lowest price of the day, or if the current price is negative (this happens!)

Below is the relevant sensor config (a have a few more, but not relevant for this problem).

config/sensors/smartenergy.yaml:

- platform: command_line
  command: >
    curl 
    -X POST 
    -H 'Content-Type: application/json'
    -H 'User-Agent: Mozilla/5.0'
    -d '{"query":"query MarketPrices($startDate: Date!, $endDate: Date!) {marketPricesElectricity(startDate: $startDate, endDate: $endDate) { till from marketPrice priceIncludingMarkup}}",
    "variables":{"startDate":"{{ as_timestamp(now()) | timestamp_custom('%Y-%m-%d') }}","endDate":"{{ as_timestamp(now() + timedelta(days=2)) | timestamp_custom('%Y-%m-%d') }}"}}'
    https://frank-graphql-prod.graphcdn.app
  name: Smart Electricity
  json_attributes:
    - data
  value_template: "OK"

- platform: template
  sensors:
    smartelec_current_marketprice:
      friendly_name: Current energy marketprice
      unit_of_measurement: "EUR"
      value_template: "{{ states.sensor.smart_electricity.attributes.data.marketPricesElectricity[now().hour].marketPrice }}"

- platform: template
  sensors:
    smartelec_lowest_today_marketprice:
      friendly_name: Lowest energy price today
      unit_of_measurement: "EUR"
      value_template: >
        {%- set today = now().strftime('%Y-%m-%d') -%}
        {%- set lowest = state_attr('sensor.smart_electricity','data').marketPricesElectricity | selectattr('from','match',today) | map(attribute='marketPrice') | list | min | round(5) -%}
        {{- lowest -}}

I stitch everything together with automations (cleaned up the mail message, as it is not relevant to this issue):

config/automations.yaml

- id: '1652464429778'
  alias: Retrieve Energy Prices
  description: ''
  trigger:
  - platform: time_pattern
    minutes: '0'
    hours: /4
  condition: []
  action:
  - service: homeassistant.update_entity
    data: {}
    target:
      entity_id:
      - sensor.smart_electricity
      - sensor.smart_gas
  - service: notify.wiwo_smtp
    data:
      target: [email protected]
      message: 'Retrieved energy prices !!

        '
      title: Energy pricing {{ now().strftime("%Y/%m/%d %H:%M") }}
      data:
        html: "<table border=\"1\">\n <tr><th colspan=\"4\">Pricing</th></tr>\n\
          \ \n {% for item in state_attr('sensor.smart_electricity','data').marketPricesElectricity\
          \ %} \n <tr>\n  <td>{{ item.from }}</td>\n  <td>{{ item.till }}</td>\n \
          \ <td>{{ item.marketPrice }} &euro;</td>\n  <td>{{ item.priceIncludingMarkup\
          \ }} &euro;</td>\n </tr>\n {% endfor %}\n</table> \n"
  mode: single
- id: '1652953357220'
  alias: Switch smart energy ON
  description: ''
  trigger:
  - platform: state
    entity_id:
    - binary_sensor.smartelec_active
    from: 'off'
    to: 'on'
  condition: []
  action:
  - service: scene.turn_on
    target:
      entity_id: scene.smartelec_scene_usage_on
    metadata: {}
  mode: single

- id: '1652953413164'
  alias: Switch smart energy OFF
  description: ''
  trigger:
  - platform: state
    entity_id:
    - binary_sensor.smartelec_active
    from: 'on'
    to: 'off'
  condition: []
  action:
  - service: scene.turn_on
    target:
      entity_id: scene.smart_energy_off
    metadata: {}
  mode: single

The problem is, that scene.smart_energy_on is turned on unexpectedly. I can find this happens because binary_sensor.smartelec_active is switched on. Today this happened on 05:56:41. scene.smart_energy_off is activated at 05:57:36

As far as I can tell, all this depends on the cli-sensor, which will run once every four hours (hours=/4, minutes=0). This sensor should only change during that update cycle.

The question is, why this binary_sensor.smartelec_active became active at this time, and how to debug this.

Regards,

Marcel

I suspect sensor.smartelec_lowest_today_marketprice is evaluated every minute because of the call to now(). Did that change at 05:56?

If I’m right, install sensor.date and use that instead: Time & Date - Home Assistant

I understand that the sensor.smartelec_lowest_today_marketprice will be evaluated every minute. But this sensor only depends on sensor.smart_electricity, which is updated in the first minute of every 4 hours.

So no, I still don’t get it.

Your tip on using sensor.date is definitely a good one and I’ll implement that today.

I’ll post the results here.

Well, that didn’t solve anything :frowning:

In the logbook I see

The correct ones are those triggered by Time, but where does the change of the state of ‘Smart Electricity’ come from?

When I look at that I don’t see any change:

And I also have no logbook events for the past 24 hours.

FYI, the config for this sensor is in

config/sensors/smartenergy.yaml:

  • platform: command_line
    command: >
    curl
    -X POST
    -H ‘Content-Type: application/json’
    -H ‘User-Agent: Mozilla/5.0’
    -d ‘{“query”:“query MarketPrices($startDate: Date!, $endDate: Date!) {marketPricesElectricity(startDate: $startDate, endDate: $endDate) { till from marketPrice priceIncludingMarkup}}”,
    “variables”:{“startDate”:“{{ states(‘sensor.date’) }}”,“endDate”:"{{ (strptime(states(‘sensor.date’),’%Y-%m-%d’) + timedelta(days=2)).date() }}"}}’
    https://frank-graphql-prod.graphcdn.app
    name: Smart Electricity
    json_attributes:
    • data
      value_template: “OK”

Which is retrieved every 4 hours with the automation:

- id: '1652464429778'
  alias: Frank Prijzen ophalen
  description: ''
  trigger:
  - platform: time_pattern
    minutes: '0'
    hours: /4
  condition: []
  action:
  - service: homeassistant.update_entity
    data: {}
    target:
      entity_id:
      - sensor.smart_electricity
      - sensor.smart_gas
  - service: notify.wiwo_smtp
    data:
      target: [email protected]
      message: 'Prijzen van Frank opgehaald. !!

        '
      title: Frank Energie prijzen {{ states('sensor.date_time') }}
      data:
        html: "<table border=\"1\">\n <tr><th colspan=\"4\">Gas Prijzen</th></tr>\n\
          \ <tr><th>Van</th><th>Tot</th><th>Inkoopprijs</th><th>Prijs</th></tr> \n\
          \ {% for item in state_attr('sensor.smart_gas','data').marketPricesGas %}\
          \ \n <tr>\n  <td>{{ item.from }}</td>\n  <td>{{ item.till }}</td>\n  <td>{{\
          \ item.marketPrice }} &euro;</td>\n  <td>{{ item.priceIncludingMarkup }}\
          \ &euro;</td>\n </tr>\n {% endfor %}\n</table> \n<table border=\"1\">\n\
          \ <tr><th colspan=\"2\">Electra Prijzen</th><th>EB</th><th>ODE</th></tr>\n\
          \ <tr><th colspan=\"2\" align=\"right\">Belastingen per kWh inc BTW</th><th>0.0445159\
          \ &euro;</th><th>0.036905 &euro;</th></tr>\n <tr><th>Van</th><th>Tot</th><th>Inkoopprijs</th><th>Prijs</th></tr>\
          \ \n {% for item in state_attr('sensor.smart_electricity','data').marketPricesElectricity\
          \ %} \n <tr>\n  <td>{{ item.from }}</td>\n  <td>{{ item.till }}</td>\n \
          \ <td>{{ item.marketPrice }} &euro;</td>\n  <td>{{ item.priceIncludingMarkup\
          \ }} &euro;</td>\n </tr>\n {% endfor %}\n</table> \n"
  mode: single

So the question remains: What is the best way to debug this?

The command_line sensor has a default scan_interval of 60 seconds (docs), so it’s updating by itself as well as via your automation. There is no “disable” / “never” setting.

See this thread:

which suggests some workarounds.

I’ll check the frequency of the sensor, but that doesn’t change the fact that in the history of this sensor the value is “OK” for the whole period. No change there!

I pinpointed my problem a bit further. In the original config, I activate a scene when the binary sensor becomes active. In that sensor an outlet switches ‘on’ or ‘off’ (among a few other things).

If I change this to:
config/automations.yaml

- id: '1652953357220'
  alias: Switch smart energy ON
  description: ''
  trigger:
  - platform: state
    entity_id:
    - binary_sensor.smartelec_active
    from: 'off'
    to: 'on'
  condition: []
  action:
  - type: turn_on
    device_id: 8eeea0c65a6a41a34b7ec03ac190cfbf
    entity_id: switch.shelly_plug_s_03
    domain: switch
  mode: single
- id: '1652953413164'
  alias: Switch smart energy OFF
  description: ''
  trigger:
  - platform: state
    entity_id:
    - binary_sensor.smartelec_active
    from: 'on'
    to: 'off'
  condition: []
  action:
  - type: turn_off
    device_id: 8eeea0c65a6a41a34b7ec03ac190cfbf
    entity_id: switch.shelly_plug_s_03
    domain: switch
  mode: single

Now I only have switching of the outlet when I expect that!

Can anyone explain?

I still don’t know the best way to debug this. Should I increase logging (I did, but got overwhelmed with messages, and the UI is a bit inconvenient to search for the root cause). My HA runs on a NUC with SSD storage, so no SDcard fatigue here (pweh!)

I’m fairly new to HA, but I always try to find out WHY things work as they do, to get a better understanding of the whole thing

Marcel