Device Type for Web Service

So I’m working on building a device type to handle a Nest thermostat. The only way I have to communicate with it is through a web service (I’m using a middle man so I don’t have to figure out the Nest API yet).

So far I have the web service functioning and the simulator commands all seem to work.

It looks like tile updating has to be done by returning the results of createEvent from the parse method. I copied the tile setup from the Z-Wave Thermostat sample as I couldn’t find any documentation for tiles.

I’m using the poll method to retrieve the current status of the thermostat. Will that method be called automatically or do I have to schedule it? Can it be scheduled?

So I thought I would be able to call parse from poll, but it doesn’t seem to update the tile. How do you update a tile?

@dianoga – You can use the send() method. If you’re updating a value tile:

send( name: "tile_name", value: "tile value", unit: "UNIT" )

If you’re updating a standard tile’s icon:

send( name: "tile_name", value: "icon_path", displayed: true )

For example, if you have a temperature tile for which you received 68.8 from your remote service and you wanted to round that to the next Integer and display with a “F” unit:

send( name: "temperature", value: Math.round( temp ), unit: "F" )

@dlieberman Thanks for the response!

send() is throwing errors for me.

send (name: 'temperature', value: response.data.temperature, unit: response.data.temperature_units)
causes
No signature of method: script13722546892872133543541.send() is applicable for argument types: (java.util.LinkedHashMap) values: [[name:temperature, value:74, unit:F]]

Also, any word on how to automate the polling?

@dianoga – Try

send(name: "temperature", value: response.data.temperature as Integer, unit: response.data.temperature_units as String)

@dlieberman that gives me the same error. It looks like the arguments are turning into a LinkedHashMap and send doesn’t like it.

@dianoga - Whoops, I’m sorry. It’s not send(), it’s sendEvent().

@dlieberman sendEvent works!

At least, it does for temperature. It doesn’t seem to be updating tiles with states. Example: fanMode can be auto, on, circulate.

@dianoga - Are you setting the value of the tile to be the name of the state, and does each state have its own icon?

@dlieberman - I think I’m setting the value to the name of the state. That’s my goal anyway.

The Tile

standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
	state "auto", label:'${name}', action:"thermostat.fanOn"
	state "on", label:'${name}', action:"thermostat.fanCirculate"
	state "circulate", label:'${name}', action:"thermostat.fanAuto"
}

The Update Bits
sendEvent (name: "fanMode", value: response.data.fan_mode)

I also tried response.data.fan_mode as String

@dianoga - So I’m learning this along with you and it looks like it wants the tile name to match the device attribute. This works for me:

		
standardTile("fanMode", "device.fanMode", inactiveLabel: false, decoration: "flat") {
			state "auto", label:'${name}', action:"thermostat.fanOn"
			state "on", label:'${name}', action:"thermostat.fanCirculate"
			state "circulate", label:'${name}', action:"thermostat.fanAuto"

And:

sendEvent( name: "fanMode", value: "circulate", displayed: true )

@dlieberman – That worked. Now I just need to get the tiles to work on Android. Thanks for your help.

@dlieberman Any idea on setting up the initial values and scheduling the poll?

@dianoga – You can set up a default tile state using the device’s last known values by doing:

valueTile("temperature", "device.temperature") {
	state "default", label:'${currentValue}°', unit:"F", action: "refresh",
}

where ${currentValue} should pull the last known value for device.temperature.

As for scheduling the poll, my understanding is that if the Device-Type Handler implements poll(), it will be called automatically by the system at 5 minute intervals, and that interval is not currently configurable.

@dlieberman Does sendEvent properly set the device states?

ALso, the Android app doesn’t seem to show all the configured tiles. But I can report that in the Android bug forums.

@dianoga – Yes, sendEvent does set the currentState property. I just tested the following code:

def off() {
    def valueToSend = device.currentValue( "temperature" ) as Integer ?: 1
    valueToSend++
    sendEvent( name: "temperature", value: valueToSend, unit: "F" )
}

And tested it several times by hitting the off button in the simulator. It behaves as expected.

As for Android, I’ll mention it to the right folks here, but if you could post it to the Android bug forums as well that’d be great, thanks!

@dlieberman It looks like poll isn’t being called as expected. When I ran the device in the simulator and manually hit poll it did set the device state, but it hasn’t updated since yesterday.

@dianoga – So three things:

1/ You need to have the Polling capability selected in the Device Type Settings
2/ Virtual devices don’t get polled in the simulator
3/ I was just told that there might be an issue introduced in the latest release of the platform that is affecting poll()

I asked Engineering to keep me in the loop on #3 - I’ll post back here when I hear more, and I’ll do some additional testing on my own.

Thanks,
-d

I setup my device type to support polling. I also deleted and readded my device just to make sure the settings get updated. I’m not sure how publishing device types is supposed to work since the publish button doesn’t seem to do anything.

The poll hasn’t run on it’s own yet. I’ll keep an eye on it.

@dianoga – Did you add your device through the My Devices page in the IDE? If it shows up there as a Device Type that you can manually add, then it’s been published into your account (Publish -> For Me). Make sure you do Publish -> For Me after each time you’ve made changes, then delete and re-add the device in the My Devices page for good measure.