Advertisement
Guest User

Untitled

a guest
Oct 17th, 2018
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.85 KB | None | 0 0
  1. metadata {
  2. // Automatically generated. Make future change here.
  3. definition (name: "Z-Wave thermostat with RH", author: "minollo@minollo.com", namespace: "minollo") {
  4. capability "Actuator"
  5. capability "Temperature Measurement"
  6. capability "Relative Humidity Measurement"
  7. capability "Thermostat"
  8. capability "Configuration"
  9. capability "Polling"
  10. capability "Refresh"
  11. capability "Sensor"
  12. capability "Battery"
  13.  
  14. attribute "thermostatFanState", "string"
  15. attribute "responsive", "string"
  16.  
  17. command "tempDown"
  18. command "tempUp"
  19. command "switchMode"
  20. command "switchFanMode"
  21. command "quickSetCool"
  22. command "quickSetHeat"
  23.  
  24. fingerprint deviceId: "0x08"
  25. fingerprint inClusters: "0x43,0x40,0x44,0x31"
  26. }
  27.  
  28. // simulator metadata
  29. simulator {
  30. status "off" : "command: 4003, payload: 00"
  31. status "heat" : "command: 4003, payload: 01"
  32. status "cool" : "command: 4003, payload: 02"
  33. status "auto" : "command: 4003, payload: 03"
  34. status "emergencyHeat" : "command: 4003, payload: 04"
  35.  
  36. status "fanAuto" : "command: 4403, payload: 00"
  37. status "fanOn" : "command: 4403, payload: 01"
  38. status "fanCirculate" : "command: 4403, payload: 06"
  39.  
  40. status "heat 60" : "command: 4303, payload: 01 01 3C"
  41. status "heat 68" : "command: 4303, payload: 01 01 44"
  42. status "heat 72" : "command: 4303, payload: 01 01 48"
  43.  
  44. status "cool 72" : "command: 4303, payload: 02 01 48"
  45. status "cool 76" : "command: 4303, payload: 02 01 4C"
  46. status "cool 80" : "command: 4303, payload: 02 01 50"
  47.  
  48. status "temp 58" : "command: 3105, payload: 01 22 02 44"
  49. status "temp 62" : "command: 3105, payload: 01 22 02 6C"
  50. status "temp 70" : "command: 3105, payload: 01 22 02 BC"
  51. status "temp 74" : "command: 3105, payload: 01 22 02 E4"
  52. status "temp 78" : "command: 3105, payload: 01 22 03 0C"
  53. status "temp 82" : "command: 3105, payload: 01 22 03 34"
  54.  
  55. status "idle" : "command: 4203, payload: 00"
  56. status "heating" : "command: 4203, payload: 01"
  57. status "cooling" : "command: 4203, payload: 02"
  58. status "fan only" : "command: 4203, payload: 03"
  59. status "pending heat" : "command: 4203, payload: 04"
  60. status "pending cool" : "command: 4203, payload: 05"
  61. status "vent economizer": "command: 4203, payload: 06"
  62.  
  63. // reply messages
  64. reply "2502": "command: 2503, payload: FF"
  65. }
  66.  
  67. tiles {
  68.  
  69. multiAttributeTile(name:"thermostatFull", type:"thermostat", width:6, height:4) {
  70. tileAttribute("device.temperature", key: "PRIMARY_CONTROL") {
  71. attributeState("temp", label:'${currentValue}', unit:"dF", defaultState: true)
  72. }
  73. tileAttribute("device.temperature", key: "VALUE_CONTROL") {
  74. attributeState("VALUE_UP", action: "tempUp")
  75. attributeState("VALUE_DOWN", action: "tempDown")
  76. }
  77. tileAttribute("device.humidity", key: "SECONDARY_CONTROL") {
  78. attributeState("humidity", label:'${currentValue}%', unit:"%", defaultState: true)
  79. }
  80. tileAttribute("device.thermostatOperatingState", key: "OPERATING_STATE") {
  81. attributeState("idle", backgroundColor:"#AAAAAA")
  82. attributeState("heating", backgroundColor:"#e86d13")
  83. attributeState("cooling", backgroundColor:"#00A0DC")
  84. }
  85. tileAttribute("device.thermostatMode", key: "THERMOSTAT_MODE") {
  86. attributeState("off", label:'${name}')
  87. attributeState("heat", label:'${name}')
  88. attributeState("cool", label:'${name}')
  89. attributeState("auto", label:'${name}')
  90. }
  91. tileAttribute("device.heatingSetpoint", key: "HEATING_SETPOINT") {
  92. attributeState("heatingSetpoint", label:'${currentValue}', unit:"dF", defaultState: true)
  93. }
  94. tileAttribute("device.coolingSetpoint", key: "COOLING_SETPOINT") {
  95. attributeState("coolingSetpoint", label:'${currentValue}', unit:"dF", defaultState: true)
  96. }
  97. }
  98.  
  99.  
  100. valueTile("temperature", "device.temperature", width: 2, height: 2) {
  101. state("temperature", label:'${currentValue}°', unit:"F",
  102. backgroundColors:[
  103. [value: 31, color: "#153591"],
  104. [value: 44, color: "#1e9cbb"],
  105. [value: 59, color: "#90d2a7"],
  106. [value: 74, color: "#44b621"],
  107. [value: 84, color: "#f1d801"],
  108. [value: 95, color: "#d04e00"],
  109. [value: 96, color: "#bc2323"]
  110. ]
  111. )
  112. }
  113. standardTile("mode", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
  114. state "off", label:'${name}', action:"switchMode", nextState:"to_heat"
  115. state "heat", label:'${name}', action:"switchMode", nextState:"to_cool"
  116. state "cool", label:'${name}', action:"switchMode", nextState:"..."
  117. state "auto", label:'${name}', action:"switchMode", nextState:"..."
  118. state "emergencyHeat", label:'${name}', action:"switchMode", nextState:"..."
  119. state "to_heat", label: "heat", action:"switchMode", nextState:"to_cool"
  120. state "to_cool", label: "cool", action:"switchMode", nextState:"..."
  121. state "...", label: "...", action:"off", nextState:"off"
  122. }
  123. standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
  124. state "fanAuto", label:'${name}', action:"switchFanMode"
  125. state "fanOn", label:'${name}', action:"switchFanMode"
  126. state "fanCirculate", label:'${name}', action:"switchFanMode"
  127. }
  128. controlTile("heatSliderControl", "device.heatingSetpoint", "slider", height: 1, width: 6, inactiveLabel: false) {
  129. state "setHeatingSetpoint", action:"thermostat.setHeatingSetpoint", backgroundColor:"#d04e00"
  130. }
  131. valueTile("heatingSetpoint", "device.heatingSetpoint", inactiveLabel: false, decoration: "flat") {
  132. state "heat", label:'${currentValue}° heat', unit:"F", backgroundColor:"#ffffff"
  133. }
  134. controlTile("coolSliderControl", "device.coolingSetpoint", "slider", height: 1, width: 6, inactiveLabel: false) {
  135. state "setCoolingSetpoint", action:"thermostat.setCoolingSetpoint", backgroundColor: "#1e9cbb"
  136. }
  137. valueTile("coolingSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
  138. state "cool", label:'${currentValue}° cool', unit:"F", backgroundColor:"#ffffff"
  139. }
  140. standardTile("refresh", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
  141. state "default", action:"polling.poll", icon:"st.secondary.refresh"
  142. }
  143. standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
  144. state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
  145. }
  146. main "thermostatFull"
  147. details(["thermostatFull", "heatSliderControl", "coolSliderControl", "mode", "fanMode", "heatingSetpoint", "coolingSetpoint", "refresh", "configure"])
  148. // details(["thermostatFull", "mode", "fanMode", "refresh", "configure"])
  149. }
  150. }
  151.  
  152. def pollDevice() {
  153. log.debug "pollDevice(); ignoring it"
  154. }
  155.  
  156. def tempUp() {
  157. def mode = device.currentValue("thermostatMode")
  158. if (mode == "heat") {
  159. log.trace "Heating setpoint UP"
  160. def value = device.currentValue("heatingSetpoint") + 1
  161. sendEvent(name: "heatingSetpoint", value: value)
  162. sendEvent(name: "thermostatSetpoint", value: value)
  163. setHeatingSetpoint(value)
  164. } else if (mode == "cool") {
  165. log.trace "Cooling setpoint UP"
  166. def value = device.currentValue("coolingSetpoint") + 1
  167. sendEvent(name: "coolingSetpoint", value: value)
  168. sendEvent(name: "thermostatSetpoint", value: value)
  169. setCoolingSetpoint(value)
  170. }
  171. }
  172.  
  173. def tempDown() {
  174. def mode = device.currentValue("thermostatMode")
  175. if (mode == "heat") {
  176. log.trace "Heating setpoint DOWN"
  177. def value = device.currentValue("heatingSetpoint") - 1
  178. sendEvent(name: "heatingSetpoint", value: value)
  179. sendEvent(name: "thermostatSetpoint", value: value)
  180. setHeatingSetpoint(value)
  181. } else if (mode == "cool") {
  182. log.trace "Cooling setpoint DOWN"
  183. def value = device.currentValue("coolingSetpoint") - 1
  184. sendEvent(name: "coolingSetpoint", value: value)
  185. sendEvent(name: "thermostatSetpoint", value: value)
  186. setCoolingSetpoint(value)
  187. }
  188. }
  189.  
  190.  
  191. def parse(String description)
  192. {
  193. def map = createEvent(zwaveEvent(zwave.parse(description, [0x42:1, 0x43:2, 0x31:3, 0x80:1])))
  194. if (!map) {
  195. return null
  196. }
  197. updateResponsiveness()
  198. def result = [map]
  199. if (map.name in ["heatingSetpoint","coolingSetpoint","thermostatMode"]) {
  200. def map2 = [
  201. name: "thermostatSetpoint",
  202. unit: getTemperatureScale()
  203. ]
  204. if (map.name == "thermostatMode") {
  205. state.lastTriedMode = map.value
  206. if (map.value == "cool") {
  207. map2.value = device.latestValue("coolingSetpoint")
  208. //log.info "THERMOSTAT, latest cooling setpoint = ${map2.value}"
  209. }
  210. else {
  211. map2.value = device.latestValue("heatingSetpoint")
  212. //log.info "THERMOSTAT, latest heating setpoint = ${map2.value}"
  213. }
  214. }
  215. else {
  216. def mode = device.latestValue("thermostatMode")
  217. //log.info "THERMOSTAT, latest mode = ${mode}"
  218. if ((map.name == "heatingSetpoint" && (mode == "heat" || mode == "emergencyHeat")) || (map.name == "coolingSetpoint" && mode == "cool")) {
  219. map2.value = map.value
  220. map2.unit = map.unit
  221. }
  222. }
  223. if (map2.value != null) {
  224. //log.debug "THERMOSTAT, adding setpoint event: $map"
  225. result << createEvent(map2)
  226. }
  227. } else if (map.name == "thermostatFanMode") {
  228. state.lastTriedFanMode = map.value
  229. }
  230. log.debug "ParseEx returned $result"
  231. result
  232. }
  233.  
  234. // Event Generation
  235.  
  236. // MultiChannelCmdEncap and MultiChannelCmdEncap are ways that devices can indicate that a message
  237. // is coming from one of multiple subdevices or "endpoints" that would otherwise be indistinguishable
  238. def zwaveEvent(hubitat.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
  239. def encapsulatedCommand = cmd.encapsulatedCommand([0x30: 3, 0x31: 3, 0x42: 1]) // can specify command class versions here like in zwave.parse
  240. if (encapsulatedCommand) {
  241. return zwaveEvent(encapsulatedCommand)
  242. }
  243. }
  244.  
  245. def zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport cmd) {
  246. if (cmd.batteryLevel <= 100) {
  247. def nowTime = new Date().time
  248. state.lastBatteryGet = nowTime
  249. def map = [ name: "battery", unit: "%" ]
  250. if (cmd.batteryLevel == 0xFF || cmd.batteryLevel == 0) {
  251. map.value = 1
  252. map.descriptionText = "$device.displayName battery is low!"
  253. } else {
  254. map.value = cmd.batteryLevel
  255. }
  256. map
  257. } else {
  258. log.warn "Bad battery value returned: ${cmd.batteryLevel}"
  259. [:]
  260. }
  261. }
  262.  
  263. def zwaveEvent(hubitat.zwave.commands.thermostatsetpointv2.ThermostatSetpointReport cmd)
  264. {
  265. def map = [:]
  266. map.value = cmd.scaledValue.toString()
  267. map.unit = cmd.scale == 1 ? "F" : "C"
  268. map.displayed = false
  269. switch (cmd.setpointType) {
  270. case 1:
  271. map.name = "heatingSetpoint"
  272. break;
  273. case 2:
  274. map.name = "coolingSetpoint"
  275. break;
  276. default:
  277. return [:]
  278. }
  279. // So we can respond with same format
  280. state.size = cmd.size
  281. state.scale = cmd.scale
  282. state.precision = cmd.precision
  283. map
  284. }
  285.  
  286. def zwaveEvent(hubitat.zwave.commands.sensormultilevelv3.SensorMultilevelReport cmd)
  287. {
  288. // log.debug "SensorMultilevelReport ${cmd}"
  289. def map = [:]
  290. switch (cmd.sensorType) {
  291. case 1:
  292. // temperature
  293. map.value = cmd.scaledSensorValue.toString()
  294. map.unit = cmd.scale == 1 ? "F" : "C"
  295. map.name = "temperature"
  296. break;
  297. case 5:
  298. // humidity
  299. map.value = cmd.scaledSensorValue.toInteger().toString()
  300. map.unit = "%"
  301. map.name = "humidity"
  302. break;
  303. }
  304. map
  305. }
  306.  
  307. def zwaveEvent(hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport cmd)
  308. {
  309. def map = [:]
  310. switch (cmd.operatingState) {
  311. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_IDLE:
  312. map.value = "idle"
  313. break
  314. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_HEATING:
  315. map.value = "heating"
  316. break
  317. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_COOLING:
  318. map.value = "cooling"
  319. break
  320. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_FAN_ONLY:
  321. map.value = "fan only"
  322. break
  323. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_PENDING_HEAT:
  324. map.value = "pending heat"
  325. break
  326. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_PENDING_COOL:
  327. map.value = "pending cool"
  328. break
  329. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_VENT_ECONOMIZER:
  330. map.value = "vent economizer"
  331. break
  332. }
  333. if (map.value != null)
  334. map.name = "thermostatOperatingState"
  335. else
  336. log.warn "Bad ThermostatOperatingStateReport command: ${cmd}"
  337. map
  338. }
  339.  
  340. def zwaveEvent(hubitat.zwave.commands.thermostatfanstatev1.ThermostatFanStateReport cmd) {
  341. def map = [name: "thermostatFanState", unit: ""]
  342. switch (cmd.fanOperatingState) {
  343. case 0:
  344. map.value = "idle"
  345. break
  346. case 1:
  347. map.value = "running"
  348. break
  349. case 2:
  350. map.value = "running high"
  351. break
  352. }
  353. map
  354. }
  355.  
  356. def zwaveEvent(hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport cmd) {
  357. def nowTime = new Date().time
  358. state.lastMoreInfoGet = nowTime
  359. def map = [:]
  360. switch (cmd.mode) {
  361. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_OFF:
  362. map.value = "off"
  363. break
  364. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_HEAT:
  365. map.value = "heat"
  366. break
  367. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_AUXILIARY_HEAT:
  368. map.value = "emergencyHeat"
  369. break
  370. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_COOL:
  371. map.value = "cool"
  372. break
  373. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_AUTO:
  374. map.value = "auto"
  375. break
  376. }
  377. map.name = "thermostatMode"
  378. map
  379. }
  380.  
  381. def zwaveEvent(hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport cmd) {
  382. def map = [:]
  383. switch (cmd.fanMode) {
  384. case hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_AUTO_LOW:
  385. map.value = "fanAuto"
  386. break
  387. case hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_LOW:
  388. map.value = "fanOn"
  389. break
  390. case hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_CIRCULATION:
  391. map.value = "fanCirculate"
  392. break
  393. }
  394. map.name = "thermostatFanMode"
  395. map.displayed = false
  396. map
  397. }
  398.  
  399. def zwaveEvent(hubitat.zwave.commands.thermostatmodev2.ThermostatModeSupportedReport cmd) {
  400. log.debug "Processing ThermostatModeSupportedReport ${cmd}"
  401. def supportedModes = ""
  402. if(cmd.off) { supportedModes += "off " }
  403. if(cmd.heat) { supportedModes += "heat " }
  404. if(cmd.auxiliaryemergencyHeat) { supportedModes += "emergencyHeat " }
  405. if(cmd.cool) { supportedModes += "cool " }
  406. if(cmd.auto) { supportedModes += "auto " }
  407.  
  408. updateState("supportedModes", supportedModes)
  409. }
  410.  
  411. def zwaveEvent(hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeSupportedReport cmd) {
  412. log.debug "Processing FanModeSupportedReport ${cmd}"
  413. def supportedFanModes = ""
  414. if(cmd.auto) { supportedFanModes += "fanAuto " }
  415. if(cmd.low) { supportedFanModes += "fanOn " }
  416. if(cmd.circulation) { supportedFanModes += "fanCirculate " }
  417.  
  418. updateState("supportedFanModes", supportedFanModes)
  419. }
  420.  
  421. def updateState(String name, String value) {
  422. state[name] = value
  423. device.updateDataValue(name, value)
  424. }
  425.  
  426. def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd) {
  427. log.debug "Zwave event received: $cmd"
  428. }
  429.  
  430. def zwaveEvent(hubitat.zwave.Command cmd) {
  431. log.warn "Unexpected zwave command $cmd"
  432. }
  433.  
  434. // Command Implementations
  435. def refresh() {
  436. poll()
  437. }
  438.  
  439. def poll() {
  440. checkResponsiveness()
  441. def commands = [
  442. zwave.sensorMultilevelV3.sensorMultilevelGet().format(), // current temperature
  443. zwave.thermostatOperatingStateV1.thermostatOperatingStateGet().format(),
  444. zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint: 2).encapsulate(zwave.sensorMultilevelV3.sensorMultilevelGet()).format(), //current RH
  445. zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
  446. zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format()
  447. ]
  448. def batteryCmd = getBattery()
  449. if (batteryCmd != null) commands.add(batteryCmd)
  450. def moreInfoCmds = getMoreInfo()
  451. if (moreInfoCmds != null) commands.addAll(moreInfoCmds)
  452. def setClockCmd = setClock()
  453. if (setClockCmd != null) commands.add(setClockCmd)
  454. delayBetween(commands, getStandardDelay())
  455. }
  456.  
  457. private getMoreInfo() { //once every 1 hour
  458. def nowTime = new Date().time
  459. def ageInMinutes = state.lastMoreInfoGet ? (nowTime - state.lastMoreInfoGet)/60000 : 60
  460. def batteryValue = device.currentValue("battery")
  461. log.debug "More info report age: ${ageInMinutes} minutes, battery charge is ${batteryValue}%"
  462. if (ageInMinutes >= 60) {
  463. log.debug "Fetching fresh more info values"
  464. [zwave.thermostatModeV2.thermostatModeGet().format(),
  465. zwave.thermostatFanModeV3.thermostatFanModeGet().format()
  466. ]
  467. } else null
  468. }
  469.  
  470. private getBattery() { //once every 10 hours
  471. def nowTime = new Date().time
  472. def ageInMinutes = state.lastBatteryGet ? (nowTime - state.lastBatteryGet)/60000 : 600
  473. log.debug "Battery report age: ${ageInMinutes} minutes"
  474. if (ageInMinutes >= 600) {
  475. log.debug "Fetching fresh battery value"
  476. zwave.batteryV1.batteryGet().format()
  477. } else null
  478. }
  479.  
  480. private setClock() { //once a day
  481.  
  482. def nowTime = new Date().time
  483. def ageInMinutes = state.lastClockSet ? (nowTime - state.lastClockSet)/60000 : 1440
  484. log.debug "Clock set age: ${ageInMinutes} minutes"
  485. if (ageInMinutes >= 1440) {
  486. state.lastClockSet = nowTime
  487. def nowCal = Calendar.getInstance(location.timeZone);
  488. def clockSetCmd = zwave.clockV1.clockSet(hour: nowCal.get(Calendar.HOUR_OF_DAY), minute: nowCal.get(Calendar.MINUTE), weekday: nowCal.get(Calendar.DAY_OF_WEEK)).format()
  489. log.debug "Setting clock: ${clockSetCmd}"
  490. clockSetCmd
  491. } else null
  492. }
  493.  
  494. def setHeatingSetpoint(degreesF) {
  495. setHeatingSetpoint(degreesF.toDouble())
  496. }
  497.  
  498. def setHeatingSetpoint(Double degreesF) {
  499. log.debug "setHeatingSetpoint(${degreesF})"
  500. def p = (state.precision == null) ? 1 : state.precision
  501. delayBetween([
  502. zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 1, scale: 1, precision: p, scaledValue: degreesF).format(),
  503. zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
  504. "delay 2400"
  505. ])
  506. }
  507.  
  508. def setCoolingSetpoint(degreesF) {
  509. setCoolingSetpoint(degreesF.toDouble())
  510. }
  511.  
  512. def setCoolingSetpoint(Double degreesF) {
  513. log.debug "setCoolingSetpoint(${degreesF})"
  514. def p = (state.precision == null) ? 1 : state.precision
  515. delayBetween([
  516. "delay 9600",
  517. zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 2, scale: 1, precision: p, scaledValue: degreesF).format(),
  518. zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format(),
  519. "delay 2400"
  520. ])
  521. }
  522.  
  523. def configure() {
  524. log.debug "Configuring..."
  525. delayBetween([
  526. zwave.thermostatModeV2.thermostatModeSupportedGet().format(),
  527. zwave.thermostatFanModeV3.thermostatFanModeSupportedGet().format(),
  528. zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format()
  529. ], 2300)
  530. }
  531.  
  532. def modes() {
  533. ["off", "heat", "cool", "auto", "emergencyHeat"]
  534. }
  535.  
  536. def switchMode() {
  537. def currentMode = device.currentState("thermostatMode")?.value
  538. def lastTriedMode = state.lastTriedMode ?: currentMode ?: "off"
  539. def supportedModes = getDataByName("supportedModes")
  540. def modeOrder = modes()
  541. def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
  542. def nextMode = next(lastTriedMode)
  543. if (supportedModes?.contains(currentMode)) {
  544. while (!supportedModes.contains(nextMode) && nextMode != "off") {
  545. nextMode = next(nextMode)
  546. }
  547. }
  548. state.lastTriedMode = nextMode
  549. delayBetween([
  550. zwave.thermostatModeV2.thermostatModeSet(mode: modeMap[nextMode]).format(),
  551. zwave.thermostatModeV2.thermostatModeGet().format()
  552. ], 1000)
  553. }
  554.  
  555. def switchToMode(nextMode) {
  556. def supportedModes = getDataByName("supportedModes")
  557. if(supportedModes && !supportedModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported"
  558. if (nextMode in modes()) {
  559. state.lastTriedMode = nextMode
  560. "$nextMode"()
  561. } else {
  562. log.debug("no mode method '$nextMode'")
  563. }
  564. }
  565.  
  566. def switchFanMode() {
  567. def currentMode = device.currentState("thermostatFanMode")?.value
  568. def lastTriedMode = state.lastTriedFanMode ?: currentMode ?: "off"
  569. def supportedModes = getDataByName("supportedFanModes") ?: "fanAuto fanOn"
  570. def modeOrder = ["fanAuto", "fanCirculate", "fanOn"]
  571. def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
  572. def nextMode = next(lastTriedMode)
  573. while (!supportedModes?.contains(nextMode) && nextMode != "fanAuto") {
  574. nextMode = next(nextMode)
  575. }
  576. switchToFanMode(nextMode)
  577. }
  578.  
  579. def switchToFanMode(nextMode) {
  580. def supportedFanModes = getDataByName("supportedFanModes")
  581. if(supportedFanModes && !supportedFanModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported"
  582.  
  583. def returnCommand
  584. if (nextMode == "fanAuto") {
  585. returnCommand = fanAuto()
  586. } else if (nextMode == "fanOn") {
  587. returnCommand = fanOn()
  588. } else if (nextMode == "fanCirculate") {
  589. returnCommand = fanCirculate()
  590. } else {
  591. log.debug("no fan mode '$nextMode'")
  592. }
  593. if(returnCommand) state.lastTriedFanMode = nextMode
  594. returnCommand
  595. }
  596.  
  597. def getDataByName(String name) {
  598. state[name] ?: device.getDataValue(name)
  599. }
  600.  
  601. def getModeMap() { [
  602. "off": 0,
  603. "heat": 1,
  604. "cool": 2,
  605. "auto": 3,
  606. "emergencyHeat": 4
  607. ]}
  608.  
  609. def setThermostatMode(String value) {
  610. delayBetween([
  611. zwave.thermostatModeV2.thermostatModeSet(mode: modeMap[value]).format(),
  612. zwave.thermostatModeV2.thermostatModeGet().format()
  613. ], standardDelay)
  614. }
  615.  
  616. def getFanModeMap() { [
  617. "auto": 0,
  618. "on": 1,
  619. "circulate": 6
  620. ]}
  621.  
  622. def setThermostatFanMode(String value) {
  623. delayBetween([
  624. zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: fanModeMap[value]).format(),
  625. zwave.thermostatFanModeV3.thermostatFanModeGet().format()
  626. ], standardDelay)
  627. }
  628.  
  629. def off() {
  630. delayBetween([
  631. zwave.thermostatModeV2.thermostatModeSet(mode: 0).format(),
  632. zwave.thermostatModeV2.thermostatModeGet().format(),
  633. "delay 2400"
  634. ])
  635. }
  636.  
  637. def heat() {
  638. delayBetween([
  639. zwave.thermostatModeV2.thermostatModeSet(mode: 1).format(),
  640. zwave.thermostatModeV2.thermostatModeGet().format(),
  641. "delay 2400"
  642. ])
  643. }
  644.  
  645. def emergencyHeat() {
  646. delayBetween([
  647. zwave.thermostatModeV2.thermostatModeSet(mode: 4).format(),
  648. zwave.thermostatModeV2.thermostatModeGet().format(),
  649. "delay 2400"
  650. ])
  651. }
  652.  
  653. def cool() {
  654. delayBetween([
  655. zwave.thermostatModeV2.thermostatModeSet(mode: 2).format(),
  656. zwave.thermostatModeV2.thermostatModeGet().format(),
  657. "delay 2400"
  658. ])
  659. }
  660.  
  661. def auto() {
  662. delayBetween([
  663. zwave.thermostatModeV2.thermostatModeSet(mode: 3).format(),
  664. zwave.thermostatModeV2.thermostatModeGet().format(),
  665. "delay 2400"
  666. ])
  667. }
  668.  
  669. def fanOn() {
  670. delayBetween([
  671. zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 1).format(),
  672. zwave.thermostatFanModeV3.thermostatFanModeGet().format(),
  673. "delay 2400"
  674. ])
  675. }
  676.  
  677. def fanAuto() {
  678. delayBetween([
  679. zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 0).format(),
  680. zwave.thermostatFanModeV3.thermostatFanModeGet().format(),
  681. "delay 2400"
  682. ])
  683. }
  684.  
  685. def fanCirculate() {
  686. delayBetween([
  687. zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 6).format(),
  688. zwave.thermostatFanModeV3.thermostatFanModeGet().format(),
  689. "delay 2400"
  690. ])
  691. }
  692.  
  693. private updateResponsiveness() {
  694. def nowTime = new Date().time
  695. state.lastResponse = nowTime
  696. if (device.currentValue("responsive") == null || device.currentValue("responsive") == "false") {
  697. log.info "Updating responsive attribute to true"
  698. sendEvent(name: "responsive", value: "true")
  699. }
  700. null
  701. }
  702.  
  703. private checkResponsiveness() {
  704. def nowTime = new Date().time
  705. if (state.lastResponse) {
  706. def lastResponseAge = (nowTime - state.lastResponse) / 60000
  707. log.debug "Last response from device was received ${lastResponseAge} minutes ago"
  708. if (lastResponseAge >= 1440) { //if no response was received in the last 24 hourse, set responsive to false
  709. if (device.currentValue("responsive") == "true") {
  710. log.info "Updating responsive attribute to false"
  711. sendEvent(name: "responsive", value: "false")
  712. }
  713. }
  714. }
  715. null
  716. }
  717.  
  718. private getStandardDelay() {
  719. 1800
  720. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement