from enum import Enum import struct import time class ParmEnum(Enum): readonly = 0 writeable = 1 class Parm(): name = None value = '读取错误' slot = None relativeIndex = None realIndex = None dataType = None size = None desc = None rdType = None def __init__(self, parmData:list, slot:int, startIndex:int, block): # print(startIndex, self.relativeIndex) # print(parmData) self.relativeIndex, self.paramName, self.desc, self.dataType, rdStr, self.size, *rest = parmData self.relativeIndex = int(self.relativeIndex) self.rdType = ParmEnum.readonly if rdStr == 'r' else ParmEnum.writeable self.realIndex = startIndex + self.relativeIndex self.slot = slot self.DPV1Master = block.DPV1Master self.address = block.address # print(self.relativeIndex, self.paramName, self.desc, self.dataType, self.rdType, self.size) def readValue(self): value = self.DPV1Master.readParm(address = self.address, slot = self.slot, index = self.realIndex, length = self.size) if value == '读取错误': return '读取错误' else: return self.unpackValue(value) def writeParm(self, values): print(*values) valueByte = self.packValue(values) result = self.DPV1Master.writeParm(address = self.address, slot = self.slot, index = self.realIndex, length = self.size, valueByte = valueByte) def unpackValue(self, value): match self.dataType: case 'Unsigned8': return self.unpackU8(value) case 'Unsigned16': return self.unpackU16(value) case 'Unsigned32': return self.unpackU32(value) case 'Float': return self.unpackFloat(value) case '101': return self.unpack101(value) case 'DS-32': return self.unpackDS32(value) case 'DS-36': return self.unpackDS36(value) case 'DS-37': return self.unpackDS37(value) case 'DS-39': return self.unpackDS39(value) case 'DS-50': return self.unpackDS50(value) case 'OctetString' | 'VisibleString': return self.unpackStr(value) case 'FloatList2': return self.unpackFloatList2(value) case _: return str(value) def packValue(self, values): match self.dataType: case 'Unsigned8': return self.packU8(values[0]) case 'Unsigned16': return self.packU16(values[0]) case 'Unsigned32': return self.packU32(values[0]) case 'Float': return self.packFloat(values[0]) case '101': return self.pack101(*values) case 'DS-32': return self.packDS32(*values) case 'DS-36': return self.packDS36(*values) case 'DS-50': return self.packDS50(*values) case 'OctetString' | 'VisibleString': return self.packStr(values[0]) case 'FloatList2': return self.packFloatList2(*values) case _: return def unpackU8(self, value): return str(struct.unpack('>b', value)[0]) def unpackU16(self, value): return str(struct.unpack('>h', value)[0]) def unpackU32(self, value): return str(struct.unpack('>i', value)[0]) def unpackFloat(self, value): return str(round(struct.unpack('>f', value)[0], 4)) def unpackStr(self, value): # return struct.unpack('{}s'.format(str(len(value))), value)[0] # print(value,2222) # print(struct.unpack('{}s'.format(str(len(value))), value)[0]) try: return value.decode('ASCII', errors = 'ignore') except Exception as e: print(e) def unpack101(self, value): valueByte, statusByte = value[:4], value[4].to_bytes(1, byteorder='little') value = self.unpackFloat(valueByte) status = self.unpackU8(statusByte) displayStr = '值:{}\r\n状态:{}'.format(value, status) return displayStr def unpackDS32(self, value): reserved = self.unpackU8(value[0:1]) blockObject = self.unpackU8(value[1:2]) parentClass = self.unpackU8(value[2:3]) clas = self.unpackU8(value[3:4]) devRev = self.unpackU16(value[4:6]) devRevComp = self.unpackU16(value[6:8]) ddRevision = self.unpackStr(value[8:10]) profile = self.unpackStr(value[10:12]) profileRevision = self.unpackU16(value[12:14]) executionTime = self.unpackU8(value[14:15]) numberOfParameters = self.unpackU16(value[15:17]) addressOfView1 = self.unpackU16(value[17:19]) numberOfViews = self.unpackU8(value[19:20]) # print(clas, parentClass) return parentClass def unpackDS36(self, value): print(len(value)) EU100Byte, EU0Byte, unitByte, decPointByte = value[:4], value[4:8], value[8:10], value[10].to_bytes(1, byteorder='little') EU100 = self.unpackFloat(EU100Byte) EU0 = self.unpackFloat(EU0Byte) decPoint = self.unpackU8(decPointByte) unitValue = self.unpackU16(unitByte) unit = self.unitConver(unitValue) displayStr = '有效上限:{}\r\n有效下限:{}\r\n单位:{}\r\n小数点:{}'.format(EU100, EU0, unit, decPoint) return displayStr def unpackDS37(self, value): actualByte, permitByte, normalByte = value[0].to_bytes(1, byteorder='little'), value[1].to_bytes(1, byteorder='little'), value[2].to_bytes(1, byteorder='little') # print(type(actualByte), permitByte, normalByte) actualMode = self.unpackU8(actualByte) permitMode = self.unpackU8(permitByte) normalMode = self.unpackU8(normalByte) displayStr = '实际模式:{}\r\n允许模式:{}\r\n正常模式:{}'.format(actualMode, permitMode, normalMode) return displayStr def unpackDS39(self, value): unacknowledgByte, alarmStateByte, timeStampByte, subcodeByte, alarmValueByte = value[0].to_bytes(1, byteorder='little'), value[1].to_bytes(1, byteorder='little'), value[2:10], value[10:12], value[12:16] unacknowledg = self.unpackU8(unacknowledgByte) alarmState = self.unpackU8(alarmStateByte) subcode = self.unpackU16(subcodeByte) alarmValue = self.unpackFloat(alarmValueByte) timestamp = int.from_bytes(timeStampByte, byteorder='big') timeStr = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)) displayStr = 'Unacknowledged:{}\r\n有无报警{}\r\n时间戳:{}\r\n报警原因:{}\r\n引起报警的值:{}'.format(unacknowledg, alarmState, timeStr, subcode, alarmValue) return displayStr def unpackDS50(self, value): simulateStatusByte, simulateValueByte, simulateEnabledByte = value[0].to_bytes(1, byteorder='little'), value[1:5], value[5].to_bytes(1, byteorder='little') simulateStatus = self.unpackU8(simulateStatusByte) simulateValue = self.unpackFloat(simulateValueByte) simulateEnabled = self.unpackU8(simulateEnabledByte) displayStr = '仿真值状态:{}\r\n仿真值:{}\r\n是否启用仿真:{}' return displayStr def unpackFloatList2(self, value): float1Byte, float2Byte = value[:4], value[4:8] float1 = self.unpackFloat(float1Byte) float2 = self.unpackFloat(float2Byte) displayStr = '值1:{}\r\n值2:{}'.format(float1, float2) return displayStr def packU8(self, value): return struct.pack('>b', int(value)) def packU16(self, value): return struct.pack('>h', int(value)) def packFloat(self, value): return struct.pack('>f', float(value)) def packU32(self, value): return struct.pack('>i', int(value)) def pack101(self, value, status): valueByte = self.packFloat(value) statusByte = self.packU8(status) packedData = valueByte + statusByte return packedData def packDS36(self, EU100, EU0, unitValue, decPoint): EU100Byte = self.packFloat(EU100) EU0Byte = self.packFloat(EU0) unitByte = self.packU16(unitValue) decPointByte = self.packU8(decPoint) packedData = EU100Byte + EU0Byte + unitByte + decPointByte return packedData def packDS50(self, simulateStatus, simulateValue, simulateEnabled): simulateStatusByte = self.packU8(simulateStatus) simulateValueByte = self.packFloat(simulateValue) simulateEnabledByte = self.packU8(simulateEnabled) packedData = simulateStatusByte + simulateValueByte + simulateEnabledByte return packedData def packFloatList2(self, float1, float2): float1Byte = self.packFloat(float1) float2Byte = self.packFloat(float2) packedData = float1Byte + float2Byte return packedData def unitConver(self, unitValue): unit, desc = '1', '1' return unit + desc def packStr(self, value): return struct.pack('>{}s'.format(len(value)), value.encode('ASCII'))