Create sensor from API results (Opensprinkler)

Hi !
I’m using Opensprinkler as water system and I use its HA Integration to manage start, stop and program of my sprinkler stations.
The HA Opensprinkler integration doesn’t provide history log entity, I have to go on Opensprinkler local website to get it.
But Opensprinkler provide an API to get that info.
Here is what kind of data I can get from the log endpoint :

[
  [99, 2, 6, 1720344992],
  [99, 3, 600, 1720345809],
  [99, 3, 600, 1720347955],
  [99, 0, 16, 1720352180],
  [99, 0, 12, 1720352232],
  [99, 0, 32, 1720352670],
  [99, 0, 7, 1720352772],
  [2, 1, 300, 1720355401],
  [2, 2, 300, 1720355701]
]

My goal is to get every row of this data (wich is not a known number beacause it depends of the number of entry in the log), and for each row, I have to map each number with a reference array to get text data and finally display it in lovelace.

But I meet some issue at the beginning of this project :sweat_smile:
Here is a first try, just to get the first row and each number of this first row :

sensor:
  - platform: rest
    name: My API Sensor
    resource: "http://192.168.1.174/jl?pw=368b2efc3406b3e44f41e2f5e2be323b&hist=0"
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0] }}"
    json_attributes:
      - data
    scan_interval: 20

  - platform: template
    sensors:
      first_element_first_list:
        value_template: "{{ state_attr('sensor.my_api_sensor', 'data')[0} }}"
      second_element_first_list:
        value_template: "{{ state_attr('sensor.my_api_sensor', 'data')[1] }}"
      third_element_first_list:
        value_template: "{{ state_attr('sensor.my_api_sensor', 'data')[2] }}"
      fourth_element_first_list:
        value_template: "{{ state_attr('sensor.my_api_sensor', 'data')[3] }}"

With that, sensor.my_api_sensor state is [99, 2, 6, 1720344992] :+1:
But sensor.first_element_first_list state is unknown whereas I’m expecting “99”

Could somebody help me with that please :pray:

I don’t see any “data” attribute in the payload.

value_template: "{{ state('sensor.my_api_sensor')[0] }}"

Do’t I have to write this to pass data as attribute ? How wold you do this ?

I changed my code with that

sensor:
  - platform: rest
    name: My API Sensor
    resource: "http://192.168.1.174/jl?pw=368b2efc3406b3e44f41e2f5e2be323b&hist=0"
    method: GET
    headers:
      Content-Type: application/json
    value_template: "{{ value_json[0] }}"
    json_attributes:
      - data
    scan_interval: 20

  - platform: template
    sensors:
      first_element_first_list:
        value_template: "{{ state('sensor.my_api_sensor') }}"

And I get Unavailable state for sensor.first_element_first_list whereas sensor.my_first_api state is still ‘[99, 2, 6, 1720344992]’

You missed the “[0]”

I tried at first with the ‘[0]’ but I got unavailable, so as debugging, I tried to get just the state of sensor.my_api_sensor state, but as I said, I get unavailable.
So this code :

- platform: template
    sensors:
      first_element_first_list:
        value_template: "{{ state('sensor.my_api_sensor')[0] }}"

doesn’t create a sensor with the value of the state of 'sensor.my_api_sensor, and I can’t figure out why.

I precise again that state of 'sensor.my_api_sensor is [99, 2, 6, 1720344992]

Hmmm ok, I used “state()” instead of "states() …

Problem now is that

value_template: "{{ state('sensor.my_api_sensor')[0] }}"

give me ‘[’ as state for first_element_first_list. Indeed, HA treats state(‘sensor.my_api_sensor’) as a sting and not an array.

Good practive would be to use “json_attributes_path” and “json_attributes” configuration variables of RESTful sensor, but it seems to work only when the API response is a formated JSON data (using key/value), but in my case I just get an array of arrays…

Do you think there is a way for me to create entites of different value I get from the API even if I get that data structure ?

No it isn’t, it’s the string:

"[99, 2, 6, 1720344992]"

States are always strings. First element, first_list should be:

{{ (states('sensor.my_api_sensor')|from_json)[0] }}

See my response here to a similar question:

1 Like

Thank you, you unblocked my situation. This works :

rest:
    scan_interval: 60
    resource: "http://192.168.1.174/jl?pw=368b2efc3406b3e82f41e2f5e2be323b&hist=0"
    sensor:
      - name: "My API all"
        value_template: "{{ value_json }}"
      - name: "My API one"
        value_template: "{{ value_json[0] }}"
      - name: "My API two"
        value_template: "{{ value_json[1] }}"
      - name: "My API third"
        value_template: "{{ value_json[2] }}"

> You could use a script (template or offline) to generate the sensor configs in a loop automatically then paste into the config file.
As you say, with that we need to handle the number of rows dynamicly and create a sensor by row. Could you just help me to begin with that please, I don’t know what syntx do I need to use to create sensors in a loop with templating

Be careful — sensor states are limited to 255 characters.

You can’t — you must create as many as you are likely to need and use the availability template to “deactivate” the excess. See my linked post above for an example.

You’re not directly creating the sensors. You’re using Jinja in the template editor to write out the YAML, which you then copy into your configuration files. You don’t have to do it this way — could use Python or even Excel…

Starter for 10:

{% for x in range(10) %}
- name: "My API row {{ x + 1 }}"
  value_template: "{{ '{{' }} value_json[{{ x }}] {{ '}}' }}"
  availability: "{{ '{{' }} value_json|length > {{ x }} {{ '}}' }}" 
{% endfor %}
1 Like