diff --git a/devicetypes/smartthings/zll-white-color-temperature-bulb-5000k.src/zll-white-color-temperature-bulb-5000k.groovy b/devicetypes/smartthings/zll-white-color-temperature-bulb-5000k.src/zll-white-color-temperature-bulb-5000k.groovy new file mode 100644 index 0000000..3c88380 --- /dev/null +++ b/devicetypes/smartthings/zll-white-color-temperature-bulb-5000k.src/zll-white-color-temperature-bulb-5000k.groovy @@ -0,0 +1,169 @@ +/** + * Copyright 2016 SmartThings + * + * 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. + * + */ +import groovy.transform.Field + +@Field Boolean hasConfiguredHealthCheck = false + +metadata { + definition (name: "ZLL White Color Temperature Bulb 5000K", namespace: "smartthings", author: "SmartThings") { + + capability "Actuator" + capability "Color Temperature" + capability "Configuration" + capability "Polling" + capability "Refresh" + capability "Switch" + capability "Switch Level" + capability "Health Check" + + attribute "colorName", "string" + command "setGenericName" + + fingerprint profileId: "C05E", deviceId: "0220", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, 0300", outClusters: "0019", manufacturer: "Eaton", model: "Halo_LT01", deviceJoinName: "Halo RL56 Wireless" + } + + // UI tile definitions + 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.light.on", backgroundColor:"#00A0DC", nextState:"turningOff" + attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn" + attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff" + attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn" + } + tileAttribute ("device.level", key: "SLIDER_CONTROL") { + attributeState "level", action:"switch level.setLevel" + } + tileAttribute ("colorName", key: "SECONDARY_CONTROL") { + attributeState "colorName", label:'${currentValue}' + } + } + + standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" + } + + controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..5000)") { + 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"]) + details(["switch", "colorTempSliderControl", "colorTemp", "refresh"]) + } +} + +// Parse incoming device messages to generate events +def parse(String description) { + log.debug "description is $description" + def event = zigbee.getEvent(description) + if (event) { + if (event.name == "colorTemperature") { + event.unit = "K" + } + sendEvent(event) + } + else { + log.warn "DID NOT PARSE MESSAGE for description : $description" + log.debug zigbee.parseDescriptionAsMap(description) + } +} + +def off() { + zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh() +} + +def on() { + zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh() +} + +def setLevel(value) { + zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() +} + +def refresh() { + def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + + // Do NOT config if the device is the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, and maybe other weird things with the others + if (!((device.getDataValue("manufacturer") == "Eaton") && (device.getDataValue("model") == "Halo_LT01"))) { + cmds = cmds + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + } + + cmds +} + +def poll() { + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() +} + +/** + * PING is used by Device-Watch in attempt to reach the Device + * */ +def ping() { + return zigbee.levelRefresh() +} + +def healthPoll() { + log.debug "healthPoll()" + def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh() + cmds.each{ sendHubCommand(new physicalgraph.device.HubAction(it))} +} + +def configureHealthCheck() { + Integer hcIntervalMinutes = 12 + if (!hasConfiguredHealthCheck) { + log.debug "Configuring Health Check, Reporting" + unschedule("healthPoll") + runEvery5Minutes("healthPoll") + // Device-Watch allows 2 check-in misses from device + sendEvent(name: "checkInterval", value: hcIntervalMinutes * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + hasConfiguredHealthCheck = true + } +} + +def configure() { + log.debug "configure()" + configureHealthCheck() + // Implementation note: for the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, so be sure this is before the call to onOffRefresh + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() +} + +def updated() { + log.debug "updated()" + configureHealthCheck() +} + +def setColorTemperature(value) { + setGenericName(value) + zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh() +} + +//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature +def setGenericName(value){ + if (value != null) { + def genericName = "" + if (value < 3300) { + genericName = "Soft White" + } else if (value < 4150) { + genericName = "Moonlight" + } else if (value <= 5000) { + genericName = "Cool White" + } else { + genericName = "Daylight" + } + sendEvent(name: "colorName", value: genericName, displayed: false) + } +} diff --git a/smartapps/gideon-api/gideon-smart-home.src/gideon-smart-home.groovy b/smartapps/gideon-api/gideon-smart-home.src/gideon-smart-home.groovy new file mode 100644 index 0000000..a198d72 --- /dev/null +++ b/smartapps/gideon-api/gideon-smart-home.src/gideon-smart-home.groovy @@ -0,0 +1,794 @@ +/** + * Gideon + * + * Copyright 2016 Nicola Russo + * + * 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. + * + */ +definition( + name: "Gideon Smart Home", + namespace: "gideon.api", + author: "Braindrain Solutions ltd", + description: "Gideon Smart Home SmartApp allows you to connect and control all of your SmartThings devices through the Gideon app, making your SmartThings devices even smarter.", + category: "Family", + iconUrl: "http://s33.postimg.org/t77u7y7v3/logo.png", + iconX2Url: "http://s33.postimg.org/t77u7y7v3/logo.png", + iconX3Url: "http://s33.postimg.org/t77u7y7v3/logo.png", + oauth: [displayName: "Gideon Smart Home API app", displayLink: "gideon.ai"]) + +preferences { + section("Control these contact sensors...") { + input "contact", "capability.contactSensor", multiple:true, required:false + } + section("Control these switch levels...") { + input "switchlevels", "capability.switchLevel", multiple:true, required:false + } +/* section("Control these thermostats...") { + input "thermostats", "capability.thermostat", multiple:true, required:false + }*/ + section("Control the color for these devices...") { + input "colors", "capability.colorControl", multiple:true, required:false + } + section("Control the color temperature for these devices...") { + input "kelvin", "capability.colorTemperature", multiple:true, required:false + } + section("Control these switches...") { + input "switches", "capability.switch", multiple:true, required:false + } + section("Control these smoke alarms...") { + input "smoke_alarms", "capability.smokeDetector", multiple:true, required:false + } + section("Control these window shades...") { + input "shades", "capability.windowShade", multiple:true, required:false + } + section("Control these garage doors...") { + input "garage", "capability.garageDoorControl", multiple:true, required:false + } + section("Control these water sensors...") { + input "water_sensors", "capability.waterSensor", multiple:true, required:false + } + section("Control these motion sensors...") { + input "motions", "capability.motionSensor", multiple:true, required:false + } + section("Control these presence sensors...") { + input "presence_sensors", "capability.presenceSensor", multiple:true, required:false + } + section("Control these outlets...") { + input "outlets", "capability.outlet", multiple:true, required:false + } + section("Control these power meters...") { + input "meters", "capability.powerMeter", multiple:true, required:false + } + section("Control these locks...") { + input "locks", "capability.lock", multiple:true, required:false + } + section("Control these temperature sensors...") { + input "temperature_sensors", "capability.temperatureMeasurement", multiple:true, required:false + } + section("Control these batteries...") { + input "batteries", "capability.battery", multiple:true, required:false + } +} + +def installed() { + log.debug "Installed with settings: ${settings}" + + initialize() +} + +def updated() { + log.debug "Updated with settings: ${settings}" + + unsubscribe() + initialize() +} + +def initialize() { +} + +private device(it, type) { + it ? [id: it.id, label: it.label, type: type] : null +} + +//API Mapping +mappings { + path("/getalldevices") { + action: [ + GET: "getAllDevices" + ] + } + /* + path("/thermostat/setcool/:id/:temp") { + action: [ + GET: "setCoolTemp" + ] + } + path("/thermostat/setheat/:id/:temp") { + action: [ + GET: "setHeatTemp" + ] + } + path("/thermostat/setfanmode/:id/:mode") { + action: [ + GET: "setFanMode" + ] + } + path("/thermostat/setmode/:id/:mode") { + action: [ + GET: "setThermostatMode" + ] + } + path("/thermostat/:id") { + action: [ + GET: "getThermostatStatus" + ] + } + */ + path("/light/dim/:id/:dim") { + action: [ + GET: "setLevelStatus" + ] + } + path("/light/kelvin/:id/:kelvin") { + action: [ + GET: "setKelvin" + ] + } + path("/colorlight/:id/:hue/:sat") { + action: [ + GET: "setColor" + ] + } + path("/light/status/:id") { + action: [ + GET: "getLightStatus" + ] + } + path("/light/on/:id") { + action: [ + GET: "turnOnLight" + ] + } + path("/light/off/:id") { + action: [ + GET: "turnOffLight" + ] + } + path("/doorlocks/lock/:id") { + action: [ + GET: "lockDoorLock" + ] + } + path("/doorlocks/unlock/:id") { + action: [ + GET: "unlockDoorLock" + ] + } + path("/doorlocks/:id") { + action: [ + GET: "getDoorLockStatus" + ] + } + path("/contacts/:id") { + action: [ + GET: "getContactStatus" + ] + } + path("/smoke/:id") { + action: [ + GET: "getSmokeStatus" + ] + } + path("/shades/open/:id") { + action: [ + GET: "openShade" + ] + } + path("/shades/preset/:id") { + action: [ + GET: "presetShade" + ] + } + path("/shades/close/:id") { + action: [ + GET: "closeShade" + ] + } + path("/shades/:id") { + action: [ + GET: "getShadeStatus" + ] +} + path("/garage/open/:id") { + action: [ + GET: "openGarage" + ] + } + path("/garage/close/:id") { + action: [ + GET: "closeGarage" + ] + } + path("/garage/:id") { + action: [ + GET: "getGarageStatus" + ] + } + path("/watersensors/:id") { + action: [ + GET: "getWaterSensorStatus" + ] + } + path("/tempsensors/:id") { + action: [ + GET: "getTempSensorsStatus" + ] + } + path("/meters/:id") { + action: [ + GET: "getMeterStatus" + ] + } + path("/batteries/:id") { + action: [ + GET: "getBatteryStatus" + ] + } + path("/presences/:id") { + action: [ + GET: "getPresenceStatus" + ] + } + path("/motions/:id") { + action: [ + GET: "getMotionStatus" + ] + } + path("/outlets/:id") { + action: [ + GET: "getOutletStatus" + ] + } + path("/outlets/turnon/:id") { + action: [ + GET: "turnOnOutlet" + ] + } + path("/outlets/turnoff/:id") { + action: [ + GET: "turnOffOutlet" + ] + } + path("/switches/turnon/:id") { + action: [ + GET: "turnOnSwitch" + ] + } + path("/switches/turnoff/:id") { + action: [ + GET: "turnOffSwitch" + ] + } + path("/switches/:id") { + action: [ + GET: "getSwitchStatus" + ] + } +} + +//API Methods +def getAllDevices() { + def locks_list = locks.collect{device(it,"Lock")} + /*def thermo_list = thermostats.collect{device(it,"Thermostat")}*/ + def colors_list = colors.collect{device(it,"Color")} + def kelvin_list = kelvin.collect{device(it,"Kelvin")} + def contact_list = contact.collect{device(it,"Contact Sensor")} + def smokes_list = smoke_alarms.collect{device(it,"Smoke Alarm")} + def shades_list = shades.collect{device(it,"Window Shade")} + def garage_list = garage.collect{device(it,"Garage Door")} + def water_sensors_list = water_sensors.collect{device(it,"Water Sensor")} + def presences_list = presence_sensors.collect{device(it,"Presence")} + def motions_list = motions.collect{device(it,"Motion")} + def outlets_list = outlets.collect{device(it,"Outlet")} + def switches_list = switches.collect{device(it,"Switch")} + def switchlevels_list = switchlevels.collect{device(it,"Switch Level")} + def temp_list = temperature_sensors.collect{device(it,"Temperature")} + def meters_list = meters.collect{device(it,"Power Meters")} + def battery_list = batteries.collect{device(it,"Batteries")} + return outlets_list + kelvin_list + colors_list + switchlevels_list + smokes_list + contact_list + water_sensors_list + shades_list + garage_list + locks_list + presences_list + motions_list + switches_list + temp_list + meters_list + battery_list +} + +//thermostat +/* +def setCoolTemp() { + def device = thermostats.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + if(device.hasCommand("setCoolingSetpoint")) { + device.setCoolingSetpoint(params.temp.toInteger()); + return [result_action: "200"] + } + else { + httpError(510, "Not supported!") + } + } +} +def setHeatTemp() { + def device = thermostats.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + if(device.hasCommand("setHeatingSetpoint")) { + device.setHeatingSetpoint(params.temp.toInteger()); + return [result_action: "200"] + } + else { + httpError(510, "Not supported!") + } + } +} +def setFanMode() { + def device = thermostats.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + if(device.hasCommand("setThermostatFanMode")) { + device.setThermostatFanMode(params.mode); + return [result_action: "200"] + } + else { + httpError(510, "Not supported!") + } + } +} +def setThermostatMode() { + def device = thermostats.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + if(device.hasCommand("setThermostatMode")) { + device.setThermostatMode(params.mode); + return [result_action: "200"] + } + else { + httpError(510, "Not supported!") + } + } +} +def getThermostatStatus() { + def device = thermostats.find{ it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [ThermostatOperatingState: device.currentValue('thermostatOperatingState'), ThermostatSetpoint: device.currentValue('thermostatSetpoint'), + ThermostatFanMode: device.currentValue('thermostatFanMode'), ThermostatMode: device.currentValue('thermostatMode')] + } +} +*/ +//light +def turnOnLight() { + def device = switches.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + device.on(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def turnOffLight() { + def device = switches.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + device.off(); + + return [Device_id: params.id, result_action: "200"] + } +} + +def getLightStatus() { + def device = switches.find{ it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Status: device.currentValue('switch'), Dim: getLevelStatus(params.id), Color: getColorStatus(params.id), Kelvin: getKelvinStatus(params.id)] + } +} + +//color control +def setColor() { + def device = colors.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + def map = [hue:params.hue.toInteger(), saturation:params.sat.toInteger()] + + device.setColor(map); + + return [Device_id: params.id, result_action: "200"] + } +} + +def getColorStatus(id) { + def device = colors.find { it.id == id } + if (!device) { + return [Color: "none"] + } else { + return [hue: device.currentValue('hue'), saturation: device.currentValue('saturation')] + } +} + +//kelvin control +def setKelvin() { + def device = kelvin.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.setColorTemperature(params.kelvin.toInteger()); + + return [Device_id: params.id, result_action: "200"] + } +} + +def getKelvinStatus(id) { + def device = kelvin.find { it.id == id } + if (!device) { + return [kelvin: "none"] + } else { + return [kelvin: device.currentValue('colorTemperature')] + } +} + +//switch level +def getLevelStatus() { + def device = switchlevels.find { it.id == params.id } + if (!device) { + [Level: "No dimmer"] + } else { + return [Level: device.currentValue('level')] + } +} + +def getLevelStatus(id) { + def device = switchlevels.find { it.id == id } + if (!device) { + [Level: "No dimmer"] + } else { + return [Level: device.currentValue('level')] + } +} + + +def setLevelStatus() { + def device = switchlevels.find { it.id == params.id } + def level = params.dim + if (!device) { + httpError(404, "Device not found") + } else { + device.setLevel(level.toInteger()) + return [result_action: "200", Level: device.currentValue('level')] + } +} + + +//contact sensors +def getContactStatus() { + def device = contact.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def args = getTempSensorsStatus(device.id) + return [Device_state: device.currentValue('contact')] + args + } +} + +//smoke detectors +def getSmokeStatus() { + def device = smoke_alarms.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('smoke')] + bat + } +} + +//garage +def getGarageStatus() { + def device = garage.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_state: device.currentValue('door')] + } +} + +def openGarage() { + def device = garage.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.open(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def closeGarage() { + def device = garage.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.close(); + + return [Device_id: params.id, result_action: "200"] + } + } +//shades +def getShadeStatus() { + def device = shades.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_state: device.currentValue('windowShade')] + } +} + +def openShade() { + def device = shades.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.open(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def presetShade() { + def device = shades.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.presetPosition(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def closeShade() { + def device = shades.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.close(); + + return [Device_id: params.id, result_action: "200"] + } + } + +//water sensor +def getWaterSensorStatus() { + def device = water_sensors.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('water')] + bat + } +} +//batteries +def getBatteryStatus() { + def device = batteries.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_state: device.latestValue("battery")] + } +} + +def getBatteryStatus(id) { + def device = batteries.find { it.id == id } + if (!device) { + return [] + } else { + return [battery_state: device.latestValue("battery")] + } +} + +//LOCKS +def getDoorLockStatus() { + def device = locks.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('lock')] + bat + } +} + +def lockDoorLock() { + def device = locks.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.lock(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def unlockDoorLock() { + def device = locks.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.unlock(); + + return [Device_id: params.id, result_action: "200"] + } + } +//PRESENCE +def getPresenceStatus() { + + def device = presence_sensors.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('presence')] + bat + } +} + +//MOTION +def getMotionStatus() { + + def device = motions.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def args = getTempSensorsStatus(device.id) + return [Device_state: device.currentValue('motion')] + args + } +} + +//OUTLET +def getOutletStatus() { + + def device = outlets.find { it.id == params.id } + if (!device) { + device = switches.find { it.id == params.id } + if(!device) { + httpError(404, "Device not found") + } + } + def watt = getMeterStatus(device.id) + + return [Device_state: device.currentValue('switch')] + watt +} + +def getMeterStatus() { + + def device = meters.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_id: device.id, Device_type: device.type, Current_watt: device.currentValue("power")] + } +} + +def getMeterStatus(id) { + + def device = meters.find { it.id == id } + if (!device) { + return [] + } else { + return [Current_watt: device.currentValue("power")] + } +} + + +def turnOnOutlet() { + def device = outlets.find { it.id == params.id } + if (!device) { + device = switches.find { it.id == params.id } + if(!device) { + httpError(404, "Device not found") + } + } + + device.on(); + + return [Device_id: params.id, result_action: "200"] +} + +def turnOffOutlet() { + def device = outlets.find { it.id == params.id } + if (!device) { + device = switches.find { it.id == params.id } + if(!device) { + httpError(404, "Device not found") + } + } + + device.off(); + + return [Device_id: params.id, result_action: "200"] +} + +//SWITCH +def getSwitchStatus() { + def device = switches.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_state: device.currentValue('switch'), Dim: getLevelStatus(params.id)] + } +} + +def turnOnSwitch() { + def device = switches.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.on(); + + return [Device_id: params.id, result_action: "200"] + } +} + +def turnOffSwitch() { + def device = switches.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.off(); + + return [Device_id: params.id, result_action: "200"] + } +} + + +//TEMPERATURE +def getTempSensorsStatus() { + def device = temperature_sensors.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + def scale = [Scale: location.temperatureScale] + return [Device_state: device.currentValue('temperature')] + scale + bat + } +} + +def getTempSensorsStatus(id) { + def device = temperature_sensors.find { it.id == id } + if (!device) { + return [] + } else { + def bat = getBatteryStatus(device.id) + return [temperature: device.currentValue('temperature')] + bat + } + } \ No newline at end of file diff --git a/smartapps/shabbatholidaymode/shabbat-and-holiday-modes.src/shabbat-and-holiday-modes.groovy b/smartapps/shabbatholidaymode/shabbat-and-holiday-modes.src/shabbat-and-holiday-modes.groovy index c6b5905..86b6b8d 100644 --- a/smartapps/shabbatholidaymode/shabbat-and-holiday-modes.src/shabbat-and-holiday-modes.groovy +++ b/smartapps/shabbatholidaymode/shabbat-and-holiday-modes.src/shabbat-and-holiday-modes.groovy @@ -30,7 +30,7 @@ preferences { input "havdalahOffset", "number", title: "Minutes After Sundown", required:true } section("Your ZipCode") { - input "zipcode", "number", title: "ZipCode", required:true + input "zipcode", "text", title: "ZipCode", required:true } section( "Notifications" ) { input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false @@ -205,4 +205,4 @@ if ( sendPushMessage != "No" ) { log.debug( "sending text message" ) sendSms( phone, msg ) } -}//END def sendMessage(msg) \ No newline at end of file +}//END def sendMessage(msg)