forked from sbender9/vedirect
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vedirect.py
139 lines (118 loc) · 4.47 KB
/
vedirect.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
138
139
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, serial, argparse
class vedirect:
def __init__(self, serialport, timeout):
self.serialport = serialport
self.ser = serial.Serial(serialport, 19200, timeout=timeout)
self.header1 = '\r'
self.header2 = '\n'
self.hexmarker = ':'
self.delimiter = '\t'
self.key = ''
self.value = ''
self.bytes_sum = 0;
self.state = self.WAIT_HEADER # global state
# global checksum state (used for stopping sum of bytes for checksum value)
self.stateTmp = self.WAIT_HEADER
self.dict = {}
(HEX, WAIT_HEADER, IN_KEY, IN_VALUE, IN_CHECKSUM) = range(5)
def getInt(self, nb, default=0):
try:
return int(nb)
except Exception:
return default
return default
def input(self, byte):
if byte == self.hexmarker and self.state != self.IN_CHECKSUM:
self.state = self.HEX
if self.state == self.WAIT_HEADER:
self.bytes_sum += ord(byte)
if byte == self.header1:
print("header1 getted \n")
self.state = self.WAIT_HEADER
elif byte == self.header2:
print("header2 getted \n")
self.state = self.IN_KEY
return None
elif self.state == self.IN_KEY:
self.bytes_sum += ord(byte)
if byte == self.delimiter:
if (self.key == 'Checksum'):
# Checksum detected (now get value and stop byte count)
self.stateTmp = self.IN_CHECKSUM
self.state = self.IN_VALUE
print("Checksum key getted \n")
else:
self.state = self.IN_VALUE
print("Key getted \n")
else:
self.key += byte
return None
elif self.state == self.IN_VALUE:
# stopping byte count only for checksum value)
if self.stateTmp != self.IN_CHECKSUM:
self.bytes_sum += ord(byte)
if byte == self.header1:
if self.stateTmp != self.IN_CHECKSUM:
self.state = self.WAIT_HEADER
self.dict[self.key] = self.value
self.key = ''
self.value = ''
print("value getted \n")
else:
self.state = self.IN_CHECKSUM
self.stateTmp = self.WAIT_HEADER
print("checksum value getted \n")
else:
self.value += byte
return None
elif self.state == self.IN_CHECKSUM:
# convert value to int
self.value = self.getInt(self.value)
self.state = self.WAIT_HEADER
if ((self.bytes_sum+self.value) % 256 == 0):
self.bytes_sum = 0
print("Packet validated \n")
return self.dict
else:
print 'Malformed packet'
self.bytes_sum = 0
self.key = ''
self.value = ''
elif self.state == self.HEX:
self.bytes_sum = 0
if byte == self.header2:
self.state = self.WAIT_HEADER
else:
raise AssertionError()
def read_data(self):
while True:
byte = self.ser.read(1)
packet = self.input(byte)
def read_data_single(self):
while True:
byte = self.ser.read(1)
packet = self.input(byte)
if (packet != None):
return packet
def read_data_callback(self, callbackFunction):
while True:
byte = self.ser.read(1)
if byte:
packet = self.input(byte)
if (packet != None):
callbackFunction(packet)
else:
break
def print_data_callback(data):
print data
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Process VE.Direct protocol')
parser.add_argument('--port', help='Serial port')
parser.add_argument('--timeout', help='Serial port read timeout', type=int, default='60')
args = parser.parse_args()
ve = vedirect(args.port, args.timeout)
#ve.read_data_single()
ve.read_data_callback(print_data_callback)
#print(ve.read_data_single())