Possible bug? Automation not running? Condition help? Dev-tool funkyness?

Tags: #<Tag:0x00007f32535a5960>

I’m having a problem with an automation that won’t run with the condition I want, and I don’t know why.

I have verified if I comment out the “condition” it does run, but I can’t get it to run with the “condition” on ISP=“Atlantic Broadband”.

Goal: If the internet speed is slow, and its on my primary ISP, re-run the speedtest after ~10 minutes (in case it was a fluke).

Relevant MQTT data sample:

{"type":"result","timestamp":"2021-02-23T15:24:19Z","ping":{"jitter":5.726,"latency":13.298},"download":{"bandwidth":116986737,"bytes":1443489480,"elapsed":13202},"upload":{"bandwidth":6719752,"bytes":24197528,"elapsed":3602},"packetLoss":0,"isp":"Atlantic Broadband","interface":{"internalIp":"24.153.32.24","name":"igb0","macAddr":"A0:36:9F:07:4C:D0","isVpn":false,"externalIp":"24.153.32.24"},"server":{"id":14335,"name":"PBW Communications, LLC","location":"Herndon, VA","country":"United States","host":"speedtest.leadmon.net","port":8080,"ip":"38.103.8.130"},"result":{"id":"b7ca89fa-7c45-4d10-a175-228254c605a8","url":"https://www.speedtest.net/result/c/b7ca89fa-7c45-4d10-a175-228254c605a8"}}

Relevant MQTT sensors:

  # ISP
  - platform: mqtt
    name: "ISP Speedtest.net"
    unique_id: "speedtest_net_isp"
    state_topic: "homeassistant/sensor/speedtest-net"
    value_template: "{{ value_json.isp }}"

  # Download Speed
  - platform: mqtt
    name: "Download Speed Speedtest.net"
    unique_id: "speedtest_net_download_speed"
    state_topic: "homeassistant/sensor/speedtest-net"
    unit_of_measurement: 'Mb/s'
    value_template: "{{ (value_json.download.bandwidth | float) * 8 / 1000000 | round(2) }}"
    icon: mdi:speedometer

  # Upload Speed
  - platform: mqtt
    name: "Upload Speed Speedtest.net"
    unique_id: "speedtest_net_upload_speed"
    state_topic: "homeassistant/sensor/speedtest-net"
    unit_of_measurement: 'Mb/s'
    value_template: "{{ (value_json.upload.bandwidth | float) * 8 / 1000000 | round(2) }}"
    icon: mdi:speedometer

My automations:
NOTE: The script and hourly one work, they are included only for reference. The “Re-Run” one fails when condition is present.

# Call script which publishes readings to MQTT
shell_command:
  speedtest_net_run_test: '/config/speedtest-net/mqtt_pub.sh'

automation:
  # Run the test on startup, and hourly
  - alias: 'Speedtest.net Run Test'
    trigger:
      - platform: homeassistant
        event: start
      - platform: time_pattern
        minutes: 0
    action:
      service: shell_command.speedtest_net_run_test

  # Re-run test when speeds are slow on primary ISP
  - alias: 'Speedtest.net Re-Run Test'
    trigger:
      - platform: time_pattern
        minutes: '/2'
      #           ^ For testing, run it a LOT so I can see if the condition works
      - platform: numeric_state
        entity_id:
          - sensor.speedtest_net_download_speed
        below: 500
        for: '00:10:00'
      - platform: numeric_state
        entity_id:
          - sensor.speedtest_net_upload_speed
        below: 25
        for: '00:10:00'
    condition:
      - condition: state
        entity_id: sensor.speedtest_net_isp
        state: 'Atlantic Broadband'
    action:
      service: shell_command.speedtest_net_run_test

Dev-Tools sensor state:

Possibly relevant, I also can not find it by searching the “state” filter, as soon as I hit the letter “t” in “Atlantic” it shows zero results.



I don’t understand why, but I wonder if this may be related to my condition failing?

I’m at a loss how to diagnose this.


UPDATE: BUG?

EDIT: I think this may be a bug related to case-sensitivity after trying something else:






Have you considered using the ‘Speedtest.net’ integration instead? I bet this gets a lot simpler that way

I’m not aware of that, but this is actually running speedtest CLI run on my pfSense router directly so I am not limited by shared Ethernet links between the HassOS machine and other network traffic (e.g. cameras) on my LAN eating into the total.

It also still does not help understand why my condition fails?

Just took a look at that integration, it doesn’t provide some of the data I want (such as current detected ISP).

I don’t want to re-run tests more often if I am on my backup ($10/GB) cellular connection, I only want to re-run them if I am on my primary (uncapped) connection. The integration seems to only expose up/down speed and ping with a blind interval to test on.

EDIT: Additional word of warning, it sounds like that integration uses a Python speedtest-cli script someone made, which provides inconsistent/inaccurate results on especially fast connections compared to the official Ookla binary CLI test (which is what I am using, and supports direct JSON output).

I can reproduce this behavior on my system. For example, the state of one entity is “Slow”. Typing ‘S’ reduces the displayed list to just the single entity but typing ‘Sl’ reduces the list to nothing.

That seems like a bug in UI for Developer Tools > States. However, I doubt this UI bug has any bearing on how a State Condition operates.

Just for fun, replace the State Condition with this Template Condition:

    condition:
      - condition: template
        value_template: "{{ states('sensor.speedtest_net_isp')|lower == 'atlantic broadband' }}"
1 Like

Gets stranger, that didn’t work but I pasted it in Templates and got “unknown”. Apparently the sensor names are inconsistent which may also be confusing me?

Under Templates:

{{states('sensor.speedtest_net_download_speed')}}
{{states('sensor.download_speed_speedtest_net')}}
{{states('sensor.isp_speedtest_net')}}
{{states('sensor.speedtest_net_isp')}}

Result:

927.595688
unknown
Atlantic Broadband
unknown

So I guess even though I defined all the sensors “the same way” somehow sometimes its going by the MQTT unique_id and other times using MQTT name field for sensor names?

This finally does seem to work:

      - condition: template
        value_template: "{{ states('sensor.isp_speedtest_net')|lower == 'atlantic broadband' }}"

When I put it back to this (with the _isp suffix MQTT unique_id changed to isp_ like the MQTT name), now that also works.

     - condition: state
        entity_id: sensor.isp_speedtest_net
        state: 'Atlantic Broadband'

So I guess next question is “why does it sometimes go by name-to-lowercase, and other times go by unique_id for sensors”?

Looks like a mix (at least for these sensors) now that I look closely:

Can you paste the state from the states page here? Or if you run python run it through this:

[ hex(ord(a)) for a in 'Atlantic Broadband' ]

It should return

['0x41', '0x74', '0x6c', '0x61', '0x6e', '0x74', '0x69', '0x63', '0x20', '0x42', '0x72', '0x6f', '0x61', '0x64', '0x62', '0x61', '0x6e', '0x64']

It uses name to define the entity’s entity_id not unique_id. I have many MQTT sensors with unique_id and their entity_id is based on name and there are no duplicates based on unique_id.

You are seeing duplicates because, somehow, they’ve been defined twice.

I don’t think I’m seeing duplicates, they are all different sensors…they just somehow have different entity_id values?

Copy pasted from the states page:

Atlantic Broadband

I don’t know how to run python on hassio, but I think I found the issue with inconsistent entity naming after the hint on the lower-case template and confusion by the dev-tools not showing filter results on uppercase.

Kind of difficult for me to be certain because the first post shows the configuration for three sensors whereas the more recent screenshot shows far more. I thought some might be duplicates but I now see they have different entity_ids. Anyway, the upshot is it doesn’t use unique_id for anything other than uniquely identifying the entity within the (hidden) entity registry.

Ah, sorry yeah - initially I was trying to post what seemed relevant and then it changed. Here is the entire unabridged package-file…which after troubleshooting DOES do what I want now!

I’m just puzzled why the inconsistent entity_id that confused me and now that I am aware, I’d like to get it consistent (if possible) to avoid future confusion.


# Call script which publishes readings to MQTT
shell_command:
  speedtest_net_run_test: '/config/speedtest-net/mqtt_pub.sh'

automation:
  # Run the test on startup, and hourly
  - alias: 'Speedtest.net Run Test'
    trigger:
      - platform: homeassistant
        event: start
      - platform: time_pattern
        minutes: 0
    action:
      service: shell_command.speedtest_net_run_test

  # Re-run test when speeds are slow on primary ISP
  - alias: 'Speedtest.net Re-Run Test'
    trigger:
      # Try again
      - platform: numeric_state
        entity_id:
          - sensor.speedtest_net_download_speed
        below: 500
        for: '00:10:00'
      - platform: numeric_state
        entity_id:
          - sensor.speedtest_net_upload_speed
        below: 25
        for: '00:10:00'
      # Back off a bit
      - platform: numeric_state
        entity_id:
          - sensor.speedtest_net_download_speed
        below: 500
        for: '00:30:00'
      - platform: numeric_state
        entity_id:
          - sensor.speedtest_net_upload_speed
        below: 25
        for: '00:30:00'
    condition:
     - condition: state
       entity_id: sensor.isp_speedtest_net
       state: 'Atlantic Broadband'
    action:
      service: shell_command.speedtest_net_run_test




# Pull in the readings from MQTT
sensor:

  # Ping Jitter
  - platform: mqtt
    name: "Ping Jitter Speedtest.net"
    unique_id: "speedtest_net_ping_jitter"
    state_topic: "homeassistant/sensor/speedtest-net"
    unit_of_measurement: 'ms'
    value_template: "{{ value_json.ping.jitter }}"

  # Ping Latency
  - platform: mqtt
    name: "Ping Latency Speedtest.net"
    unique_id: "speedtest_net_ping_latency"
    state_topic: "homeassistant/sensor/speedtest-net"
    unit_of_measurement: 'ms'
    value_template: "{{ value_json.ping.latency }}"

  # Download Speed
  - platform: mqtt
    name: "Download Speed Speedtest.net"
    unique_id: "speedtest_net_download_speed"
    state_topic: "homeassistant/sensor/speedtest-net"
    unit_of_measurement: 'Mb/s'
    value_template: "{{ (value_json.download.bandwidth | float) * 8 / 1000000 | round(2) }}"
    icon: mdi:speedometer

  # Upload Speed
  - platform: mqtt
    name: "Upload Speed Speedtest.net"
    unique_id: "speedtest_net_upload_speed"
    state_topic: "homeassistant/sensor/speedtest-net"
    unit_of_measurement: 'Mb/s'
    value_template: "{{ (value_json.upload.bandwidth | float) * 8 / 1000000 | round(2) }}"
    icon: mdi:speedometer

  # Packet Loss
  - platform: mqtt
    name: "Packet Loss Speedtest.net"
    unique_id: "speedtest_net_packet_loss"
    state_topic: "homeassistant/sensor/speedtest-net"
    unit_of_measurement: '%'
    value_template: "{{ value_json.packetLoss }}"

  # ISP
  - platform: mqtt
    name: "ISP Speedtest.net"
    unique_id: "speedtest_net_isp"
    state_topic: "homeassistant/sensor/speedtest-net"
    value_template: "{{ value_json.isp }}"

  # Server Name
  - platform: mqtt
    name: "Server Name Speedtest.net"
    unique_id: "speedtest_net_server_name"
    state_topic: "homeassistant/sensor/speedtest-net"
    value_template: "{{ value_json.server.name }}"

  # Server Location
  - platform: mqtt
    name: "Server Location Speedtest.net"
    unique_id: "speedtest_net_server_location"
    state_topic: "homeassistant/sensor/speedtest-net"
    value_template: "{{ value_json.server.location }}"

  # Result ID
  - platform: mqtt
    name: "Speedtest.net Result ID"
    unique_id: "speedtest_net_result_id"
    state_topic: "homeassistant/sensor/speedtest-net"
    value_template: "{{ value_json.result.id }}"

  # Result URL
  - platform: mqtt
    name: "Speedtest.net Result URL"
    unique_id: "speedtest_net_result_url"
    state_topic: "homeassistant/sensor/speedtest-net"
    value_template: "{{ value_json.result.url }}"

For the curious, the mqtt_pub.sh just does a passwordless-SSH with public-private key into the my router to call the speedtest-binary and push the resulting JSON out to mqtt-pub executable.