-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmeter_reader.py
116 lines (99 loc) · 4.2 KB
/
meter_reader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python
# Reads data via optical interface from EasyMeter Q3D
# connected to serial Port
# Publishes Data to an MQTT Server
from __future__ import division
from pprint import pprint
import paho.mqtt.client as mqtt
import serial
MQTT_server = '192.168.10.2'
MQTT_protocol = 3
serialport = '/dev/ttyAMA0'
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Publis units of measurements
client.publish('kwh_consumption/unit', payload='kWh', qos=1, retain=True)
client.publish('kwh_delivered/unit', payload='kWh', qos=1, retain=True)
client.publish('kwh_absolute/unit', payload='kWh', qos=1, retain=True)
client.publish('power_l1/unit', payload='W', qos=1, retain=True)
client.publish('power_l2/unit', payload='W', qos=1, retain=True)
client.publish('power_l3/unit', payload='W', qos=1, retain=True)
client.publish('power_sum/unit', payload='W', qos=1, retain=True)
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client = mqtt.Client(protocol = MQTT_protocol)
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_server, 1883, 60, )
# Run the MQTT loop
client.loop_start()
ser = serial.Serial(serialport, 9600, parity=serial.PARITY_EVEN, bytesize=7)
start = False
while True:
line = ser.readline().strip()
if len(line) == 0:
pass
elif line[0] == '/':
start = True
data = dict()
sdata = dict()
lineparts = line[1:].split()
sdata['factory_id'] = lineparts[0]
sdata['version'] = lineparts[1]
elif line[0] == '!':
if start == True:
pprint(data)
for key in data:
print " " + key + ": " + str(data[key])
client.publish('home/meter/' + str(sdata['factory_number']) + '/' + key, data[key] )
start = False
elif start == True:
lineparts = line.split("(")
if lineparts[0] == "1-0:0.0.0*255":
sdata['owner_id'] = lineparts[1].rstrip(")")
elif lineparts[0] == "1-0:1.8.0*255":
data['kwh_consumption/value'] = float(lineparts[1].rstrip(")").split("*")[0])
elif lineparts[0] == "1-0:2.8.0*255":
data['kwh_delivered/value'] = float(lineparts[1].rstrip(")").split("*")[0])
elif lineparts[0] == "1-0:15.8.0*255":
data['kwh_absolute/value'] = float(lineparts[1].rstrip(")").split("*")[0])
elif lineparts[0] == "1-0:21.7.0*255":
data['power_l1/value'] = float(lineparts[1].rstrip(")").split("*")[0])
elif lineparts[0] == "1-0:41.7.0*255":
data['power_l2/value'] = float(lineparts[1].rstrip(")").split("*")[0])
elif lineparts[0] == "1-0:61.7.0*255":
data['power_l3/value'] = float(lineparts[1].rstrip(")").split("*")[0])
elif lineparts[0] == "1-0:1.7.0*255":
data['power_sum/value'] = float(lineparts[1].rstrip(")").split("*")[0])
elif lineparts[0] == "1-0:96.5.5*255":
flag = int(lineparts[1].rstrip(")"))
# Not sure about this, but reversed bits seem to fit
if flag & 2 ^^ 7 == True:
data['flag/error'] == 'true'
else:
data['flag/error'] == 'false'
if flag & 2 ^^ 6 == True:
data['flag/sync'] == 'true'
else:
data['flag/sync'] == 'false'
if flag & 2 ^^ 3 == True:
data['flag/l1_0V'] == 'true'
else:
data['flag/l1_0V'] == 'false'
if flag & 2 ^^ 2 == True:
data['flag/l2_0V'] == 'true'
else:
data['flag/l2_0V'] == 'false'
if flag & 2 ^^ 1 == True:
data['flag/l3_0V'] == 'true'
else:
data['flag/l3_0V'] == 'false'
if flag & 2 ^^ 0 == True:
data['flag/empty'] == 'true'
else:
data['flag/empty'] == 'false'
data['flag/raw'] = flag
elif lineparts[0] == "0-0:96.1.255*255":
sdata['factory_number'] = lineparts[1].rstrip(")")