from construct import ( Byte, Bytes, Float32l, Struct, Computed, this, GreedyBytes, ) # Base packet structure # Format: [header, cmd, type, length, data..., checksum] packet = Struct( "header" / Byte, "cmd" / Byte, "type" / Byte, "length" / Byte, "data" / Bytes(this.length), "checksum" / Byte, "checksum_valid" / Computed( lambda ctx: (ctx.type + ctx.length + sum(ctx.data)) % 0x100 == ctx.checksum ), ) # Data structures for different response types float_response = Struct( "value" / Float32l, ) float3_response = Struct( "value1" / Float32l, "value2" / Float32l, "value3" / Float32l, ) byte_response = Struct( "value" / Byte, ) # All data structure (type 255) all_data = Struct( "inputVoltage" / Float32l, # 0-4 "setVoltage" / Float32l, # 4-8 "setCurrent" / Float32l, # 8-12 "outputVoltage" / Float32l, # 12-16 "outputCurrent" / Float32l, # 16-20 "outputPower" / Float32l, # 20-24 "temperature" / Float32l, # 24-28 "group1setVoltage" / Float32l, # 28-32 "group1setCurrent" / Float32l, # 32-36 "group2setVoltage" / Float32l, # 36-40 "group2setCurrent" / Float32l, # 40-44 "group3setVoltage" / Float32l, # 44-48 "group3setCurrent" / Float32l, # 48-52 "group4setVoltage" / Float32l, # 52-56 "group4setCurrent" / Float32l, # 56-60 "group5setVoltage" / Float32l, # 60-64 "group5setCurrent" / Float32l, # 64-68 "group6setVoltage" / Float32l, # 68-72 "group6setCurrent" / Float32l, # 72-76 "overVoltageProtection" / Float32l, # 76-80 "overCurrentProtection" / Float32l, # 80-84 "overPowerProtection" / Float32l, # 84-88 "overTemperatureProtection" / Float32l, # 88-92 "lowVoltageProtection" / Float32l, # 92-96 "brightness" / Byte, # 96 "volume" / Byte, # 97 "metering" / Byte, # 98 "outputCapacity" / Float32l, # 99-103 "outputEnergy" / Float32l, # 103-107 "outputClosedRaw" / Byte, # 107 "protectionStateRaw" / Byte, # 108 "modeRaw" / Byte, # 109 "unknown1" / Byte, # 110 "upperLimitVoltage" / Float32l, # 111-115 "upperLimitCurrent" / Float32l, # 115-119 "unknownVoltage" / Float32l, # 119-123 "unknownCurrent" / Float32l, # 123-127 "unknown2" / Float32l, # 127-131 "unknown3" / Float32l, # 131-135 "unknown4" / Float32l, # 135-139 "extra" / GreedyBytes, # Any extra data "meteringClosed" / Computed(lambda ctx: ctx.metering == 0), "outputClosed" / Computed(lambda ctx: ctx.outputClosedRaw == 1), )