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}. got len {len(self.getData())}") 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 = '