@johnconstantelo I used your device drive for my HEM v1. I have not claimed the device to power line yet.
I saw these errors in the Live log:
I
@johnconstantelo I used your device drive for my HEM v1. I have not claimed the device to power line yet.
I saw these errors in the Live log:
I
I was getting the same error so I changed line 113 to the following and it worked fine.
statusTextmsg = "Home is currently using ${device.currentState('powerDisp')?.value}.\nMin was ${device.currentState('powerOne')?.value}.\nMax was ${device.currentState('powerTwo')?.value}."
Thanks @cuboy29, I updated that line in th code on Github just now.
Good catch @binhton. I actually didnāt watch the live logs all that close to see this earlier. Thanks!
How long does it take before the Min value gets updated? I have mine running all day today and itās still showing NULL. Are you guys getting the Min value?
Edit: NVM⦠it started updating the min value right after I did the reset must have not done it for awhile.
@JSCGS350 - thanks for this device type! Iām having an issue though - If I hit ārefreshā everything updates as expected, but I get no other updates⦠whether I wait hours or a day⦠it only updates the when I press ārefreshā - any thoughts? I have have changed the intervals enabled/disabled selective reporting, etc⦠but my HEM (USB powered) will only send out an update when prodded.
Hi @stevesell, thatās really odd. You donāt happen to have the batteries installed along with USB power? Iāve not seen your issue before, so you may want to exclude and reinclude the HEM just in case. Set your device type settings back to what I have in the Github source before doing that.
@johnconstantelo - one thing I noticed in your code - parameter 8 is size 1 according to the documentation I have, but you have it as size 2. Obviously, this isnāt causing you an issue, but thought I should let you know.
@johnconstantelo, I am using the battery powered one with ur device typeā¦Is there way to get battery level reporting?
Thanks
Just realized for severely degraded the performance is with running on batteries, need to figure out how to wire this inside the circuit breaker!!
If anyone here has done this, then any sort of guidance will be helpful and a picture will be greatā¦Reading through the install documentation provided in one the above posts in the mean time!
Iāve made some modifications to this great device type by @johnconstantelo including the parameter 8 size fix.
DrShaw changes:
If youāre interested:
/**
* Aeon HEM12
*
* 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.
*
* Aeon Home Energy Meter v1 (US)
*
* DrShaw Modifications: Updated configuration settings and tiles
*/
metadata {
definition (name: "My Aeon Home Energy Monitor v2", namespace: "jscgs350", author: "SmartThings")
{
capability "Energy Meter"
capability "Power Meter"
capability "Configuration"
capability "Sensor"
capability "Refresh"
capability "Polling"
capability "Battery"
attribute "energy", "string"
attribute "energyDisp", "string"
attribute "energyOne", "string"
attribute "energyTwo", "string"
attribute "power", "string"
attribute "powerDisp", "string"
attribute "powerOne", "string"
attribute "powerTwo", "string"
command "reset"
command "configure"
command "resetmaxmin"
fingerprint deviceId: "0x2101", inClusters: " 0x70,0x31,0x72,0x86,0x32,0x80,0x85,0x60"
}
// tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"powerDisp", type: "lighting", width: 6, height: 4, decoration: "flat", canChangeIcon: true){
tileAttribute ("device.powerDisp", key: "PRIMARY_CONTROL") {
attributeState "default", action: "refresh", label: '${currentValue}', icon: "st.switches.light.on", backgroundColor: "#79b821"
}
tileAttribute ("statusText", key: "SECONDARY_CONTROL") {
attributeState "statusText", label:'${currentValue}'
}
}
// Power row
valueTile("energyDisp", "device.energyDisp", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state("default", label: '${currentValue}', backgroundColor:"#ffffff")
}
valueTile("energyOne", "device.energyOne", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state("default", label: '${currentValue}', backgroundColor:"#ffffff")
}
valueTile("energyTwo", "device.energyTwo", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state("default", label: '${currentValue}', backgroundColor:"#ffffff")
}
// Controls row
standardTile("reset", "device.energy", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'Reset All', action:"reset", icon:"st.secondary.refresh-icon"
}
standardTile("refresh", "device.power", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}
standardTile("configure", "device.power", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "configure", label:'', action:"configure", icon:"st.secondary.configure"
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""
}
valueTile("statusText", "statusText", width: 3, height: 2, inactiveLabel: false) {
state "statusText", label:'${currentValue}', backgroundColor:"#ffffff"
}
valueTile("min", "powerOne", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'Min:\n${currentValue}', backgroundColor:"#ffffff"
}
valueTile("max", "powerTwo", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'Max:\n${currentValue}', backgroundColor:"#ffffff"
}
standardTile("resetmaxmin", "device.energy", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:'Reset Max/Min', action:"resetmaxmin", icon:"st.secondary.refresh-icon"
}
main (["powerDisp"])
details(["powerDisp", "energyDisp", "energyOne", "energyTwo", "min", "max", "refresh", "resetmaxmin", "reset", "configure"])
}
preferences {
input "kWhCost", "string", title: "\$/kWh (0.16)", defaultValue: "0.16" as String
}
}
def parse(String description) {
// log.debug "Parse received ${description}"
def result = null
def cmd = zwave.parse(description, [0x31: 1, 0x32: 1, 0x60: 3])
if (cmd) {
result = createEvent(zwaveEvent(cmd))
}
// if (result) log.debug "Parse returned ${result}"
def statusTextmsg = ""
statusTextmsg = "Home is currently using ${device.currentState('powerDisp').value}.\nMin was ${device.currentState('powerOne').value}.\nMax was ${device.currentState('powerTwo').value}."
sendEvent("name":"statusText", "value":statusTextmsg)
// log.debug statusTextmsg
return result
}
def zwaveEvent(physicalgraph.zwave.commands.meterv1.MeterReport cmd) {
//log.debug "zwaveEvent received ${cmd}"
def dispValue
def newValue
def timeString = new Date().format("yyyy-MM-dd h:mm a", location.timeZone)
if (cmd.meterType == 33) {
if (cmd.scale == 0) {
newValue = cmd.scaledMeterValue
if (newValue != state.energyValue) {
dispValue = String.format("%5.2f",newValue)+"\nkWh"
sendEvent(name: "energyDisp", value: dispValue as String, unit: "")
state.energyValue = newValue
BigDecimal costDecimal = newValue * ( kWhCost as BigDecimal)
def costDisplay = String.format("%3.2f",costDecimal)
sendEvent(name: "energyTwo", value: "Cost\n\$${costDisplay}", unit: "")
[name: "energy", value: newValue, unit: "kWh"]
}
} else if (cmd.scale == 1) {
newValue = cmd.scaledMeterValue
if (newValue != state.energyValue) {
dispValue = String.format("%5.2f",newValue)+"\nkVAh"
sendEvent(name: "energyDisp", value: dispValue as String, unit: "")
state.energyValue = newValue
[name: "energy", value: newValue, unit: "kVAh"]
}
}
else if (cmd.scale==2) {
newValue = Math.round( cmd.scaledMeterValue ) // really not worth the hassle to show decimals for Watts
if (newValue != state.powerValue) {
dispValue = newValue+"w"
sendEvent(name: "powerDisp", value: dispValue as String, unit: "")
if (newValue < state.powerLow) {
dispValue = newValue+"w"+" on "+timeString
sendEvent(name: "powerOne", value: dispValue as String, unit: "")
state.powerLow = newValue
}
if (newValue > state.powerHigh) {
dispValue = newValue+"w"+" on "+timeString
sendEvent(name: "powerTwo", value: dispValue as String, unit: "")
state.powerHigh = newValue
}
state.powerValue = newValue
[name: "power", value: newValue, unit: "W"]
}
}
}
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [:]
map.name = "battery"
map.unit = "%"
if (cmd.batteryLevel == 0xFF) {
map.value = 1
map.descriptionText = "${device.displayName} has a low battery"
map.isStateChange = true
} else {
map.value = cmd.batteryLevel
}
// log.debug map
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() {
delayBetween([
zwave.meterV2.meterGet(scale: 0).format(),
zwave.meterV2.meterGet(scale: 2).format()
])
}
def poll() {
refresh()
}
def reset() {
log.debug "${device.name} reset all values"
state.powerHigh = 0
state.powerLow = 99999
def timeString = new Date().format("yyyy-MM-dd h:mm a", location.timeZone)
sendEvent(name: "energyOne", value: "Since:\n"+timeString, unit: "")
sendEvent(name: "powerOne", value: "", unit: "")
sendEvent(name: "powerDisp", value: "", unit: "")
sendEvent(name: "energyDisp", value: "", unit: "")
sendEvent(name: "energyTwo", value: "Cost\n--", unit: "")
sendEvent(name: "powerTwo", value: "", unit: "")
// No V1 available
def cmd = delayBetween( [
zwave.meterV2.meterReset().format(),
zwave.meterV2.meterGet(scale: 0).format()
])
cmd
}
def resetmaxmin() {
log.debug "${device.name} reset max/min values"
state.powerHigh = 0
state.powerLow = 99999
sendEvent(name: "powerOne", value: "", unit: "")
sendEvent(name: "powerTwo", value: "", unit: "")
refresh()
}
def configure() {
def cmd = delayBetween([
zwave.configurationV1.configurationSet(parameterNumber: 3, size: 1, scaledConfigurationValue: 0).format(), // Disable selective reporting, so always update based on schedule below <set to 1 to reduce network traffic>
zwave.configurationV1.configurationSet(parameterNumber: 4, size: 2, scaledConfigurationValue: 50).format(), // (DISABLED by first option) Don't send unless watts have changed by 50 <default>
zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: 10).format(), // (DISABLED by first option) Or by 10% <default>
zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 4).format(), // Combined energy in Watts
zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 15).format(), // Every 15 Seconds (for Watts)
zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 8).format(), // Combined energy in kWh
zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 60).format(), // every 60 seconds (for kWh)
zwave.configurationV1.configurationSet(parameterNumber: 103, size: 4, scaledConfigurationValue: 0).format(), // Disable report 3
zwave.configurationV1.configurationSet(parameterNumber: 113, size: 4, scaledConfigurationValue: 0).format() // Disable report 3
])
log.debug cmd
cmd
}
Well done @drshaw, thanks for your contributions! Thatās what this community is all about. Too bad iOS and Android differences needed to be addressed, but none the less Iāll update my code on Github with yours.
I see in the description that you mention the v2 of the device so you also updated it to work with both HEM v1 and v2 or only v2?
This is version 2 of the device type for version 1 of the HEM that uses the new attributeTile code and tile formatting. It really should say Aeon HEM1 instead of Aeon HEM12, but thatās how I found the original way back when I first got the device last year. It does say Aeon Home Energy Meter v1 (US) further into the codeās comments.
Iām so glad the v1 of HEM is getting love via this thread!
Just in case anyone is searching for help on this in the future⦠somehow during the process of moving my HEM from hub v1 to hub v2 (and simultaneously switching the device type from one I hacked earlier to this one by John) the thing just stopped reporting. The only way to get it to report was to send it a ārefreshā command. I finally had to do a factory reset and re-add it my system. The factory reset was hard for me to find how to do So hereās how:
Also - Here is the only place I could find what appears to be the correct technical specification document (for programming). Engineering Spec - Aeon Labs Home Energy Monitor.pdf - And even at that it appears to be cached by google.
I put the meter clamps in my main box over the weekend. The device works and displays all of the numbers. I donāt know how accurate it is. One thing I notice so far. Since I put this device in the Garage Room in ST app, it floods the Recently tab with all of the messages when it reports the numbers. I may have to create a separate room just to put this device in. However, it will still fill the Activity Feed tab in the Notification page. Is there a way not to display all of these messages? If we increase how often it reports, let say 1min, then it becomes less accurate in measurement of total kWh and cost? Does it report every 15 seconds now?
You can adjust the reporting frequency by adjusting these lines of the code. After adjusting, you need to āPublish For Meā in the IDE, then open up the device in the ST mobile app, and press āConfigureā which will apply your changes to the HEM device.
If youāre using my version, then yes, right now it reports every 15 seconds. By changing the first parameter below to 1, you can make it only report based on certain threshold changes (open 2 and 3), or just change option 5 for frequency on total watts, and Option 7 for frequency on KWH.
Iām not positive, but I think it works like this: If you adjust them to, say once per minute or even once every 5 minutes, it wonāt be āless accurateā. It will just push the information to you less frequently. But I think the device stores the running total of kwh (up until you reset it). And the total watts information, at a glance, may be 1-5 minutes old unless you manually refresh it by clicking the green light-icon, or pushing the refresh tile. The reason you do it every 15 seconds, like I do, is if you are pulling that information out to run data analytic type stuff on the energy usage of you home. Say to something like PlotWatt (as weāve talked about earlier in this thread, or you can search the forums for cool smart apps that will push your HEM readings to it) or GroveStreams etc⦠where pushing them your readings as frequently as you can helps plot and track usage, patterns, spikes, etc⦠so you can start to understand where energy is going in your house.
But maybe there is a way that Iām not aware of (Iām new to this), that lets you get readings, without flooding the Activity Feed? @johnconstantelo may know.
def configure() {
def cmd = delayBetween([
zwave.configurationV1.configurationSet(parameterNumber: 3, size: 1, scaledConfigurationValue: 0).format(), // Disable selective reporting, so always update based on schedule below <set to 1 to reduce network traffic>
zwave.configurationV1.configurationSet(parameterNumber: 4, size: 2, scaledConfigurationValue: 50).format(), // (DISABLED by first option) Don't send unless watts have changed by 50 <default>
zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: 10).format(), // (DISABLED by first option) Or by 10% <default>
zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 4).format(), // Combined energy in Watts
zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 15).format(), // Every 15 Seconds (for Watts)
zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 8).format(), // Combined energy in kWh
zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 60).format(), // every 60 seconds (for kWh)
zwave.configurationV1.configurationSet(parameterNumber: 103, size: 4, scaledConfigurationValue: 0).format(), // Disable report 3
zwave.configurationV1.configurationSet(parameterNumber: 113, size: 4, scaledConfigurationValue: 0).format() // Disable report 3
])
Thanks. I adjusted the frequency on Watts to 60 seconds, and KHW to 180 seconds. I checked the Activity Feed and saw correct update frequency. However, for every Watt update, there are 3 entries in the Feed: 1 for statusText, other 2 are power disp. Are they from sendEvent?
Just picked up an Aeon HEM and was going to install it, but I want to make sure I do it correctly. When I removed the cover from my breaker panel, I was expecting to see some shielded wires to attach to, but I donāt have any. Would I hook a clamp on the two metal pieces I have marked in the following image? Obviously after I shut off the main breaker right above them.
Thanks for your help.
Looks like thatās the right location but Canāt tell how high the bars are, it may be impossible to fit a rigid CT there. Otherwise youād have to put them on the feeders under the guard, which are always live, and thatās a fine way to electrocute yourself.
Do you have a meter to check your conditions? Donāt assume switches grounds breakers.