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):
        self.relativeIndex, self.paramName, self.desc, self.dataType, rdStr, self.size, *rest = parmData
        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:
            self.analysisValue(value)
    
    def analysisValue(self, value):
        pass

    def unpackU8(self, value):
    	return str(struct.unpack('>b', value))

    def unpackU16(self, value):
    	return str(struct.unpack('>h', value))

    def unpackFloat(self, value):
    	return str(struct.unpack('>f', value))

    def unpackStr(self, value):
    	return struct.unpack('{}s'.format{str(len(value))}, value)

    def unpack101(self, value):
    	valueByte, statusByte = value[:4], value[4]
    	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])
        return


    def unpackDS36(self, value):
    	EU100Byte, EU0Byte, unitByte, decPointByte = value[:4], value[4:], value[8:10], value[10]
    	EU100 = self.unpackFloat(EU100Byte)
    	EU0 = self.unpackFloat(EU0Byte)
    	decPoint = self.unpackU8(decPointByte)
    	unitValue = self.unpackU16(unitByte)
    	unit = self.unitConver(unitValue)
    	displayStr = '有效上限:{} 有效下限:{} 单位:{} 小数点:{}'.format(EU100, EU0, unit, decPoint)
    	return displayStr

    def unpackDS37(self, value):
    	actualByte, permitByte, normalByte = value[0], value[1], value[2]
    	actualMode = self.unpackU8(actualByte)
    	permitMode = self.unpackU8(permitByte)
    	normalMode = self.unpackU8(normalByte)
    	displayStr = '实际模式:{} 允许模式:{} 正常模式:{}'.format(actualMode, permitMode, normalMode)
    	return displayStr

    def unpackDS39(self, value):
    	unacknowledgByte, alarmStateByte, timeStampByte, subcodeByte, alarmValueByte = value[0], value[1], 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:{} 有无报警{} 时间戳:{} 报警原因:{} 引起报警的值:{}'.format(unacknowledg, alarmState, timeStr, subcode, alarmValue)
    	return displayStr

    def unpackDS50(self, value):
    	simulateStatusByte, simulateValueByte, simulateEnabledByte = value[0], value[1:5], value[5]
    	simulateStatus = self.unpackU8(simulateStatusByte)
    	simulateValue = self.unpackFloat(simulateValueByte)
    	simulateEnabled = self.unpackU8(simulateEnabledByte)
    	displayStr = '仿真值状态:{} 仿真值:{} 是否启用仿真:{}'
    	return displayStr

    def packU8(self, value):
    	return struct.pack('>b', value)

    def packU16(self, value):
    	return struct.pack('>h', value)

    def packFloat(self, value):
    	return struct.pack('>f', 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 unitConver(self, unitValue):
    	unit, desc = '1', '1'
    	return unit + desc