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

236 lines
9.1 KiB
Python

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 = '值:{}状态:{}'.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'))