Get one var from json

Hey all,

I have spotcast set up, and when it has an attribute called devices_json

This json is like this:

[{"name": "Kitchen display", "cast_type": "cast", "model_name": "Google Nest Hub", "uuid": "9afaa83d-d64c-5485-d64d-cf464b9fc300", "manufacturer": "Unknown manufacturer"}, {"name": "Tiebe Bedroom", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "aeaf0506-0e8e-f1e9-fadf-3ca2a9c6d6e6", "manufacturer": "Unknown manufacturer"}, {"name": "Bedroom Lotte speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "5e8e2113-597d-ed67-c7a1-e28e52e9f824", "manufacturer": "Unknown manufacturer"}, {"name": "Living Room speaker", "cast_type": "audio", "model_name": "Google Home", "uuid": "38aaf3c3-be68-f00a-a9ce-ce577a17751e", "manufacturer": "Unknown manufacturer"}, {"name": "Home group", "cast_type": "group", "model_name": "Google Cast Group", "uuid": "ce756229-6610-4d69-9aa5-c5da4add3cff", "manufacturer": "Unknown manufacturer"}, {"name": "Office speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "0b55fd19-91b5-68f0-1c47-b6f153629716", "manufacturer": "Unknown manufacturer"}]

I would like to get all the name data, and put them in a input_select.

Is this possible, if so, how would I do this?

Thanks in advance.

Is this possible?

It’s possible using python_script.

It’s not possible with a Jinja2 template because everything it produces is a string and you need a list for input_select.set_options.

From the documentation:

    action:
      - service: input_select.set_options
        data:
          entity_id: input_select.who_cooks
          options: ["Item A", "Item B", "Item C"]  #<--- This must be a list
1 Like

I am using spotcast, how would I change its code to make it send back a list?

Given that you have access to spotcast’s source-code, you are free to modify it to return whatever information you want in whatever format you need.

I don’t use spotcast so I will leave it to someone else to help you modify it. However, if I did use it, I wouldn’t change its code but simply create a python_script to extract the desired names and assign them to the input_select.

1 Like

I do understand how spotcast works, but would it work to just simply return a list?

What are the entity names of your spotcast sensor and the input_select?

1 Like

spotcast: sensor.chromecast_devices
input_select: input_select.spotcast_select

I believe the python_script will be something like this (which is untested and may require modifications):

devices = hass.states.get('sensor.chromecast_devices').attributes['devices_json']
options = []

for d in devices:
  options.append(d['name'])

if len(options) > 0:
  service_data = {'entity_id': 'input_select.spotcast_select', 'options': options}
  hass.services.call('input_select', 'set_options', service_data)
  • It gets the devices_json attribute from sensor.chromecast_devices.
  • It creates an empty list called options.
  • It loops through the devices_json list and extracts the value of the key called “name”. It appends this value to the options list.
  • It checks if the options list contains items.
  • It creates a JSON string, called service_data, containing all the information needed for the set_options service.
  • Finally, it calls input_select.set_options using service_data.

If you don’t know how to use the python_script integration, here’s the documentation and feel free to ask me any questions to help you get it running.


EDIT
Replaced original, defective code with new, functional code.

1 Like

Getting the error

string value is None @ data['options'][0]

any help?

Tell me how you installed and executed the script.

1 Like

Install:
made python_scripts folder and added python_script: to the config file
then made a new python script and pasted your code in there,

then I made a button to call on a service, which is the python script,

then i got that error

It’s going to take me a bit of time to simulate sensor.chromecast_devices then test the python_script with it.


EDIT

I’ve managed to simulate the sensor so that I get the same error message you did. Now I can proceed to solve the problem.
Screenshot from 2020-03-23 17-45-06

1 Like

Alright! Thanks for your help!!!

I found my mistake and corrected it. I also made it verify the options list is not empty before it attempts to assign it to the input_select.

I tested and confirmed this works:

devices = hass.states.get('sensor.chromecast_devices').attributes['devices_json']
options = []

for d in devices:
  options.append(d['name'])

if len(options) > 0:
  service_data = {'entity_id': 'input_select.spotcast_select', 'options': options}
  hass.services.call('input_select', 'set_options', service_data)

EDIT

I’ve replaced the original defective code (in my previous post) with the new functional code.

1 Like

Hmmm strange…

I’m getting this error now:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/python_script/__init__.py", line 196, in execute
    exec(compiled.code, restricted_globals)
  File "spotcastinput.py", line 5, in <module>
  File "/usr/local/lib/python3.7/site-packages/RestrictedPython/Eval.py", line 35, in default_guarded_getitem
    return ob[index]
TypeError: string indices must be integers

Edit:

I can confirm the last 2 lines of your code work, so it must be something in where it parses the data.

Edit 2:
Going to try to see what the output of the devices variable is. Let’s see…

Edit 3:
The error is when it tries to do the loop for d in devices
hmmm strange…

Edit 4:
The error is in the data spotcast returns. If I take away the devices = and replace it with just this

[{“name”: “Kitchen display”, “cast_type”: “cast”, “model_name”: “Google Nest Hub”, “uuid”: “9afaa83d-d64c-5485-d64d-cf464b9fc300”, “manufacturer”: “Unknown manufacturer”}, {“name”: “Tiebe Bedroom”, “cast_type”: “audio”, “model_name”: “Google Home Mini”, “uuid”: “aeaf0506-0e8e-f1e9-fadf-3ca2a9c6d6e6”, “manufacturer”: “Unknown manufacturer”}, {“name”: “Bedroom Lotte speaker”, “cast_type”: “audio”, “model_name”: “Google Home Mini”, “uuid”: “5e8e2113-597d-ed67-c7a1-e28e52e9f824”, “manufacturer”: “Unknown manufacturer”}, {“name”: “Living Room speaker”, “cast_type”: “audio”, “model_name”: “Google Home”, “uuid”: “38aaf3c3-be68-f00a-a9ce-ce577a17751e”, “manufacturer”: “Unknown manufacturer”}, {“name”: “Home group”, “cast_type”: “group”, “model_name”: “Google Cast Group”, “uuid”: “ce756229-6610-4d69-9aa5-c5da4add3cff”, “manufacturer”: “Unknown manufacturer”}, {“name”: “Office speaker”, “cast_type”: “audio”, “model_name”: “Google Home Mini”, “uuid”: “0b55fd19-91b5-68f0-1c47-b6f153629716”, “manufacturer”: “Unknown manufacturer”}]

Then it works fine…

Could it be that hass.states.get delivers as a string?

Nevermind, solved it! Used a different attribute called “devices” which also outputs json, but I suppose not as a string!

1 Like