Parse JSON to use in HabPanel

Hello,

I’m still learning to do openhab. I’m creating an custom widget to control an Hue group. I would like to set the scene to the group. I’m able to do this by a rule which uses sendHttpPutRequest to switch to the scene, but currently the scene ID is fixed in the rule. I would like to enumurate the scene Ids from the Hue bridge, and use them in my Openhab widget.

I can get them in a JSON response from:
http://api//scenes

Format:

{"CchzXmkNLypkgtq":{"name":"Arctische dageraad","lights":["3","4","5","6","7","8","9","12","13"],"owner":"none","recycle":false,"locked":false,"appdata":{"version":1,"data":"a9iwJ_r01_d17"},"picture":"","lastupdated":"2017-12-05T16:43:58","version":2},
"IQzfjQpsbNE-VGq":{"name":"Savanne zonsondergang","lights":["3","4","5","6","7","8","9","12","13"],"owner":"none","recycle":false,"locked":false,"appdata":{"version":1,"data":"JvkFV_r01_d15"},"picture":"","lastupdated":"2017-12-10T14:07:54","version":2}}

It’s possible to parse JSON in an item, but I can only parse a single string and not an array.

What would be my options here?

Any help is very welcome, thanks!
Bastiaan

The best way is use a controller, but since you’re making a custom widget, I assume you want to make this available for everyone? Controller-less code is better so users wont have to mess with code. So, to solve your issue:

  1. Use JsonPath to parse your data and extract this part
    ["3","4","5","6","7","8","9","12","13"]

  2. Save that onto an item, for example,

    String sceneArray1
    
  3. The ‘hackish’ part

    <div ng-repeat="scene in (itemValue('sceneArray1') || '').split('[')[1].split(']')[0].split(',') track by $index">
        Scene: {{scene.replace('"','').replace('"','')}}
    </div>
    

image

1 Like

Assuming you’ve got your JSON as posted above in an item named “Hue_Scenes” you can use this:

<div ng-repeat="json in [itemState('Hue_Scenes')]">
  <div ng-repeat="(id, scene) in $eval(json)">
    <button class="btn btn-default">{{scene.name}}</button>
    <br />
  </div>
</div>

This gives you:
image

The first ng-repeat on a singleton array is a trick to avoid “infinite digest” errors.

Thank you for your replies. This two approaches should get me started. Thanks for this!

I’m busy with JSONPath, and it doens not allow me to get key and value. I want to display the scene names in Habpanel, but need the corresponding uid in order to tell the HUE api to switch to this scene. Any idea’s on this?

Shouldn’t uid be unique and a known value?

If I want to make it completely dynamic, so we can add scene’s thru the HUE app, I do not know the uid’s in advance.

uid = “CchzXmkNLypkgtq” / name = "Arctische dageraad"
uid = “IQzfjQpsbNE-VGq” / name = “Savanne zonsondergang”

I could create two strings, one getting the uid’s, and the other the names. The order should be equal. And then build it with angular which would result in:

<select name="selected-uid">
<option name="CchzXmkNLypkgtq">Arctische dageraad</option>
<option name="IQzfjQpsbNE-VGq">Savanne zonsondergang</option>
....
</select>

Would that be possible?

I ended up defining the scene id’s in the HabPanel widget. When the select is changed, a rule is triggered and changes the scene aganst the HUE API.

rule "Hue Scene Select - Woonkamer"
when
	Item Hue_Scene_Woonkamer changed
then
	sendHttpPutRequest("http://192.168.1.222/api/<yourusername>/groups/1/action", "application/json", '{"scene": "'+ Hue_Scene_Woonkamer.state +'"}')
	logInfo("Hue Woonkamer", "Hue Scene Woonkamer changed to " + Hue_Scene_Woonkamer.state)
	
	// Change brightness to current value (not one stored in scene)
	createTimer(now.plusSeconds(3), [|
		var int brightness = Hue_Brightness_Woonkamer.state
		sendCommand(Hue_Brightness_Woonkamer, brightness)
		logInfo("Hue Woonkamer", "Hue Scene Woonkamer brightness changed to " + Hue_Brightness_Woonkamer.state)
	])
end

rule "Hue Brightness - Woonkamer"
when
	Item Hue_Brightness_Woonkamer changed
then
	sendHttpPutRequest("http://192.168.1.222/api/<yourusername>/groups/1/action", "application/json", '{"bri": '+ Hue_Brightness_Woonkamer.state +'}')
	logInfo("Hue Woonkamer", "Hue Brightness Woonkamer changed to " + Hue_Brightness_Woonkamer.state)
end