-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathEmonHubTx3eInterfacer.py
112 lines (82 loc) · 3.06 KB
/
EmonHubTx3eInterfacer.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
import re
import Cargo
from . import EmonHubSerialInterfacer as ehi
"""class EmonHubTx3eInterfacer
EmonHub Serial Interfacer key:value pair format
e.g: ct1:0,ct2:0,ct3:0,ct4:0,vrms:524,pulse:0
for csv format use the EmonHubSerialInterfacer
"""
class EmonHubTx3eInterfacer(ehi.EmonHubSerialInterfacer):
def __init__(self, name, com_port='', com_baud=9600):
"""Initialize interfacer
com_port (string): path to COM port e.g /dev/ttyUSB0
com_baud (numeric): typically 115200 now for emontx etc
"""
# Initialization
super().__init__(name, com_port, com_baud)
self._settings.update({
'nodename': ""
})
# Initialize RX buffer
self._rx_buf = ''
def read(self):
"""Read data from serial port and process if complete line received.
Read data format is key:value pairs e.g:
ct1:0,ct2:0,ct3:0,ct4:0,vrms:524,pulse:0
"""
if not self._ser:
return False
# Read serial RX
self._rx_buf = self._rx_buf + self._ser.readline().decode()
# If line incomplete, exit
if '\r\n' not in self._rx_buf:
# If string longer than 3 print message
if len(self._rx_buf) > 3:
self._log.info("START MESSAGE: %s", self._rx_buf.rstrip())
self._rx_buf = ''
return False
#Check for MSG data string. If not found...
if self._rx_buf.find("MSG:",0,4) == -1:
self._log.info("START MESSAGE: %s", self._rx_buf.rstrip())
self._rx_buf = ''
return False
# Remove CR,LF
f = self._rx_buf[:-2].strip()
# Create a Payload object
c = Cargo.new_cargo(rawdata=f)
# Reset buffer
self._rx_buf = ''
# Parse the ESP format string
values = []
names = []
for item in f.split(','):
parts = item.split(':')
if len(parts) == 2:
# check for alphanumeric input name
if re.match(r'^[\w-]+$', parts[0]):
# check for numeric value
value = 0
try:
value = float(parts[1])
except Exception:
self._log.debug("input value is not numeric: %s", parts[1])
names.append(parts[0])
values.append(value)
else:
self._log.debug("invalid input name: %s", parts[0])
if self._settings["nodename"] != "":
c.nodename = self._settings["nodename"]
c.nodeid = self._settings["nodename"]
else:
c.nodeid = int(self._settings['nodeoffset'])
c.realdata = values
c.names = names
if len(values) == 0:
return False
return c
def set(self, **kwargs):
for key, setting in self._settings.items():
if key in kwargs:
# replace default
# self._log.debug(kwargs[key])
self._settings[key] = kwargs[key]