Assistance needed with REST sensor / templates

I am trying to create REST sensors using the API endpoint: http://192.168.1.2:61208/api/3/network

The above endpoint returns:

[
  {
    "interface_name": "Local Area Connection",
    "time_since_update": 17.019418716430664,
    "cumulative_rx": 8186154495,
    "rx": 393341,
    "cumulative_tx": 21468189580,
    "tx": 264864,
    "cumulative_cx": 29654344075,
    "cx": 658205,
    "is_up": true,
    "speed": 1048576000,
    "key": "interface_name"
  },
  {
    "interface_name": "Loopback Pseudo-Interface 1",
    "time_since_update": 17.019418716430664,
    "cumulative_rx": 0,
    "rx": 0,
    "cumulative_tx": 0,
    "tx": 0,
    "cumulative_cx": 0,
    "cx": 0,
    "is_up": true,
    "speed": 1125122048,
    "key": "interface_name"
  }
]

The below code is my best attempt trying to do this; unfortunately, my rest sensors are giving unavailable values. I’d really appreciate it someone could tell me what I’m doing wrong.

  - platform: rest
    name: network
    resource: http://192.168.1.2:61208/api/3/network
    value_template: '{{ ( value_json[0] / 1000000 ) | round(2) }}'
    json_attributes:
      - rx
      - tx
      - cx
    scan_interval: 5


  - platform: template
    sensors:
      horizon_download_speed:
        value_template: '{{ states.sensor.network.attributes["rx"] }}'
        unit_of_measurement: "Mbps"
  - platform: template
    sensors:
      horizon_upload_speed:
        value_template: '{{ states.sensor.network.attributes["tx"] }}'
        unit_of_measurement: "Mbps"
  - platform: template
    sensors:
      horizon_total_speed:
        value_template: '{{ states.sensor.network.attributes["cx"] }}'
        unit_of_measurement: "Mbps"

What does this return in the template editor?

{{ states('sensor.network') }}

It returns:

unknown

@tom_l can you please confirm that my code I posted is right? Maybe there’s a better way to create the REST sensor and respective template?

@Troon Thank you for the quick reply. I am not getting an error in HA (like what’s mentioned in this post). The issue might be something else. Heck, I don’t even know if the code I posted in the OP is correct. Maybe I’m doing something wrong?

Anyway, I am able to create two separate REST sensors (and respective REST calls) which does work for me. I’m not sure why the below code works; where the other code doesn’t:

  - platform: rest
    resource: http://192.168.1.2:61208/api/3/network
    name: Glances Download Speed
    value_template: '{{ ( value_json[0].rx / 1000000 ) | round(2) }}'
    unit_of_measurement: "Mbps"
    scan_interval: 5
  - platform: rest
    resource: http://192.168.1.2:61208/api/3/network
    name: Glances Upload Speed
    value_template: '{{ ( value_json[0].tx / 1000000 ) | round(2) }}'
    unit_of_measurement: "Mbps"
    scan_interval: 5

The rest sensor in the OP results in unknown for the state because your value_template is invalid. You’re trying to divide a dictionary by a number. Maybe try:

value_template: "{{ (value_json[0].speed / 1000000) | round(2) }}"

What is the “full state” of the sensor, including attributes?

@pnbruckner thank you so much for helping me out. I’m confused. I am not sure which line you want me to replace with the line you posted. It looks like it’s specific to just the attribute “speed”.

I’m referring to the rest sensor in your OP. My main point is it was invalid, which lead to the state string being unknown. You can change it to whatever you want; it doesn’t really matter if what you’re really after are the attributes so that they can be used in the template sensors. Which is why I asked about the “full state” of the rest sensor – i.e., specifically, are the attributes being created correctly so that they can be used by the template sensors? (Someone earlier asked you for the state of the rest sensor, and you only answered with the state string, but not the attributes, which are also part of the entity’s state.)

@pnbruckner If I just create a sensor using the below code:

  - platform: rest
    name: network
    resource: http://192.168.1.2:61208/api/3/network
    value_template: '{{ ( value_json[0] ) }}'
    json_attributes:
      - interface_name
      - time_since_update
      - cumulative_rx
      - rx
      - cumulative_tx
      - tx
      - cumulative_cx
      - cx
      - is_up
      - speed
      - key
    scan_interval: 5

Below, is what I get:
network_state

Sorry, I’m not very experienced with REST sensors. So, if my code is wrong, I’d really appreciate it if you could tell me what code to use so it will work correctly.

You might want to turn on debug:

logger:
  default: info
  logs:
    homeassistant.components.rest.sensor: debug

Then restart HA and look in home-assistant.log. There should be some lines in the file with additional debug info that can help you understand what the sensor is doing and how it’s interacting with the server.

EDIT: Also, have you checked the LOGS tab to see if there are any associated errors or warnings?

This is also a problem. An entity’s state is limited to 255 characters. The length of the resulting string, according to the data in your OP, would be 276 characters. If you don’t care what the rest sensor’s state string is (because you only care about the attributes so they can be used in template sensors), then just do something like:

value_template: N/A

This was very useful. After enabling debugging in the logger, I found out why i was getting the result, “unknown”:

