Meter readings monthly

From Domoticz
Revision as of 20:00, 17 September 2015 by ThinkPad (talk | contribs) (→‎The Python code for the script: Updated script, added output to .txt file)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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" )



--ThinkPad (talk) 00:21, 23 May 2015 (CEST)