Smappee integration into OpenHAB - rules, scripts, Items

Hello all,
elsewhere on this forum i was asked to move this post into the tutorial section:

So here my solution for reading and controlling a smappee energy meter in the LAN https://www.smappee.com
smappee-home-energy-monitor-600px

This solution does interact with the smappee device only on local level ( LAN Smappee Client). The use of the webbased Smappee API ( API Client Usage), which is now behind a paywall, is in this way avoided.

Requirements:

Implementation - Reading Values from Smappee
In my system I use the scripts below in order to fetch the consumption on all 3 electric phases every 10sec. This is good enough for me to calculate the overall consumption, consumed energy per phase and finally monitor the impact of different consumers in my home via Grafana.

I use the data from the local smappee as well to calculate a graph with 5min power consumption, as this is the interval, which the Smappee webservice displays. This graph comes handy in order to find out, how well the local Smappee inquiry works. The data from local Smappee and webbased Smappee API fit actually quite well. However, these values drift over time. Therefor I fetch the hourly, daily and monthly values via the smappee API. These values proved to be closer to the monthly bill of consumption from my electricity provider.

Implementation - Controlling Smappee Device via openHAB
The Smappee device can be quite extensively remotely controlled via the LAN Smappee Client. The only thing I use this possibility for is to restart the smappee device every night, as I had experienced, that the device got some “hickup” regularly and a reset helped. However this might be very specific to my household and other might want to implement other commands. I paste the script at the end of this long thread for information reasons

Script
Here the python3 script, which queries Smappee

#!/usr/bin/python3
from smappy import LocalSmappee
ls = LocalSmappee(ip='YOUR_SMAPPEE_IP_ADRESS')
ls.logon(password="YOUR_PASSWORD")
inst = ls.load_instantaneous()
values = [float(i['value']) for i in inst if i['key'].endswith('ActivePower')]
print(values)

Rule
Here the rule, which triggers the python script and processes the output of the script for openHAB items.
I have build in an if - clause, as Smappee sends from time to time abnormally high values.
(The transformation of the string, which comes from python into consumable values and the overall code could probably be done more elegantly)

import org.joda.time.*

rule "10sec Instantaneous and Active Pwr"
when 
Time cron "0/10 * * * * ?"
then
        val String instNow = executeCommandLine("python3 /etc/openhab2/scripts/lsInstantaneous.py", 6000) //wait 6000ms for reply from Smappee - could be shorter

//Transform String to single Active Power Values
        var String TransformString = (instNow.replace(' ',''))
        var String TransformString0 = (TransformString.replace('[','').replace(']', ''))
        var String TransformString1 = (TransformString0.replace('.0',''))
        val numsStr = TransformString1.split(",")
        val int first = Integer::parseInt(numsStr.get(0))
        val int second = Integer::parseInt(numsStr.get(1))
        val int third = Integer::parseInt(numsStr.get(2))

//Limiter - exit rule execution, when fake value (> 30000kwh)
        if(first > 30000000) {                
                logError("Phase Limiter - Alarm", "Fake value on PwrPhase01 >30000000")
                sendMail("martin.tamke@gmail.com", "Phase Limiter - Alarm","Fake value on PwrPhase01 >30000000")
                return;} 
        if(second > 30000000) {                
                logError("Phase Limiter - Alarm", "Fake value on PwrPhase02 >30000000")
                sendMail("martin.tamke@gmail.com", "Phase Limiter - Alarm","Fake value on PwrPhase02 >30000000")
                return;} 
        if(third > 30000000) {                
                logError("Phase Limiter - Alarm", "Fake value on PwrPhase03 >30000000")
                sendMail("martin.tamke@gmail.com", "Phase Limiter - Alarm","Fake value on PwrPhase03 >30000000")
                return;} 

//write Active Power per Phase
        PwrPhase01.sendCommand(first as Number) 
        PwrPhase02.sendCommand(second as Number)  
        PwrPhase03.sendCommand(third as Number) 

//write Total activePower
        val int PwrActiveNow = (first+second+third) / 1000
        PwrActive10s.sendCommand(PwrActiveNow)

end

Items
and here the items, which are updated (standard)

Number PwrActive10s "ActivePower [%d]" <"energy"> (gPwr)

Number PwrPhase01 "Phase1 [%d]" <"energy"> (gPwr, gPhase)
Number PwrPhase02 "Phase2 [%d]" <"energy"> (gPwr, gPhase)
Number PwrPhase03 "Phase3 [%d]" <"energy"> (gPwr, gPhase)

Controlling Smappee remotely
Finally the python script to restart Smappee. It is again triggered by a rule every day at night. the devic e restarts super fast:

#!/usr/bin/python3
from smappy import LocalSmappee
ls = LocalSmappee(ip='YOUR_SMAPPEE_IP')
ls.logon(password="YOUR_PASSWORD")
ls.restart()
print "Smappee restarted!"

I hope these scripts help and inspire others and minimise the time you need to figure things out. If someone is interested in the Smappee API scripts - please tell in this thread.

6 Likes

Hi Martin

Excellent guide
I followed it step-by-step , took me less than 10 minutes to implement, and now I have readings from my Smappee. :partying_face:
Now comes the hard part - to actually understand what I’m doing … but that’s another story.

/Lars

2 Likes

Works perfect - thank you!!