Securifi Peanut Plug Power Meter

Ha, I don't recall how I found it, nor does power reporting work(have latest firmware
Here's the driver from same guy, can't find the link for the life of me.
Hope it helps you

metadata {
definition (name: "Peanut Plug", namespace: "pakmanwg", author: "pakmanw@sbcglobal.net", ocfDeviceType: "oic.d.switch",
vid: "generic-switch-power-energy") {
capability "Energy Meter"
capability "Actuator"
capability "Switch"
capability "Power Meter"
capability "Polling"
capability "Refresh"
capability "Configuration"
capability "Sensor"
capability "Light"
capability "Health Check"
capability "Voltage Measurement"

	attribute "current","number"

	command "reset"
   
	fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0B04, 0B05",
		outClusters: "0000, 0001, 0003, 0004, 0005, 0006, 0019, 0B04, 0B05"
}

// tile definitions
tiles {
	standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
		state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
		state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
	}
	valueTile("power", "device.power") {
		state "default", label:'${currentValue} W'
	}
	valueTile("energy", "device.energy") {
		state "default", label:'${currentValue} kWh'
	}
	valueTile("voltage", "device.voltage") {
		state "default", label:'${currentValue} V'
	}
	valueTile("current", "device.current") {
		state "default", label:'${currentValue} A'
	}
	standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat") {
		state "default", label:'reset kWh', action:"reset"
	}
	standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat") {
		state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
	}

	main(["switch","power","energy","voltage","current"])
	details(["switch","power","energy","voltage","current","refresh","reset"])
}

}

def parse(String description) {

log.debug "description is $description"
def event = zigbee.getEvent(description)
if (event) {
	if (event.name == "power") {
		def powerValue
		powerValue = (event.value as Integer) * getPowerMultiplier()
		sendEvent(name: "power", value: powerValue)
		def time = (now() - state.time) / 3600000 / 1000
		state.time = now()
		log.debug "powerValues is $state.powerValue"
		state.energyValue = state.energyValue + (time * state.powerValue)
		state.powerValue = powerValue
		// log.debug "energyValue is $state.energyValue"
		sendEvent(name: "energy", value: state.energyValue)
	} else {
		sendEvent(event)
	}
} else if (description?.startsWith("read attr -")) {
	def descMap = zigbee.parseDescriptionAsMap(description)
    log.debug "Desc Map: $descMap"
    if (descMap.clusterInt == zigbee.ELECTRICAL_MEASUREMENT_CLUSTER) {
    	def intVal = Integer.parseInt(descMap.value,16)
    	if (descMap.attrInt == 0x0600) {
        	log.debug "ACVoltageMultiplier $intVal"
            state.voltageMultiplier = intVal
        } else if (descMap.attrInt == 0x0601) {
        	log.debug "ACVoltageDivisor $intVal"
            state.voltageDivisor = intVal
        } else if (descMap.attrInt == 0x0602) {
        	log.debug "ACCurrentMultiplier $intVal"
            state.currentMultiplier = intVal
        } else if (descMap.attrInt == 0x0603) {
        	log.debug "ACCurrentDivisor $intVal"
            state.currentDivisor = intVal
        } else if (descMap.attrInt == 0x0604) {
        	log.debug "ACPowerMultiplier $intVal"
            state.powerMultiplier = intVal
        } else if (descMap.attrInt == 0x0605) {
        	log.debug "ACPowerDivisor $intVal"
            state.powerDivisor = intVal
        } else if (descMap.attrInt == 0x0505) {
            def voltageValue = intVal * getVoltageMultiplier()
            log.debug "Voltage ${voltageValue}"
            state.voltage = $voltageValue
            sendEvent(name: "voltage", value: voltageValue)
        } else if (descMap.attrInt == 0x0508) {
            def currentValue = intVal * getCurrentMultiplier()
            log.debug "Current ${currentValue}"
            state.current = $currentValue
            sendEvent(name: "current", value: currentValue)
        }
    } else {
    	log.warn "Not an electrical measurement"
    }
} else {
	log.warn "DID NOT PARSE MESSAGE for description : $description"
	log.debug zigbee.parseDescriptionAsMap(description)
}

}

def installed() {
reset()
configure()
refresh()
}

def off() {
zigbee.off()
}

def on() {
zigbee.on()
}

def refresh() {
Integer reportIntervalMinutes = 5
zigbee.onOffRefresh() +
zigbee.simpleMeteringPowerRefresh() +
zigbee.electricMeasurementPowerRefresh() +
zigbee.onOffConfig(0, reportIntervalMinutes * 60) +
zigbee.simpleMeteringPowerConfig() +
zigbee.electricMeasurementPowerConfig() +
voltageMeasurementRefresh() +
voltageMeasurementConfig() +
currentMeasurementRefresh() +
currentMeasurementConfig() +
zigbee.readAttribute(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0600) +
zigbee.readAttribute(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0601) +
zigbee.readAttribute(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0602) +
zigbee.readAttribute(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0603) +
zigbee.readAttribute(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0604) +
zigbee.readAttribute(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0605)
}

def currentMeasurementConfig(minReportTime=1, maxReportTime=600, reportableChange=0x0030) {
zigbee.configureReporting(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0508, DataType.UINT16, minReportTime, maxReportTime, reportableChange)
}

