Skip to content

Instantly share code, notes, and snippets.

@tehmaze
Created January 1, 2014 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tehmaze/8208299 to your computer and use it in GitHub Desktop.
Save tehmaze/8208299 to your computer and use it in GitHub Desktop.
P1 power meter daemon that stuffs data into graphite
#!/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