@PatA Please try the code here - I made a small change so it includes the metadata for capabilities, attributes, and commands. Hopefully this resolves things! Be sure to let us know how it goes.
Best,
Matt
@PatA Please try the code here - I made a small change so it includes the metadata for capabilities, attributes, and commands. Hopefully this resolves things! Be sure to let us know how it goes.
Best,
Matt
Have you had any success? I’m trying to decide whether to purchase one of these and want to ensure all 5 channels are accessible from SmartThings. @bigpunk6 can you confirm that it was working for all channels for you? Thanks!
First, thank you for getting us this far!
You are getting somewhere for sure. I just tried it today. It does respond to the individual switches. However, when you press a switch, there is a delay, and all of the switches icons appear in the same mode regardless of what they are really doing. If you press refresh, it does nothing. But if you flip to Activity, you will see everything is responding properly. If you switch screens and return to the multi-switch screen, you will see the icons are all responding correctly. So it seems these changes are still required: 1) Faster response to pressing a switch. 2) Make refresh function and display proper activity of each switch.
@matt_coulter That’s great news - about how long does it take before it actually responds to your button push? To clarify, the switch status information does display properly, but you have to leave the device page and then return to it? Do you use any valve actuators with your PE653? Sounds like @bigpunk6 had it just about working - my guess is that there were some changes to the ST API that impacted his original code.
Sorry for the log hiatus
I posted the updated code to gethub.
https://github.com/bigpunk6/device-type.PE653
Thanks, @bigpunk6
What devices are you using with your PE653? I’m really curious about trying out some automatic valve actuators so i can press one button and have the pool go into “hot tub” mode. Do you have any suggestions for refreshing status more quickly? Perhaps Pollster? Thanks for your contributions!
Hey @mbial and @bigpunk6,
Trying the new code now. Happy to have temp readings. The results with the switches are the same. Yes, the switch information does display properly, but you have to leave the page and return to see a true refreshed view, otherwise the screen reports that all switches are either on or off depending on what you did to the last switch you pressed. This pool does not have actuators but others I have installed do (my dad has a pool company and I have helped him install a lot of these units). Switch 4 is reserved for Actuator control if you have the unit setup for Pool/Spa mode. So yes, it will work fine when you just press Switch 4. And likewise, Switch 5 is reserved for Heat Pump on/off if you are using one, so it will automatically kick on if there is a demand. Lastly, while the temp reading is good, it does not do anything when you press the temp icon. But I wasn’t sure if it is supposed to yet. Hope this information is helpful. Like what you all are doing. Thanks!
@mbial and @matt_coulter
I have a thermometer, pump and lights connected now. I also have the problem with the refreshing status. I did have poll configured after a switch command but ST has disabled that. The temp icon has no function associated with it now since poll is disabled.
I know this device is capable of more I just never configured it since I don’t need it.
Jumping on this thread because it is the reason I ordered my ST hub. I had a few questions before I get started so that I can temper my expectations.
I have a pentair VS Pump connected to my PE653. I have no idea what circuit it is on as I actually access the pump VIA my PE953 remote on a separate screen. When I go to the separate screen I choose the pump speed. Has anyone successfully been able to control the pump speed through the ST app?
My heater is setup so that it will not run unless my pump speed exceeds 750rpm (the heater just needs a strong enough flow). Has anyone setup a 1 button scene to create a scenario wherein the heater will kick in and the pump will turn on?
Anxious to try this stuff out and great work!
Ok, something seems strange. I copied the code and did the setup. I even added the device and assigned it device ID12345.
But how does that link the device to my actual pool control? Don’t I have to try to include the device or add a new device? Is that the way I should do it.
Anyone out there? Anyone do anything about the PE953 (the remote?).
@JDogg016 My guess is that the PE953 won’t be necessary if you’re bothering to link the system to SmartThings.
You will add a new device to SmartThings and pair the PE653. I’m not sure what default device type ST will assign it as I don’t have one of these (yet). Once you have paired the device, go into the API and change its device type to the code here. Let us know how it works out for you!
Got it and got it paired. I even got my remote to act as a slave device. Now I just need to get the VSP setup. Any thoughts on that. None of my switches activate the pump because it’s variable.
@JDogg016 Try opening the device under “My Devices” in the API. There should be some options to configure under “Preferences” you can edit. Let us know!
Yeah, you see this is the issue. Since I copied @bigpunk6 code, I cannot simply go into preferences and check boxes anymore.
I looked at his code and with a rudimentary understanding of the code plainly see there is no thermostat control whatsoever. I presume because @bigpunk6 does not have a heater unit, but has a temperature monitoring unit.
There would be two parts to what I need.
The pool pump is NOT directly controlled by a switch on the PE653 meaning I don’t hit “1” for example to activate the pump. Instead, I go to the PE953 remote unit and Navigate to a secondary screen that allows me to choose my pump speed. This is important because the pump must run at a certain speed in order to create enough flow to turn on the pool heater. For instance, if I could set the temperature of the pool to 80 degrees, it would be useless to do so unless I can turn the pool pump on to pump water through the heater and back through the pool.
One thought I did have (which I will really have to try out) is to experiment with the PE953 remote unit and create scenes for the remote itself. For example, create a scene on my remote control unit that will turn on the pool pump and the heater and then find a way to get that scene from the pool remote to the Smartthings Hub.
Has anyone in here had any thoughts or experience with operating a z-wave remote control and copying the controls over to another device?
If this all works it will be pretty EPIC!
@JDogg016 It’s possible the Intermatic PE953 could be configured as a secondary controller. Take a look at the instructions about the Intermatic HA07/HA09 here for setup ideas.
@matt_coulter Because your family is in the business, could you please explain whether I need a separate “expansion module” or “load center” like Intermatic sells in this package? How would the actuators otherwise be wired if those items are not necessary? Thanks so much for the clarification! Once I get my hands on one of these, I’ll be much more likely to assist here.
This is a great update. I was able to make the PE953 a secondary controller which is good because I am having all sorts of issues working with @bigpunk6 device type code (they’re are my issues regarding lack of programming ability and not his). Anyway, a few more thoughts
Switch 4 controls my light and it is nice to see that switch on the main screen however I cannot automate this switch (ie. turn off ‘Pool Remote’ Switch 4 when I go to bed. Is there a way to do this? Perhaps creating a virtual button.
The idea of creating scenes on the remote is useless because the remote only permits you to create scenes by adding extra devices (not through the pool unit itself).
Bringing me back to square 1 which is how can a create a thermostat tile and thermostat slider and
How do I add a VSP pump to control each level of speed.
Thanks for all your input thus far! You all have been great!
Ok… i sort of tried to work with @bigpunk6 code to at least integrate the heater… so far nothing. This is what I got.
/**
http://www.apache.org/licenses/LICENSE-2.0
*/
metadata {
definition (name: “PoolSwitch”, author: “bigpunk6”) {
capability "Actuator"
capability "Switch"
capability "Polling"
capability "Configuration"
capability "Refresh"
capability "Temperature Measurement"
capability "Sensor"
capability “Thermostat”
attribute "switch1", "string"
attribute "switch2", "string"
attribute "switch3", "string"
attribute "switch4", "string"
attribute "switch5", "string"
command "onMulti"
command "offMulti"
command "on1"
command "off1"
command "on2"
command "off2"
command "on3"
command "off3"
command "on4"
command "off4"
command "on5"
command "off5"
command "poll"
}
simulator {
simulator {
status "off" : "command: 4003, payload: 00"
status "heat" : "command: 4003, payload: 01"
status "cool" : "command: 4003, payload: 02"
status "auto" : "command: 4003, payload: 03"
status "emergencyHeat" : "command: 4003, payload: 04"
status "fanAuto" : "command: 4403, payload: 00"
status "fanOn" : "command: 4403, payload: 01"
status "fanCirculate" : "command: 4403, payload: 06"
status "heat 60" : "command: 4303, payload: 01 01 3C"
status "heat 68" : "command: 4303, payload: 01 01 44"
status "heat 72" : "command: 4303, payload: 01 01 48"
status "cool 72" : "command: 4303, payload: 02 01 48"
status "cool 76" : "command: 4303, payload: 02 01 4C"
status "cool 80" : "command: 4303, payload: 02 01 50"
status "temp 58" : "command: 3105, payload: 01 22 02 44"
status "temp 62" : "command: 3105, payload: 01 22 02 6C"
status "temp 70" : "command: 3105, payload: 01 22 02 BC"
status "temp 74" : "command: 3105, payload: 01 22 02 E4"
status "temp 78" : "command: 3105, payload: 01 22 03 0C"
status "temp 82" : "command: 3105, payload: 01 22 03 34"
status "idle" : "command: 4203, payload: 00"
status "heating" : "command: 4203, payload: 01"
status "cooling" : "command: 4203, payload: 02"
status "fan only" : "command: 4203, payload: 03"
status "pending heat" : "command: 4203, payload: 04"
status "pending cool" : "command: 4203, payload: 05"
status "vent economizer": "command: 4203, payload: 06"
// reply messages
reply "2502": "command: 2503, payload: FF"
}
}
// tile definitions
tiles {
standardTile("switch1", "device.switch1",canChangeIcon: true) {
state "on", label: "switch1", action: "off1", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: "switch1", action: "on1", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
standardTile("switch2", "device.switch2",canChangeIcon: true) {
state "on", label: "switch2", action: "off2", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: "switch2", action: "on2", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
standardTile("switch3", "device.switch3",canChangeIcon: true) {
state "on", label: "switch3", action: "off3", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: "switch3", action:"on3", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
standardTile("switch4", "device.switch4",canChangeIcon: true) {
state "on", label: "switch4", action: "off4", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: "switch4", action:"on4", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
standardTile("switch5", "device.switch5",canChangeIcon: true) {
state "on", label: "switch5", action: "off5", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: "switch5", action:"on5", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
valueTile("temperature", "device.temperature", width: 2, height: 2) {
state("temperature", label:'${currentValue}°', unit:"F",
backgroundColors:[
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
)
}
standardTile("mode", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
state "off", label:'${name}', action:"switchMode"
state "heat", label:'${name}', action:"switchMode"
state "emergencyHeat", label:'${name}', action:"switchMode"
state "cool", label:'${name}', action:"switchMode"
state "auto", label:'${name}', action:"switchMode"
}
standardTile("fanMode", "device.thermostatFanMode", inactiveLabel: false, decoration: "flat") {
state "fanAuto", label:'${name}', action:"switchFanMode"
state "fanOn", label:'${name}', action:"switchFanMode"
state "fanCirculate", label:'${name}', action:"switchFanMode"
}
controlTile("heatSliderControl", "device.heatingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
state "setHeatingSetpoint", action:"thermostat.setHeatingSetpoint", backgroundColor:"#d04e00"
}
valueTile("heatingSetpoint", "device.heatingSetpoint", inactiveLabel: false, decoration: "flat") {
state "heat", label:'${currentValue}° heat', unit:"F", backgroundColor:"#ffffff"
}
controlTile("coolSliderControl", "device.coolingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
state "setCoolingSetpoint", action:"thermostat.setCoolingSetpoint", backgroundColor: "#1e9cbb"
}
valueTile("coolingSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
state "cool", label:'${currentValue}° cool', unit:"F", backgroundColor:"#ffffff"
}
standardTile("refresh", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
state "default", action:"polling.poll", icon:"st.secondary.refresh"
}
standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
}
main (["switch4"])
details(["switch1","switch2","switch3","switch4","switch5","temperature","thermostat","refresh"])
}
}
import physicalgraph.zwave.commands.*
//Parse
def parse(String description)
{
def map = createEvent(zwaveEvent(zwave.parse(description, [0x42:1, 0x43:2, 0x31:3, 0x80:1])))
if (!map) {
return null
}
def result = [map]
if (map.isStateChange && map.name in ["heatingSetpoint","coolingSetpoint","thermostatMode"]) {
def map2 = [
name: "thermostatSetpoint",
unit: "F"
]
if (map.name == "thermostatMode") {
updateState("lastTriedMode", map.value)
if (map.value == "cool") {
map2.value = device.latestValue("coolingSetpoint")
log.info "THERMOSTAT, latest cooling setpoint = ${map2.value}"
}
else {
map2.value = device.latestValue("heatingSetpoint")
log.info "THERMOSTAT, latest heating setpoint = ${map2.value}"
}
}
else {
def mode = device.latestValue("thermostatMode")
log.info "THERMOSTAT, latest mode = ${mode}"
if ((map.name == "heatingSetpoint" && mode == "heat") || (map.name == "coolingSetpoint" && mode == "cool")) {
map2.value = map.value
map2.unit = map.unit
}
}
if (map2.value != null) {
log.debug "THERMOSTAT, adding setpoint event: $map"
result << createEvent(map2)
}
} else if (map.name == "thermostatFanMode" && map.isStateChange) {
updateState("lastTriedFanMode", map.value)
}
log.debug "ParseEx returned $result"
result
}
//Reports
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def nowTime = new Date().time
state.lastBatteryGet = nowTime
def map = [ name: “battery”, unit: “%” ]
if (cmd.batteryLevel == 0xFF || cmd.batteryLevel == 0) {
map.value = 1
map.descriptionText = “$device.displayName battery is low!”
} else {
map.value = cmd.batteryLevel
}
map
}
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv3.SensorMultilevelReport cmd)
{
log.debug "SensorMultilevelReport ${cmd}"
def map = [:]
switch (cmd.sensorType) {
case 1:
// temperature
map.value = cmd.scaledSensorValue.toString()
map.unit = cmd.scale == 1 ? “F” : "C"
map.name = "temperature"
break;
case 5:
// humidity
map.value = cmd.scaledSensorValue.toInteger().toString()
map.unit = "%"
map.name = "humidity"
break;
}
map
}
def zwaveEvent(physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport cmd)
{
def map = [:]
switch (cmd.operatingState) {
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_IDLE:
map.value = "idle"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_HEATING:
map.value = "heating"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_COOLING:
map.value = "cooling"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_FAN_ONLY:
map.value = "fan only"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_PENDING_HEAT:
map.value = "pending heat"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_PENDING_COOL:
map.value = "pending cool"
break
case physicalgraph.zwave.commands.thermostatoperatingstatev1.ThermostatOperatingStateReport.OPERATING_STATE_VENT_ECONOMIZER:
map.value = "vent economizer"
break
}
map.name = "thermostatOperatingState"
map
}
def zwaveEvent(physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport cmd) {
def map = [:]
switch (cmd.mode) {
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_OFF:
map.value = "off"
break
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_HEAT:
map.value = "heat"
break
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_AUXILIARY_HEAT:
map.value = "emergencyHeat"
break
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_COOL:
map.value = "cool"
break
case physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeReport.MODE_AUTO:
map.value = "auto"
break
}
map.name = "thermostatMode"
map
}
def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport cmd) {
def map = [:]
switch (cmd.fanMode) {
case physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_AUTO_LOW:
map.value = "fanAuto"
break
case physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_LOW:
map.value = "fanOn"
break
case physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeReport.FAN_MODE_CIRCULATION:
map.value = "fanCirculate"
break
}
map.name = "thermostatFanMode"
map.displayed = false
map
}
def zwaveEvent(physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeSupportedReport cmd) {
def supportedModes = ""
if(cmd.off) { supportedModes += "off " }
if(cmd.heat) { supportedModes += "heat " }
if(cmd.auxiliaryemergencyHeat) { supportedModes += "emergencyHeat " }
if(cmd.cool) { supportedModes += "cool " }
if(cmd.auto) { supportedModes += "auto " }
updateState("supportedModes", supportedModes)
}
def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeSupportedReport cmd) {
def supportedFanModes = ""
if(cmd.auto) { supportedFanModes += "fanAuto " }
if(cmd.low) { supportedFanModes += "fanOn " }
if(cmd.circulation) { supportedFanModes += "fanCirculate " }
updateState("supportedFanModes", supportedFanModes)
}
def updateState(String name, String value) {
state[name] = value
device.updateDataValue(name, value)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
log.debug “Zwave event received: $cmd”
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
log.warn “Unexpected zwave command $cmd”
}
def zwaveEvent(sensormultilevelv1.SensorMultilevelReport cmd)
{
def map = [:]
map.value = cmd.scaledSensorValue.toString()
map.unit = cmd.scale == 1 ? “F” : "C"
map.name = "temperature"
map
}
def zwaveEvent(thermostatsetpointv2.ThermostatSetpointReport cmd)
{
def map = [:]
map.value = cmd.scaledValue.toString()
map.unit = cmd.scale == 1 ? “F” : "C"
map.displayed = false
switch (cmd.setpointType) {
case 1:
map.name = "poolSetpoint"
break;
case 7:
map.name = "spaSetpoint"
break;
default:
return [:]
}
// So we can respond with same format
state.size = cmd.size
state.scale = cmd.scale
state.precision = cmd.precision
map
}
def zwaveEvent(multichannelv3.MultiInstanceReport cmd) {
log.debug “$cmd”
}
def zwaveEvent(multichannelv3.MultiChannelCapabilityReport cmd) {
log.debug “$cmd”
}
def zwaveEvent(multichannelv3.MultiChannelEndPointReport cmd) {
log.debug “$cmd”
}
def zwaveEvent(multichannelv3.MultiInstanceCmdEncap cmd) {
log.debug "$cmd"
def map = [ name: “switch$cmd.instance” ]
if (cmd.commandClass == 37){
if (cmd.parameter == [0]) {
map.value = “off”
}
if (cmd.parameter == [255]) {
map.value = “on”
}
}
createEvent(map)
}
def zwaveEvent(multichannelv3.MultiChannelCmdEncap cmd) {
log.debug "$cmd"
def map = [ name: “switch$cmd.destinationEndPoint” ]
if (cmd.commandClass == 37){
if (cmd.parameter == [0]) {
map.value = “off”
}
if (cmd.parameter == [255]) {
map.value = “on”
}
}
createEvent(map)
}
def zwaveEvent(cmd) {
log.warn “Captured zwave command $cmd”
}
//Commands
private getBattery() { //once every 10 hours
def nowTime = new Date().time
def ageInMinutes = state.lastBatteryGet ? (nowTime - state.lastBatteryGet)/60000 : 600
log.debug "Battery report age: ${ageInMinutes} minutes"
if (ageInMinutes >= 600) {
log.debug "Fetching fresh battery value"
zwave.batteryV1.batteryGet().format()
} else “delay 87”
}
private setClock() { //once a day
def nowTime = new Date().time
def ageInMinutes = state.lastClockSet ? (nowTime - state.lastClockSet)/60000 : 1440
log.debug "Clock set age: ${ageInMinutes} minutes"
if (ageInMinutes >= 1440) {
log.debug "Setting clock"
state.lastClockSet = nowTime
def nowCal = Calendar.getInstance(TimeZone.getTimeZone(“America/New_York”));
zwave.clockV1.clockSet(hour: nowCal.get(Calendar.HOUR_OF_DAY), minute: nowCal.get(Calendar.MINUTE), weekday: nowCal.get(Calendar.DAY_OF_WEEK)).format()
} else “delay 87”
}
def setHeatingSetpoint(degreesF) {
setHeatingSetpoint(degreesF.toDouble())
}
def setHeatingSetpoint(Double degreesF) {
def p = (state.precision == null) ? 1 : state.precision
delayBetween([
zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 1, scale: 1, precision: p, scaledValue: degreesF).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format()
])
}
def setCoolingSetpoint(degreesF) {
setCoolingSetpoint(degreesF.toDouble())
}
def setCoolingSetpoint(Double degreesF) {
def p = (state.precision == null) ? 1 : state.precision
delayBetween([
zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 2, scale: 1, precision: p, scaledValue: degreesF).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format()
])
}
def configure() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSupportedGet().format(),
zwave.thermostatFanModeV3.thermostatFanModeSupportedGet().format(),
zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format()
], 2300)
}
def modes() {
[“off”, “auto”, “emergencyHeat”, “heat”, “cool”]
}
def switchMode() {
def currentMode = device.currentState(“thermostatMode”)?.value
def lastTriedMode = getDataByName(“lastTriedMode”) ?: currentMode ?: "off"
def supportedModes = getDataByName(“supportedModes”)
def modeOrder = modes()
def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
def nextMode = next(lastTriedMode)
if (supportedModes?.contains(currentMode)) {
while (!supportedModes.contains(nextMode) && nextMode != “off”) {
nextMode = next(nextMode)
}
}
switchToMode(nextMode)
}
def switchToMode(nextMode) {
def supportedModes = getDataByName(“supportedModes”)
if(supportedModes && !supportedModes.contains(nextMode)) log.warn "thermostat mode ‘$nextMode’ is not supported"
if (nextMode in modes()) {
updateState(“lastTriedMode”, nextMode)
return “$nextMode”()
} else {
log.debug(“no mode method ‘$nextMode’”)
}
}
def switchFanMode() {
def currentMode = device.currentState(“thermostatFanMode”)?.value
def lastTriedMode = getDataByName(“lastTriedFanMode”) ?: currentMode ?: "off"
def supportedModes = getDataByName(“supportedFanModes”) ?: "fanAuto fanOn"
def modeOrder = [“fanAuto”, “fanCirculate”, “fanOn”]
def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
def nextMode = next(lastTriedMode)
while (!supportedModes?.contains(nextMode) && nextMode != “fanAuto”) {
nextMode = next(nextMode)
}
switchToFanMode(nextMode)
}
def switchToFanMode(nextMode) {
def supportedFanModes = getDataByName(“supportedFanModes”)
if(supportedFanModes && !supportedFanModes.contains(nextMode)) log.warn “thermostat mode ‘$nextMode’ is not supported”
def returnCommand
if (nextMode == "fanAuto") {
returnCommand = fanAuto()
} else if (nextMode == "fanOn") {
returnCommand = fanOn()
} else if (nextMode == "fanCirculate") {
returnCommand = fanCirculate()
} else {
log.debug("no fan mode '$nextMode'")
}
if(returnCommand) updateState("lastTriedFanMode", nextMode)
returnCommand
}
def getDataByName(String name) {
state[name] ?: device.getDataValue(name)
}
def getModeMap() { [
“off”: 0,
“heat”: 1,
“cool”: 2,
“emergency heat”: 4
]}
def setThermostatMode(String value) {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: modeMap[value]).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}
def getFanModeMap() { [
“auto”: 0,
“on”: 1,
“circulate”: 6
]}
def setThermostatFanMode(String value) {
delayBetween([
zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: fanModeMap[value]).format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format()
])
}
def heat() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: 1).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}
def emergencyHeat() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: 4).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}
def cool() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: 2).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}
def auto() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSet(mode: 3).format(),
zwave.thermostatModeV2.thermostatModeGet().format()
])
}
def fanOn() {
delayBetween([
zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 1).format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format()
])
}
def fanAuto() {
delayBetween([
zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 0).format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format()
])
}
def fanCirculate() {
delayBetween([
zwave.thermostatFanModeV3.thermostatFanModeSet(fanMode: 6).format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format()
])
}
def setPoolSetpoint(degreesF) {
setHeatingSetpoint(degreesF.toDouble())
}
def setPoolSetpoint(Double degreesF) {
def p = (state.precision == null) ? 1 : state.precision
delayBetween([
zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 1, scale: 1, precision: p, scaledValue: degreesF).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format()
])
}
def setSpaSetpoint(degreesF) {
setSpaSetpoint(degreesF.toDouble())
}
def setSpaSetpoint(Double degreesF) {
def p = (state.precision == null) ? 1 : state.precision
delayBetween([
zwave.thermostatSetpointV1.thermostatSetpointSet(setpointType: 7, scale: 1, precision: p, scaledValue: degreesF).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 7).format()
])
}
def on() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: 1, destinationEndPoint: 1, commandClass:37, command:1, parameter:[255]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: 1, destinationEndPoint: 1, commandClass:37, command:2).format()
], 2300)
}
def off() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: 1, destinationEndPoint: 1, commandClass:37, command:1, parameter:[0]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: 1, destinationEndPoint: 1, commandClass:37, command:2).format()
], 2300)
}
//switch instance
def onMulti(value) {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: value, destinationEndPoint: value, commandClass:37, command:1, parameter:[255]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: value, destinationEndPoint: value, commandClass:37, command:2).format()
], 2300)
}
def offMulti(value) {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: value, destinationEndPoint: value, commandClass:37, command:1, parameter:[0]).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint: value, destinationEndPoint: value, commandClass:37, command:2).format()
], 2300)
}
//switch1
def on1() {
onMulti(1)
}
def off1() {
offMulti(1)
}
//switch2
def on2() {
onMulti(2)
}
def off2() {
offMulti(2)
}
//switch3
def on3() {
onMulti(3)
}
def off3() {
offMulti(3)
}
//switch4
def on4() {
onMulti(4)
}
def off4() {
offMulti(4)
}
//switch5
def on5() {
onMulti(5)
}
def off5() {
offMulti(5)
}
def poll() {
zwave.sensorMultilevelV1.sensorMultilevelGet().format()
}
def refresh() {
delayBetween([
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:3, destinationEndPoint:3, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:4, destinationEndPoint:4, commandClass:37, command:2).format(),
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:5, destinationEndPoint:5, commandClass:37, command:2).format(),
zwave.sensorMultilevelV1.sensorMultilevelGet().format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 7).format()
], 2500)
}
I would like to think I have no idea what I am doing.
@mbial The actuators are 24v devices. The PE953 does not have a transformer so you do currently need the P5043ME module to convert to the low voltage for the actuators. The last time I talked to an Intermatic rep, they did claim to be working on a unit that would include the transformer but I do not think that exists yet. You can get any cabinet that contains these Intermatic “clock” size modules, but you do need room for wiring and you need a separate channel for low voltage wiring to be up to code.
Hope that helps you out.
@matt_coulter - Thanks for your reply. I ended up going with the Intermatic PE24065RC package which includes the PE653, remote control, 60 amp panel, enclosure, P4043ME Actuator Control, and 2 PE24VE valve actuators for $489 total here. If anyone else is considering getting these products, I’m pretty sure this package is a great value. I’ll let you know once I have everything installed!
@mbial Yes the P4043ME is just an earlier version of the other module I believe. This kit is a good deal which is why we try to install these over Aqualinks anyway. There are single components in the Aqualinks that if you have to replace, cost more than twice of this whole kit.