def currentMeasurementRefresh() {
zigbee.readAttribute(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0508);
}

def voltageMeasurementConfig(minReportTime=1, maxReportTime=600, reportableChange=0x0018) {
zigbee.configureReporting(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0505, DataType.UINT16, minReportTime, maxReportTime, reportableChange)
}

def voltageMeasurementRefresh() {
zigbee.readAttribute(zigbee.ELECTRICAL_MEASUREMENT_CLUSTER, 0x0505);
}

def getCurrentMultiplier() {
if (state.currentMultiplier && state.currentDivisor) {
return (state.currentMultiplier / state.currentDivisor)
} else {
return 0.001831
}
}

def getVoltageMultiplier() {
if (state.voltageMultiplier && state.voltageDivisor) {
return (state.voltageMultiplier / state.voltageDivisor)
} else {
return 0.0045777
}
}

def getPowerMultiplier() {
if (state.powerMultiplier && state.powerDivisor) {
return (state.powerMultiplier / state.powerDivisor)
} else {
return 0.277
}
}

def configure() {
log.debug "in configure()"
return configureHealthCheck()
}

def configureHealthCheck() {
Integer hcIntervalMinutes = 12
sendEvent(name: "checkInterval", value: hcIntervalMinutes * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
return refresh()
}

def updated() {
log.debug "in updated()"
// updated() doesn't have it's return value processed as hub commands, so we have to send them explicitly
def cmds = configureHealthCheck()
cmds.each{ sendHubCommand(new hubitat.device.HubAction(it)) }
}

def ping() {
return zigbee.onOffRefresh()
}

def reset() {
state.energyValue = 0.0
state.powerValue = 0.0
state.voltage = 0.0
state.current = 0.0
state.time = now()
sendEvent(name: "energy", value: state.energyValue)
}

Did it work?

I don't have a Securifi Almond to update the Peanuts with so have paused my effort on this. If I ever come across a cheapo Almond I may try to make it work.

I have a couple of Peanut Plugs and installed this driver. It works for on/off, but never seems to get any values for any of the power settings. I had a driver installed in my ST days and it was always sketchy as well. I'll keep my eye out for anything I see.

My peanut plugs are up-to-date and with the above driver. It worked perfectly on ST but not on HE. I get this on HE in the log.

warnDID NOT PARSE MESSAGE for description : read attr - raw: 91AD010B040A0505215266, dni: 91AD, endpoint: 01, cluster: 0B04, size: 0A, attrId: 0505, encoding: 21, command: 0A, value: 5266

I updated the penaut plugs using almond router/hub
using generic zigbee outlet driver, it is working so far, but the values are sometimes wrong, like 2588 watts when it's usually around 250. not sure if someone has another code that I could try

did u sort out your peanut problems?

Sorry for the late response. Never got the power reading to work. I just use the plugs for ON/OFF and repeaters.

I have taken the original SmartThings driver written by pakmanwg and ported it to Hubitat.
I modified it to make the power/voltage/current work and allow the setting of reporting criteria.

The code is on GidHub at:

Peanut Plug Driver

It appears to be working on my Hubitat including reporting of power/voltage/current.
The installation instructions are in the readme.
If you have any problems with the driver, please let me know.
Hope folks find this useful.

5 Likes

@jim1 I am assuming that if the current and voltage read 0E-10 that it needs that upgrade you mentioned?

Oops. After posting I realized I'd gotten so busy getting the readme written and uploaded that I'd forgotten to upload the latest PeanutPlug.groovy.
It is now in GitHub. Try it again and see if it doesn't work ok.
Sorry, I didn't expect such quick response.

1 Like

@jim1 Loaded it in and here is a pic.

If you scroll down a bit to Preferences do you see 'Power Change Report Value, Power Reporting Interval, etc.?
If you do, then you have the correct version of the app.
It's curious that I have an entry for energy but you don't. You might try deleting the plug and re-paring it but I don't really expect that to help.
I've never tried using a Peanut Plug with the original firmware so I can't say for sure that this is what is happening but, the consensus from the postings I see is unanimous that old firmware WON'T report power. Even on SmartThings.
Any way you can update the firmware?

Edit:
I forgot to mention that after you update the app you need to click 'Save Preferences' and probably clicking 'Configure' and 'Refresh' wouldn't hurt either. Otherwise, it might not notice that the app has been changed.

1 Like

@jim1 I have Energy on the right and I have those settings you mentioned in Preferences. There are 6 of them.

Do you have a light or something plugged into it so it draws power?

@jim1 Yes I have one of my cameras plugged into it. The camera uses a wall transformer.

Does it draw more than 2.6 watts? Won't read less than that.

I changed "Power Change Report Value" to 1. But wall transformer reads Input at 120VAC at .2 Amps and output as 5VDC at 1 Amp.

That's 24 watts so it should be showing a value for power and current. Again, though, if you are running old firmware on the plug then it definitely won't report power, etc.
Wouldn't happen to have a Almond Securifi+ laying around the house? Or maybe a friend who does?

No I unfortunately don't have one. I guess I will have to use it as a on/off device which will be OK for the cameras. Thanks for your help. Let me know if a new way comes along to get it to work.

Does you driver do anything to the repeater part of this outlet? Better, no change?