Command_Line executed before Available?

Hi Community,

I have scripted some command_line sensors that require parameters to be set before execution. For checking the parameters I have set up the availability tag. Sadly it seems like to be executed before checking the availability. From documentation I would expect the following behavior:

  1. Startup HomeAssist Server
  2. Try execute Command_line sensor (Check availability)
    A) True: Command_line gets executed and will be executed again when sensor_interval is reached.
    B) False: Command_line gets checked again periodically if availability template signals „available“

Instead the following seems to be the case:

  1. Startup HomeAssist Server
  2. Command_line sensor is executed besides of unavailability. State is set to unavailable.
  3. Command_line gets executed again after sensor_interval is reached.
- sensor:
    unique_id: waste_commandline_city
    name: waste_commandline_city
    scan_interval: 3600
    availability: >-
      {% if
        is_state('sensor.home_rest_address', 'OK') and
        state_attr('sensor.home_rest_address', 'city') != none and
        state_attr('sensor.home_rest_address', 'district') != none
      %}
        {{
          (state_attr('sensor.home_rest_address', 'city') | length) > 2 or
          (state_attr('sensor.home_rest_address', 'district') | length) > 2
        }}
      {% else %}
        {{ false }}
      {% endif %}
    command: 'curl ''https://zac.jumomind.com/mmapp/api.php?r=cities_web''
      | jq ''.[]
      | .name |= ascii_downcase
      | select(
      (.name == "{{ state_attr(''sensor.home_rest_address'', ''district'') | lower }}")
      or (.name == "{{ state_attr(''sensor.home_rest_address'', ''city'') | lower }}")
      )'''
    json_attributes:
      - name
      - _name
      - id
      - area_id
    value_template: >
      {% if value_json is defined %}
        {{ "OK" }}
      {% else %}
        {{ "Error" }}
      {% endif %}

Problem is that the rest command is executed without the nessesary paramters and therefore throws the following error in the event log:

JSON result was not a dictionary
Logger: homeassistant.components.command_line
Source: components/command_line/sensor.py:169
Integration: Command Line (documentation, issues)

and

Empty reply found when expecting JSON data
Logger: homeassistant.components.command_line
Source: components/command_line/sensor.py:173
Integration: Command Line (documentation, issues)

Workaround:
Create and Automation that triggers homeassistant.update_entity on the sensor.

Question:
Is there any other way to reach the goal of not sending useless requests to the rest endpoint? Am I doing something wrong? Why is the command_line executed anyway?

1 Like

I have the same observation. The possible workaround is to define a template for the command that will check the availability and execute or not the actual command accordingly. See below my working example:

- sensor:
    name: Desktop Users
    availability: '{{ is_state("switch.desktop_adama","on") }}'
    command: >-
      echo &&
      {% if is_state("switch.desktop_adama","on") %}
        {{ 'ssh -i /config/custom_files/ssh.txt -o StrictHostKeyChecking=no [email protected] "powershell c:\\scripts\\users.ps1"' }}
      {% else %}
        {{ 'echo' }}
      {% endif %}
    value_template: >-
      {% if value_json[0] is defined %}
        {{ value_json | length }}
      {% else %}
        1
      {% endif %}

Note the echo && at the beginning of the command template, this is due to an unresolved issue with templating the command, described in this issue: command_line sensor with templated command: inconsistency (still) · Issue #75601 · home-assistant/core · GitHub

solved it by using if then else statements of shell:

- sensor:
    unique_id: apsystems_getDeviceInfo
    name: apsystems_getDeviceInfo
    scan_interval: 10
    icon: mdi:api
    availability: "{{- is_state('binary_sensor.apsystems_ez1_api_ready', 'on') -}}"
    command: |-
      if
        {{ is_state('binary_sensor.apsystems_ez1_api_ready', 'on') | lower -}};
      then
        curl -L '{{- states('sensor.apsystems_ez1_url_getDeviceInfo') -}}' |
        jq -cn -f /config/custom_packages/apsystems_ez1/jq/process_json.jq;
      else
        python3 /config/scripts/check_data.py;
      fi

positive thing about this solution: with “python3 /config/scripts/check_data.py” I’m checking if the data is valid and if null a json with { “State”: “Error” } is generated. which means: No more a rest command delivered an empty json warnings in the Log…

1 Like