I had browsed around at different laundry solutions and ultimately couldn’t find one that worked good for me. The first I tried was a multi sensor but the washer nor dryer shook enough to trigger it unless I put it inside the dryer on the drum… Funny cause I remembered those things being way more sensitive than that so I wonder if they have decreased the sensitivity with firmware over time? Anyways for list of wants I had for this project.
- I wanted continuing notifications until the laundry was attended to at set intervals
- I wanted it to arm and disarm the continuing notifications automatically
- I didn’t want to open up or alter the chord or anything warranty voiding electrical manipulation on my new washer and dryer.
- I wanted the devices in smartthings to look like they were specific to a washer and dryer
- I wanted power monitoring for curiosity sake
With all that in mind I settled on the following hardware approach…
For the washer:
- A smarthtings outlet (any power monitoring outlet would do with some editing of the device handler)
- A xiaomi contact sensor again any would work these things are just like 5 bucks and super small
For the dryer:
- Aeon home energy monitor. (this was a good way to monitor a 240 volt appliance)
- Another contact sensor for the dryer door
I was able to find one device handler for the aeon that did both a washer and a dryer but it killed the accurate power monitoring and it required device modifications on the washer and dryer. Plus it was set up to do both a washer and a dryer and I wanted to just have the dryer with power monitoring. With that in mind I set out to make my own. I edited the popular device handler created by jscgs350 that has tons of good customizing options for the HEM to basically have the functionality of a dryer. I then did the same thing with stock device handler for the smartthings outlet and I just removed the plug functions since I couldn’t see a use and I just wanted to keep the plug hot all the time. The washer plugs right into the smartthings plug and they HEM for the dryer I just put out in my electrical panel where the wires leave the breaker. The door sensors on each of the washer and dryer doors to cancel the continuing alerts. The Whole schebang is then tied together with a webcore piston.
Some pics
The device handlers… Once installed change the trip point of the waher and dryer to a good value for your setup using the settings cog in the smartthings mobile app. I found sometimes my energy efficient washer will drop to no electrical load for a couple minutes at a time here and there which is why my webcore piston factors in some delays to start and send the notifications.
washer
/*
* 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.
*/
metadata {
// Automatically generated. Make future change here.
definition(name: "WasherSTOutlet", namespace: "Brennon's Apps", author: "bscuderi", ocfDeviceType: "oic.d.smartplug") {
capability "Power Meter"
capability "Refresh"
capability "Sensor"
// removed capabilities for device health and swith and added attribute washer status
attribute "washerstatus", "enum"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3200", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3200-Sgb", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "4257050-RZHAC", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 000F, 0B04", outClusters: "0019", manufacturer: "SmartThings", model: "outletv4", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019"
}
// simulator metadata
simulator {
}
preferences {
section {
image(name: 'educationalcontent', multiple: true, images: [
"http://cdn.device-gse.smartthings.com/Outlet/US/OutletUS1.jpg",
"http://cdn.device-gse.smartthings.com/Outlet/US/OutletUS2.jpg"
])
}
// ask for desired trippoint on settings page
input "trippoint", "number", title: "washer on trip point", defaultValue: 9, required: true, displayDuringSetup: true
}
// UI tile definitions
tiles(scale: 2) {
multiAttributeTile(name: "main", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
tileAttribute("device.washerstatus", key: "PRIMARY_CONTROL") {
attributeState "on", label: 'Washing', icon: "st.Appliances.appliances8", backgroundColor: "#0000FF"
attributeState "off", label: 'Off', icon: "st.Appliances.appliances8", backgroundColor: "#ffffff"
}
tileAttribute("power", key: "SECONDARY_CONTROL") {
attributeState "power", label: '${currentValue} W'
}
}
standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label: '', action: "refresh.refresh", icon: "st.secondary.refresh"
}
main "main"
details(["main", "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 == "power") {
def value = (event.value as Integer) / 10
// change washer status to on if power goes > trippoint
if (value >= trippoint){
sendEvent(name: 'washerstatus', value: 'on')
}
// change washer status to off if power goes < trippoint
if (value <= trippoint){
sendEvent(name: 'washerstatus', value: 'off')
}
event = createEvent(name: event.name, value: value, descriptionText: '{{ device.displayName }} power is {{ value }} Watts', translatable: true)
}
}
return event ? createEvent(event) : event
}
def refresh() {
zigbee.electricMeasurementPowerRefresh()
}
// added to define and store data for washer status
def updated() {
log.debug "Updated !"
state.washerstatus = 1
log.debug "device.washerstatus: ${device.washerstatus}"
}
Dryer
// created as a spinoff from jscgs350's device typr for version 1 adapted to just show my dryer as a switch running or not
metadata {
definition (name: "Dryer Energy Monitor", namespace: "Brennon's Apps", author: "bscuderi")
{
capability "Energy Meter"
capability "Power Meter"
capability "Configuration"
capability "Sensor"
capability "Refresh"
capability "Polling"
capability "Battery"
// capability "Health Check"
attribute "currentKWH", "string" // Used to show current kWh since last reset
attribute "currentWATTS", "string" // Used to show current watts being used on the main tile
attribute "minWATTS", "string" // Used to store/display minimum watts used since last reset
attribute "maxWATTS", "string" // Used to store/display maximum watts used since last reset
attribute "resetMessage", "string" // Used for messages of what was reset (min, max, energy, or all values)
attribute "kwhCosts", "string" // Used to show energy costs since last reset
attribute "batteryStatus", "string"
attribute "kWhLastReset", "number"
attribute "CostLastReset", "number"
attribute "dryerstatus", "enum" // added for mock dryer capability
command "resetkwh"
command "resetmin"
command "resetmax"
command "resetMeter"
fingerprint deviceId: "0x2101", inClusters: " 0x70,0x31,0x72,0x86,0x32,0x80,0x85,0x60"
}
// tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"main", type: "lighting", width: 6, height: 4, decoration: "flat"){
tileAttribute ("device.dryerstatus", key: "PRIMARY_CONTROL") {
attributeState "on", label: "Drying", icon: "st.Appliances.appliances1", backgroundColor: "#FF0000"
attributeState "off", label: "Off", icon: "st.Appliances.appliances1", backgroundColor: "#ffffff"
}
tileAttribute ("device.currentWATTS", key: "SECONDARY_CONTROL") {
attributeState "default", label: '${currentValue}W', icon: "https://raw.githubusercontent.com/constjs/jcdevhandlers/master/img/device-activity-tile@2x.png"
}
}
standardTile("iconTile", "iconTile", inactiveLabel: false, width: 1, height: 1) {
state "default", icon:"https://raw.githubusercontent.com/constjs/jcdevhandlers/master/img/device-activity-tile@2x.png"
}
valueTile("statusText", "statusText", inactiveLabel: false, decoration: "flat", width: 5, height: 1) {
state "statusText", label:'${currentValue}', backgroundColor:"#ffffff"
}
valueTile("resetMessage", "device.resetMessage", width: 5, height: 1, inactiveLabel: false, decoration: "flat") {
state("default", label: '${currentValue}', backgroundColor:"#ffffff")
}
valueTile("currentKWH", "device.currentKWH", width: 3, height: 1, inactiveLabel: false, decoration: "flat") {
state("default", action: "refresh", label: '${currentValue}', backgroundColor:"#ffffff")
}
valueTile("kwhCosts", "device.kwhCosts", width: 3, height: 1, inactiveLabel: false, decoration: "flat") {
state("default", label: 'Cost ${currentValue}', backgroundColor:"#ffffff")
}
standardTile("resetmin", "device.resetmin", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'Reset Min', action:"resetmin", icon:"st.secondary.refresh-icon"
}
standardTile("resetmax", "device.resetmax", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'Reset Max', action:"resetmax", icon:"st.secondary.refresh-icon"
}
standardTile("resetkwh", "device.resetkwh", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'Reset Energy', action:"resetkwh", icon:"st.secondary.refresh-icon"
}
standardTile("refresh", "device.refresh", width: 3, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'Refresh', action:"refresh", icon:"st.secondary.refresh-icon"
}
standardTile("configure", "device.configure", width: 3, height: 2, inactiveLabel: false, decoration: "flat") {
state "configure", label:'', action:"configure", icon:"st.secondary.configure"
}
valueTile("history", "device.history", decoration:"flat",width: 6, height: 2) {
state "history", label:'${currentValue}'
}
details(["main", "currentKWH", "kwhCosts", "history", "resetmin", "resetmax", "resetkwh", "refresh", "configure"])
}
preferences {
// added trippoint setting
input "trippoint", "number", title: "dryer on trip point", defaultValue: 30, required: true, displayDuringSetup: true
input "displayEvents", "boolean", title: "Display all power and energy events in the Recently tab and the device's event log?", defaultValue: false, required: false, displayDuringSetup: true
input "displayBatteryLevel", "boolean", title: "Display battery level on main tile and Recently tab?", defaultValue: true, required: false, displayDuringSetup: true
input "kWhCost", "string", title: "Enter your cost per kWh (or just use the default, or use 0 to not calculate):", defaultValue: 0.16, required: false, displayDuringSetup: true
input "wattsLimit", "number", title: "Sometimes the HEM will send a wildly large watts value. What limit should be in place so that it's not processed? (in watts)", defaultValue: 20000, required: false, displayDuringSetup: true
input "reportType", "number", title: "ReportType: Send watt/kWh data on a time interval (0), or on a change in wattage (1)? Enter a 0 or 1:", defaultValue: 1, range: "0..1", required: false, displayDuringSetup: true
input "wattsChanged", "number", title: "For ReportType = 1, Don't send unless watts have changed by this many watts: (range 0 - 32,000W)", defaultValue: 50, range: "0..32000", required: false, displayDuringSetup: true
input "wattsPercent", "number", title: "For ReportType = 1, Don't send unless watts have changed by this percent: (range 0 - 99%)", defaultValue: 10, range: "0..99", required: false, displayDuringSetup: true
input "secondsWatts", "number", title: "For ReportType = 0, Send Watts data every how many seconds? (range 0 - 65,000 seconds)", defaultValue: 15, range: "0..65000", required: false, displayDuringSetup: true
input "secondsKwh", "number", title: "For ReportType = 0, Send kWh data every how many seconds? (range 0 - 65,000 seconds)", defaultValue: 60, range: "0..65000", required: false, displayDuringSetup: true
input "secondsBattery", "number", title: "If the HEM has batteries installed, send battery data every how many seconds? (range 0 - 65,000 seconds)", defaultValue: 900, range: "0..65000", required: false, displayDuringSetup: true
input "decimalPositions", "number", title: "How many decimal positions do you want watts AND kWh to display? (range 0 - 3)", defaultValue: 3, range: "0..3", required: false, displayDuringSetup: true
}
}
def updated() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
state.displayDisabled = ("true" == displayEvents)
state.displayBattery = ("true" == displayBatteryLevel)
log.debug "updated (kWhCost: ${kWhCost}, wattsLimit: ${wattsLimit}, reportType: ${reportType}, wattsChanged: ${wattsChanged}, wattsPercent: ${wattsPercent}, secondsWatts: ${secondsWatts}, secondsKwh: ${secondsKwh}, secondsBattery: ${secondsBattery}, decimalPositions: ${decimalPositions})"
// add dryer capability a place to store info
state.dryerstatus = 1
log.debug "device.dryerstatus: ${device.dryerstatus}"
//
response(configure())
}
def parse(String description) {
// log.debug "Parse received ${description}"
def result = null
def cmd = zwave.parse(description, [0x31: 1, 0x32: 1, 0x60: 3, 0x80: 1])
// log.debug "Parse returned ${cmd}"
if (cmd) {
result = createEvent(zwaveEvent(cmd))
}
// if (result) log.debug "Result returned ${result}"
if (state.displayBattery) {
def batteryStatusmsg = "USB power, batteries at ${device.currentState('battery')?.value}%"
sendEvent(name: "batteryStatus", value: batteryStatusmsg, displayed: false)
} else {
def batteryStatusmsg = "USB power"
sendEvent(name: "batteryStatus", value: batteryStatusmsg, displayed: false)
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.meterv1.MeterReport cmd) {
def dispValue
def newValue
def switchValue
def timeString = new Date().format("MM-dd-yy h:mm a", location.timeZone)
if (cmd.meterType == 33) {
if (cmd.scale == 0) {
newValue = cmd.scaledMeterValue
// log.debug "newValue is ${newValue} and prevValue is ${state.energyValue}"
if (newValue != state.energyValue) {
if (decimalPositions == 2) {
dispValue = String.format("%3.2f",newValue)
} else if (decimalPositions == 1) {
dispValue = String.format("%3.1f",newValue)
} else if (decimalPositions == 0) {
dispValue = Math.round(cmd.scaledMeterValue)
} else {
dispValue = String.format("%3.3f",newValue) // default
}
dispValue += " kWh"
sendEvent(name: "currentKWH", value: dispValue as String, unit: "", displayed: false)
state.energyValue = newValue
BigDecimal costDecimal = newValue * (kWhCost as BigDecimal)
def costDisplay = "\$"
costDisplay += String.format("%3.2f",costDecimal)
sendEvent(name: "kwhCosts", value: costDisplay as String, unit: "", displayed: false)
if (state.displayDisabled) {
[name: "energy", value: newValue, unit: "kWh", displayed: true]
} else {
[name: "energy", value: newValue, unit: "kWh", displayed: false]
}
}
} else if (cmd.scale == 1) {
newValue = cmd.scaledMeterValue
if (newValue != state.energyValue) {
dispValue = newValue + " kVAh"
sendEvent(name: "currentKWH", value: dispValue as String, unit: "", displayed: false)
state.energyValue = newValue
if (state.displayDisabled) {
[name: "energy", value: newValue, unit: "kVAh", displayed: true]
} else {
[name: "energy", value: newValue, unit: "kVAh", displayed: false]
}
}
}
else if (cmd.scale==2) {
newValue = cmd.scaledMeterValue // Remove all rounding
if (newValue < 0) {newValue = state.powerValue} // Don't want to see negative numbers as a valid minimum value (something isn't right with the meter) so use the last known good meter reading
if (newValue < wattsLimit) { // don't handle any wildly large readings due to firmware issues
if (newValue != state.powerValue) { // Only process a meter reading if it isn't the same as the last one
if (decimalPositions == 2) {
dispValue = String.format("%3.2f",newValue)
} else if (decimalPositions == 1) {
dispValue = String.format("%3.1f",newValue)
} else if (decimalPositions == 0) {
dispValue = Math.round(cmd.scaledMeterValue)
} else {
dispValue = String.format("%3.3f",newValue) // default
}
if (newValue < state.powerLow) {
def dispLowValue = dispValue+"w on "+timeString
sendEvent(name: "minWATTS", value: dispLowValue as String, unit: "", displayed: false)
state.powerLow = newValue
def historyDisp = ""
historyDisp = "Minimum/Maximum Readings as of ${timeString}\n------------------------------------------------------\nPower Low : ${device.currentState('minWATTS')?.value}\nPower High : ${device.currentState('maxWATTS')?.value}\nMessages : ${device.currentState('resetMessage')?.value}"
sendEvent(name: "history", value: historyDisp, displayed: false)
}
if (newValue > state.powerHigh) {
def dispHighValue = dispValue+"w on "+timeString
def historyDisp = ""
sendEvent(name: "maxWATTS", value: dispHighValue as String, unit: "", displayed: false)
state.powerHigh = newValue
historyDisp = "Minimum/Maximum Readings as of ${timeString}\n------------------------------------------------------\nPower Low : ${device.currentState('minWATTS')?.value}\nPower High : ${device.currentState('maxWATTS')?.value}\nMessages : ${device.currentState('resetMessage')?.value}"
sendEvent(name: "history", value: historyDisp, displayed: false)
}
////////// //Dryer on or off
if (newValue >= trippoint){
sendEvent(name: 'dryerstatus', value: 'on')
}
if (newValue <= trippoint){
sendEvent(name: 'dryerstatus', value: 'off')
}
sendEvent(name: "currentWATTS", value: dispValue as String, unit: "", displayed: false)
state.powerValue = newValue
if (state.displayDisabled) {
[name: "power", value: newValue, unit: "W", displayed: true]
} else {
[name: "power", value: newValue, unit: "W", displayed: false]
}
}
}
}
}
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
if (state.displayBattery) {
def map = [:]
map.name = "battery"
map.unit = "%"
map.displayed = true
if (cmd.batteryLevel == 0xFF) { // low battery message from device
map.value = 1
map.isStateChange = true
} else {
map.value = cmd.batteryLevel
map.isStateChange = true
}
sendEvent(name: "battery", value: map.value as String, displayed: true)
return map
} else {
def map = [:]
map.name = "battery"
map.unit = "%"
map.value = 99
map.displayed = false
map.isStateChange = true
sendEvent(name: "battery", value: map.value as String, displayed: false)
return map
}
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
log.debug "Unhandled event ${cmd}"
[:]
}
def refresh() {
log.debug "Refreshed ${device.name}"
state.energyValue = -1 // force tile update
state.powerValue = -1
delayBetween([
zwave.meterV2.meterGet(scale: 0).format(),
zwave.meterV2.meterGet(scale: 2).format()
])
}
def poll() {
refresh()
}
// PING is used by Device-Watch in attempt to reach the Device
def ping() {
refresh()
}
def resetkwh() {
log.debug "${device.name} reset kWh/Cost values"
def timeString = new Date().format("MM-dd-yy h:mm a", location.timeZone)
def resetDisp = ""
resetDisp = "kWh value at time of last reset was ${device.currentState('currentKWH')?.value}"
sendEvent(name: "kWhLastReset", value: resetDisp, displayed: true)
resetDisp = "Costs at time of last reset was ${device.currentState('kwhCosts')?.value}"
sendEvent(name: "CostLastReset", value: resetDisp, displayed: true)
def historyDisp = ""
sendEvent(name: "resetMessage", value: "Energy Data (kWh/Cost) Reset On:\n"+timeString, unit: "", displayed: true)
sendEvent(name: "currentKWH", value: "", unit: "", displayed: false)
sendEvent(name: "kwhCosts", value: "", unit: "", displayed: false)
historyDisp = "Minimum/Maximum Readings as of ${timeString}\n------------------------------------------------------\nPower Low : ${device.currentState('minWATTS')?.value}\nPower High : ${device.currentState('maxWATTS')?.value}\nMessages : ${device.currentState('resetMessage')?.value}"
sendEvent(name: "history", value: historyDisp, displayed: false)
state.energyValue = 0
def cmd = delayBetween( [
zwave.meterV2.meterReset().format(),
zwave.meterV2.meterGet(scale: 0).format(),
zwave.meterV2.meterGet(scale: 2).format()
])
cmd
}
def resetmin() {
log.debug "${device.name} reset minimum watts value"
def historyDisp = ""
state.powerLow = 99999
def timeString = new Date().format("MM-dd-yy h:mm a", location.timeZone)
sendEvent(name: "resetMessage", value: "Watts Data Minimum Value Reset On:\n"+timeString, unit: "")
sendEvent(name: "minWATTS", value: "", unit: "", displayed: false)
historyDisp = "Minimum/Maximum Readings as of ${timeString}\n------------------------------------------------------\nPower Low : ${device.currentState('minWATTS')?.value}\nPower High : ${device.currentState('maxWATTS')?.value}\nMessages : ${device.currentState('resetMessage')?.value}"
sendEvent(name: "history", value: historyDisp, displayed: false)
def cmd = delayBetween( [
zwave.meterV2.meterGet(scale: 0).format(),
zwave.meterV2.meterGet(scale: 2).format()
])
cmd
}
def resetmax() {
log.debug "${device.name} reset maximum watts value"
def historyDisp = ""
state.powerHigh = 0
def timeString = new Date().format("MM-dd-yy h:mm a", location.timeZone)
sendEvent(name: "resetMessage", value: "Watts Data Maximum Value Reset On:\n"+timeString, unit: "")
sendEvent(name: "maxWATTS", value: "", unit: "", displayed: false)
historyDisp = "Minimum/Maximum Readings as of ${timeString}\n------------------------------------------------------\nPower Low : ${device.currentState('minWATTS')?.value}\nPower High : ${device.currentState('maxWATTS')?.value}\nMessages : ${device.currentState('resetMessage')?.value}"
sendEvent(name: "history", value: historyDisp, displayed: false)
def cmd = delayBetween( [
zwave.meterV2.meterGet(scale: 0).format(),
zwave.meterV2.meterGet(scale: 2).format()
])
cmd
}
def resetMeter() {
log.debug "Resetting all home energy meter values..."
def resetDisp = ""
resetDisp = "kWh value at time of last reset was ${device.currentState('currentKWH')?.value}"
sendEvent(name: "kWhLastReset", value: resetDisp, displayed: true)
resetDisp = "Costs at time of last reset was ${device.currentState('kwhCosts')?.value}"
sendEvent(name: "CostLastReset", value: resetDisp, displayed: true)
def historyDisp = ""
state.powerHigh = 0
state.powerLow = 99999
state.energyValue = 0
sendEvent(name: "minWATTS", value: "", unit: "", displayed: false)
sendEvent(name: "maxWATTS", value: "", unit: "", displayed: false)
sendEvent(name: "currentKWH", value: "", unit: "", displayed: false)
sendEvent(name: "kwhCosts", value: "Cost\n--", unit: "", displayed: false)
def timeString = new Date().format("MM-dd-yy h:mm a", location.timeZone)
sendEvent(name: "resetMessage", value: "HEM was reset on "+timeString, unit: "", displayed: true)
historyDisp = "Minimum/Maximum Readings as of ${timeString}\n------------------------------------------------------\nPower Low : ${device.currentState('minWATTS')?.value}\nPower High : ${device.currentState('maxWATTS')?.value}\nMessages : ${device.currentState('resetMessage')?.value}"
sendEvent(name: "history", value: historyDisp, displayed: false)
def cmd = delayBetween( [
zwave.meterV2.meterReset().format(),
zwave.meterV2.meterGet(scale: 0).format(),
zwave.meterV2.meterGet(scale: 2).format()
])
cmd
}
def configure() {
log.debug "${device.name} configuring..."
def cmd = delayBetween([
// Perform a complete factory reset. Use this all by itself and comment out all others below.
// Once reset, comment this line out and uncomment the others to go back to normal
// zwave.configurationV1.configurationSet(parameterNumber: 255, size: 4, scaledConfigurationValue: 1).format()
// Accumulate kWh energy when Battery Powered. By default this is disabled to assist saving battery power. (0 == disable, 1 == enable)
zwave.configurationV1.configurationSet(parameterNumber: 12, size: 1, scaledConfigurationValue: 1).format(),
// Send data based on a time interval (0), or based on a change in wattage (1). 0 is default and enables parameters 111, 112, and 113. 1 enables parameters 4 and 8.
zwave.configurationV1.configurationSet(parameterNumber: 3, size: 1, scaledConfigurationValue: reportType).format(),
// If parameter 3 is 1, don't send unless watts have changed by 50 <default> for the whole device.
zwave.configurationV1.configurationSet(parameterNumber: 4, size: 2, scaledConfigurationValue: wattsChanged).format(),
// If parameter 3 is 1, don't send unless watts have changed by 10% <default> for the whole device.
zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: wattsPercent).format(),
// Defines the type of report sent for Reporting Group 1 for the whole device. 1->Battery Report, 4->Meter Report for Watt, 8->Meter Report for kWh
zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 4).format(), //watts
// If parameter 3 is 0, report every XX Seconds (for Watts) for Reporting Group 1 for the whole device.
zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: secondsWatts).format(),
// Defines the type of report sent for Reporting Group 2 for the whole device. 1->Battery Report, 4->Meter Report for Watt, 8->Meter Report for kWh
zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 8).format(), //kWh
// If parameter 3 is 0, report every XX seconds (for kWh) for Reporting Group 2 for the whole device.
zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: secondsKwh).format(),
// Defines the type of report sent for Reporting Group 3 for the whole device. 1->Battery Report, 4->Meter Report for Watt, 8->Meter Report for kWh
zwave.configurationV1.configurationSet(parameterNumber: 103, size: 4, scaledConfigurationValue: 1).format(), //battery
// If parameter 3 is 0, report every XX seconds (for battery) for Reporting Group 2 for the whole device.
zwave.configurationV1.configurationSet(parameterNumber: 113, size: 4, scaledConfigurationValue: secondsBattery).format()
])
cmd
}
Webcore Piston
**edited this part cause I found an error. here’s the new one so it doesn’t keep notifying