Python Forum
Need help with coding in script
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need help with coding in script
#1
Hi,

I'm trying to get the info for a JSON file in to a script.

    def onMessagetoonSceneinfo(self, Connection, Response):	
        Domoticz.Debug("onMessagetoonSceneinfo called")
        if 'states' in Response:
            for state in Response['states']['state']:
                self.scenes[state['id'][0]] = int(state['tempValue'][0])
But this gives the following error

Error:
2023-02-03 20:25:06.213 Error: for state in Response['states']['state']: 2023-02-03 20:25:06.213 Error: TypeError: list indices must be integers or slices, not str
The output of the JSON files is as follows

Output:
{ "states": [ { "state": [ { "id": [ "0" ], "tempValue": [ "2000" ], "dhw": [ "1" ] }, { "id": [ "1" ], "tempValue": [ "1900" ], "dhw": [ "1" ] }, { "id": [ "2" ], "tempValue": [ "1700"
Who can help me with this

Many thanks
Reply
#2
Response['states'] is a list of one or more dicts. states imply there may be more than one dict
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
(Feb-03-2023, 07:37 PM)buran Wrote: Response['states'] is a list of one or more dicts

Hi Buran,

I'm sorry but i do not have a lot of knowlegde of python (yet)
What i try to achieve is to change a currrent script a bit to get a list of 4 scenes out of the JSON

Something like this:

self.scene1='1800'
self.scene2='1700'
self.scene3='1900'
self.scene4='2000'

this is the complete JSON

Output:
"states": [ { "state": [ { "id": [ "0" ], "tempValue": [ "2000" ], "dhw": [ "1" ] }, { "id": [ "1" ], "tempValue": [ "1900" ], "dhw": [ "1" ] }, { "id": [ "2" ], "tempValue": [ "1700" ], "dhw": [ "1" ] }, { "id": [ "3" ], "tempValue": [ "1800" ], "dhw": [ "1" ] }, { "id": [ "4" ], "tempValue": [ "1000" ], "dhw": [ "1" ] } ] } ],
ID# = tempValue
Reply
#4
By "scenes" do you mean these?
Output:
{'id': ['0'], 'tempValue': ['2000'], 'dhw': ['1']} {'id': ['1'], 'tempValue': ['1900'], 'dhw': ['1']} {'id': ['2'], 'tempValue': ['1700'], 'dhw': ['1']} {'id': ['3'], 'tempValue': ['1800'], 'dhw': ['1']} {'id': ['4'], 'tempValue': ['1000'], 'dhw': ['1']}
I got those like this:
import json

with open("test.txt", "r") as file:
    json_data = json.load(file)
    states = json_data["states"][0]["state"]

print(*states, sep="\n")
The top level of your json file is a dictionary.
The dictionary has a key['states']. It appears to be the only key in the dictionary.
The value for 'states' is a list. In the example you posted, the list length is 1.
json_data['states'][0] is another dictionary. From your posted file it too appears to have only one key, 'state'.
json_data['states'][0]['state'] is another list. I think this list are the 'scenes' you mention.
Reply
#5
(Feb-03-2023, 08:13 PM)deanhystad Wrote: By "scenes" do you mean these?
Output:
{'id': ['0'], 'tempValue': ['2000'], 'dhw': ['1']} {'id': ['1'], 'tempValue': ['1900'], 'dhw': ['1']} {'id': ['2'], 'tempValue': ['1700'], 'dhw': ['1']} {'id': ['3'], 'tempValue': ['1800'], 'dhw': ['1']} {'id': ['4'], 'tempValue': ['1000'], 'dhw': ['1']}
I got those like this:
import json

with open("test.txt", "r") as file:
    json_data = json.load(file)
    states = json_data["states"][0]["state"]

print(*states, sep="\n")
The top level of your json file is a dictionary.
The dictionary has a key['states']. It appears to be the only key in the dictionary.
The value for 'states' is a list. In the example you posted, the list length is 1.
json_data['states'][0] is another dictionary. From your posted file it too appears to have only one key, 'state'.
json_data['states'][0]['state'] is another list. I think this list are the 'scenes' you mention.

Yes.
What i like to have
'id': ['1'], 'tempValue': ['1900']

With a output to be something like this

self.scene1=1900

ID1 must be self.scene1 with corresponding tempValue of ID1
ID2 must be self.scene2 with corresponding tempValue of ID2
etc...
Reply
#6
import json

with open("test.txt", "r") as file:
    json_data = json.load(file)
    states = json_data["states"][0]["state"]

for state in states:
    print(
        "id =", state["id"][0], "value =", state["tempValue"][0], "dhw", state["dhw"][0]
    )
Output:
id = 0 value = 2000 dhw 1 id = 1 value = 1900 dhw 1 id = 2 value = 1700 dhw 1 id = 3 value = 1800 dhw 1 id = 4 value = 1000 dhw 1
Reply
#7
It can be useful to make json data to a Pandas the DataFrame,then is easier to work with datat eg query and get a result.
Example.
import pandas as pd
import json

with open('state.json') as file:
    json_data = json.load(file)

df = pd.json_normalize(json_data['states'][0], record_path='state')
Usage.
>>> df
    id tempValue  dhw
0  [0]    [2000]  [1]
1  [1]    [1900]  [1]
2  [2]    [1700]  [1]
3  [3]    [1800]  [1]
4  [4]    [1000]  [1]

>>> # Clean up
>>> df = df.applymap(lambda x: x[0]).astype(int)
>>> df
   id  tempValue  dhw
0   0       2000    1
1   1       1900    1
2   2       1700    1
3   3       1800    1
4   4       1000    1

>>> # To eg get id-1 tempValue 
>>> df.query('id == 1')['tempValue']
1    1900

>>> val = df.query('id == 1')['tempValue']
>>> val.values[0]
1900
Reply
#8
(Feb-03-2023, 08:29 PM)deanhystad Wrote:
import json

with open("test.txt", "r") as file:
    json_data = json.load(file)
    states = json_data["states"][0]["state"]

for state in states:
    print(
        "id =", state["id"][0], "value =", state["tempValue"][0], "dhw", state["dhw"][0]
    )
Output:
id = 0 value = 2000 dhw 1 id = 1 value = 1900 dhw 1 id = 2 value = 1700 dhw 1 id = 3 value = 1800 dhw 1 id = 4 value = 1000 dhw 1

Many thanks for your support.
This helped a lot

    def onMessagetoonSceneinfo(self, Connection, Response):	
        Domoticz.Debug("onMessagetoonSceneinfo called")
        if 'states' in Response:
            #this message contains the scenes
            Domoticz.Debug("onMessagetoonSceneinfo processing list of scenes")
            for state in Response["states"][0]["state"]:
                Domoticz.Log("id ="+ state["id"][0] + " Temp =" + state["tempValue"][0])
Output:
2023-02-04 09:58:02.200 Toon: id =0 Temp =2000 2023-02-04 09:58:02.200 Toon: id =1 Temp =1900 2023-02-04 09:58:02.200 Toon: id =2 Temp =1700 2023-02-04 09:58:02.200 Toon: id =3 Temp =1800 2023-02-04 09:58:02.201 Toon: id =4 Temp =1000
Still getting this error

Error:
TypeError: list indices must be integers or slices, not str
How can i solve this?
Reply
#9
The input JSON as your complete posted is not valied
Tips use jsoncrack to check if valid and see structure.
state.json
Output:
{ "states": [ { "state": [ { "id": [ "0" ], "tempValue": [ "2000" ], "dhw": [ "1" ] }, { "id": [ "1" ], "tempValue": [ "1900" ], "dhw": [ "1" ] }, { "id": [ "2" ], "tempValue": [ "1700" ], "dhw": [ "1" ] }, { "id": [ "3" ], "tempValue": [ "1800" ], "dhw": [ "1" ] }, { "id": [ "4" ], "tempValue": [ "1000" ], "dhw": [ "1" ] } ] } ] }
Code of your code and print it,insted of the log stuff.
import json

with open('state.json') as file:
    Response = json.load(file)
    if 'states' in Response:
        for state in Response["states"][0]["state"]:
            print("id ="+ state["id"][0] + " Temp =" + state["tempValue"][0])
Output:
id =0 Temp =2000 id =1 Temp =1900 id =2 Temp =1700 id =3 Temp =1800 id =4 Temp =1000
With f-string.
import json

with open('state.json') as file:
    Response = json.load(file)
    if 'states' in Response:
        for state in Response["states"][0]["state"]:
            print(f'id = {state["id"][0]} Temp = {state["tempValue"][0]}')
Output:
id = 0 Temp = 2000 id = 1 Temp = 1900 id = 2 Temp = 1700 id = 3 Temp = 1800 id = 4 Temp = 1000
Reply
#10
Hi snippsat

Thank for the JSON check site.
I've check the JSON and it is correct.
Probably a copy/pase error to the forum

What i'm look for is not an output to a log or text
I want the output from the JSON as variable

So
Scene0 = Tempvalue for ID 0
Scene1 = Tempvalue for ID 1
etc...

Then further in the script use this variable as and equation
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  coding error from a script (absolute noob) fuchls 2 3,856 Jun-08-2018, 02:29 PM
Last Post: webrunner1981

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020