forked from bsdphk/PyDLMS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dlms.py
113 lines (103 loc) · 2.24 KB
/
dlms.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
#!/usr/local/bin/python
from __future__ import print_function
import serial
class dlmsError(Exception):
def __init__(self, reason):
self.reason = reason
def __str__(self):
return repr(self.reason)
class dlms(object):
def __init__(self, serial_port = "/dev/cuaU3"):
self.ser = serial.Serial(
port = serial_port,
baudrate = 300,
bytesize = serial.SEVENBITS,
parity = serial.PARITY_EVEN,
timeout = 3.0)
def query(self):
self.ser.write("/?!\r\n")
state = 0
id = ""
cont = ""
sum = 0
while True:
a = self.ser.read(1)
if len(a) == 0:
raise dlmsError("Rx Timeout")
b = bytearray(a)[0] #Reads the ascii code of the first character
if state == 0:
# Read ID string
if b >= 32: #32 is a space
id += a
elif b == 13: #is carrige return
state = 1
else:
raise dlmsError(
"Illegal char in ident 0x%02x" % b)
state = 99
elif state == 1:
# NL ending ID string
if b != 10: #10 is new line
raise dlmsError(
"Ident has 0x%02x after CR" % b)
state = 99
else:
state = 2
elif state == 2:
# STX
if b != 2: #start of text
raise dlmsError(
"Expected STX not 0x%02x" % b)
state = 99
else:
state = 3
elif state == 3:
# message body
sum ^= b
if b != 3:
cont += a
else:
state = 4
elif state == 4:
# Checksum
if sum != b:
raise dlmsError(
"Checksum Mismatch")
state == 99
else:
return self.parse(id, cont)
elif state == 99:
# Error, flush
pass
assert False
def parse(self, id, cont):
l = list()
l.append(id)
l.append(dict())
cont = cont.split("\r\n")
if cont[-1] != "":
raise dlmsError(
"Last data item lacks CRNL")
if cont[-2] != "!":
raise dlmsError(
"Last data item not '!'")
for i in cont[:-2]:
if i[-1] != ")":
raise dlmsError(
"Last char of data item not ')'")
return None
i = i[:-1].split("(")
j = i[1].split("*")
l[1][i[0]] = j
return l
if __name__ == "__main__":
foo = dlms()
a = foo.query()
print("%16s: %s" % ("identifier", a[0]))
print("")
for i in a[1]:
j = a[1][i]
if len(j) == 2:
print("%16s: %s [%s]" % (i, j[0], j[1]))
else:
print("%16s: %s" % (i, j[0]))