Advertisement
Guest User

Untitled

a guest
Dec 29th, 2020
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.44 KB | None | 0 0
  1. /**
  2. * ZTS-110 Thermostat by Remotec
  3. *
  4. * Copyright 2016 Dennis Spanogle / Template used Copyright Smart Things
  5. *
  6. * Modified Smart Things generic Z-Wave Thermostat
  7. * added 3 configuration parameters (for now)
  8. * added battery status report (in case user selects battery)
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  11. * in compliance with the License. You may obtain a copy of the License at:
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  16. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  17. * for the specific language governing permissions and limitations under the License.
  18. *
  19. *
  20. */
  21. metadata {
  22. // Automatically generated. Make future change here.
  23. definition (name: "ZTS-110 Thermostat (Click config to activate reporting)", namespace: "Thermostat Config Setup", author: "Tim") {
  24. capability "Actuator"
  25. capability "Temperature Measurement"
  26. capability "Relative Humidity Measurement"
  27. capability "Thermostat"
  28. capability "Configuration"
  29. capability "Polling"
  30. capability "Sensor"
  31. capability "Battery" // DES
  32. attribute "thermostatFanState", "string" //DES added , "string" (This does not seem to be used)
  33. attribute "Calibration", "number" // DES added
  34. attribute "Autorpt_DegF", "number" // DES added
  35. attribute "Autorpt_Hr", "number" // DES added
  36. command "switchMode"
  37. command "switchFanMode"
  38. command "quickSetCool"
  39. command "quickSetHeat"
  40. //DES replaced fingerprint to match the raw descrption from theRomotec ZTS-110
  41. //raw description (DES): 0 0 0x1001 0 0 0 4 0x25 0x27 0x86 0x72
  42. //raw dscription (Tim): 0 0 0x0806 0 0 0 d 0x20 0x31 0x40 0x42 0x43 0x44 0x45 0x47 0x70 0x72 0x81 0x85 0x86
  43. //fingerprint deviceId:"0x0806", inClusters:"0x20, 0x31, 0x40, 0x42, 0x43, 0x44, 0x45, 0x47, 0x70, 0x72, 0x81, 0x85, 0x86"
  44. }
  45. // simulator metadata
  46. simulator {
  47. status "off" : "command: 4003, payload: 00"
  48. status "heat" : "command: 4003, payload: 01"
  49. status "cool" : "command: 4003, payload: 02"
  50. status "auto" : "command: 4003, payload: 03"
  51. status "emergencyHeat" : "command: 4003, payload: 04"
  52.  
  53. status "fanAuto" : "command: 4403, payload: 00"
  54.  
  55. status "fanOn" : "command: 4403, payload: 01"
  56. status "fanCirculate" : "command: 4403, payload: 06"
  57.  
  58. status "heat 60" : "command: 4303, payload: 01 09 3C"
  59. status "heat 68" : "command: 4303, payload: 01 09 44"
  60. status "heat 72" : "command: 4303, payload: 01 09 48"
  61.  
  62. status "cool 72" : "command: 4303, payload: 02 09 48"
  63. status "cool 76" : "command: 4303, payload: 02 09 4C"
  64. status "cool 80" : "command: 4303, payload: 02 09 50"
  65.  
  66. status "temp 58" : "command: 3105, payload: 01 2A 02 44"
  67. status "temp 62" : "command: 3105, payload: 01 2A 02 6C"
  68. status "temp 70" : "command: 3105, payload: 01 2A 02 BC"
  69. status "temp 74" : "command: 3105, payload: 01 2A 02 E4"
  70. status "temp 78" : "command: 3105, payload: 01 2A 03 0C"
  71. status "temp 82" : "command: 3105, payload: 01 2A 03 34"
  72.  
  73. status "idle" : "command: 4203, payload: 00"
  74. status "heating" : "command: 4203, payload: 01"
  75. status "cooling" : "command: 4203, payload: 02"
  76. status "fan only" : "command: 4203, payload: 03"
  77. status "pending heat" : "command: 4203, payload: 04"
  78. status "pending cool" : "command: 4203, payload: 05"
  79. status "vent economizer": "command: 4203, payload: 06"
  80.  
  81. // reply messages
  82. reply "2502": "command: 2503, payload: FF"
  83. }
  84. // DES changed the layout scale and height, width for all tiles
  85. tiles (scale: 2) {
  86. valueTile("temperature", "device.temperature", width: 4, height: 4) {
  87. state("temperature", label:'${currentValue}°',
  88. backgroundColors:[
  89. [value: 31, color: "#153591"],
  90. [value: 44, color: "#1e9cbb"],
  91. [value: 59, color: "#90d2a7"],
  92. [value: 74, color: "#44b621"],
  93. [value: 84, color: "#f1d801"],
  94. [value: 95, color: "#d04e00"],
  95. [value: 96, color: "#bc2323"]
  96. ]
  97. )
  98. }
  99. // DES removed depreciated inactiveLabel: false from all tiles
  100. standardTile("mode", "device.thermostatMode", decoration: "flat", width: 2, height: 2) {
  101. state "off", label:'${name}', action:"switchMode", nextState:"to_heat"
  102. state "heat", label:'${name}', action:"switchMode", nextState:"to_cool"
  103. state "cool", label:'${name}', action:"switchMode", nextState:"..."
  104. state "auto", label:'${name}', action:"switchMode", nextState:"..."
  105. state "emergencyHeat", label:'${name}', action:"switchMode", nextState:"..."
  106. state "to_heat", label: "heat", action:"switchMode", nextState:"to_cool"
  107. state "to_cool", label: "cool", action:"switchMode", nextState:"..."
  108. state "...", label: "...", action:"off", nextState:"off"
  109. }
  110. standardTile("fanMode", "device.thermostatFanMode", decoration: "flat", width: 2, height: 2) {
  111. state "fanAuto", label:'${name}', action:"switchFanMode"
  112. state "fanOn", label:'${name}', action:"switchFanMode"
  113. state "fanCirculate", label:'${name}', action:"switchFanMode"
  114. }
  115. controlTile("heatSliderControl", "device.heatingSetpoint", "slider", height: 1, width: 4) {
  116. state "setHeatingSetpoint", action:"quickSetHeat", backgroundColor:"#d04e00"
  117. }
  118. valueTile("heatingSetpoint", "device.heatingSetpoint", decoration: "flat", width: 2, height: 1) {
  119. state "heat", label:'${currentValue}° heat', backgroundColor:"#ffffff"
  120. }
  121. controlTile("coolSliderControl", "device.coolingSetpoint", "slider", height: 1, width: 4) {
  122. state "setCoolingSetpoint", action:"quickSetCool", backgroundColor: "#1e9cbb"
  123. }
  124. valueTile("coolingSetpoint", "device.coolingSetpoint", decoration: "flat", width: 2, height: 1) {
  125. state "cool", label:'${currentValue}° cool', backgroundColor:"#ffffff"
  126. }
  127. standardTile("refresh", "device.thermostatMode", decoration: "flat", width: 2, height: 2) {
  128. state "default", action:"polling.poll", icon:"st.secondary.refresh"
  129. }
  130. // DES since edit device in app returns configure, this tile is really not needed
  131. //standardTile("configure", "device.configure", decoration: "flat", width: 2, height: 2) {
  132. //state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
  133. //}
  134. // DES added This tile to match attribute attribute "Calibration", "number"
  135. valueTile("Calibration", "device.Calibration", decoration: "flat", width: 2, height: 1) {
  136. state "Calibration", label:'Cal: ${currentValue}°' //, action:"configuration.configure"
  137. }
  138. valueTile("Autorpt_Hr", "device.Autorpt_Hr", decoration: "flat", width: 2, height: 1) {
  139. state "Autorpt_Hr", label:'Rpt: ${currentValue}hr' // , action:"configuration.configure"
  140. }
  141. valueTile("Autorpt_DegF", "device.Autorpt_DegF", decoration: "flat", width: 2, height: 1) {
  142. state "Autorpt_DegF", label:'Rpt: ${currentValue}°F' //, action:"configuration.configure"
  143. }
  144. valueTile("battery", "device.battery", decoration: "flat", width: 2, height: 1) {
  145. state "battery", label:'Bat: ${currentValue}%', unit:""
  146. }
  147.  
  148. main "temperature"
  149. details(["temperature", "mode", "fanMode", "heatSliderControl", "heatingSetpoint", "coolSliderControl",
  150. "coolingSetpoint", "refresh", "configure", "Calibration", "Autorpt_DegF", "Autorpt_Hr", "battery" ])
  151.  
  152. }
  153. }
  154. // DES add preferences
  155. // ** Get inputs for the configuration (only 3 of the possible configurations are included at this time)
  156. preferences {
  157. // parm 13 = calibration -3,-2,-1,0,1,2, 3 Etc
  158. input "cal", "number", title: "Calibration: -10°F to +10°F (0=default)",
  159. description: "Offset -2,-1,0 (default),1,2 Etc", defaultValue: 0,
  160. required: false //, displayDuringSetup: true // also displayed during edit in mobile app
  161. // parm 12 = autoreport time trigger: 0 = never, 1 = 30 min, 2 = 1 hr (default)
  162. input "RptTime", "number", title: "Auto Report Time: 0=Never, 1 to 16 half hrs (2=default=1hr)",
  163. description: "0=Never, 1=.5hr, 2=1hr (default), 3=1.5hr, .. max 16=8hr", defaultValue: 2,
  164. required: false //, displayDuringSetup: true
  165. // parm 11 Trigger autoreport if room temp different from last report
  166. // 1 = 1 deg F, 2 = 2 degree F, 3 = 3, 4 = 4 deg F = default Set to 1
  167. input "RptDelta", "number", title: "Auto Report °F Change: 0=Never, 1°F to 8°F (4=default)",
  168. description: "0=Never, 1=1°F, 2=2°F, 3=3°F, 4=4°F (default), .. max8=8°F", defaultValue: 4,
  169. required: false //, displayDuringSetup: true
  170. }
  171. // DES add battery Event Generation
  172. def zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport cmd) {
  173. def map = [ name: "battery", unit: "%" ]
  174. if (cmd.batteryLevel == 0xFF) {
  175. map.value = 1
  176. map.descriptionText = "${device.displayName} Low Battery"
  177. map.isStateChange = true
  178. } else {
  179. map.value = cmd.batteryLevel
  180. }
  181. state.lastbatt = now()
  182. // log.debug "Got Battery status: ${map}"
  183. map
  184. }
  185. // DES add Configuration Event Generation
  186. def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
  187. //log.debug " in zwave Event ConfigurationReport"
  188. def map = [:]
  189. def value = cmd.configurationValue[0]
  190. switch (cmd.parameterNumber) {
  191. case 11:
  192. map.name = "Autorpt_DegF"
  193. if (value < 0){value = 0}
  194. if (value > 8){value = 8}
  195. map.value = value
  196. break
  197. case 12:
  198. map.name = "Autorpt_Hr"
  199. if (value < 0){value = 0} // DES These probably redundant
  200. if (value > 16){value = 16}
  201. map.value = value/2 // report in hours instead of half hours as entered.
  202. break
  203. case 13:
  204. map.name = "Calibration"
  205. if (value > 128){
  206. value = value - 246
  207. }
  208. map.value = value
  209. //log.debug " did Cal map cal = ${map.value}"
  210. break
  211. }
  212. map
  213. }
  214. // DES added updated()
  215. def updated() {
  216. log.trace "Updated Input Settings: ${settings}"
  217. if(settings.cal > 10){settings.cal = 10} // calibration must be between -10 ann +10
  218. if(settings.cal < -10){settings.cal = -10}
  219. if(settings.RptTime > 16){settings.RptTime = 16} // Every 8 hours is max
  220. if(settings.RptTime < 0){settings.RptTime = 0} // Note 0 disables auto report by time
  221. if(settings.RptDelta > 8){settings.RptDelta = 8} // delta of 8 degrees is max
  222. if(settings.RptDelta < 0){settings.RptDelta = 0} // Note 0 disables auto report if different than last
  223. log.trace "Updated Corrected Settings: ${settings}"
  224. response(configure())
  225. }
  226. // DES modified configure()
  227. def configure() {
  228. delayBetween([
  229. zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format(),
  230. zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format(),
  231. //Tim's Code End
  232.  
  233.  
  234. ], 2300)
  235. }
  236. // DES modified Command Implementation polling
  237. def poll() {
  238. // DES add poll of calibration parameter 13
  239. delayBetween([
  240. zwave.sensorMultilevelV3.sensorMultilevelGet().format(), // current temperature
  241. zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
  242. zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format(),
  243. zwave.thermostatModeV2.thermostatModeGet().format(),
  244. zwave.thermostatFanModeV3.thermostatFanModeGet().format(),
  245. zwave.thermostatOperatingStateV1.thermostatOperatingStateGet().format(),
  246. // DES update the configurations tiles
  247. zwave.configurationV1.configurationGet(parameterNumber: 13).format(),
  248. zwave.configurationV1.configurationGet(parameterNumber: 12).format(),
  249. zwave.configurationV1.configurationGet(parameterNumber: 11).format(),
  250. // DES get the battery status
  251. zwave.batteryV1.batteryGet().format()
  252. ], 2300)
  253. }
  254. def parse(String description)
  255. {
  256. // DES added 0x70: COMMAND_CLASS_CONFIGURATION so this will process configuration reports
  257. // DES added 0x80: COMMAND_CLASS_BATTERY so this will process battery reports
  258. def map = createEvent(zwaveEvent(zwave.parse(description, [0x42:1, 0x43:2, 0x31: 3, 0x70: 1, 0x80: 1]))) // DES added 0x70, 1
  259. if (!map) {
  260. return null
  261. }
  262. def result = [map]
  263. if (map.isStateChange && map.name in ["heatingSetpoint","coolingSetpoint","thermostatMode"]) {
  264. def map2 = [
  265. name: "thermostatSetpoint",
  266. unit: getTemperatureScale()
  267. ]
  268. if (map.name == "thermostatMode") {
  269. state.lastTriedMode = map.value
  270. if (map.value == "cool") {
  271. map2.value = device.latestValue("coolingSetpoint")
  272. log.info "THERMOSTAT, latest cooling setpoint = ${map2.value}"
  273. }
  274. else {
  275. map2.value = device.latestValue("heatingSetpoint")
  276. log.info "THERMOSTAT, latest heating setpoint = ${map2.value}"
  277. }
  278. }
  279. else {
  280. def mode = device.latestValue("thermostatMode")
  281. log.info "THERMOSTAT, latest mode = ${mode}"
  282. if ((map.name == "heatingSetpoint" && mode == "heat") || (map.name == "coolingSetpoint" && mode == "cool")) {
  283. map2.value = map.value
  284. map2.unit = map.unit
  285. }
  286. }
  287. if (map2.value != null) {
  288. log.debug "THERMOSTAT, adding setpoint event: $map"
  289. result << createEvent(map2)
  290. }
  291. } else if (map.name == "thermostatFanMode" && map.isStateChange) {
  292. state.lastTriedFanMode = map.value
  293. }
  294. log.debug "Parse returned $result"
  295. result
  296. }
  297. // Event Generation
  298. def zwaveEvent(hubitat.zwave.commands.thermostatsetpointv2.ThermostatSetpointReport cmd)
  299. {
  300. def cmdScale = cmd.scale == 1 ? "F" : "C"
  301. def map = [:]
  302. map.value = convertTemperatureIfNeeded(cmd.scaledValue, cmdScale, cmd.precision)
  303. map.unit = getTemperatureScale()
  304. map.displayed = false
  305. switch (cmd.setpointType) {
  306. case 1:
  307. map.name = "heatingSetpoint"
  308. break;
  309. case 2:
  310. map.name = "coolingSetpoint"
  311. break;
  312. default:
  313. return [:]
  314. }
  315. // So we can respond with same format
  316. state.size = cmd.size
  317. state.scale = cmd.scale
  318. state.precision = cmd.precision
  319. map
  320. }
  321. def zwaveEvent(hubitat.zwave.commands.sensormultilevelv3.SensorMultilevelReport cmd)
  322. {
  323. def map = [:]
  324. if (cmd.sensorType == 1) {
  325. map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmd.scale == 1 ? "F" : "C", cmd.precision)
  326. map.unit = getTemperatureScale()
  327. map.name = "temperature"
  328. } else if (cmd.sensorType == 5) {
  329. map.value = cmd.scaledSensorValue
  330. map.unit = "%"
  331. map.name = "humidity"
  332. }
  333. map
  334. }
  335. def zwaveEvent(hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport cmd)
  336. {
  337. def map = [:]
  338. switch (cmd.operatingState) {
  339. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_IDLE:
  340. map.value = "idle"
  341. break
  342. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_HEATING:
  343. map.value = "heating"
  344. break
  345. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_COOLING:
  346. map.value = "cooling"
  347. break
  348. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_FAN_ONLY:
  349. map.value = "fan only"
  350. break
  351. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_PENDING_HEAT:
  352. map.value = "pending heat"
  353. break
  354. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_PENDING_COOL:
  355. map.value = "pending cool"
  356. break
  357. case hubitat.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_VENT_ECONOMIZER:
  358. map.value = "vent economizer"
  359. break
  360. }
  361. map.name = "thermostatOperatingState"
  362. map
  363. }
  364. def zwaveEvent(hubitat.zwave.commands.thermostatfanstatev1.ThermostatFanStateReport cmd) {
  365. def map = [name: "thermostatFanState"]
  366. switch (cmd.fanOperatingState) {
  367. case 0:
  368. map.value = "idle"
  369. break
  370. case 1:
  371. map.value = "running"
  372. break
  373. case 2:
  374. map.value = "running high"
  375. break
  376. }
  377. map
  378. }
  379. def zwaveEvent(hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport cmd) {
  380. def map = [:]
  381. switch (cmd.mode) {
  382. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_OFF:
  383. map.value = "off"
  384. break
  385. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_HEAT:
  386. map.value = "heat"
  387. break
  388. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_AUXILIARY_HEAT:
  389. map.value = "emergencyHeat"
  390. break
  391. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_COOL:
  392. map.value = "cool"
  393. break
  394. case hubitat.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_AUTO:
  395. map.value = "auto"
  396. break
  397. }
  398. map.name = "thermostatMode"
  399. map
  400. }
  401. def zwaveEvent(hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport cmd) {
  402. def map = [:]
  403. switch (cmd.fanMode) {
  404. case hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_AUTO_LOW:
  405. map.value = "fanAuto"
  406. break
  407. case hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_LOW:
  408. map.value = "fanOn"
  409. break
  410. case hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_CIRCULATION:
  411. map.value = "fanCirculate"
  412. break
  413. }
  414. map.name = "thermostatFanMode"
  415. map.displayed = false
  416. map
  417. }
  418. def zwaveEvent(hubitat.zwave.commands.thermostatmodev2.ThermostatModeSupportedReport cmd) {
  419. def supportedModes = ""
  420. if(cmd.off) { supportedModes += "off " }
  421. if(cmd.heat) { supportedModes += "heat " }
  422. if(cmd.auxiliaryemergencyHeat) { supportedModes += "emergencyHeat " }
  423. if(cmd.cool) { supportedModes += "cool " }
  424. if(cmd.auto) { supportedModes += "auto " }
  425. state.supportedModes = supportedModes
  426. }
  427. def zwaveEvent(hubitat.zwave.commands.thermostatfanmodev3.ThermostatFanModeSupportedReport cmd) {
  428. def supportedFanModes = ""
  429. if(cmd.auto) { supportedFanModes += "fanAuto " }
  430. if(cmd.low) { supportedFanModes += "fanOn " }
  431. if(cmd.circulation) { supportedFanModes += "fanCirculate " }
  432. state.supportedFanModes = supportedFanModes
  433. }
  434. def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd) {
  435. log.debug "Zwave event received: $cmd"
  436. }
  437. def zwaveEvent(hubitat.zwave.Command cmd) {
  438. log.warn "Unexpected zwave command $cmd"
  439. }
  440. // Command Implementations
  441. def quickSetHeat(degrees) {
  442. setHeatingSetpoint(degrees, 1000)
  443. }
  444. def setHeatingSetpoint(degrees, delay = 30000) {
  445. setHeatingSetpoint(degrees.toDouble(), delay)
  446. }
  447. def setHeatingSetpoint(Double degrees, Integer delay = 30000) {
  448. log.trace "setHeatingSetpoint($degrees, $delay)"
  449. def deviceScale = state.scale ?: 1
  450. def deviceScaleString = deviceScale == 2 ? "C" : "F"
  451. def locationScale = getTemperatureScale()
  452. def p = (state.precision == null) ? 1 : state.precision
  453. def convertedDegrees
  454. if (locationScale == "C" && deviceScaleString == "F") {
  455. convertedDegrees = celsiusToFahrenheit(degrees)
  456. } else if (locationScale == "F" && deviceScaleString == "C") {
  457. convertedDegrees = fahrenheitToCelsius(degrees)
  458. } else {
  459. convertedDegrees = degrees
  460. }
  461.  
  462. delayBetween([
  463. zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 1, scale: deviceScale, precision: p, scaledValue: convertedDegrees).format(),
  464. zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format()
  465. ], delay)
  466. }
  467. def quickSetCool(degrees) {
  468. setCoolingSetpoint(degrees, 1000)
  469. }
  470. def setCoolingSetpoint(degrees, delay = 30000) {
  471. setCoolingSetpoint(degrees.toDouble(), delay)
  472. }
  473. def setCoolingSetpoint(Double degrees, Integer delay = 30000) {
  474. log.trace "setCoolingSetpoint($degrees, $delay)"
  475. def deviceScale = state.scale ?: 1
  476. def deviceScaleString = deviceScale == 2 ? "C" : "F"
  477. def locationScale = getTemperatureScale()
  478. def p = (state.precision == null) ? 1 : state.precision
  479. def convertedDegrees
  480. if (locationScale == "C" && deviceScaleString == "F") {
  481. convertedDegrees = celsiusToFahrenheit(degrees)
  482. } else if (locationScale == "F" && deviceScaleString == "C") {
  483. convertedDegrees = fahrenheitToCelsius(degrees)
  484. } else {
  485. convertedDegrees = degrees
  486. }
  487.  
  488. delayBetween([
  489. zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 2, scale: deviceScale, precision: p, scaledValue: convertedDegrees).format(),
  490. zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format()
  491. ], delay)
  492. }
  493. def modes() {
  494. ["off", "heat", "cool", "auto", "emergencyHeat"]
  495. }
  496. def switchMode() {
  497. def currentMode = device.currentState("thermostatMode")?.value
  498. def lastTriedMode = state.lastTriedMode ?: currentMode ?: "off"
  499. def supportedModes = getDataByName("supportedModes")
  500. def modeOrder = modes()
  501. def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
  502. def nextMode = next(lastTriedMode)
  503. if (supportedModes?.contains(currentMode)) {
  504. while (!supportedModes.contains(nextMode) && nextMode != "off") {
  505. nextMode = next(nextMode)
  506. }
  507. }
  508. state.lastTriedMode = nextMode
  509. delayBetween([
  510. zwave.thermostatModeV2.thermostatModeSet(mode: modeMap[nextMode]).format(),
  511. zwave.thermostatModeV2.thermostatModeGet().format()
  512. ], 1000)
  513. }
  514. def switchToMode(nextMode) {
  515. def supportedModes = getDataByName("supportedModes")
  516. if(supportedModes && !supportedModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported"
  517. if (nextMode in modes()) {
  518. state.lastTriedMode = nextMode
  519. "$nextMode"()
  520. } else {
  521. log.debug("no mode method '$nextMode'")
  522. }
  523. }
  524. def switchFanMode() {
  525. def currentMode = device.currentState("thermostatFanMode")?.value
  526. def lastTriedMode = state.lastTriedFanMode ?: currentMode ?: "off"
  527. def supportedModes = getDataByName("supportedFanModes") ?: "fanAuto fanOn"
  528. def modeOrder = ["fanAuto", "fanCirculate", "fanOn"]
  529. def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
  530. def nextMode = next(lastTriedMode)
  531. while (!supportedModes?.contains(nextMode) && nextMode != "fanAuto") {
  532. nextMode = next(nextMode)
  533. }
  534. switchToFanMode(nextMode)
  535. }
  536. def switchToFanMode(nextMode) {
  537. def supportedFanModes = getDataByName("supportedFanModes")
  538. if(supportedFanModes && !supportedFanModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported"
  539. def returnCommand
  540. if (nextMode == "fanAuto") {
  541. returnCommand = fanAuto()
  542. } else if (nextMode == "fanOn") {
  543. returnCommand = fanOn()
  544. } else if (nextMode == "fanCirculate") {
  545. returnCommand = fanCirculate()
  546. } else {
  547. log.debug("no fan mode '$nextMode'")
  548. }
  549. if(returnCommand) state.lastTriedFanMode = nextMode
  550. returnCommand
  551. }
  552. def getDataByName(String name) {
  553. state[name] ?: device.getDataValue(name)
  554. }
  555. def getModeMap() { [
  556. "off": 0,
  557. "heat": 1,
  558. "cool": 2,
  559. "auto": 3,
  560. "emergencyHeat": 4
  561. ]}
  562. def setThermostatMode(String value) {
  563. delayBetween([
  564. zwave.thermostatModeV2.thermostatModeSet(mode: modeMap[value]).format(),
  565. zwave.thermostatModeV2.thermostatModeGet().format()
  566. ], standardDelay)
  567. }
  568. def getFanModeMap() { [
  569. "auto": 0,
  570. "on": 1,
  571. "circulate": 6
  572. ]}
  573. def setThermostatFanMode(String value) {
  574. delayBetween([
  575. zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: fanModeMap[value]).format(),
  576. zwave.thermostatFanModeV3.thermostatFanModeGet().format()
  577. ], standardDelay)
  578. }
  579. def off() {
  580. delayBetween([
  581. zwave.thermostatModeV2.thermostatModeSet(mode: 0).format(),
  582. zwave.thermostatModeV2.thermostatModeGet().format()
  583. ], standardDelay)
  584. }
  585. def heat() {
  586. delayBetween([
  587. zwave.thermostatModeV2.thermostatModeSet(mode: 1).format(),
  588. zwave.thermostatModeV2.thermostatModeGet().format()
  589. ], standardDelay)
  590. }
  591. def emergencyHeat() {
  592. delayBetween([
  593. zwave.thermostatModeV2.thermostatModeSet(mode: 4).format(),
  594. zwave.thermostatModeV2.thermostatModeGet().format()
  595. ], standardDelay)
  596. }
  597. def cool() {
  598. delayBetween([
  599. zwave.thermostatModeV2.thermostatModeSet(mode: 2).format(),
  600. zwave.thermostatModeV2.thermostatModeGet().format()
  601. ], standardDelay)
  602. }
  603. def auto() {
  604. delayBetween([
  605. zwave.thermostatModeV2.thermostatModeSet(mode: 3).format(),
  606. zwave.thermostatModeV2.thermostatModeGet().format()
  607. ], standardDelay)
  608. }
  609. def fanOn() {
  610. delayBetween([
  611. zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 1).format(),
  612. zwave.thermostatFanModeV3.thermostatFanModeGet().format()
  613. ], standardDelay)
  614. }
  615. def fanAuto() {
  616. delayBetween([
  617. zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 0).format(),
  618. zwave.thermostatFanModeV3.thermostatFanModeGet().format()
  619. ], standardDelay)
  620. }
  621. def fanCirculate() {
  622. delayBetween([
  623. zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 6).format(),
  624. zwave.thermostatFanModeV3.thermostatFanModeGet().format()
  625. ], standardDelay)
  626. }
  627. private getStandardDelay() {
  628. 1000
  629. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement