Meter readings monthly
Purpose
This script will send you the meter readings of the smartmeter in a Pushover notification at the first day of each month at 00:01.
You can use this if you want to do calculations with the meter readings yourself, outside of Domoticz. The message will contain the same values as if you would look at the meter yourself.
Dependencies - hardware / software / operating system
Pushover
For this script you need a Pushover account. Create an account at https://pushover.net/
When logged in, click on the 'Create New Application/Plugin', so you generate a token that you can use.
Python
The scripts needs 'python' to be installed. If not yet installed, you can do so by running:
sudo apt-get install python
from the terminal.
If it says that 'python' is already installed, you can continue further with this tutorial.
Smartmeter
The scripts needs data from a smartmeter (Dutch: 'slimme meter').
Maybe the values of an other device can be fetched instead of the Dutch smartmeter, but i haven't tried.
Installation instructions
Create the script
Create a new file in the /home/pi/domoticz/scripts/ folder. Name the file 'pushover_meterreading.py'. Copy the contents from the script on this page to the file, and save it.
The Python code for the script
import sys
import json
import urllib2
import re
import time
import datetime
import httplib, urllib
def open_port():
pass
def close_port():
pass
class Domoticz():
def __init__(self, url):
self.baseurl = url
def __execute__(self, url):
req = urllib2.Request(url)
return urllib2.urlopen(req, timeout=5)
def get_device(self, xid):
"""
Get the Domoticz device information.
"""
url = "%s/json.htm?type=devices&rid=%s" % (self.baseurl, xid)
data = json.load(self.__execute__(url))
return data
def get_el_values(url, device_id):
"""
Get electricity meter readings.
"""
device_data = Domoticz(url).get_device(device_id)
data = device_data['result'][0]['Data']
ex = re.compile('^([0-9\.]+);([0-9\.]+);([0-9\.]+);([0-9\.]+);([0-9\.]+);([0-9\.]+)$')
groups = ex.match(data).group
meter_high = float(groups(1)) / 1000
meter_low = float(groups(2)) / 1000
#out_high = float(groups(3)) / 1000
#out_low = float(groups(4)) / 1000
#actual_in = float(groups(5)) / 1000
#actual_out = float(groups(6)) / 1000
return meter_high, meter_low#, out_high, out_low, actual_in, actual_out
def get_gas_values(url, device_id):
"""
Get gasmeter reading.
"""
device_data = Domoticz(url).get_device(device_id)
data = device_data['result'][0]['Data']
ex = re.compile('^([0-9\.]+)$')
groups = ex.match(data).group
gasstand = float(groups(1)) #/ 1000
return gasstand
# example usage
domoticzurl = "http://localhost:8084"
domoticzdeviceid_el = 6
domoticzdeviceid_gas = 7
#ElectricityRateUsedPeak, ElectricityRateUsedOffPeak, ElectricityRateGeneratedPeak, ElectricityRateGeneratedOffPeak, ElectricityTotalUsed, ElectricityCurrentRateOut = get_el_values(domoticzurl, domoticzdeviceid_el)
ElectricityRateUsedOffPeak, ElectricityRateUsedPeak = get_el_values(domoticzurl, domoticzdeviceid_el)
GasMeterReading = get_gas_values(domoticzurl, domoticzdeviceid_gas)
#print "-- DOMOTICZ ENERGIE--"
#print "Meterstand piektarief (hoog):\t\t"+str(ElectricityRateUsedPeak)+"kWh"
#print "Meterstand daltarief (laag):\t\t"+str(ElectricityRateUsedOffPeak)+"kWh"
#print "Gasmeterstand:\t\t\t\t"+str(GasMeterReading)+"m3"
#print "Totaal:\t\t\t"+str(ElectricityRateUsedPeak + ElectricityRateUsedOffPeak)+"kWh"
#print ""
#print "- Teruggeleverd"
#print "Daltarief:\t\t"+str(ElectricityRateGeneratedOffPeak)+"kWh"
#print "Piektarief:\t\t"+str(ElectricityRateGeneratedPeak)+"kWh"
#print "Huidig verbruik:\t"+str(ElectricityTotalUsed)
conn = httplib.HTTPSConnection("api.pushover.net:443")
conn.request("POST", "/1/messages.json",
urllib.urlencode({
"token": "YOUR_TOKEN_HERE",
"user": "YOUR_USERKEY_HERE",
"message": "Meterstand elektra hoog: "+str(ElectricityRateUsedPeak)+"\n""Meterstand elektra laag: "+str(ElectricityRateUsedOffPeak)+"\n""Gasmeterstand: "+str(GasMeterReading)+"\n Zie ook /volume1/@appstore/domoticz/var/scripts/python/verbruik.txt",
"title": "Domoticz - meterstanden",
"priority": "-1",
}), { "Content-type": "application/x-www-form-urlencoded" })
conn.getresponse()
# creeer een bestand met de waarde / create a file with the readings
name = '/volume1/@appstore/domoticz/var/scripts/python/verbruik.txt' # Naam tekstbestand / Name of text file
now = datetime.datetime.now()
try:
file = open(name,'a') # create file / creeer bestand
# write the readings to the file / schrijf de waarde naar het bestand
file.write('Meterstanden op ' + str(now.strftime("%Y-%m-%d %H:%M")) + ' waren als volgt: \n' 'Elektra laagtarief: ' +str(ElectricityRateUsedPeak) + '\n' 'Elektra hoogtarief: ' +str(ElectricityRateUsedOffPeak) + '\n' 'Gasmeter: ' +str(GasMeterReading) + '\n\n')
# close the file / sluit het bestand (vergelijkbaar met het 'save' en daarna 'close' commando in word)
#file.close()
except: # something went wrong / in het vorige blok is iets niet goed gegaan (error)
print('Something went wrong!')
sys.exit(0) # quit if something goes wrong Python / stop als er iets mis is gegaan
The script needs 4 parameters to run:
- IDX of electricity meter
- IDX of gasmeter
- IP& port where Domoticz is running at ('localhost' and '8080' by default, probably don't need to change it)
- Pushover token- and userkey
- Location where it can write the .txt file (in my case /volume1/@appstore/domoticz/var/scripts/python/verbruik.txt)
Edit the file so the settings match your setup and save the script.
Make script executable
In the terminal, go to /home/pi/domoticz/scripts/
Execute the command chmod +x pushover_meterreading.py
I am not sure if executing this command is necessary, but it doesn't harm anything ;)
Let the script run at certain times (cron)
To let the script work correctly, it needs to be run automatically at certain times. This can be done by using 'cron', the task scheduler on Linux.
On the terminal, run crontab -e
(for Raspberry) or vi /etc/crontab
for Synology and possibly others.
In the screen that opens, add the line below
1 0 1 * * python /home/pi/domoticz/scripts/pushover_meterreading.py
For Raspbmc, a user advised that you need to put sudo python
in front of the command. So then it will look like this:
1 0 1 * * sudo python /home/pi/domoticz/scripts/pushover_meterreading.py
Exit the crontab editor by pressing CTRL-O (character 'O', not zero) and hitting Enter.
Test the script
With the script saved, having it made executable, we can now test it.
In the terminal, type: python pushover_meterreading.py
and press Enter. After a few seconds you should receive a message like in the screenshot above.
Troubleshooting
It can happen that the script is not working in your situation. Follow the steps below to debug the problem.
Sending a test notification
You can add the token- and userkey you received from Pushover into Domoticz (Setup > Settings > Notifications) and then click the 'Test' button. You should then receive a message on your phone almost immediately
Check if the script works
You can run the script by hand to see if it works correctly. Run it by typing python pushover_meterreading.py
in the terminal. You should receive a message like in the screenshot above.
Check if 'cron' service is running
A user told me he had difficulties on using this script on Raspbmc. He said the 'cron' service was not running by default on his Raspbmc installation.
You can check if 'cron' is active by issueing sudo service cron status
.
If it is running, it should say [ ok ] cron is running.
. If it is not running, you can start it by sudo service cron start
.
To view the log of cron, you can issue grep CRON /var/log/syslog
. You should see some lines of text if cron is active.
To enable 'cron' on Raspbmc, have a look this tutorial: http://www.averagemanvsraspberrypi.com/2014/07/using-cron-with-raspbmc.html
Expanding/modifying the script
Adding energy production data
I only consume energy, but it could be that you also produce energy.
If you look at the script, you can see it already has the lines for the grabbing other values of the meter. Uncomment them (remove the #) and add them in the "message": part.
The script is not very hard, it is quite self-explanatory.
Changing message priority
A message is now sent with Priority '-1', which translates to: will be considered low priority and will not generate any sound or vibration, but will still generate a popup/scrolling notification depending on the client operating system.
If you want to change the priority or other parameters, have a look at: https://pushover.net/api
Prowl alternative
User 'MvVeelen' created an alternative that uses 'Prowl'. Prowl is a (free) pushnotification service for iOS.
http://www.prowlapp.com/
In this script also a .txt file is created where all monthly readings will be added (for later use?).
import sys
import json
import urllib2
import re
import time
import datetime
import httplib, urllib
def open_port():
pass
def close_port():
pass
class Domoticz():
def __init__(self, url):
self.baseurl = url
def __execute__(self, url):
req = urllib2.Request(url)
return urllib2.urlopen(req, timeout=5)
def get_device(self, xid):
"""
Get the Domoticz device information.
"""
url = "%s/json.htm?type=devices&rid=%s" % (self.baseurl, xid)
data = json.load(self.__execute__(url))
return data
def get_el_values(url, device_id):
"""
Get electricity meter readings.
"""
device_data = Domoticz(url).get_device(device_id)
data = device_data['result'][0]['Data']
ex = re.compile('^([0-9\.]+);([0-9\.]+);([0-9\.]+);([0-9\.]+);([0-9\.]+);([0-9\.]+)$')
groups = ex.match(data).group
meter_high = float(groups(1)) / 1000
meter_low = float(groups(2)) / 1000
#out_high = float(groups(3)) / 1000
#out_low = float(groups(4)) / 1000
#actual_in = float(groups(5)) / 1000
#actual_out = float(groups(6)) / 1000
return meter_high, meter_low#, out_high, out_low, actual_in, actual_out
def get_gas_values(url, device_id):
"""
Get gasmeter reading.
"""
device_data = Domoticz(url).get_device(device_id)
data = device_data['result'][0]['Data']
ex = re.compile('^([0-9\.]+)$')
groups = ex.match(data).group
gasstand = float(groups(1)) #/ 1000
return gasstand
# example usage
domoticzurl = "http://localhost:8084"
domoticzdeviceid_el = 92
domoticzdeviceid_gas = 93
#ElectricityRateUsedPeak, ElectricityRateUsedOffPeak, ElectricityRateGeneratedPeak, ElectricityRateGeneratedOffPeak, ElectricityTotalUsed, ElectricityCurrentRateOut = get_el_values(domoticzurl, domoticzdeviceid_el)
ElectricityRateUsedOffPeak, ElectricityRateUsedPeak = get_el_values(domoticzurl, domoticzdeviceid_el)
GasMeterReading = get_gas_values(domoticzurl, domoticzdeviceid_gas)
# Prowl settings
API = "***********************"
PRIO = "0"
Appl = "Domoticz"
Evnt = "Meterstanden slimme meter"
ElHigh = "Elektra hoog (T2): "
ElLow = "Elektra laag (T1): "
Gas = "Gas: "
# creeer een bestand met de waarde
name = '/volume1/@appstore/domoticz/var/scripts/python/maandverbruik.txt' # Name of text file
today = datetime.date.today()
try: #probeer zo lang het goed gaat
file = open(name,'a') # creeer bestand
# schrijf de waarde naar het bestand
file.write(ElHigh + ' op ' + str(today) + ' was ' + str(ElectricityRateUsedPeak) + " kWh" + "\n")
file.write(ElLow + ' op ' + str(today) + ' was ' + str(ElectricityRateUsedOffPeak) + " kWh" + "\n")
file.write(Gas + ' op ' + str(today) + ' was ' + str(GasMeterReading) + " M3" + "\n\n")
# sluit het bestand (vergelijkbaar met het 'save' en daarna 'close' commando in word)
#file.close()
except: # in het vorige blok is iets niet goed gegaan (error)
print('Something went wrong! Can\'t tell what....')
sys.exit(0) # quit if something goes wrong Python
urllib.urlopen("https://prowl.weks.net/publicapi/add?apikey=" + API + "&priority=" + PRIO + "&application=" + Appl + "&event=" + Evnt + "&description=" + ElHigh + str(ElectricityRateUsedPeak) + " kWh" + "\n" + ElLow + str(ElectricityRateUsedOffPeak) + " kWh" + "\n" + Gas +str(GasMeterReading) + " M3" )