Logger:
Updating from http://192.168.1.2:61208/api/3/network
Updating rest sensor tool longer than the scheduled update interval 0:00:05

After increasing the update interval to 10 seconds, I am getting a full reply back:

It seems like the 255 character limit isn’t adversely affecting my sensor afterall.

I am now testing the below template… that’s the only thing left to do as far as i can tell.

</s> <s> - platform: template</s> <s> sensors:</s> <s> horizon_download_speed:</s> <s> value_template: '{{ ( states.sensor.network.attributes["rx"] / 1000000 ) | round(2) }}'</s> <s> unit_of_measurement: "Mbps"</s> <s> - platform: template</s> <s>

Everything seems to be working now. Thank you so much for being so patient with me.

That only applies to the state string, not its attributes. See the documentation on State Objects. In your case the state string is “N/A”, which is only three characters long.

No problem. Glad to help, and glad it’s working for you!

@pnbruckner: I’m not sure if you’re still reading this. For the purposes of me learning the mechanics of Home Assistant better…when I put:

value_template: "{{ (value_json[0].speed / 1000000) | round(2) }}"

instead of using:

value_template: N/A

…the logger only shows a read time out error (see below). I guess that’s what the logger will show when reaching a 255 character limit for the “full state” of the sensor entity?

If I were to use python to get around this limit, what additional functionality would I get for my sensor as opposed to going down the route I did?

2020-07-01 12:44:36 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.network is taking over 10 seconds
2020-07-01 12:44:36 ERROR (SyncWorker_4) [homeassistant.components.rest.sensor] Error fetching data: http://192.168.1.2:61208/api/3/network failed with HTTPConnectionPool(host='192.168.1.2', port=61208): Read timed out. (read timeout=10)

What you use for the value_template has nothing to do with the warning & error you show. They are telling you it didn’t get anything back from the server. I.e., it hasn’t even been able to make it far enough to attempt to parse the JSON or evaluate the value_template template because it got nothing to parse.

If it does get back a response, and it is able to parse the JSON, and your value_template results in a string that is too long, you’ll see a different error, one that says something like “Invalid state encountered for entity id: sensor.network. State max length is 255 characters.”

Thanks for explaining. I really hate to ask, but I have one more related question; so I dont have to create a separate forum thread. I tried looking looking this up; however, I just couldn’t figure it out.

Assuming the API endpoint: http://192.168.1.2:61208/api/3/diskio

returns:

[
    {
        "time_since_update": 16.995006322860718,
        "disk_name": "PhysicalDrive0",
        "read_count": 9,
        "write_count": 332,
        "read_bytes": 37888,
        "write_bytes": 2387968,
        "key": "disk_name"
    },
    {
        "time_since_update": 16.995006322860718,
        "disk_name": "PhysicalDrive1",
        "read_count": 5,
        "write_count": 112,
        "read_bytes": 4096,
        "write_bytes": 1734112,
        "key": "disk_name"
    },
    {
        "time_since_update": 16.995006322860718,
        "disk_name": "PhysicalDrive2",
        "read_count": 0,
        "write_count": 0,
        "read_bytes": 0,
        "write_bytes": 0,
        "key": "disk_name"
    },
    {
        "time_since_update": 16.995006322860718,
        "disk_name": "PhysicalDrive3",
        "read_count": 0,
        "write_count": 0,
        "read_bytes": 0,
        "write_bytes": 0,
        "key": "disk_name"
    },
    {
        "time_since_update": 16.995006322860718,
        "disk_name": "PhysicalDrive4",
        "read_count": 0,
        "write_count": 0,
        "read_bytes": 0,
        "write_bytes": 0,
        "key": "disk_name"
    },
    {
        "time_since_update": 16.995006322860718,
        "disk_name": "PhysicalDrive5",
        "read_count": 0,
        "write_count": 0,
        "read_bytes": 0,
        "write_bytes": 0,
        "key": "disk_name"
    },
    {
        "time_since_update": 16.995006322860718,
        "disk_name": "PhysicalDrive6",
        "read_count": 0,
        "write_count": 0,
        "read_bytes": 0,
        "write_bytes": 0,
        "key": "disk_name"
    }
]

How can I create a single REST sensor for the above data and parse all that data with templates? I only know how to create a multiple sensors (one for each physical disk).
For example, the below sensor would only handle PhysicalDrive1.

I’ve created the below sensor:

  - platform: rest
    name: diskio
    resource: http://192.168.1.2:61208/api/3/diskio
    value_template: '{{ ( value_json[1] ) }}'
    json_attributes:
      - time_since_update
      - disk_name
      - read_count
      - write_count
      - read_bytes
      - write_bytes
    scan_interval: 7

Honestly, I don’t think you can. The REST sensor is a bit limited in what it can do. For json_attributes you can only specify top-level keys, or (if the top level is an array) keys that are in the first element. E.g., with what you showed, it would actually take value_json[0].time_since_update, etc. for the attributes.

For this type of data you may need to write an external script (e.g., an external Python or shell script) that retrieves the data and then creates corresponding entities in HA’s State Machine using HA’s REST API.

1 Like