Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save cramforce/f53913ba1de5f283e411226d0318b0b4 to your computer and use it in GitHub Desktop.
Save cramforce/f53913ba1de5f283e411226d0318b0b4 to your computer and use it in GitHub Desktop.
A SmartThings Device Handler for Elgato Key Light
/**
* Copyright 2020 Malte Ubl
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
*/
// Reverse engineering reference https://gitlab.com/obviate.io/pyleglight/-/blob/master/leglight/leglight.py
metadata {
definition (name: "Elgato Key Light", namespace: "cramforce", author: "Malte Ubl") {
capability "Switch Level"
capability "Actuator"
capability "Switch"
capability "Refresh"
capability "Sensor"
capability "Health Check"
capability "Light"
}
preferences {
input name: "hostname", type: "text", title: "IP Address", description: "IP Address of the light. Should be fixed.", required: true
}
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel"
}
}
standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}
valueTile("level", "device.level", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "level", label:'${currentValue} %', unit:"%", backgroundColor:"#ffffff"
}
main(["switch"])
details(["switch", "level", "refresh"])
}
}
def installed() {
updated()
}
def updated() {
unschedule()
runEvery5Minutes(refresh)
refresh()
}
def on() {
sendElgatoOn(true)
}
def off() {
sendElgatoOn(false)
}
def setLevel(value) {
sendElgatoLevel(value)
}
def setLevel(value, duration) {
setLevel(value)
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
refresh()
}
def refresh() {
sendHttpRequest("GET", hostname + ":9123", "/elgato/lights")
}
def sendElgatoOn(on) {
sendHttpRequest("PUT", hostname + ":9123", "/elgato/lights", """{"numberOfLights":1,"lights":[{"on":${on ? 1 : 0}}]}""")
}
def sendElgatoLevel(level) {
sendHttpRequest("PUT", hostname + ":9123", "/elgato/lights", """{"numberOfLights":1,"lights":[{"brightness": ${level}}]}""")
}
def sendHttpRequest(method, host, path, body="") {
log.debug "Executing 'sendHttpRequest' method: "+method+" host: "+host+" path: "+path+" body: "+body
def bodyHead = "";
if(!body.equals("")) {
bodyHead = "Content-Type: application/json\r\nContent-Length: ${body.length()}\r\n";
body = body;
}
def httpRequest = """${method} ${path} HTTP/1.1\r\nHOST: $host\r\n${bodyHead}\r\n${body}"""
log.debug httpRequest
sendHubCommand(new physicalgraph.device.HubAction(httpRequest, physicalgraph.device.Protocol.LAN, host, [callback: cb]))
}
def cb(physicalgraph.device.HubResponse hubResponse) {
log.debug "Response: " + hubResponse.status + " Body: " + hubResponse.body
def json = hubResponse.json
if (json == null) {
log.debug "No JSON"
return;
}
log.debug "json" + json
def on = json.lights[0].on == 1
def level = json.lights[0].brightness
sendEvent(name: "switch", value: on ? "on" : "off")
sendEvent(name: "level", value: level)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment