[SOLVED] Parsing a json value from an existing entity in a template sensor

Here’s what I’m trying to do. I have a REST sensor to get status from my rooted TV:

sensor:
  - platform: rest
    resource: !secret samygo_tv_living_channelinfo
    method: GET
    name: TV Living Channel Info
    scan_interval: '00:05'

The data returned by this sensor is in JSON format and has several fields (extracted from the entitiy view for sensor.tv_living_channel_info):

{"source":"TV (0)","pvr_status":"NONE","powerstate":"Normal","tv_mode":"Cable (1)","volume":"7","channel_number":"45","channel_name":"Nat Geo HD","program_name":"Personaje ale nazismului","resolution":"1920x1080","error":false}

Now, instead fo setting up several similar sensors and making multiple queries to the TV and filter just the field I want, I’d like to set up templated sensors instead which parse this one entity and extract various fields:

sensor:
  - platform: template
    sensors:
      tv_living_source:
        value_template: todo

The problem is I’m not sure how to parse the json to extract the source field, for example.
Normally one would do {{ value_json.source }}, but I need to somehow reference the entity which holds the data (states.sensor.tv_living_channel_info).

I’ve tried several value_json options, but all fail:

  • states.sensor.tv_living_channel_info.source
  • states.sensor.tv_living_channel_info.value_json.source
  • value_json.states.sensor.tv_living_channel_info.source
  • states.sensor.tv_living_channel_info | value_json.source

Thanks!

I have not used rest sensors, but was wondering if the attributes are already there and you can just lookup the attributes like in the template sensor docs

ie states.sensor.tv_living_channel_info.attributes.source

Unfortunately I get no value. Also, there is no error in the log.

Here’s something else I tried to do (and failed).
I tried to set up a different REST sensor and query HA’s internal API to get the same result and parse it with value_json.
The configuration looks like this:

  - platform: rest
    resource: 'http://127.0.0.1:8123/api/states/sensor.tv_living_channel_info'
    headers:
      x-ha-access: !secret api_password
      Content-Type: application/json
    method: GET
    name: TV Living Source 2

The plan was to use value_template to extract the data (somehow).

The problem is that when HA is started, the API is offline and the REST request fails and the component is not initialized. I tried it to read from a different HA install and the component was initialized. Maybe this request could help this situation: Have Home Assistant periodically try to initialize failed components

Any other ideas on how I could do this?

Ok, I’m trying to extend the REST Sensor and create a custom one that parses the value and stores the JSON inside an object that would be accessible from inside HA.

Here is the custom component: http://paste.ubuntu.com/24971980/
Most notable changes are here: http://paste.ubuntu.com/24972003/

On update I parse the response and populate an _attributes property. The configuration looks like this now:

  - platform: jsonrest
    resource: !secret samygo_tv_living_channelinfo
    method: GET
    name: TV Living ChannelInfo
    scan_interval: '00:05'

However, I’m not sure how I can access it. Inside the template editor, I can access the following:

{{ states.sensor.tv_living_channel_info }} - results in:

<state sensor.tv_living_channel_info={"source":"TV (0)","pvr_status":"NONE","powerstate":"Normal","tv_mode":"Cable (1)","volume":"8","channel_number":"45","channel_name":"Nat Geo HD","program_name":"Alaska: Reparatii mari","resolution":"1920x1080","error":false}; friendly_name=TV Living Channel Info @ 2017-06-28T15:12:44.818431+03:00>

{{ states.sensor.tv_living_channel_info.attributes }} - results in:

{'friendly_name': 'TV Living Channel Info'}

However, this doesn’t work:

{{ states.sensor.tv_living_channel_info.attributes.source }} - doesn’t output anything.

Any idea?

Coming to this mid-conversation… but it appears that it’s just a matter of figuring out how arrays work in Jinja.

{% set value={'friendly_name': 'TV Living Channel Info'} %}
{{value}}

{{value['friendly_name']}}

Use the template dev tool to work on it. Rather than “value” in my example below, use your states.sensor.tv_living_channel_info.attributes

1 Like

Thanks for the suggestion, but I’m not trying to extract friendly_name. I’m trying to extract data attributes such as source, pvr_status, powerstate that are saved inside an _attributes property in the jsonrest object. Most likely it’s not exposed as the attributes that I can see (like friendly_name).

I’m guessing I shouldn’t call states.XXX, because it’s not a state - it’s something else. But calling it attributes.XXX doesn’t work.

You can get an attribute like this:
states.light.master_bath_ledge_accent_level_22_0.attributes.brightness
That’s the brightness attribute for one of my Zwave lights. However you do it, use the template dev tool to experiment.

Then I’m not really setting attributes correctly. I will spy on how other components do it, thanks!

You should be able to look at the states dev tool and tell what state and attributes your sensor has.

I’m trying to create a custom component starting from the REST Sensor code but where I add attributes. I’ve read the documentation and development guide (especially https://home-assistant.io/developers/development_states/), but it’s still not clear to me how I add attributes to a component programmatically. Can you tell me which sensor you are using exactly and has attributes in addition to state?

a couple of “attribute rich” components:

plant

media player

Thank you, @phileep. I analyzed the plant component and I found out how it processes attributes. It seems one needs to write this method:

    @property
    def state_attributes(self):
        """Return the attributes of the entity.

           Provide the parsed JSON data (if any).
        """

        return self._attributes

Right now, my component is called jsonrest and I copied it in ~homeassistant/.homeassistant/custom_components/sensor/jsonrest.py. The complete code is here: http://paste.ubuntu.com/24981070/

The configuration looks like this:

sensor:
  - platform: jsonrest
    resource: !secret samygo_tv_living_channelinfo
    method: GET
    name: TV Living ChannelInfo
    scan_interval: '00:05'
  - platform: template
    sensors:
      tv_living_source:
        value_template: '{{ states.sensor.tv_living_channelinfo.attributes.source }}'
        friendly_name: TV Living Source
      tv_living_channel_number:
        value_template: '{{ states.sensor.tv_living_channelinfo.attributes.channel_number }}'
        friendly_name: TV Living Channel Number

And it works. Behold!


6 Likes

I suppose you can only get that level of information because you actually installed SamyGo on your Samsung TV, right?

All I’ve been able to do without going the SamyGo route, was to control it as if it was using a remote control, using this and this Kodi addon, to allow turning it on via HDMI-CEC and the RPi connected to it.

I’d love to have more TV info like you do on Home Assistant, but I will probably not be able without SamyGo, right?

I’ve checked your links, but that remote control uses an API that has been removed from H series onwards unfortunately.

But yes, SamyGo gives you (apart from root) a series of libraries and tools that hook into the normal TV processes and can expose or inject information, or bypass things, so for instance the recordings are saved unencrypted. I’ve only made a simple web api that exposes that functionality over the network. My API currently works until H series, but can be adapted for J/K with a bit of work.

Here is everything you need once you’ve installed SamyGo: http://forum.samygo.tv/viewtopic.php?p=100959#p100959
And here are the Home Assistant bits: https://forum.samygo.tv/viewtopic.php?f=79&t=11882

2 Likes

Thank you for this @mad_ady! Its just what I needed and works great (using with a different device).

With release 0.57 the jsonrest custom component maybe doesn’t work anymore if the state value of the sensor is bigger than 255 char. I used this great custom component to put the values of multiple json values into different template sensors.

Now I need another solution. The API of tankerkoenig.de only allows 1 request until 10 minutes. I need the price from different gas stations. Simple HA RESTful sensors don’t work with this limitation…

I will test it. I didn’t know there was a limit introduced and report back. Although the state size will probably not matter. Because state is retrieved and parsed into attributes in the same function call (in python), and it doesn’t really matter if it’s truncated when stored, because you already have the attributes.
Anyway, I need to refine it and push it upstream. Ideally it needs to be able to handle nested structures and handle 404 errors gracefully.

1 Like

Thank you for your response. I changed the state allocation to the STATE_ON constant. Now everything works great again on 0.57.1 :wink:

1 Like

Thanks @sti0!
I’ve incorporated your fix in my github repo.

1 Like