Compare commits

...

3 Commits

Author SHA1 Message Date
Greg Crowley
0f383bb480 MSA-1517: foscam modified device type 2016-10-08 21:39:48 -05:00
dsainteclaire
84323afa04 Merge pull request #1324 from james-smartthings/DVCSMP-2097-add-alterSetpoint-check
alterSetpoint - check for auto or off mode
2016-10-07 10:03:08 -07:00
James Chen
12b09acfa8 alterSetpoint - check for auto or off mode
changed debug message
2016-10-06 16:02:09 -07:00
2 changed files with 202 additions and 43 deletions

View File

@@ -655,55 +655,60 @@ void lowerSetpoint() {
void alterSetpoint(temp) {
def mode = device.currentValue("thermostatMode")
def heatingSetpoint = device.currentValue("heatingSetpoint")
def coolingSetpoint = device.currentValue("coolingSetpoint")
def deviceId = device.deviceNetworkId.split(/\./).last()
def targetHeatingSetpoint
def targetCoolingSetpoint
//step1: check thermostatMode, enforce limits before sending request to cloud
if (mode == "heat" || mode == "auxHeatOnly"){
if (temp.value > coolingSetpoint){
targetHeatingSetpoint = temp.value
targetCoolingSetpoint = temp.value
} else {
targetHeatingSetpoint = temp.value
targetCoolingSetpoint = coolingSetpoint
}
} else if (mode == "cool") {
//enforce limits before sending request to cloud
if (temp.value < heatingSetpoint){
targetHeatingSetpoint = temp.value
targetCoolingSetpoint = temp.value
} else {
targetHeatingSetpoint = heatingSetpoint
targetCoolingSetpoint = temp.value
}
}
log.debug "alterSetpoint >> in mode ${mode} trying to change heatingSetpoint to $targetHeatingSetpoint " +
"coolingSetpoint to $targetCoolingSetpoint with holdType : ${holdType}"
def sendHoldType = holdType ? (holdType=="Temporary")? "nextTransition" : (holdType=="Permanent")? "indefinite" : "indefinite" : "indefinite"
def coolingValue = location.temperatureScale == "C"? convertCtoF(targetCoolingSetpoint) : targetCoolingSetpoint
def heatingValue = location.temperatureScale == "C"? convertCtoF(targetHeatingSetpoint) : targetHeatingSetpoint
if (parent.setHold(heatingValue, coolingValue, deviceId, sendHoldType)) {
sendEvent("name": "thermostatSetpoint", "value": temp.value, displayed: false)
sendEvent("name": "heatingSetpoint", "value": targetHeatingSetpoint, "unit": location.temperatureScale)
sendEvent("name": "coolingSetpoint", "value": targetCoolingSetpoint, "unit": location.temperatureScale)
log.debug "alterSetpoint in mode $mode succeed change setpoint to= ${temp.value}"
if (mode == "off" || mode == "auto") {
log.warn "this mode: $mode does not allow alterSetpoint"
} else {
log.error "Error alterSetpoint()"
def heatingSetpoint = device.currentValue("heatingSetpoint")
def coolingSetpoint = device.currentValue("coolingSetpoint")
def deviceId = device.deviceNetworkId.split(/\./).last()
def targetHeatingSetpoint
def targetCoolingSetpoint
//step1: check thermostatMode, enforce limits before sending request to cloud
if (mode == "heat" || mode == "auxHeatOnly"){
sendEvent("name": "thermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
if (temp.value > coolingSetpoint){
targetHeatingSetpoint = temp.value
targetCoolingSetpoint = temp.value
} else {
targetHeatingSetpoint = temp.value
targetCoolingSetpoint = coolingSetpoint
}
} else if (mode == "cool") {
sendEvent("name": "thermostatSetpoint", "value": coolingSetpoint.toString(), displayed: false)
//enforce limits before sending request to cloud
if (temp.value < heatingSetpoint){
targetHeatingSetpoint = temp.value
targetCoolingSetpoint = temp.value
} else {
targetHeatingSetpoint = heatingSetpoint
targetCoolingSetpoint = temp.value
}
}
log.debug "alterSetpoint >> in mode ${mode} trying to change heatingSetpoint to $targetHeatingSetpoint " +
"coolingSetpoint to $targetCoolingSetpoint with holdType : ${holdType}"
def sendHoldType = holdType ? (holdType=="Temporary")? "nextTransition" : (holdType=="Permanent")? "indefinite" : "indefinite" : "indefinite"
def coolingValue = location.temperatureScale == "C"? convertCtoF(targetCoolingSetpoint) : targetCoolingSetpoint
def heatingValue = location.temperatureScale == "C"? convertCtoF(targetHeatingSetpoint) : targetHeatingSetpoint
if (parent.setHold(heatingValue, coolingValue, deviceId, sendHoldType)) {
sendEvent("name": "thermostatSetpoint", "value": temp.value, displayed: false)
sendEvent("name": "heatingSetpoint", "value": targetHeatingSetpoint, "unit": location.temperatureScale)
sendEvent("name": "coolingSetpoint", "value": targetCoolingSetpoint, "unit": location.temperatureScale)
log.debug "alterSetpoint in mode $mode succeed change setpoint to= ${temp.value}"
} else {
log.error "Error alterSetpoint()"
if (mode == "heat" || mode == "auxHeatOnly"){
sendEvent("name": "thermostatSetpoint", "value": heatingSetpoint.toString(), displayed: false)
} else if (mode == "cool") {
sendEvent("name": "thermostatSetpoint", "value": coolingSetpoint.toString(), displayed: false)
}
}
generateStatusEvent()
}
generateStatusEvent()
}
def generateStatusEvent() {

View File

@@ -0,0 +1,154 @@
import static java.util.UUID.randomUUID
import java.security.MessageDigest
import javax.crypto.spec.SecretKeySpec
import javax.crypto.Mac
import java.security.SignatureException
metadata {
// Automatically generated. Make future change here.
definition (name: "Virtual Foscam", namespace: "smartthings", author: "sidoh") {
capability "Actuator"
capability "Image Capture"
capability "Switch"
command "enableRecording"
command "disableRecording"
attribute "preset", "enum", ["Door", "Couch", "Table"]
command "setPresetDoor"
command "setPresetCouch"
command "setPresetTable"
}
preferences {
input "camera", "text", title: "Camera Identifier", displayDuringSetup: true
}
simulator {
// TODO: define status and reply messages here
}
tiles {
standardTile("camera", "device.image", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: true) {
state "default", label: "", action: "", icon: "st.camera.dropcam-centered", backgroundColor: "#FFFFFF"
}
carouselTile("cameraDetails", "device.image", width: 3, height: 2) { }
standardTile("take", "device.image", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: false) {
state "take", label: "Take", action: "Image Capture.take", icon: "st.camera.dropcam", backgroundColor: "#FFFFFF", nextState:"taking"
state "taking", label:'Taking', action: "", icon: "st.camera.dropcam", backgroundColor: "#53a7c0"
state "image", label: "Take", action: "Image Capture.take", icon: "st.camera.dropcam", backgroundColor: "#FFFFFF", nextState:"taking"
}
standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.Entertainment.entertainment9", backgroundColor:"#79b821", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.Entertainment.entertainment9", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', icon:"st.Entertainment.entertainment9", backgroundColor:"#79b821"
state "turningOff", label:'${name}', icon:"st.Entertainment.entertainment9", backgroundColor:"#ffffff"
}
standardTile("presetDoor", "device.preset", width: 1, height: 1, canChangeIcon: true) {
state "Door", label: '${name}', backgroundColor:"#79b821", action: "setPresetDoor"
}
standardTile("presetCouch", "device.preset", width: 1, height: 1, canChangeIcon: true) {
state "Couch", label: '${name}', backgroundColor:"#79b821", action: "setPresetCouch"
}
standardTile("presetTable", "device.preset", width: 1, height: 1, canChangeIcon: true) {
state "Table", label: '${name}', backgroundColor:"#79b821", action: "setPresetTable"
}
main "switch"
details(["cameraDetails", "take", "switch", "presetDoor", "presetCouch", "presetTable"])
}
}
def setPresetDoor() {
setPreset("Door")
}
def setPresetCouch() {
setPreset("Couch")
}
def setPresetTable() {
setPreset("Table")
}
def on() {
sendEvent(name: "switch", value: "on")
gwPost('', [recording: true])
}
def off() {
sendEvent(name: "switch", value: "off")
gwPost('', [recording: false])
}
def take() {
log.info "Executing 'take'"
gwGet('/snapshot.jpg') {
final def imageName = "${randomUUID() as String}.jpg"
storeImage(imageName, it.data)
}
}
def hmac(String data, String key) throws SignatureException {
final Mac hmacSha1;
try {
hmacSha1 = Mac.getInstance("HmacSHA1");
} catch (Exception nsae) {
hmacSha1 = Mac.getInstance("HMAC-SHA-1");
}
final SecretKeySpec macKey = new SecretKeySpec(key.getBytes(), "RAW");
hmacSha1.init(macKey);
final byte[] signature = hmacSha1.doFinal(data.getBytes());
return signature.encodeHex()
}
def getHmacHeaders() {
final def payload = randomUUID() as String
long time = new Date().getTime()
time /= 1000L
final String signature = hmac(payload + time, '<security_token>')
[
'X-Signature-Timestamp': time,
'X-Signature-Payload': payload,
'X-Signature': signature
]
}
def setPreset(preset) {
gwPost('', [preset: preset])
runIn(2, take)
sendEvent(name: 'preset', value: preset)
}
def gwPost(path, params, success = {}) {
httpPost(
[
uri: ("http://<ha_gateway_url>/camera/${settings.camera}${path}"),
body: params,
headers: getHmacHeaders(),
success: success
]
)
}
def gwGet(path, success = {}) {
httpGet(
[
uri: ("http://<ha_gateway_url>/camera/${settings.camera}${path}"),
headers: getHmacHeaders(),
success: success
]
)
}