Compare commits

...

9 Commits

Author SHA1 Message Date
김지섭
5769e72c3d MSA-932: VER. TEST 2016-03-08 03:23:06 -06:00
Vinay Rao
e83d08cf2f Merge pull request #597 from workingmonk/bug/cree_bulb
[DVCSMP-1442] Cree bulb does not properly reflect dimming value
2016-03-07 20:17:53 -08:00
Vinay Rao
55905a10da issue with CREE Bulb not reporting back state
updating copyright and spacing
2016-03-07 19:13:19 -08:00
Juan Pablo Risso
546ee007f1 Merge pull request #561 from juano2310/hue-PROB-528
PROB-528 - Commented singleInstance: true
2016-03-07 17:27:37 -08:00
Juan Pablo Risso
21ae20302c Merge pull request #584 from juano2310/Hue_ColorTemp
DVCSMP-1565 & DVCSMP-1548
2016-03-07 17:27:18 -08:00
juano2310
9880ced851 Fix wrong DT for Hue bulb 2016-03-07 17:05:06 -08:00
juano2310
fb99a81704 fixed rich-control 2016-03-04 17:15:49 -05:00
juano2310
6bda59c340 DVCSMP-1565 & DVCSMP-1548
DVCSMP-1565 Color for light is not adjusted.
DVCSMP-1548 Color temperature
2016-03-04 17:08:24 -05:00
Juan Pablo Risso
600a9a2ca1 PROB-528 - Commented singleInstance: true
This will allow any one with more than one Hue Bridge to install an instance for each Bridge.
2016-02-26 14:45:12 -05:00
6 changed files with 206 additions and 111 deletions

View File

