79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
# dmm_decoder.py
|
|
|
|
import json
|
|
|
|
class DMMDecoder:
|
|
"""Base class for DMM screen/binary decoders."""
|
|
def __init__(self, config):
|
|
self.xorkey = self.str2hexarray(config["xorkey"])
|
|
self.icon_regions = config["icon_regions"]["default"]
|
|
self.icon_table = config["icon_table"]
|
|
|
|
@staticmethod
|
|
def str2hexarray(string):
|
|
string = string.replace(' ', '').lower()
|
|
return [int(string[i:i+2], 16) for i in range(0, len(string), 2)]
|
|
|
|
@staticmethod
|
|
def bytewise_XOR(array, xorkey):
|
|
return [array[x] ^ xorkey[x % len(xorkey)] for x in range(len(array))]
|
|
|
|
@staticmethod
|
|
def hex2bin(array):
|
|
return [bin(x)[2:].zfill(8) for x in array]
|
|
|
|
@staticmethod
|
|
def flip_bits(array):
|
|
return [b[::-1] for b in array]
|
|
|
|
@staticmethod
|
|
def array2str(array):
|
|
return ''.join(array)
|
|
|
|
def extract_icon_bits(self, bitstring):
|
|
bits = self.icon_regions
|
|
# Concatenate bit ranges
|
|
return bitstring[bits[0]:bits[1]] + bitstring[bits[2]:bits[3]]
|
|
|
|
def decode_icons(self, icon_bits):
|
|
return [self.icon_table[i] for i, b in enumerate(icon_bits) if b == '1' and i < len(self.icon_table)]
|
|
|
|
def decode_packet(self, hexstring):
|
|
encoded_array = self.str2hexarray(hexstring)
|
|
# pad xorkey if needed
|
|
xorkey = (self.xorkey * ((len(encoded_array) // len(self.xorkey)) + 1))[:len(encoded_array)]
|
|
xordecoded = self.bytewise_XOR(encoded_array, xorkey)
|
|
binary = self.hex2bin(xordecoded)
|
|
flipped = self.flip_bits(binary)
|
|
bitstring = self.array2str(flipped)
|
|
icon_bits = self.extract_icon_bits(bitstring)
|
|
icons = self.decode_icons(icon_bits)
|
|
return {'icons': icons}
|
|
|
|
# Example derived decoder for ZT-5B (can be extended for other models)
|
|
class ZT5BDecoder(DMMDecoder):
|
|
def __init__(self, config):
|
|
super().__init__(config)
|
|
# add any ZT-5B-specific setup here if needed
|
|
|
|
# --- Usage Example ---
|
|
if __name__ == "__main__":
|
|
# Minimal config example
|
|
config = {
|
|
"xorkey": "41217355a2c1327166aa3bd0e2a833142021aabb",
|
|
"icon_regions": {
|
|
"default": [24, 28, 60, 87]
|
|
},
|
|
"icon_table": [
|
|
"LowBattery","Delta","BT","BUZ","HOLD","ºF","ºC","DIODE",
|
|
"MAX","MIN","%","AC","F","u(F)","m(F)","n(F)","Hz",
|
|
"ohm","K(ohm)","M(ohm)","V","m(V)","DC","A","AUTO",
|
|
"?7","u(A)","m(A)","?8","?9","?10","?11"
|
|
]
|
|
}
|
|
|
|
decoder = ZT5BDecoder(config)
|
|
hexstring = "1b847195453ad9fa668a"
|
|
result = decoder.decode_packet(hexstring)
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|