DataInformationBlock calculations
This commit is contained in:
parent
53789088f2
commit
d64e8bff98
2
.settings/org.eclipse.core.resources.prefs
Normal file
2
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/MeterbusLib.py=iso-8859-15
|
289
MeterbusLib.py
289
MeterbusLib.py
@ -1,3 +1,6 @@
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
|
||||
'''
|
||||
Created on 11.06.2015
|
||||
|
||||
@ -7,6 +10,7 @@ Created on 11.06.2015
|
||||
import MeterbusTypeConversion
|
||||
|
||||
from MeterbusLibExceptions import *
|
||||
import struct
|
||||
|
||||
class Frame(object):
|
||||
def __init__(self, startCharacter, frameLength, firstPayload, telegram):
|
||||
@ -46,6 +50,10 @@ class SingleCharacter(Frame):
|
||||
|
||||
def parse2(self):
|
||||
pass
|
||||
|
||||
def getJSON(self):
|
||||
j = {}
|
||||
return j
|
||||
|
||||
|
||||
class ShortFrame(Frame):
|
||||
@ -55,6 +63,10 @@ class ShortFrame(Frame):
|
||||
def parse2(self):
|
||||
self.cField = self.telegram[1]
|
||||
self.address = self.telegram[2]
|
||||
|
||||
def getJSON(self):
|
||||
j = {'c': self.cField, 'a': self.address}
|
||||
return j
|
||||
|
||||
|
||||
class ControlFrame(Frame):
|
||||
@ -69,6 +81,10 @@ class ControlFrame(Frame):
|
||||
self.cField = self.telegram[4]
|
||||
self.address = self.telegram[5]
|
||||
self.ciField = self.telegram[6]
|
||||
|
||||
def getJSON(self):
|
||||
j = {'c': self.cField, 'a': self.address, 'ci': self.ciField}
|
||||
return j
|
||||
|
||||
|
||||
class LongFrame(ControlFrame):
|
||||
@ -83,9 +99,14 @@ class LongFrame(ControlFrame):
|
||||
self.medium = MeterbusTypeConversion.mediumCode(self.data[7])
|
||||
self.accessNo = self.data[8]
|
||||
self.status = self.data[9]
|
||||
self.signature = self.data[10:]
|
||||
self.signature = [s for s in self.data[10:]]
|
||||
if self.signature[0] != 0 or self.signature[1] != 0:
|
||||
raise InvalidFrameException("signature should be zero")
|
||||
|
||||
def getJSON(self):
|
||||
j = {'identNr': self.identNr, 'manufacturer': self.manufacturer, 'version': self.version, 'medium': self.medium,
|
||||
'accessNo': self.accessNo, 'status': self.status, 'signature': self.signature}
|
||||
return j
|
||||
|
||||
class DataInformationElement(object):
|
||||
def __init__(self, data):
|
||||
@ -109,8 +130,200 @@ class LongFrame(ControlFrame):
|
||||
return j
|
||||
|
||||
class DataInformationBlock(DataInformationElement):
|
||||
VALUE_LENGTH_MAP = [0, 1, 2, 3, 4, 4, 6, 8, 0, 1, 2, 3, 4, -1, 6, 0 ]
|
||||
|
||||
DATA_FIELD_CODES = (
|
||||
('No Data', 0, None),
|
||||
('8 Bit Integer', 1, lambda x: x[0]),
|
||||
('16 Bit Integer', 2, lambda x: (x[1] << 8) + x[0]),
|
||||
('24 Bit Integer', 3, lambda x: (x[2] << 16) + (x[1] << 8) + x[0]),
|
||||
('32 Bit Integer', 4, lambda x: (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]),
|
||||
('32 Bit Real', 4, lambda x: struct.unpack('f', x.getAll())[0]),
|
||||
('48 Bit Integer', 6, lambda x: (x[5] << 40) + (x[4] << 32) + (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]),
|
||||
('64 Bit Integer', 8, lambda x: (x[7] << 56) + (x[6] << 48) + (x[5] << 40) + (x[4] << 32) + (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]),
|
||||
('Selection for Readout', 0, None),
|
||||
('2 Digit BCD', 1, lambda x: MeterbusTypeConversion.bcd(x)),
|
||||
('4 Digit BCD', 2, lambda x: MeterbusTypeConversion.bcd(x)),
|
||||
('6 Digit BCD', 3, lambda x: MeterbusTypeConversion.bcd(x)),
|
||||
('8 Digit BCD', 4, lambda x: MeterbusTypeConversion.bcd(x)),
|
||||
('variable length', -1, None),
|
||||
('12 Digit BCD', 6, lambda x: MeterbusTypeConversion.bcd(x)),
|
||||
('Special Function', 0, None),
|
||||
)
|
||||
VIF_CODES = (
|
||||
(0b01111000, 0b00000000, 'Energy', 'Wh', 0b00000111, lambda d: 10**(d-3)),
|
||||
(0b01111000, 0b00001000, 'Energy', 'J', 0b00000111, lambda d: 10**d),
|
||||
(0b01111000, 0b00010000, 'Volume', 'm**3', 0b00000111, lambda d: 10**(d-6)),
|
||||
(0b01111000, 0b00011000, 'Mass', 'kg', 0b00000111, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b00100000, 'On Time', 'TimeCalc', 0b00000011, lambda d: d),
|
||||
(0b01111100, 0b00100100, 'Operating Time', 'TimeCalc', 0b00000011, lambda d: d),
|
||||
(0b01111000, 0b00101000, 'Power', 'W', 0b00000111, lambda d: 10**(d-3)),
|
||||
(0b01111000, 0b00110000, 'Power', 'J/h', 0b00000111, lambda d: 10**d),
|
||||
(0b01111000, 0b00111000, 'Volume Flow', 'm**3/h', 0b00000111, lambda d: 10**(d-6)),
|
||||
(0b01111000, 0b01000000, 'Volume Flow ext.', 'm**3/min', 0b00000111, lambda d: 10**(d-7)),
|
||||
(0b01111000, 0b01001000, 'Volume Flow ext.', 'm**3/s', 0b00000111, lambda d: 10**(d-9)),
|
||||
(0b01111000, 0b01010000, 'Mass Flow', 'kg/h', 0b00000111, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01011000, 'Flow Temperature', '°C', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01011100, 'Return Temperature', '°C', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01100000, 'Temperature Diff.', 'K', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01100100, 'Extern. Temp', '°C', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01101000, 'Pressure', 'bar', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111110, 0b01101100, 'Time Point', 'TimePointCalc', 0b00000001,lambda d: d),
|
||||
(0b01111111, 0b01101110, 'Units for H.C.A.', '', 0, None),
|
||||
(0b01111111, 0b01101111, 'Reserved', '', 0, None),
|
||||
(0b01111100, 0b01110000, 'Averaging Duration', 'TimeCalc', 0b00000011, lambda d: d),
|
||||
(0b01111100, 0b01110100, 'Actuality Duration', 'TimeCalc', 0b00000011, lambda d: d),
|
||||
(0b01111111, 0b01111000, 'Fabrication Number', '', 0, None),
|
||||
(0b01111111, 0b01111001, 'Enhanced Ident.', '', 0, None),
|
||||
(0b01111111, 0b01111010, 'Bus Address', '', 0, None),
|
||||
(0b11111111, 0b11111011, 'Extensions 1', 'Table8.4.4b', 0, None),
|
||||
(0b11111111, 0b11111101, 'Extensions 2', 'Table8.4.4a', 0, None),
|
||||
)
|
||||
|
||||
TABLE844a = (
|
||||
(0b01111100, 0b00000000, 'Credit', 'Currency Unit', 0b00000011, lambda d: 10*(d-3)),
|
||||
(0b01111100, 0b00000100, 'Debit', 'Currency Unit', 0b00000011, lambda d: 10*(d-3)),
|
||||
(0b01111111, 0b00001000, 'Access Number', '', 0, None),
|
||||
(0b01111111, 0b00001001, 'Medium', '', 0, None),
|
||||
(0b01111111, 0b00001010, 'Manufacturer', '', 0, None),
|
||||
(0b01111111, 0b00001011, 'Parameter set ident','', 0, None),
|
||||
(0b01111111, 0b00001100, 'Model / Version', '', 0, None),
|
||||
(0b01111111, 0b00001101, 'Hardware Version', '', 0, None),
|
||||
(0b01111111, 0b00001110, 'Firmware Version', '', 0, None),
|
||||
(0b01111111, 0b00001111, 'Software Version', '', 0, None),
|
||||
(0b01111111, 0b00010000, 'Customer Location', '', 0, None),
|
||||
(0b01111111, 0b00010001, 'Customer', '', 0, None),
|
||||
(0b01111111, 0b00010010, 'Access Code User', '', 0, None),
|
||||
(0b01111111, 0b00010011, 'Access Code Operator','', 0, None),
|
||||
(0b01111111, 0b00010100, 'Access Code System Operator','', 0, None),
|
||||
(0b01111111, 0b00010101, 'Access Code Developer','', 0, None),
|
||||
(0b01111111, 0b00010110, 'Password', '', 0, None),
|
||||
(0b01111111, 0b00010111, 'Error Flags', '', 0, None),
|
||||
(0b01111111, 0b00011000, 'Error Mask', '', 0, None),
|
||||
(0b01111111, 0b00011001, 'Reserved', '', 0, None),
|
||||
(0b01111111, 0b00011010, 'Digital Output', '', 0, None),
|
||||
(0b01111111, 0b00011011, 'Digital Input', '', 0, None),
|
||||
(0b01111111, 0b00011100, 'Baudrate', 'Baud', 0, None),
|
||||
(0b01111111, 0b00011101, 'response delay time', '', 0, None),
|
||||
(0b01111111, 0b00011110, 'retry', '', 0, None),
|
||||
(0b01111111, 0b00011111, 'Reserved', '', 0, None),
|
||||
(0b01111111, 0b00100000, 'First storage', '', 0, None),
|
||||
(0b01111111, 0b00100001, 'Last storage', '', 0, None),
|
||||
(0b01111111, 0b00100010, 'Size of storage blk', '', 0, None),
|
||||
(0b01111111, 0b00100011, 'Reserved', '', 0, None),
|
||||
(0b01111100, 0b00100100, 'Storage interval', '', 0b00000011, lambda d: d),
|
||||
(0b01111111, 0b00101000, 'Storage interval month', '', 0, None),
|
||||
(0b01111111, 0b00101001, 'Storage interval years', '', 0, None),
|
||||
(0b01111111, 0b00101010, 'Reserved', '', 0, None),
|
||||
(0b01111111, 0b00101011, 'Reserved', '', 0, None),
|
||||
(0b01111111, 0b00101100, 'Duration since last read', '', 0b00000011, lambda d: d),
|
||||
(0b01111111, 0b00110000, 'Start of tariff', '', 0, None),
|
||||
(0b01111111, 0b00110000, 'Duration of tariff', '', 0b00000011, lambda d: d),
|
||||
(0b01111111, 0b00110100, 'Period of tariff', '', 0b00000011, lambda d: d),
|
||||
(0b01111111, 0b00111010, 'dimensionless', '', 0, None),
|
||||
(0b01111111, 0b00111011, 'Reserved', '', 0, None),
|
||||
(0b01111100, 0b00111100, 'Reserved', '', 0, None),
|
||||
(0b01110000, 0b01000000, 'Voltage', 'V', 0b00001111, lambda d: 10**(d-9)),
|
||||
(0b01110000, 0b01010000, 'Current', 'A', 0b00001111, lambda d: 10**(d-12)),
|
||||
(0b01111111, 0b01100000, 'Reset Counter', '', 0, None),
|
||||
(0b01111111, 0b01100001, 'Cumulation Counter', '', 0, None),
|
||||
(0b01111111, 0b01100010, 'Control Signal', '', 0, None),
|
||||
(0b01111111, 0b01100011, 'Day of week', '', 0, None),
|
||||
(0b01111111, 0b01100100, 'Week number', '', 0, None),
|
||||
(0b01111111, 0b01100101, 'Time point of day change', '', 0, None),
|
||||
(0b01111111, 0b01100110, 'State of parameter activation', '', 0, None),
|
||||
(0b01111111, 0b01100111, 'Special supplier info', '', 0, None),
|
||||
(0b01111100, 0b01101000, 'Duration since last cumulation', '', 0b00000011, lambda d: d),
|
||||
(0b01111100, 0b01101100, 'Operating time battery', '', 0b00000011, lambda d: d),
|
||||
(0b01111111, 0b01110000, 'Date/time of bat. change', '', 0, None)
|
||||
)
|
||||
|
||||
TABLE844b = (
|
||||
(0b01111110, 0b00000000, 'Energy', 'MWh', 0b00000001, lambda d: 10**(d-1)),
|
||||
(0b01111110, 0b00000010, 'Reserved', '', 0, None),
|
||||
(0b01111100, 0b00000100, 'Reserved', '', 0, None),
|
||||
(0b01111110, 0b00001000, 'Energy', 'GJ', 0b00000001, lambda d: 10**(d-1)),
|
||||
(0b01111110, 0b00001010, 'Reserved', '', 0, None),
|
||||
(0b01111100, 0b00001100, 'Reserved', '', 0, None),
|
||||
(0b01111110, 0b00010000, 'Volume', 'm**3', 0b00000001, lambda d: 10**(d+2)),
|
||||
(0b01111110, 0b00010010, 'Reserved', '', 0, None),
|
||||
(0b01111100, 0b00010100, 'Reserved', '', 0, None),
|
||||
(0b01111110, 0b00011000, 'Mass', 't', 0b00000001, lambda d: 10**(d+2)),
|
||||
(0b01111111, 0b00100001, 'Volume', 'feet**3', 0, lambda d: 0.1),
|
||||
(0b01111111, 0b00100010, 'Volume', 'am. gallon', 0, lambda d: 0.1),
|
||||
(0b01111111, 0b00100011, 'Volume', 'am. gallon', 0, lambda d: 1),
|
||||
(0b01111111, 0b00100100, 'Volume flow', 'am. gallon/min', 0, lambda d: 0.001),
|
||||
(0b01111111, 0b00100101, 'Volume flow', 'am. gallon/min', 0, lambda d: 1),
|
||||
(0b01111111, 0b00100110, 'Volume flow', 'am. gallon/h', 0, lambda d: 1),
|
||||
(0b01111111, 0b00100111, 'Reserved', '', 0, None),
|
||||
(0b01111110, 0b00101000, 'Power', 'MW', 0b00000001, lambda d: 10**(d-1)),
|
||||
(0b01111110, 0b00101010, 'Reserved', '', 0, None),
|
||||
(0b01111100, 0b00101100, 'Reserved', '', 0, None),
|
||||
(0b01111110, 0b00110000, 'Power', 'GJ/h', 0b00000001, lambda d: 10**(d-1)),
|
||||
(0b01111100, 0b01011000, 'Flow Temperature', '°F', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01011100, 'Return Temperature', '°F', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01100000, 'Temperature Diff.', '°F', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01100100, 'Extern. Temp.', '°F', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111000, 0b01101000, 'Reserved', '', 0, None),
|
||||
(0b01111100, 0b01110000, 'Cold/Warm Temp.Limit', '°F', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111100, 0b01110100, 'Cold/Warm Temp.Limit', '°C', 0b00000011, lambda d: 10**(d-3)),
|
||||
(0b01111000, 0b01111000, 'cumul. count max power', 'W', 0b00000111, lambda d: 10**(d-3))
|
||||
)
|
||||
|
||||
|
||||
TIME_UNITS = ('seconds', 'minutes', 'hours', 'days')
|
||||
TIME_POINT_UNITS = ('date', 'time & date')
|
||||
|
||||
@classmethod
|
||||
def extVifCalc(cls, table, vife):
|
||||
retDescr = 'unknown'
|
||||
retUnit = 'unknown'
|
||||
retRange = 'unknown'
|
||||
|
||||
for vifeCode in table:
|
||||
# print vifeCode
|
||||
(mask, value, descr, unit, rangeMask, rangeFunc) = vifeCode
|
||||
if (vife & mask) == value:
|
||||
if rangeFunc == None:
|
||||
retRange = 1
|
||||
else:
|
||||
rangeHelper = vife & rangeMask
|
||||
retRange = rangeFunc(rangeHelper)
|
||||
retDescr = descr
|
||||
retUnit = unit
|
||||
break
|
||||
return (retDescr, retUnit, retRange)
|
||||
|
||||
|
||||
@classmethod
|
||||
def vifCalc(cls, vif, vife):
|
||||
retDescr = 'unknown'
|
||||
retUnit = 'unknown'
|
||||
retRange = 1
|
||||
for vifCode in cls.VIF_CODES:
|
||||
(mask, value, descr, unit, rangeMask, rangeFunc) = vifCode
|
||||
if (vif & mask) == value:
|
||||
if unit == 'TimeCalc':
|
||||
retDescr = descr
|
||||
retUnit = cls.TIME_UNITS[vif & rangeMask]
|
||||
retRange = None
|
||||
elif unit == 'Table8.4.4a':
|
||||
(retDescr, retUnit, retRange) = cls.extVifCalc(cls.TABLE844a, vife[0])
|
||||
elif unit == 'Table8.4.4b':
|
||||
(retDescr, retUnit, retRange) = cls.extVifCalc(cls.TABLE844b, vife[0])
|
||||
elif unit == 'TimePointCalc':
|
||||
retDescr = descr
|
||||
retUnit = cls.TIME_POINT_UNITS[vif & rangeMask]
|
||||
retRange = None
|
||||
else:
|
||||
retDescr = descr
|
||||
retUnit = unit
|
||||
if rangeFunc != None:
|
||||
rangeHelper = vif & rangeMask
|
||||
retRange = rangeFunc(rangeHelper)
|
||||
break
|
||||
# print("vifCalc: %s %s %s %s" % (retDescr, retRange, retUnit, rangeHelper))
|
||||
return (retDescr, retUnit, retRange)
|
||||
|
||||
|
||||
def parse(self):
|
||||
self.dif = self.data[self.consumed]
|
||||
self.consumed += 1
|
||||
@ -134,51 +347,27 @@ class LongFrame(ControlFrame):
|
||||
break
|
||||
self.vifData = []
|
||||
if self.vif & 0x7f == 0x7c:
|
||||
dataLength = self.data[self.consumed]
|
||||
vifDataLength = self.data[self.consumed]
|
||||
self.consumed += 1
|
||||
self.vifData = [v for v in self.data[self.consumed:self.consumed+dataLength]]
|
||||
self.consumed += dataLength
|
||||
self.userData = [u for u in self.data[self.consumed:self.consumed+LongFrame.DataInformationBlock.VALUE_LENGTH_MAP[self.dif&0x0f]]]
|
||||
self.vifData = [v for v in self.data[self.consumed:self.consumed+vifDataLength]]
|
||||
self.consumed += vifDataLength
|
||||
userDataLength = LongFrame.DataInformationBlock.DATA_FIELD_CODES[self.dif&0x0f][1]
|
||||
self.userData = [u for u in self.data[self.consumed:self.consumed+userDataLength]]
|
||||
self.consumed += userDataLength
|
||||
|
||||
self.value = LongFrame.DataInformationBlock.DATA_FIELD_CODES[self.dif & 0x0f][2](self.userData)
|
||||
self.dataType = LongFrame.DataInformationBlock.DATA_FIELD_CODES[self.dif & 0x0f][0]
|
||||
(self.quantity, self.unit, self.factor) = LongFrame.DataInformationBlock.vifCalc(self.vif, self.vife)
|
||||
|
||||
return self.consumed
|
||||
|
||||
def value(self):
|
||||
res = 0
|
||||
difCode = self.dif & 0x0f
|
||||
if difCode == 0:
|
||||
# 0
|
||||
pass
|
||||
elif difCode == 1:
|
||||
# 8bit int
|
||||
res = self.userData[0]
|
||||
elif difCode == 2:
|
||||
# 16bit int
|
||||
res = (self.userData[1] << 8) + self.userData[0]
|
||||
elif difCode == 3:
|
||||
# 24bit int
|
||||
res = (self.userData[2] << 16) + (self.userData[1] << 8) + self.userData[0]
|
||||
elif difCode == 4:
|
||||
# 32bit int
|
||||
res = (self.userData[3] << 24) + (self.userData[2] << 16) + (self.userData[1] << 8) + self.userData[0]
|
||||
elif difCode == 5:
|
||||
# 32bit float
|
||||
res = 1.0
|
||||
elif difCode == 6:
|
||||
# 48bit int
|
||||
res = (self.userData[5] << 40) + (self.userData[4] << 32) + (self.userData[3] << 24) + (self.userData[2] << 16) + (self.userData[1] << 8) + self.userData[0]
|
||||
elif difCode == 7:
|
||||
# 64bit int
|
||||
res = (self.userData[7] << 56) + (self.userData[6] << 48) + (self.userData[5] << 40) + (self.userData[4] << 32) + (self.userData[3] << 24) + (self.userData[2] << 16) + (self.userData[1] << 8) + self.userData[0]
|
||||
elif difCode == 8:
|
||||
# strange
|
||||
res = 0
|
||||
elif difCode in [9, 10, 11, 12, 14]:
|
||||
res = MeterbusTypeConversion.bcd(self.userData)
|
||||
return res
|
||||
|
||||
|
||||
def getJSON(self):
|
||||
j = {'dif': self.dif, 'dife': self.dife, 'vif': self.vif, 'vife': self.vife,
|
||||
'vifData': self.vifData, 'userData':self.userData, 'value':self.value()}
|
||||
'vifData': self.vifData, 'userData':self.userData,
|
||||
'dataType': self.dataType, 'value':self.value,
|
||||
'quantity': self.quantity, 'factor': self.factor, 'unit': self.unit,
|
||||
}
|
||||
return j
|
||||
|
||||
|
||||
@ -193,14 +382,20 @@ class LongFrame(ControlFrame):
|
||||
consumed = 0
|
||||
#print("Telegram length: %d" % len(self.telegram))
|
||||
while True:
|
||||
curDib = LongFrame.DataInformationElement.create(self.telegram[(19 + consumed):])
|
||||
curDib = LongFrame.DataInformationElement.create(self.telegram[(19 + consumed):-2])
|
||||
consumed += curDib.parse()
|
||||
self.dib.append(curDib)
|
||||
#print("PayloadLength: %d, Consumed: %d" % (self.payloadLength, consumed))
|
||||
print("DIB: %s" % str(curDib.getJSON()))
|
||||
if (consumed + 12 + 3 - 1) >= self.payloadLength:
|
||||
#print("DIB: %s" % str(curDib.getJSON()))
|
||||
# 3 for the fields, 12 for the fixed data header, 2 for checksum and stop code, 1 off since consumed is an index and no length
|
||||
if (consumed + 3 + 12 + 2 - 1) >= self.payloadLength:
|
||||
break
|
||||
|
||||
def getJSON(self):
|
||||
superJSON = super(LongFrame, self).getJSON()
|
||||
j = {'header': self.fixedDataHeader.getJSON(), 'dib': [dib.getJSON() for dib in self.dib]}
|
||||
j.update(superJSON)
|
||||
return j
|
||||
|
||||
class Telegram(object):
|
||||
def __init__(self):
|
||||
@ -228,5 +423,9 @@ class Telegram(object):
|
||||
|
||||
self.frame.parse()
|
||||
|
||||
def getJSON(self):
|
||||
j = {'frameType': self.frame.__class__.__name__, 'frame': self.frame.getJSON()}
|
||||
return j
|
||||
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@ from MeterbusLibExceptions import MediumConversionException
|
||||
|
||||
def bcd(data):
|
||||
v = ""
|
||||
for c in data:
|
||||
for c in reversed(data):
|
||||
v += str((c & 0xf0) >> 4)
|
||||
v += str(c & 0x0f)
|
||||
return v
|
||||
|
8
test2.py
8
test2.py
@ -6,9 +6,13 @@ Created on 11.06.2015
|
||||
|
||||
|
||||
import MeterbusLib
|
||||
import json
|
||||
|
||||
inputOkLongFrame_1phase_electric = "68 38 38 68 08 53 72 17 00 13 00 2E 19 24 02 D6 00 00 00 8C 10 04 01 02 00 00 8C 11 04 01 02 00 00 02 FD C9 FF 01 E4 00 02 FD DB FF 01 03 00 02 AC FF 01 01 00 82 40 AC FF 01 FA FF 20 16"
|
||||
inputOkLongFrame_1phase_electric = "68 38 38 68 " + "08 53 72 " + "17 00 13 00 2E 19 24 02 D6 00 00 00 " + "8C 10 04 01 02 00 00 " + "8C 11 04 01 02 00 00 " + "02 FD C9 FF 01 E4 00 " + "02 FD DB FF 01 03 00 " + "02 AC FF 01 01 00 " + "82 40 AC FF 01 FA FF " + "20 16"
|
||||
inputOkLongFrame_3phase_electric = "68 92 92 68 08 50 72 81 14 01 11 2E 19 16 02 88 00 00 00 8C 10 04 58 43 86 00 8C 11 04 58 43 86 00 8C 20 04 00 00 00 00 8C 21 04 00 00 00 00 02 FD C9 FF 01 E4 00 02 FD DB FF 01 5A 00 02 AC FF 01 D2 00 82 40 AC FF 01 00 00 02 FD C9 FF 02 DF 00 02 FD DB FF 02 0F 00 02 AC FF 02 21 00 82 40 AC FF 02 FD FF 02 FD C9 FF 03 E3 00 02 FD DB FF 03 04 00 02 AC FF 03 02 00 82 40 AC FF 03 F4 FF 02 FF 68 00 00 02 AC FF 00 F5 00 82 40 AC FF 00 F1 FF 01 FF 13 00 F4 16"
|
||||
|
||||
telegram = MeterbusLib.Telegram()
|
||||
telegram.fromHexString(inputOkLongFrame_1phase_electric)
|
||||
telegram.fromHexString(inputOkLongFrame_3phase_electric)
|
||||
telegram.parse()
|
||||
|
||||
print(json.dumps(telegram.getJSON(), indent=2))
|
||||
|
Loading…
x
Reference in New Issue
Block a user