Device Type Response JSON


(Rakote) #1

So I have a bit of a quandary. I have a custom device type that I created. When I send a command via local LAN (figured out how to do it via device type) I am expecting a JSON response. I can get my bulb to turn off but the tile never updates. I am not sure I understand how to receive a device response and update the UI. Here is the code I have.

/**
 *  LIFX Bulb
 *
 *  Author: Andrew Filipowski with parts borrowed from Smartthings Sonos Smartapp and From Eran (Smartthings Community) as well as dianoga7@3dgo.net
 *  Date: 2014-03-28
 *
 *
 */

 preferences {
    input("server", "text", title: "Server", description: "Your LIFX-HTTP Server IP")
    input("port", "text", title: "Port", description: "Your LIFX-HTTP Server Port")
    input("deviceNetworkId", "text", title: "Server HEX Code", description: "Hex Code to talk to server")
}

 // for the UI
metadata {
	definition (name: "LIFX Bulb", author: "Andrew Filipowski") {
		capability "Switch"
		capability "Switch Level"
		capability "Color Control"
	}

	simulator {
		// TODO: define status and reply messages here
	}

	tiles {
		// TODO: define your main and details tiles here
		standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) 
		{
			state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
			state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
			state "turningOn", label:'${name}', icon:"st.switches.switch.on", backgroundColor:"#79b821"
			state "turningOff", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ffffff"
		}
		controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false) 
		{
			state "level", action:"switch level.setLevel"
		}
		standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat") 
		{
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}
		main "switch"
		details(["switch","refresh","levelSliderControl"])
	}
}

// parse events into attributes
def parse(String description) {
	log.debug "Parsing '${description}'"
}

// handle commands
def on() {
	log.debug "Executing 'on'"
	api('on') {
        sendEvent(name: 'switch', value: "on")
    }
}

def off() {
	log.debug "Executing 'off'"
	api('off') {
        sendEvent(name: 'switch', value: "off")
    }
}

def setLevel() {
	log.debug "Executing 'setLevel'"
	// TODO: handle 'setLevel' command
}

def setHue() {
	log.debug "Executing 'setHue'"
	// TODO: handle 'setHue' command
}

def setSaturation() {
	log.debug "Executing 'setSaturation'"
	// TODO: handle 'setSaturation' command
}

def setColor() {
	log.debug "Executing 'setColor'"
	// TODO: handle 'setColor' command
}

def api(String bulbRequest, success = {}) {
	def ip = "${settings.server}:${settings.port}"
    def deviceNetworkId = "${settings.deviceNetworkId}"
    def encodedName = device.name.replaceAll(" ", "%20")

    if ( bulbRequest == "on" )
    {
    	def uri = "/lights/label:${name}/on?_method=put"
    	def turnOn = new physicalgraph.device.HubAction("""GET /lights/label:${encodedName}/on?_method=put HTTP/1.1\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}")
    }
    else if ( bulbRequest == "off" )
    {
    	def uri = "/lights/label:${name}/off?_method=put"
    	def turnOff = new physicalgraph.device.HubAction("""GET /lights/label:${encodedName}/off?_method=put HTTP/1.1\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}")
    }

    

  
    
    
}

Thru the UI on the things page I can get my light to turn off however I am getting the following message in my logs:

04e69a29-4f0c-43a2-b1d8-56a390043203 10:53:55 AM CDT: warn Body not XML
04e69a29-4f0c-43a2-b1d8-56a390043203 10:53:55 AM CDT: trace HTTP/1.1 200 OK 659 bytes, body = 266 bytes, sid =
45cfcdf6-2ffe-43d7-9a56-77fd709bbffd 10:53:53 AM CDT: debug Executing 'off'

I know it is not XML but I can’t figure out via example code and or on the web how the parse method works or how to get the response from the bulb and update the UI. The expected response is JSON and here is an example of what I expect to get back from the bulb in the body:

{"id":"d073d5003ab1","label":"Living Room Couch","site_id":"d073d5005b92","tags":["Living Room","Living Room Floor"],"on":false,"color":{"hue":0.0,"saturation":0.0,"brightness":1.0,"kelvin":3500},"last_seen":"2014-04-04T11:02:03-05:00","seconds_since_seen":0.001232}

I can’t seem to figure this response out. Any pointers or direction would be much appreciated.

Thanks


(Nicolas) #2

I have no clue yet on how to read the JSON response. From the Sonos Example you can subscribe to event in the Hub and parse HTTP responses, but i haven’t figure how yet.

Concerning you Tile not being updated, it’s because you never actually send the event “sendEvent(name: ‘switch’, value: “off”)”.
This code doesn’t get executed. This is the “success” callback that you have in “def api(String bulbRequest, success = {})”

However it never run… I’m guessing you built your code with example that use httpGet which use callback like (http://build.smartthings.com/forums/topic/basic-control-of-lifx-bulbs/)

Basically you can modify your commands like:

// handle commands
def on() {
	log.debug "Executing 'on'"
	api('on')
        sendEvent(name: 'switch', value: "on")
}

def off() {
	log.debug "Executing 'off'"
	api('off')
        sendEvent(name: 'switch', value: "off")
}

This will work however, it’s not waiting for the request to be done.


(Duncan) #3

When the response comes back to the server it is not connected to the action you sent so it has to be routed to the device. The deviceNetworkId is used for that. Do you have your deviceNetworkId set properly?

The logs look like the response is getting passed to the parse() method of a Sonos device type handler. Did you used to have the parse method copied from Sonos? You may have to republish this device type handler if so.


(Morgan) #4

Bump, I’m having the same issue but with a different device. Anyone have code to parse that JSON?