I thought I'd jot down a few of the driver porting changes I've encountered. Please add additional ones you find to this list.
Replace physicalgraph with hubitat
Replace variables beginning with data with device.data
Add to params calls that give a java error the following before headers:
requestContentType: "application/json",
Replace pause(int) with pauseExecution(long) (units are milliseconds)
include ‘asynchttp_v1’ is not supported - comment this out and replace affected code with synchronous httpPut, httpGet, etc... calls or use async method calls documented below.
If you get an error trying to schedule a runIn(t, command) function, try changing it to runIn(t.toInteger(), command) to see if that solves it.
Button Devices are handled differently in Hubitat. Please see this post for details - Hubitat's button implementation
Hubitat Safety Monitor api calls detailed here - Hubitat Safety Monitor API - #3 by bravenel
Getting Hub Information is slightly changed... See following as an example
def hub = location.hubs[0]
log.debug "id: ${hub.id}"
log.debug "zigbeeId: ${hub.zigbeeId}"
log.debug "zigbeeEui: ${hub.zigbeeEui}"
log.debug "type: ${hub.type}"
log.debug "name: ${hub.name}"
log.debug "localIP: ${hub.getDataValue("localIP")}"
log.debug "localSrvPortTCP: ${hub.getDataValue("localSrvPortTCP")}"
Getting an OAuth2 endpoint is a little different as well. Also, both LOCAL and CLOUD Endpoints are supported:
Cloud
getApiServerUrl()
getFullApiServerUrl()
apiServerUrl(String url)
fullApiServerUrl(String url)
Local
getLocalApiServerUrl()
getFullLocalApiServerUrl()
localApiServerUrl(String url)
fullLocalApiServerUrl(String url)
So, an example for a local endpoint would be:
def localEndPoint = fullLocalApiServerUrl("<YOUR_PATH_HERE>") + "?access_token=${state.accessToken}"
JsonSlurper . The JsonSlurper function will not work in habitat without including (at the beginning of the file): import groovy.json.JsonSlurper
sendHubCommand does not appear to work within drivers; however, it works in applications.
runEvery1Minute does not work in Hubitat. I have tested 5, 10, 15, and 30 minutes. Others need testing.
Telnet
All of this goes in a driver for a device that will connect to telnet. You open the connection this way:
telnetConnect(String ip, int port, String username, String password)
or
telnetConnect(Map options, String ip, int port, String username, String password)
Only option is "termChars" which changes what the termination character is. You can also pass in null for the password and userid if your endpoint doesn't require a login.
Then, to send/receive messages:
def sendMsg(String msg) {
return new hubitat.device.HubAction(msg, hubitat.device.Protocol.TELNET)
}
and
def parse(String msg) {
// process incoming telnet messages
}
And, finally,
telnetClose()
ASYNC HTTP Calls
Asynchronous calls are now available in the Hubitat Elevation system.
The following methods are available:
void asynchttpGet(String callbackMethod, Map params, Map data = null)
void asynchttpPost(String callbackMethod, Map params, Map data = null)
void asynchttpPut(String callbackMethod, Map params, Map data = null)
void asynchttpDelete(String callbackMethod, Map params, Map data = null)
void asynchttpPatch(String callbackMethod, Map params, Map data = null)
void asynchttpHead(String callbackMethod, Map params, Map data = null)
Possible values for params are as such:
name | value |
---|---|
uri (required) | A URI or URL of the endpoint to send a request to |
path | Request path that is merged with the URI. |
query | Map of URL query parameters. |
headers | Map of HTTP headers. |
requestContentType | The value of the Content-Type request header. Defaults to 'application/json'. |
contentType | The value of the Accept request header. Defaults to the value of the requestContentType parameter if not specified. |
body | The request body to send. Can be a string, or if the requestContentType is "application/json", a Map or List (will be serialized to JSON). |
The callback method should be defined as such:
def processCallBack(response, data) {
}
the name of the callback method can be whatever you choose, just pass it's name to the async method and the system will call it with the results of the http call and also any data you wish to pass to the method.
The first parameter to the callback method (response) is an AsyncResponse object. The methods available on this object are as follows:
Method | Description |
---|---|
int getStatus() | The status code of the response from the call |
Map<String, String> getHeaders() | A map of the headers returned from the call |
String getData() | String value of the response body from the call |
String getErrorData() | |
String getErrorJson() | |
String getErrorMessage() | |
GPathResult getErrorXml() | |
Object getJson() | |
GPathResult getXml() | |
boolean hasError() |
Below is an example of code which would be used to send a POST to a server and the callback method to process the response:
def sendAsynchttpPost() {
def postParams = [
uri: "http://httpbin.org/post",
requestContentType: 'application/json',
contentType: 'application/json',
headers: ['CustomHeader':'CustomHeaderValue'],
body : ["name": "value"]
]
asynchttpPost('myCallbackMethod', postParams, [dataitem1: "datavalue1"])
}
def myCallbackMethod(response, data) {
if(data["dataitem1"] == "datavalue1")
log.debug "data was passed successfully"
log.debug "status of post call is: ${response.status}"
}
Composite Device Drivers
Hubitat now supports devices having child devices. The methods that are available are as follows:
Parent Device Methods:
ChildDeviceWrapper addChildDevice(String namespace, String typeName, String deviceNetworkId, Map properties = [:])
ChildDeviceWrapper addChildDevice(String typeName, String deviceNetworkId, Map properties = [:])
Creates a new child device and returns that device from the method call.
Parameters:
Type | Parameter | description |
---|---|---|
String | namespace | The namespace of the child driver to add as a child device (optional, if not specified it will default the the namespace of the parent) |
String | typeName | The name of the child driver to add as a child device |
String | deviceNetworkId | unique identifier for this device |
Map | properties | optional parameters for this child device. Possible values listed below: |
properties:
boolean | isComponent | true or false, if true, device will still show up in device list but will not be able to be deleted or edited in the UI. If false, device can be modified/deleted on the UI. |
String | name | name of child device, if not specified, driver name is used. |
String | label | label of child device, if not specified it is left blank. |
List<ChildDeviceWrapper> getChildDevices()
Gets a list of all child devices for this device.
ChildDeviceWrapper getChildDevice(String deviceNetworkId)
Gets a specific child device with the device network id specified.
void deleteChildDevice(String deviceNetworkId)
Deletes a specific child device with the device network id sepcified.
Child Device Methods:
ParentDeviceWrapper getParent()
Returns the parent device when called from a child device.
How to get Latitude and Longtitude of the hub programatically
location.getLatitude()
location.getLongitude()
Converting an object to JSON
Replace uses of util.toJson
with groovy.json.JsonOutput.toJson