You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.6 KiB

import struct
from .CRC16 import modbus_crc16
def get_bit(byte, position):
return (byte >> position) & 1
class IdiBusMES:
def __init__(self, data: bytearray):
if len(data) == 0:
raise TypeError("Data is an empty bytearray")
self.data = data
def validate(self):
if self.getCRC() != modbus_crc16(self.data[0:-2]):
return -1
else:
return 0
def getAddress(self):
return int(self.data[0])
def getCRC(self):
return self.data[-2::]
def __repr__(self):
return f"Addr:{self.getAddress()}, Body:{self.data[1::]}"
class IdiBusMMESParser(IdiBusMES):
def __init__(self, data: bytearray):
super().__init__(data)
def getMMPS(self):
return self.data[1]
def getLongMes(self):
return get_bit(int(self.data[1]), 0)
def getMesType(self):
return get_bit(int(self.data[1]), 1)
def getAlarm(self):
return get_bit(int(self.data[1]), 6)
def getEncStatus(self):
return get_bit(int(self.data[1]), 7)
def getDEV(self):
return int(self.data[2])
def getCHAN(self):
return int(self.data[3])
def getCMD(self):
return int(self.data[4])
def getData(self):
return self.data[4:-2]
class IdiBusMMESGParser(IdiBusMES):
def __init__(self, data: bytearray):
super().__init__(data)
def getMMPS(self):
return int(self.data[1])
def getCMD(self):
return int(self.data[2])
def getData(self):
return self.data[3:-2]
class IdiBusSMESParser(IdiBusMES):
def __init__(self, data: bytearray):
super().__init__(data)
def getSPDU(self):
return int(self.data[1])
def getErrorBit(self):
return get_bit(self.data[1], 0)
def getLongMessage(self):
return get_bit(self.data[1], 1)
def getErrcode(self):
return int(self.data[2])
def getData(self):
return self.data[3:-2]
def getDataStruct(self, format_string):
try:
unpacked = struct.unpack(format_string, self.getData())
return unpacked
except struct.error as e:
print(f"Parse error: {e}")
return None
except UnicodeDecodeError as e:
print(f"Parse error: {e}")
return None
class IdiBusDeviceInfoParser():
# Формат: 'B H I f 10s'
# B - unsigned char (1 байт)
# H - unsigned short (2 байта)
# I - unsigned int (4 байта)
# f - float (4 байта)
# 10s - строка из 10 байт
format_string = '<B 3s 6s 3s 2B 7s 6s 2B I'
def __init__(self, data: bytearray):
if len(data) == 0:
raise TypeError("Data is an empty bytearray")
self.data = data
#print(data[-4::])
def getStruct(self):
try:
unpacked = struct.unpack(self.format_string, self.data)
packed = {
'Padding': unpacked[0],
'GS1_country': unpacked[1].decode('utf-8'),
'GS1_company': unpacked[2].decode('utf-8'),
'ModuleType': unpacked[3].decode('utf-8'),
'HW_revison': str(unpacked[4]) +"." + str(unpacked[5]),
'SN': unpacked[6].decode('utf-8'),
'MAC': unpacked[7].decode('utf-8'),
'SW': str(unpacked[8]) + "." + str(unpacked[9]),
'AppCRC': hex(unpacked[10]),
}
return packed
except struct.error as e:
print(f"Parse error: {e}")
return None
except UnicodeDecodeError as e:
print(f"Parse error: {e}")
return None