Created
January 1, 2014 14:10
-
-
Save tehmaze/8208299 to your computer and use it in GitHub Desktop.
P1 power meter daemon that stuffs data into graphite
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
# usage: p1-daemon graphite.host.here | |
import serial | |
import socket | |
import sys | |
import time | |
ser = serial.Serial( | |
'/dev/ttyUSB0', | |
baudrate = 9600, | |
bytesize = serial.SEVENBITS, | |
parity = serial.PARITY_EVEN, | |
stopbits = serial.STOPBITS_ONE, | |
xonxoff = 0, | |
rtscts = 0, | |
timeout = 20, | |
) | |
ser.open() | |
STORE = 'sensor.home' | |
OBIS = { | |
'1.8.1': 'power.recv_t1', | |
'1.8.2': 'power.recv_t2', | |
'2.8.1': 'power.sent_t1', | |
'2.8.2': 'power.sent_t2', | |
'1.7.0': 'power.recv_now', | |
'2.7.0': 'power.sent_now', | |
'24.3.1': 'gas.recv', | |
} | |
def write(gram): | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
s.connect((sys.argv[1], 2003)) | |
n = int(time.time()) | |
for k in OBIS.values(): | |
v = gram.get(k, 0) | |
metric = '%s %s %d\n' % ('.'.join([STORE, k]), str(v), n) | |
print 'gfx', metric.strip() | |
s.send(metric) | |
s.close() | |
def update(packet, obis, value): | |
print 'upd', obis, value | |
if obis in OBIS: | |
packet[OBIS[obis]] = value | |
def decode(gram, line): | |
print 'rcv', line | |
if line.startswith('/'): # device identifier | |
if gram: | |
print 'gram', gram | |
write(gram) | |
gram = {} | |
elif line == '!': | |
if gram: | |
print 'gram', gram | |
write(gram) | |
gram = {} | |
elif line[3] == ':': | |
prefix, blob = line.split(':', 1) | |
if '(' in blob: | |
obis, data = blob.split('(', 1) | |
data = data.rstrip(')').replace('\x00', '') # wtfnullbytes? | |
print 'dat', repr(data) | |
if data.endswith('*kWh'): | |
update(gram, obis, long(float(data[:-4]) * 1000L)) | |
elif data.endswith('*kW'): | |
update(gram, obis, long(float(data[:-3]) * 1000L)) | |
else: | |
update(gram, obis, data) | |
elif line.startswith('('): # my gas meter reading is on a new line? | |
update(gram, '24.3.1', long(float(line[1:-1]) * 1000L)) | |
init = True | |
gram = {} | |
while True: | |
line = ser.readline().strip('\x00\x0a\x0d\x20') | |
print '<<<', repr(line) | |
if init: | |
if line.startswith('/'): | |
init = False | |
gram = {} | |
print '!!! received initalisation packet' | |
elif line == '': | |
continue | |
else: | |
try: | |
decode(gram, line) | |
except Exception, e: | |
print '!!!', str(e) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment