comparison iec1107.py @ 3:535076e31660

Parse the result.
author Daniel O'Connor <darius@dons.net.au>
date Wed, 20 Nov 2013 14:45:16 +1030
parents 8f1a773a3cd5
children 10a16898903d
comparison
equal deleted inserted replaced
2:8f1a773a3cd5 3:535076e31660
2 2
3 # 3 #
4 # http://www.domoticaforum.eu/viewtopic.php?f=71&t=7489 4 # http://www.domoticaforum.eu/viewtopic.php?f=71&t=7489
5 # 5 #
6 6
7 import datetime
7 import exceptions 8 import exceptions
9 import re
8 import serial 10 import serial
9 import sys 11 import sys
10 import time 12 import time
11 13
12 baudtable = {'0' : 300, '1' : 600, '2' : 1200, '3' : 2400, '4' : 4800, '5' : 9600, '6' : 19200} 14 baudtable = {'0' : 300, '1' : 600, '2' : 1200, '3' : 2400, '4' : 4800, '5' : 9600, '6' : 19200}
15 parsere = re.compile('([0-9A-Z](\.[0-9A-Z]){1,})\((.*)\)')
13 16
14 class Error(exceptions.BaseException): 17 class Error(exceptions.BaseException):
15 pass 18 pass
16 19
17 class IEC1107Reading(object): 20 class IEC1107Reading(object):
74 raise Error('Invalid reply header 0x%02x' % (ord(head))) 77 raise Error('Invalid reply header 0x%02x' % (ord(head)))
75 78
76 # Read result lines 79 # Read result lines
77 while True: 80 while True:
78 line = s.readline() 81 line = s.readline()
79 cksum ^= reduce(lambda x, y: x ^ y, map(ord, line))
80 if len(line) == 0: 82 if len(line) == 0:
81 raise Error('Timeout during message') 83 raise Error('Timeout during message')
82 if line == '!': 84
85 cksum ^= reduce(lambda x, y: x ^ y, map(ord, line))
86 if line.strip() == '!':
83 break 87 break
84 lines.append(line) 88 lines.append(line)
85 89
86 # Read trailer 90 # Read trailer
87 fin = s.read(2) 91 fin = s.read(2)
95 if cksum != ord(fin[1]): 99 if cksum != ord(fin[1]):
96 raise Error('Checksum mismatch, expected 0x%02x, got 0x%02x' % (cksum, ord(fin[1]))) 100 raise Error('Checksum mismatch, expected 0x%02x, got 0x%02x' % (cksum, ord(fin[1])))
97 self.rawreading = lines 101 self.rawreading = lines
98 del s 102 del s
99 103
104 self.parse()
105 self.readdate = datetime.datetime.now()
106
107 def parse(self):
108 for l in self.rawreading:
109 m = parsere.match(l)
110 if m == None:
111 raise Error('Unable to parse result \"%s\"' % (l))
112
113 (code, xxx, value) = m.groups()
114 if code == 'C.1':
115 self.meterid, date = value.split('(')
116 # XXX: The meter I have is an hour slow
117 self.meterdate = datetime.datetime.strptime(date, '%H:%M %d-%m-%y')
118 elif code == '1.8.0':
119 self.importWh = int(value[0:-3])
120 elif code[0:4] == '1.8.':
121 # Differing tarrifs which I don't care about
122 pass
123 elif code == '2.8.0':
124 self.exportWh = int(value[0:-3])
125 else:
126 print 'Unknown code', code
127
128 def __str__(self):
129 return 'Time: %s, Meter: %s, Import: %d Wh, Export: %d Wh' % (self.readdate.strftime('%Y/%m/%d %H:%M'),
130 self.meterid, self.importWh, self.exportWh)
100 def main(): 131 def main():
101 if len(sys.argv) != 2: 132 if len(sys.argv) != 2:
102 print 'Bad usage' 133 print 'Bad usage'
103 print '\t%s portname' % (sys.argv[0]) 134 print '\t%s portname' % (sys.argv[0])
104 sys.exit(1) 135 sys.exit(1)