Created
August 21, 2016 18:44
-
-
Save ius/e59adb64bbe8855cfc5c18297f6d692e to your computer and use it in GitHub Desktop.
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/env python2 | |
import re | |
import sys | |
import time | |
import requests | |
from datetime import datetime | |
from pytz import timezone, utc | |
url = 'http://127.0.0.1:8086/write' | |
fp = sys.stdin | |
table = [ | |
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, | |
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, | |
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, | |
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, | |
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, | |
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, | |
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, | |
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, | |
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, | |
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, | |
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, | |
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, | |
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, | |
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, | |
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, | |
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, | |
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, | |
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, | |
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, | |
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, | |
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, | |
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, | |
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, | |
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, | |
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, | |
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, | |
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, | |
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, | |
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, | |
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, | |
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, | |
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 | |
] | |
obis_objects = { | |
'1-3:0.2.8': 'version_info', | |
'0-0:1.0.0': 'datetime_stamp', | |
'0-0:96.1.1': 'equipment_id_electricity', | |
'1-0:1.8.1': 'mr_toclient_t1', | |
'1-0:1.8.2': 'mr_toclient_t2', | |
'1-0:2.8.1': 'mr_fromclient_t1', | |
'1-0:2.8.2': 'mr_fromclient_t2', | |
'0:96.14.0': 'tariff_indicator', | |
'1-0:1.7.0': 'actual_power_delivered', | |
'1-0:2.7.0': 'actual_power_received', | |
'0-0:96.7.21': 'total_pf', | |
'0-0:96.7.9': 'total_long_pf', | |
'1-0:99.97.0': 'pf_event_log', | |
'1-0:32.32.0': 'volt_sag_l1', | |
'1-0:52.32.0': 'volt_sag_l2', | |
'1-0:72.32.0': 'volt_sag_l3', | |
'1-0:32.36.0': 'volt_swell_l1', | |
'1-0:52.36.0': 'volt_swell_l2', | |
'1-0:72.36.0': 'volt_swell_l3', | |
'0-0:96.13.1': 'text_message_codes', | |
'0-0:96.13.0': 'text_message', | |
'1-0:31.7.0': 'inst_current_l1', | |
'1-0:51.7.0': 'inst_current_l2', | |
'1-0:71.7.0': 'inst_current_l3', | |
'1-0:21.7.0': 'inst_power_l1', | |
'1-0:41.7.0': 'inst_power_l2', | |
'1-0:61.7.0': 'inst_power_l3', | |
'0-1:96.1.0': 'equipment_id_gas', | |
'0-1:24.2.1': 'gas_toclient', | |
'0-1:24.1.0': 'device_type', | |
} | |
def crc16(s): | |
crc = 0x00 | |
for ch in s: | |
crc = (crc >> 8) ^ table[(crc ^ ord(ch)) & 0xff] | |
return crc | |
def obis_map(ref, value): | |
if ref in obis_objects: | |
ref = obis_objects[ref] | |
return ref, value | |
def parse(buf): | |
values = {} | |
for line in buf.split(): | |
mo = re.findall('^([0-9.:-]+)(.+)', line.rstrip()) | |
for match in mo: | |
pair = obis_map(*match) | |
values.update([pair]) | |
print '%s: %s' % pair | |
return values | |
def verify_and_parse(buf): | |
crc = int(buf[-1][1:5], 16) | |
data = ''.join(buf[:-1]) + '!' | |
if crc == crc16(data): | |
return parse(data) | |
def parse_value(s): | |
return re.findall('\(([0-9.-]+[SW]?).*?\)', s) | |
def parse_ts(s): | |
tm, tz = s[:-1], s[-1] | |
is_dst = (tz == 'S') | |
if tm.startswith('23'): | |
tm = '16' + tm[2:] | |
date = datetime.strptime(tm, '%y%m%d%H%M%S') | |
ams_tz = timezone('Europe/Amsterdam') | |
date = ams_tz.localize(date, is_dst=is_dst) | |
#date = date.astimezone(utc) | |
unix = time.mktime(date.timetuple()) | |
return int(unix) | |
def handle(values): | |
ts = parse_ts(parse_value(values['datetime_stamp'])[0]) | |
keys = ['mr_toclient_t1', 'mr_toclient_t2', 'inst_power_l1'] | |
#'gas': ('device_type', 'equipment_id_gas', 'gas_toclient') | |
gas_ts, gas_value = parse_value(values['gas_toclient']) | |
gas_ts = parse_ts(gas_ts) | |
vals = lambda v: ','.join('%s=%s' % (k, parse_value(values[k])[0]) for k in v) | |
postdata = '%s %s %d\n' % ('electricity', vals(keys), ts) | |
postdata += '%s gas_toclient=%s %d\n' % ('gas', gas_value, gas_ts) | |
#postdata += '\n' | |
print '-------' | |
print postdata | |
print '-------' | |
r = requests.post(url, params={'db': 'utilities', 'precision': 's'}, data=postdata) | |
if __name__ == '__main__': | |
buf = [] | |
while True: | |
line = fp.readline().strip('\x00') | |
if line.startswith('/'): | |
buf = [line] | |
else: | |
buf.append(line) | |
if line.startswith('!'): | |
values = verify_and_parse(buf) | |
if values: | |
handle(values) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment