Reducing power reporting noise in a device type

I was looking at the device type for power reporting items like the SmartOutlet. In the recent activity you see power reporting every few seconds and it fills up the log to the point where you can’t use that activity log to see the last few times something was switched on or off.

I had an idea, to throttle the reporting in the log based on the % of change. So only log the power consumption when it changes by enough that I care. Bonus points would be to keep the indicator on the tile “live” or as frequent as possible, and maybe even in the device configuration allow me to set the % of change that is important to me (defaulting to 25% maybe.

I went and looked at the code, and t’s not as obvious as I had hoped. I’m not sure I can control the activity separately from the display on the tile. But even skipping that, I’ve been having trouble getting my head around the groovy code and SDK.

Anybody ever done anything like this before? I’ve started and stopped a few SmartThings dev projects already, every time I either get to a point where I feel like the dev tools (i.e. simulator) don’t work so I can’t really figure things out, or the documentation is just lacking (sometimes it’s old and unclear to me).

2 Likes

It’s a great idea!

You’ll have to accept that the simulator doesn’t work for 90% of anything beyond the most basic cases, and the forum and examples are much more valuable than the Documentation.

That said, I may get a chance to make some suggestions for your code… Or others will do so soon!

I noticed this problem with a Iris Smart Plug (which uses this device type) when I was trying to log the power usage of a washing machine (into InitialState). When the washer was running, it generated nearly 4000 events in the course of 40 minutes. I started looking into having the InitialState squelch excess events, but I like your approach better (fix it at the source).

1 Like

The ZigBee power profile can be configured so that the physical device itself reports less frequently. A Community Member has already modified the stock DTH to do this. I’ve offered, but not yet followed through, on added a Preference page for this and submitting it as a Pull Request to SmartThings.

Ummm… I’m too lazy/busy to Search even, but will post a link if I find it.

I think a lower frequency is sufficient for most cases. Averaging and smoothing the data is more “accurate” (and … possible, I’m sure), but not as likely to be needed by the average consumer.

1 Like

Yes, the 0.1W reporting differential on the SmartSense/Centralite outlet is ridiculous. 1.0W default with selectable differential would be far more efficient.

I expect over-reporting by SmartSense/Centralite motion sensors is part of what causes high load at peak times. By default they report motion 3-4 times per minute - 99+% junkmail. Does each update force its smartapp(s) to pay attention?

The “Virtual Thermostat” smartapp sent an ON command for every motion update - it worked but seemed excessive.

1 Like

wait, every outlet i have is reporting that up through the internet every second?! I assumed this data was staying local. Ugh…

1 Like

Yes… That’s why the most efficient approach is to send the hardware configuration commands to the device to change the reporting frequency.

Otherwise, except for the eventual locally executing Device Type Handler, any type of filtering will put load on the cloud.

I searched the forums, and found other posts of yours on SmartPower Outlet flood feed

But there wasn’t a final resolution to it. You point out the place where the code needs to be modified, but personally I haven’t successfully made any DTH or even modifications to them. Apparently my C, PHP, and SQL programming skills simply haven’t translated to this world (I can’t seem to grasp the model yet… maybe i just haven’t devoted enough time to how the system works.)

Anyway, Github searches are pretty useless as well – if you don’t know the specific name of the project or user you’re looking for.

oh wait, I found a fix here: Smartthings Outlet Sends Notification Every Minute Or Two While On?

But that just stops the reporting from showing up in the activity feed, it doesn’t modify the granularity. Do you know where/what documentation there is for changing the granularity of reporting?

The answer is in the post below. I coded some variation of this in my test library and it works cleanly.

So if the below doesn’t help, I’ll dig up my code (or probably share it up later anyway…).

I created my own script to log to a MySQL database all power events from my 26 smart plugs and Aeon Labs power meter. After a month there are 1.8 million records! That’s just silly to move around so much data.

I’m going to try your code modifications tonight to see if they help. I really don’t care about energy changes unless they exceed 1 watt.

For the record, the Iris Smart Plugs seem to be very stable and accurate on their energy reporting. I have found that over a few minutes an air conditioner will generate hundreds of power events due to usage fluctuations, while a light bulb will generate just 1 event.

1 Like

I wasn’t able to figure out the “minimum change amount” part of the configuration, but at least could set the reporting interval.

The definition of “maximum reporting frequency” vs. “minimum” should be obvious, but… well, results aren’t always as expected.

Regardless, I hope I can still earn my “Helpful” title by sharing this commented code section below.
NB: I highly recommend adding a “Config” sub-tile to your DTH so you can call the configure() method on demand.

def configure() {
    /* Call configure using raw zdo bind and zcl clusters. */
	zigbee.onOffConfig() + powerConfig() + refresh()
    /* Call zigbee.configureReporting() method. */
    //powerConfigST() + refresh()
}

//power config for devices with min reporting interval as 1 seconds and reporting interval if no activity as 10min (600s)
//min change in value is 01
def powerConfig() {
    log.debug "powerConfig send..."
    /* Per ZigBee Cluster Library Specification, Page ~26-27 of this or later doc:
       https://people.ece.cornell.edu/land/courses/ece4760/FinalProjects/s2011/kjb79_ajm232/pmeter/ZigBee%20Cluster%20Library.pdf
    
       Direction, Attribute identifier, Attribute data type, Minimum reporting interval, Maximum reporting interval, Reportable change
    */
	[
		"zdo bind 0x${device.deviceNetworkId} 1 ${endpointId} 0x0B04 {${device.zigbeeId}} {}", "delay 200",
        /* From Forum post, 6400 / 6401 supposed to be 1 hour reporting -- but why not 2600? */
        //"zcl global send-me-a-report 0x0B04 0x050B 0x29 6400 6401 {64 0000}",	//The send-me-a-report is custom to the attribute type for CentraLite
        /* Using 120 instead of 6400 results in 2 minutes, though isn't that the min instead of max? Gotta experiment with both min and max. */
		"zcl global send-me-a-report 0x0B04 0x050B 0x29 300 300 {64 0000}",	
		"send 0x${device.deviceNetworkId} 1 ${endpointId}", "delay 500"
	]
}

def powerConfigST() {
	log.debug "powerConfigST (zigbee.configureReporting) send..."
    /* Attempting 3600 = 1 hour maximum reporting interval. 600 = Five minutes minimum reporting interval. 0 = minimum change. */
    zigbee.configureReporting(0x0B04, 0x050B, 0x29, 3600, 600, 1)
}
2 Likes

I made a version of the DTH that has preferences so you can turn logging on/off and pick how many watts of change in power you care about when it’s on. This isn’t super polished, but it seems to work for now.

Add these lines in the preferences block:

preferences {
    // ...
    // original code
    // ...
    input name: "prefLogPower", type: "bool", title: "Show power usage?", description: "", required: true
    input name: "prefLogPowerDelta", type: "decimal", title: "Only show changes over…", description: "Enter watts", required: true
}

Add these in parse()

// ...
// bunch of stuff
// ...
else if (finalResult.type == "power") {
    def powerValue = (finalResult.value as Integer)/10
    def changeValue = powerValue - state.lastPowerValue

    if (prefLogPower == true) {
        if (changeValue > prefLogPowerDelta || changeValue < -prefLogPowerDelta || powerValue == 0 || state.lastPowerValue == 0) {
            sendEvent(name: "power", value: powerValue, descriptionText: '{{ device.displayName }} power is {{ value }} Watts', translatable: true )
            state.lastPowerValue = powerValue
        }
    }
    // ...
    // only other thing here in the original code was a big comment.
    // ...
}
1 Like

Okay, I actually fixed it so the tile now reports the power usage continuously. Turning off the setting just removes the reporting from the activity feed, or restricts it to only when the power usage changes by the set amount.

6 Likes

Deleted post

I switched my power outlet to your DTH but I don’t see the option for turning on/off the power reporting. It is not reporting any power usage at this time. That is ok as I don’t really need it. Just curious about the setting.

(Putting this here for future visitors) - to implement this and fix your reporting:

  1. Go into graph and create a new device handler using the code here: https://github.com/instanttim/SmartThings/tree/master/devicetypes/instanttim/smartpower-outlet.src
  2. Edit your smartthings power outlet device and change its “type” to the new device handler (usually at the bottom of the list)
  3. Open the smartthings app and go to that device, then click the gear in the top right and you can change the settings there.
6 Likes

Took a while but finally found this. Spent several hours trying to code it myself and finally ran across your script which works perfectly.

Thank you!!!

1 Like

Thank you
did it per your instructions and it worked perfectly. now my log is is not flooded anymore and the whole system seems to run more stable

1 Like

I am having similar problem. I see the “Show power in activity” preference in Settings, however, it does not store my preference (True or False). In other words, it is disabled every time I go to Setting, even if I had set to True last time. Any thoughts?