-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp1logger.py
137 lines (109 loc) · 4.22 KB
/
p1logger.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/python3
# Python script for P1 Telegrams - DSMR5 Fluvius
import datetime
import re
import serial
import paho.mqtt.client as paho
# VARIABLES
## broker - define your mqtt broker here
## broker="mqtt.homelab.local"
broker="mqtt.homelab.local"
## port - define the mqtt port
## e.g. port=1883
port=1883
## p1device - define your P1 serial device
## e.g. p1device="/dev/ttyUSB0" - you can typically find these via ls -l /dev/tty*
p1device="/dev/ttyP1"
## HERE BE DRAGONS ##
## (do not edit :)) ##
# Non-blocking readline - see https://github.com/pyserial/pyserial/issues/216
class ReadLine:
def __init__(self, s):
self.buf = bytearray()
self.s = s
def readline(self):
i = self.buf.find(b"\n")
if i >= 0:
r = self.buf[:i+1]
self.buf = self.buf[i+1:]
return r
while True:
i = max(1, min(2048, self.s.in_waiting))
data = self.s.read(i)
i = data.find(b"\n")
if i >= 0:
r = self.buf + data[:i+1]
self.buf[0:] = data[i+1:]
return r
else:
self.buf.extend(data)
def on_publish(client1,userdata,result): #create function for callback
#print("data published \n")
pass
client1=paho.Client("control1") #create client object
client1.on_publish = on_publish #assign function to callback
client1.connect(broker,port) #establish connection
# Serial Port config
ser = serial.Serial()
# DSMR 5 Fluvius > 115200 8N1:
ser.baudrate = 115200
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE
ser.xonxoff = 0
ser.rtscts = 0
ser.timeout = 12
ser.port = p1device
rl = ReadLine(ser) # Non-blocking readline
ser.close()
client1.loop_start()
ser.open()
# Run indefinitely
while True:
#ser.open()
checksum_found = False
# Process below logic until checksum found
while not checksum_found:
telegram_line = (rl.readline()) # Read a line
telegram_line = telegram_line.decode('utf-8').strip() # Strip spaces and blank lines
#print (telegram_line) #debug
if re.match(r'(?=1-0:1.7.0)', telegram_line): #1-0:1.7.0 = Instantaneous draw in kW
kwAf = telegram_line[10:-4] # cut kW (0000.54)
wattAf = float(kwAf) * 1000 # multiply to Watt (540.0)
wattAf = int(wattAf) # round float (540)
if re.match(r'(?=1-0:2.7.0)', telegram_line): #1-0:2.7.0 = Instantaneous injection in kW
kwIn = telegram_line[10:-4] # cut kW (0000.54)
wattIn = float(kwIn) * 1000 # multiply to Watt (540.0)
wattIn = int(wattIn) # round float (540)
if re.match(r'(?=1-0:1.8.1)', telegram_line): #1-0:1.8.1 - Total Day draw / 1-0:1.8.1(13579.595*kWh)
kwhAfDag = telegram_line[10:-5] # cut kWh (13579.595)
kwhAfDag = float(kwhAfDag)
if re.match(r'(?=1-0:1.8.2)', telegram_line): #1-0:1.8.2 - Total Night draw / 1-0:1.8.2(14655.223*kWh)
kwhAfNacht = telegram_line[10:-5] # cut kWh (14655.223)
kwhAfNacht = float(kwhAfNacht)
if re.match(r'(?=1-0:2.8.1)', telegram_line): #1-0:1.8.1 - Total Day injection / 1-0:1.8.1(13579.595*kWh)
kwhInDag = telegram_line[10:-5] # cut kWh (13579.595)
kwhInDag = float(kwhInDag)
if re.match(r'(?=1-0:2.8.2)', telegram_line): #1-0:1.8.2 - Total Night injection / 1-0:1.8.2(14655.223*kWh)
kwhInNacht = telegram_line[10:-5] # cut kWh (14655.223)
kwhInNacht = float(kwhInNacht)
if re.match(r'(?=0-1:24.2.3\(.+\))', telegram_line): #0-1:24.2.3 - Total gas use m3 / 0-1:24.2.3(200827154000S)(00002.072*m3)
gasm3 = telegram_line[26:-4] # cut m3 (00002.072)
gasm3 = float(gasm3)
# Check if checksum received - marks end of telegram
if re.match(r'(?=!)', telegram_line):
checksum_found = True
#ser.close()
######################################
# MQTT PUBLISH
######################################
client1.publish("fluvius/wattAf", wattAf)
client1.publish("fluvius/wattIn", wattIn)
client1.publish("fluvius/kwhAfDag", kwhAfDag)
client1.publish("fluvius/kwhAfNacht", kwhAfNacht)
client1.publish("fluvius/kwhInDag", kwhInDag)
client1.publish("fluvius/kwhInNacht", kwhInNacht)
client1.publish("fluvius/gasm3", gasm3)
print("Afname: ",wattAf,"| Injection: ",wattIn)
client1.disconnect()
ser.close()