@@ -1,7 +1,7 @@
/** /**
* Cree Bulb * Cree Bulb
* *
* Copyright 2014 SmartThings * Copyright 2016 SmartThings
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * 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: * in compliance with the License. You may obtain a copy of the License at:
@@ -15,29 +15,29 @@
*/ */
metadata { metadata {
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") { definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") {
capability "Actuator" capability "Actuator"
capability "Configuration" capability "Configuration"
capability "Refresh" capability "Refresh"
capability "Switch" capability "Switch"
capability "Switch Level" capability "Switch Level"
fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0000,0019" fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0000,0019"
} }
// simulator metadata // simulator metadata
simulator { simulator {
// status messages // status messages
status "on": "on/off: 1" status "on": "on/off: 1"
status "off": "on/off: 0" status "off": "on/off: 0"
// reply messages // reply messages
reply "zcl on-off on": "on/off: 1" reply "zcl on-off on": "on/off: 1"
reply "zcl on-off off": "on/off: 0" reply "zcl on-off off": "on/off: 0"
} }
// UI tile definitions // UI tile definitions
tiles(scale: 2) { tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){ multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
@@ -62,18 +62,12 @@ metadata {
def parse(String description) { def parse(String description) {
log.debug "description is $description" log.debug "description is $description"
def resultMap = zigbee.getKnownDescription(description) def resultMap = zigbee.getEvent(description)
if (resultMap) { if (resultMap) {
log.info resultMap sendEvent(resultMap)
if (resultMap.type == "update") {
log.info "$device updates: ${resultMap.value}"
}
else {
sendEvent(name: resultMap.type, value: resultMap.value)
}
} }
else { else {
log.warn "DID NOT PARSE MESSAGE for description : $description" log.debug "DID NOT PARSE MESSAGE for description : $description"
log.debug zigbee.parseDescriptionAsMap(description) log.debug zigbee.parseDescriptionAsMap(description)
} }
} }
@@ -87,7 +81,7 @@ def on() {
} }
def setLevel(value) { def setLevel(value) {
zigbee.setLevel(value) zigbee.setLevel(value) + ["delay 500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
} }
def refresh() { def refresh() {

View File

@@ -1,4 +1,3 @@
/** /**
* Hue Bulb * Hue Bulb
* *
@@ -11,13 +10,14 @@ metadata {
capability "Switch Level" capability "Switch Level"
capability "Actuator" capability "Actuator"
capability "Color Control" capability "Color Control"
capability "Color Temperature"
capability "Switch" capability "Switch"
capability "Refresh" capability "Refresh"
capability "Sensor" capability "Sensor"
command "setAdjustedColor" command "setAdjustedColor"
command "reset" command "reset"
command "refresh" command "refresh"
} }
simulator { simulator {
@@ -25,7 +25,7 @@ metadata {
} }
tiles (scale: 2){ tiles (scale: 2){
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){ multiAttributeTile(name:"rich-control", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
@@ -33,23 +33,58 @@ metadata {
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
} }
tileAttribute ("device.level", key: "SLIDER_CONTROL") { tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel" attributeState "level", action:"switch level.setLevel", range:"(0..100)"
}
tileAttribute ("device.level", key: "SECONDARY_CONTROL") {
attributeState "level", label: 'Level ${currentValue}%'
} }
tileAttribute ("device.color", key: "COLOR_CONTROL") { tileAttribute ("device.color", key: "COLOR_CONTROL") {
attributeState "color", action:"setAdjustedColor" attributeState "color", action:"setAdjustedColor"
} }
} }
standardTile("reset", "device.reset", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
}
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2000..6500)") {
state "colorTemperature", action:"color temperature.setColorTemperature"
}
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "colorTemperature", label: '${currentValue} K'
}
standardTile("reset", "device.reset", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:"Reset Color", action:"reset", icon:"st.lights.philips.hue-single" state "default", label:"Reset Color", action:"reset", icon:"st.lights.philips.hue-single"
} }
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { standardTile("refresh", "device.switch", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
} }
} controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") {
state "level", action:"switch level.setLevel"
}
valueTile("level", "device.level", inactiveLabel: false, decoration: "flat") {
state "level", label: 'Level ${currentValue}%'
}
controlTile("saturationSliderControl", "device.saturation", "slider", height: 1, width: 2, inactiveLabel: false) {
state "saturation", action:"color control.setSaturation"
}
valueTile("saturation", "device.saturation", inactiveLabel: false, decoration: "flat") {
state "saturation", label: 'Sat ${currentValue} '
}
controlTile("hueSliderControl", "device.hue", "slider", height: 1, width: 2, inactiveLabel: false) {
state "hue", action:"color control.setHue"
}
valueTile("hue", "device.hue", inactiveLabel: false, decoration: "flat") {
state "hue", label: 'Hue ${currentValue} '
}
main(["switch"]) main(["switch"])
details(["switch", "levelSliderControl", "rgbSelector", "refresh", "reset"]) details(["rich-control", "colorTempSliderControl", "colorTemp", "reset", "refresh"])
}
} }
// parse events into attributes // parse events into attributes
@@ -119,19 +154,27 @@ void setColor(value) {
void reset() { void reset() {
log.debug "Executing 'reset'" log.debug "Executing 'reset'"
def value = [level:100, hex:"#90C638", saturation:56, hue:23] def value = [level:100, hex:"#90C638", saturation:56, hue:23]
setAdjustedColor(value) setAdjustedColor(value)
parent.poll() parent.poll()
} }
void setAdjustedColor(value) { void setAdjustedColor(value) {
if (value) { if (value) {
log.trace "setAdjustedColor: ${value}" log.trace "setAdjustedColor: ${value}"
def adjusted = value + [:] def adjusted = value + [:]
adjusted.hue = adjustOutgoingHue(value.hue) adjusted.hue = adjustOutgoingHue(value.hue)
// Needed because color picker always sends 100 // Needed because color picker always sends 100
adjusted.level = null adjusted.level = null
setColor(adjusted) setColor(adjusted)
}
}
void setColorTemperature(value) {
if (value) {
log.trace "setColorTemperature: ${value}k"
parent.setColorTemperature(this, value)
sendEvent(name: "colorTemperature", value: value)
} }
} }

View File

@@ -9,51 +9,59 @@ metadata {
definition (name: "Hue Lux Bulb", namespace: "smartthings", author: "SmartThings") { definition (name: "Hue Lux Bulb", namespace: "smartthings", author: "SmartThings") {
capability "Switch Level" capability "Switch Level"
capability "Actuator" capability "Actuator"
capability "Color Temperature"
capability "Switch" capability "Switch"
capability "Refresh" capability "Refresh"
capability "Sensor" capability "Sensor"
command "refresh" command "refresh"
} }
simulator { simulator {
// TODO: define status and reply messages here // TODO: define status and reply messages here
} }
tiles(scale: 2) { tiles(scale: 2) {
multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){ multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
}
tileAttribute ("device.level", key: "SECONDARY_CONTROL") {
attributeState "level", label: 'Level ${currentValue}%'
} }
tileAttribute ("device.level", key: "SLIDER_CONTROL") { }
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
}
tileAttribute ("device.level", key: "SECONDARY_CONTROL") {
attributeState "level", label: 'Level ${currentValue}%'
}
}
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) { standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
} }
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") { controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") {
state "level", action:"switch level.setLevel" state "level", action:"switch level.setLevel"
} }
standardTile("refresh", "device.switch", inactiveLabel: false, height: 2, width: 2, decoration: "flat") { controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2000..6500)") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" state "colorTemperature", action:"color temperature.setColorTemperature"
} }
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "colorTemperature", label: '${currentValue} K'
}
main(["switch"]) standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
details(["rich-control", "refresh"]) state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
} }
main(["switch"])
details(["rich-control", "colorTempSliderControl", "colorTemp", "refresh"])
}
} }
// parse events into attributes // parse events into attributes
@@ -90,6 +98,14 @@ void setLevel(percent) {
sendEvent(name: "level", value: percent) sendEvent(name: "level", value: percent)
} }
void setColorTemperature(value) {
if (value) {
log.trace "setColorTemperature: ${value}k"
parent.setColorTemperature(this, value)
sendEvent(name: "colorTemperature", value: value)
}
}
void refresh() { void refresh() {
log.debug "Executing 'refresh'" log.debug "Executing 'refresh'"
parent.manualRefresh() parent.manualRefresh()

View File

@@ -0,0 +1,35 @@
/**
* TEST
*
* Copyright 2016 김지섭
*
* 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.
*
*/
metadata {
definition (name: "TEST", namespace: "TEST1", author: "김지섭") {
capability "Temperature Measurement"
}
simulator {
// TODO: define status and reply messages here
}
tiles {
// TODO: define your main and details tiles here
}
}
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
// TODO: handle 'temperature' attribute
}

View File

@@ -15,7 +15,7 @@
* for the specific language governing permissions and limitations under the License. * for the specific language governing permissions and limitations under the License.
* *
*/ */
definition( definition(
name: "Hue (Connect)", name: "Hue (Connect)",
namespace: "smartthings", namespace: "smartthings",
@@ -24,7 +24,7 @@ definition(
category: "SmartThings Labs", category: "SmartThings Labs",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/hue.png", iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/hue.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/hue@2x.png", iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/hue@2x.png",
singleInstance: true //singleInstance: true
) )
preferences { preferences {
@@ -58,7 +58,7 @@ def bridgeDiscovery(params=[:])
state.bridges = [:] state.bridges = [:]
state.bridgeRefreshCount = 0 state.bridgeRefreshCount = 0
app.updateSetting("selectedHue", "") app.updateSetting("selectedHue", "")
} }
subscribe(location, null, locationHandler, [filterEvents:false]) subscribe(location, null, locationHandler, [filterEvents:false])
@@ -130,8 +130,8 @@ def bulbDiscovery() {
def bulboptions = bulbsDiscovered() ?: [:] def bulboptions = bulbsDiscovered() ?: [:]
def numFound = bulboptions.size() ?: 0 def numFound = bulboptions.size() ?: 0
if (numFound == 0) if (numFound == 0)
app.updateSetting("selectedBulbs", "") app.updateSetting("selectedBulbs", "")
if((bulbRefreshCount % 5) == 0) { if((bulbRefreshCount % 5) == 0) {
discoverHueBulbs() discoverHueBulbs()
} }
@@ -140,7 +140,7 @@ def bulbDiscovery() {
section("Please wait while we discover your Hue Bulbs. Discovery can take five minutes or more, so sit back and relax! Select your device below once discovered.") { section("Please wait while we discover your Hue Bulbs. Discovery can take five minutes or more, so sit back and relax! Select your device below once discovered.") {
input "selectedBulbs", "enum", required:false, title:"Select Hue Bulbs (${numFound} found)", multiple:true, options:bulboptions input "selectedBulbs", "enum", required:false, title:"Select Hue Bulbs (${numFound} found)", multiple:true, options:bulboptions
} }
section { section {
def title = getBridgeIP() ? "Hue bridge (${getBridgeIP()})" : "Find bridges" def title = getBridgeIP() ? "Hue bridge (${getBridgeIP()})" : "Find bridges"
href "bridgeDiscovery", title: title, description: "", state: selectedHue ? "complete" : "incomplete", params: [override: true] href "bridgeDiscovery", title: title, description: "", state: selectedHue ? "complete" : "incomplete", params: [override: true]
@@ -246,13 +246,13 @@ def installed() {
def updated() { def updated() {
log.trace "Updated with settings: ${settings}" log.trace "Updated with settings: ${settings}"
unsubscribe() unsubscribe()
unschedule() unschedule()
initialize() initialize()
} }
def initialize() { def initialize() {
log.debug "Initializing" log.debug "Initializing"
unsubscribe(bridge) unsubscribe(bridge)
state.inBulbDiscovery = false state.inBulbDiscovery = false
state.bridgeRefreshCount = 0 state.bridgeRefreshCount = 0
@@ -281,18 +281,18 @@ def uninstalled(){
def bulbListHandler(hub, data = "") { def bulbListHandler(hub, data = "") {
def msg = "Bulbs list not processed. Only while in settings menu." def msg = "Bulbs list not processed. Only while in settings menu."
def bulbs = [:] def bulbs = [:]
if (state.inBulbDiscovery) { if (state.inBulbDiscovery) {
def logg = "" def logg = ""
log.trace "Adding bulbs to state..." log.trace "Adding bulbs to state..."
state.bridgeProcessedLightList = true state.bridgeProcessedLightList = true
def object = new groovy.json.JsonSlurper().parseText(data) def object = new groovy.json.JsonSlurper().parseText(data)
object.each { k,v -> object.each { k,v ->
if (v instanceof Map) if (v instanceof Map)
bulbs[k] = [id: k, name: v.name, type: v.type, hub:hub] bulbs[k] = [id: k, name: v.name, type: v.type, hub:hub]
} }
} }
def bridge = null def bridge = null
if (selectedHue) if (selectedHue)
bridge = getChildDevice(selectedHue) bridge = getChildDevice(selectedHue)
bridge.sendEvent(name: "bulbList", value: hub, data: bulbs, isStateChange: true, displayed: false) bridge.sendEvent(name: "bulbList", value: hub, data: bulbs, isStateChange: true, displayed: false)
msg = "${bulbs.size()} bulbs found. ${bulbs}" msg = "${bulbs.size()} bulbs found. ${bulbs}"
@@ -318,7 +318,7 @@ def addBulbs() {
} else { } else {
log.debug "$dni in not longer paired to the Hue Bridge or ID changed" log.debug "$dni in not longer paired to the Hue Bridge or ID changed"
} }
} else { } else {
//backwards compatable //backwards compatable
newHueBulb = bulbs.find { (app.id + "/" + it.id) == dni } newHueBulb = bulbs.find { (app.id + "/" + it.id) == dni }
d = addChildDevice("smartthings", "Hue Bulb", dni, newHueBulb?.hub, ["label":newHueBulb?.name]) d = addChildDevice("smartthings", "Hue Bulb", dni, newHueBulb?.hub, ["label":newHueBulb?.name])
@@ -344,7 +344,7 @@ def addBridge() {
def d = getChildDevice(selectedHue) def d = getChildDevice(selectedHue)
if(!d) { if(!d) {
// compatibility with old devices // compatibility with old devices
def newbridge = true def newbridge = true
childDevices.each { childDevices.each {
if (it.getDeviceDataByName("mac")) { if (it.getDeviceDataByName("mac")) {
def newDNI = "${it.getDeviceDataByName("mac")}" def newDNI = "${it.getDeviceDataByName("mac")}"
@@ -354,10 +354,10 @@ def addBridge() {
it.setDeviceNetworkId("${newDNI}") it.setDeviceNetworkId("${newDNI}")
if (oldDNI == selectedHue) if (oldDNI == selectedHue)
app.updateSetting("selectedHue", newDNI) app.updateSetting("selectedHue", newDNI)
newbridge = false newbridge = false
} }
} }
} }
if (newbridge) { if (newbridge) {
d = addChildDevice("smartthings", "Hue Bridge", selectedHue, vbridge.value.hub) d = addChildDevice("smartthings", "Hue Bridge", selectedHue, vbridge.value.hub)
log.debug "created ${d.displayName} with id ${d.deviceNetworkId}" log.debug "created ${d.displayName} with id ${d.deviceNetworkId}"
@@ -368,13 +368,13 @@ def addBridge() {
childDevice.sendEvent(name: "networkAddress", value: vbridge.value.ip + ":" + vbridge.value.port) childDevice.sendEvent(name: "networkAddress", value: vbridge.value.ip + ":" + vbridge.value.port)
childDevice.updateDataValue("networkAddress", vbridge.value.ip + ":" + vbridge.value.port) childDevice.updateDataValue("networkAddress", vbridge.value.ip + ":" + vbridge.value.port)
} else { } else {
childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.ip) + ":" + convertHexToInt(vbridge.value.port)) childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.ip) + ":" + convertHexToInt(vbridge.value.port))
childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.ip) + ":" + convertHexToInt(vbridge.value.port)) childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.ip) + ":" + convertHexToInt(vbridge.value.port))
} }
} else { } else {
childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress)) childDevice.sendEvent(name: "networkAddress", value: convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress))
childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress)) childDevice.updateDataValue("networkAddress", convertHexToIP(vbridge.value.networkAddress) + ":" + convertHexToInt(vbridge.value.deviceAddress))
} }
} }
} else { } else {
log.debug "found ${d.displayName} with id $selectedHue already exists" log.debug "found ${d.displayName} with id $selectedHue already exists"
@@ -436,7 +436,7 @@ def locationHandler(evt) {
dstate.name = "Philips hue ($ip)" dstate.name = "Philips hue ($ip)"
d.sendEvent(name:"networkAddress", value: host) d.sendEvent(name:"networkAddress", value: host)
d.updateDataValue("networkAddress", host) d.updateDataValue("networkAddress", host)
} }
} }
} }
} }
@@ -504,11 +504,11 @@ def isValidSource(macAddress) {
///////////////////////////////////// /////////////////////////////////////
def parse(childDevice, description) { def parse(childDevice, description) {
def parsedEvent = parseLanMessage(description) def parsedEvent = parseLanMessage(description)
if (parsedEvent.headers && parsedEvent.body) { if (parsedEvent.headers && parsedEvent.body) {
def headerString = parsedEvent.headers.toString() def headerString = parsedEvent.headers.toString()
def bodyString = parsedEvent.body.toString() def bodyString = parsedEvent.body.toString()
if (headerString?.contains("json")) { if (headerString?.contains("json")) {
def body def body
try { try {
body = new groovy.json.JsonSlurper().parseText(bodyString) body = new groovy.json.JsonSlurper().parseText(bodyString)
@@ -516,11 +516,11 @@ def parse(childDevice, description) {
log.warn "Parsing Body failed - trying again..." log.warn "Parsing Body failed - trying again..."
poll() poll()
} }
if (body instanceof java.util.HashMap) { if (body instanceof java.util.HashMap) {
//poll response //poll response
def bulbs = getChildDevices() def bulbs = getChildDevices()
for (bulb in body) { for (bulb in body) {
def d = bulbs.find{it.deviceNetworkId == "${app.id}/${bulb.key}"} def d = bulbs.find{it.deviceNetworkId == "${app.id}/${bulb.key}"}
if (d) { if (d) {
if (bulb.value.state?.reachable) { if (bulb.value.state?.reachable) {
sendEvent(d.deviceNetworkId, [name: "switch", value: bulb.value?.state?.on ? "on" : "off"]) sendEvent(d.deviceNetworkId, [name: "switch", value: bulb.value?.state?.on ? "on" : "off"])
@@ -535,18 +535,18 @@ def parse(childDevice, description) {
} }
} else { } else {
sendEvent(d.deviceNetworkId, [name: "switch", value: "off"]) sendEvent(d.deviceNetworkId, [name: "switch", value: "off"])
sendEvent(d.deviceNetworkId, [name: "level", value: 100]) sendEvent(d.deviceNetworkId, [name: "level", value: 100])
if (bulb.value.state.sat) { if (bulb.value.state.sat) {
def hue = 23 def hue = 23
def sat = 56 def sat = 56
def hex = colorUtil.hslToHex(23, 56) def hex = colorUtil.hslToHex(23, 56)
sendEvent(d.deviceNetworkId, [name: "color", value: hex]) sendEvent(d.deviceNetworkId, [name: "color", value: hex])
sendEvent(d.deviceNetworkId, [name: "hue", value: hue]) sendEvent(d.deviceNetworkId, [name: "hue", value: hue])
sendEvent(d.deviceNetworkId, [name: "saturation", value: sat]) sendEvent(d.deviceNetworkId, [name: "saturation", value: sat])
} }
} }
} }
} }
} }
else else
{ //put response { //put response
@@ -595,7 +595,7 @@ def parse(childDevice, description) {
} }
} }
} }
} else { } else {
log.debug "parse - got something other than headers,body..." log.debug "parse - got something other than headers,body..."
return [] return []
@@ -616,7 +616,7 @@ def off(childDevice) {
def setLevel(childDevice, percent) { def setLevel(childDevice, percent) {
log.debug "Executing 'setLevel'" log.debug "Executing 'setLevel'"
def level def level
if (percent == 1) level = 1 else level = Math.min(Math.round(percent * 255 / 100), 255) if (percent == 1) level = 1 else level = Math.min(Math.round(percent * 255 / 100), 255)
put("lights/${getId(childDevice)}/state", [bri: level, on: percent > 0]) put("lights/${getId(childDevice)}/state", [bri: level, on: percent > 0])
} }
@@ -633,6 +633,14 @@ def setHue(childDevice, percent) {
put("lights/${getId(childDevice)}/state", [hue: level]) put("lights/${getId(childDevice)}/state", [hue: level])
} }
def setColorTemperature(childDevice, huesettings) {
log.debug "Executing 'setColorTemperature($huesettings)'"
def ct = Math.round(Math.abs((huesettings / 12.96829971181556) - 654))
def value = [ct: ct, on: true]
log.trace "sending command $value"
put("lights/${getId(childDevice)}/state", value)
}
def setColor(childDevice, huesettings) { def setColor(childDevice, huesettings) {
log.debug "Executing 'setColor($huesettings)'" log.debug "Executing 'setColor($huesettings)'"
def hue = Math.min(Math.round(huesettings.hue * 65535 / 100), 65535) def hue = Math.min(Math.round(huesettings.hue * 65535 / 100), 65535)
@@ -689,7 +697,7 @@ HOST: ${host}
} }
private put(path, body) { private put(path, body) {
def host = getBridgeIP() def host = getBridgeIP()
def uri = "/api/${state.username}/$path" def uri = "/api/${state.username}/$path"
def bodyJSON = new groovy.json.JsonBuilder(body).toString() def bodyJSON = new groovy.json.JsonBuilder(body).toString()
def length = bodyJSON.getBytes().size().toString() def length = bodyJSON.getBytes().size().toString()
@@ -715,11 +723,11 @@ private getBridgeIP() {
host = d.getDeviceDataByName("networkAddress") host = d.getDeviceDataByName("networkAddress")
else else
host = d.latestState('networkAddress').stringValue host = d.latestState('networkAddress').stringValue
} }
if (host == null || host == "") { if (host == null || host == "") {
def serialNumber = selectedHue def serialNumber = selectedHue
def bridge = getHueBridges().find { it?.value?.serialNumber?.equalsIgnoreCase(serialNumber) }?.value def bridge = getHueBridges().find { it?.value?.serialNumber?.equalsIgnoreCase(serialNumber) }?.value
if (!bridge) { if (!bridge) {
bridge = getHueBridges().find { it?.value?.mac?.equalsIgnoreCase(serialNumber) }?.value bridge = getHueBridges().find { it?.value?.mac?.equalsIgnoreCase(serialNumber) }?.value
} }
if (bridge?.ip && bridge?.port) { if (bridge?.ip && bridge?.port) {
@@ -729,9 +737,9 @@ private getBridgeIP() {
host = "${convertHexToIP(bridge?.ip)}:${convertHexToInt(bridge?.port)}" host = "${convertHexToIP(bridge?.ip)}:${convertHexToInt(bridge?.port)}"
} else if (bridge?.networkAddress && bridge?.deviceAddress) } else if (bridge?.networkAddress && bridge?.deviceAddress)
host = "${convertHexToIP(bridge?.networkAddress)}:${convertHexToInt(bridge?.deviceAddress)}" host = "${convertHexToIP(bridge?.networkAddress)}:${convertHexToInt(bridge?.deviceAddress)}"
} }
log.trace "Bridge: $selectedHue - Host: $host" log.trace "Bridge: $selectedHue - Host: $host"
} }
return host return host
} }

View File

@@ -139,5 +139,4 @@ private hasBeenRecentMotion()
isActive = true isActive = true
} }
isActive isActive
} }