From 53a773155ededc8d301a259994445bdb6a874b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=20=E6=B3=BD=E9=9A=86?= Date: Wed, 9 Oct 2024 00:35:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8F=82=E6=95=B0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E8=84=9A=E6=9C=AC;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/dev_LaminaController.py | 4 +- source/func_frame.py | 2 +- source/test_devController.py | 278 +++++++++++++++++++-------------- 3 files changed, 162 insertions(+), 122 deletions(-) diff --git a/source/dev_LaminaController.py b/source/dev_LaminaController.py index 68881c1..9a5b27f 100644 --- a/source/dev_LaminaController.py +++ b/source/dev_LaminaController.py @@ -90,8 +90,8 @@ ParamMap_LaminaController = { 0x83: ["llc软起开始电压", 2, 10], 0x84: ["boost开始运行电压", 2, 10], 0x85: ["boost停止运行电压", 2, 10], - 0x86: ["绝缘检测正阻抗限值", 3], - 0x88: ["绝缘检测负阻抗限值", 3], + 0x86: ["绝缘检测正阻抗限值", 3, 1], + 0x88: ["绝缘检测负阻抗限值", 3, 1], 0x8A: ["抖动频率下限", 2, 10], 0x8B: ["抖动频率上限", 2, 10], 0x8C: ["保留地址项", 2], diff --git a/source/func_frame.py b/source/func_frame.py index ac876b8..e8229a8 100644 --- a/source/func_frame.py +++ b/source/func_frame.py @@ -135,7 +135,7 @@ def make_frame_modbus(block:dict) -> bytearray: if data_len > item_len: raise Exception("Modbus data len oversize.") elif data_len < item_len: - data_val += '\000' * (item_len - data_len) + data_val += b'\000' * (item_len - data_len) data_len = len(data_val) frame.append(data_addr // 256 % 256) frame.append(data_addr % 256) diff --git a/source/test_devController.py b/source/test_devController.py index b7f7dfc..efb3fb6 100644 --- a/source/test_devController.py +++ b/source/test_devController.py @@ -1,5 +1,5 @@ import time - +from tools.ByteConv import display_hex from dev_LaminaController import LaminaController from dev_LaminaController import ParamMap_LaminaController @@ -41,103 +41,142 @@ def test_parameters(device:LaminaController, ParamMap:dict, ParamCase:dict): return device.frame_write_dual(address, value) else: return device.frame_write_str(address, value) + def frame_read(device:LaminaController, address, info): """ 整合参数读取接口 """ length = 2 if info[1] in [3, 6] else 1 length = info[2] if info[1] in [4, 5, 7] else length if device.frame_read(address, length): - return device.output['Regs'][address] + return device.output['Regs'][address][1] else: return None - def check_result(device:LaminaController, item_param, value, result:bool): - """ 测试参数写入结果 """ - addr_param, info_param = item_param - len_param = 2 if info_param[1] in [3, 6] else 1 - len_param = info_param[2] if info_param[1] in [4, 5, 7] else len_param - - device.frame_write_one(addr_param, value) - device.frame_read(addr_param, len_param) - - output_value = device.output['Regs'][addr_param] - if result: - assert value == output_value - else: - assert value != output_value - for addr_param, info_param in ParamMap.items(): - if addr_param in ParamCase.keys(): - itemCase = ParamCase[addr_param] - list_case = [] - if 0 in itemCase.keys(): - """ 常规读写用例测试 """ - for data_write, data_read in itemCase[0]: - list_case.append((data_write, data_read, True)) - if 1 in itemCase.keys(): - """ 写入范围用例测试 """ - deadzone = 0.5 - val_min, val_max = itemCase[1] - if 2 in itemCase.keys(): - """ 存在大小约束相关项 """ - list_case_relate = [] - mode_relate, addr_relate, deadzone = itemCase[2] - val_relate = frame_read(device, addr_relate, ParamCase[addr_relate]) - if mode_relate == 1: - if val_relate > val_min: - list_case_relate.append((val_min - deadzone, val_min - deadzone, True)) - val_min = val_relate - else: - val_min - elif mode_relate == 2: - if val_relate < val_max: - list_case_relate.append((val_max + deadzone, val_max + deadzone, True)) - val_max = val_relate - else: - val_max - list_case.append((val_min - deadzone, val_min - deadzone, False)) - list_case.append((val_min, val_min, True)) - list_case.append((val_min + deadzone, val_min + deadzone, True)) - list_case.append((val_max + deadzone, val_max + deadzone, False)) - list_case.append((val_max, val_max, True)) - list_case.append((val_max - deadzone, val_max - deadzone, True)) - + if addr_param not in ParamCase.keys(): + continue - - current_value = frame_read(device, addr_param, info_param) - frame_write(device, addr_param, info_param, val_min - 1) - result = frame_read(device, addr_param, info_param) - assert result == current_value - frame_write(device, addr_param, info_param, val_min - 0.5) - result = frame_read(device, addr_param, info_param) - assert result == current_value - frame_write(device, addr_param, info_param, val_min) - result = frame_read(device, addr_param, info_param) - assert result == val_min - current_value = result - frame_write(device, addr_param, info_param, val_max + 1) - result = frame_read(device, addr_param, info_param) - assert result == current_value - frame_write(device, addr_param, info_param, val_max + 0.5) - result = frame_read(device, addr_param, info_param) - assert result == current_value - frame_write(device, addr_param, info_param, val_max) - result = frame_read(device, addr_param, info_param) - assert result == val_max + addr_relate = None + itemCase = ParamCase[addr_param] + list_case_normal = [] + if 0 in itemCase.keys(): + """ 常规读写用例测试 """ + for data_write, data_read in itemCase[0]: + list_case_normal.append((data_write, data_read, True)) + if 1 in itemCase.keys(): + """ 写入范围用例测试 """ + testzone = 0.7 if info_param[1] in [2, 3] and len(info_param) < 3 else 7 / info_param[2] + accuracy = 0.20001 if info_param[1] in [2, 3] and len(info_param) < 3 else 2.0001 / info_param[2] + val_min, val_max = itemCase[1] if 2 in itemCase.keys(): - """ 大小关联用例测试 """ - if itemCase[0] == 0: - """ 数值相等关联项 """ - pass + """ 存在大小约束相关项 """ + list_case_relate = [] # 对约束相关项的修改 + list_case_late = [] # 存在约束相关项影响后的测试用例 + mode_relate, addr_relate, deadzone = itemCase[2] + val_relate = frame_read(device, addr_relate, ParamCase[addr_relate]) + if mode_relate == 1: + if (val_relate - deadzone) < val_max: + """ 约束项已限制写入范围 """ + list_case_relate.append((val_max + 2 * abs(deadzone), val_max + 2 * abs(deadzone), True)) + list_case_late.append((val_max + testzone, val_max + testzone, False)) + list_case_late.append((val_max, val_max, True)) + list_case_late.append((val_max - testzone, val_max - testzone, True)) + val_max = val_relate - deadzone + else: + """ 约束项未限制写入范围 """ + val_relate = val_max + list_case_relate.append((val_relate, val_relate, True)) + list_case_late.append((val_relate - deadzone + testzone, val_relate - deadzone + testzone, False)) + list_case_late.append((val_relate - deadzone, val_relate - deadzone, True)) + list_case_late.append((val_relate - deadzone - testzone, val_relate - deadzone - testzone, True)) + elif mode_relate == 2: + if (val_relate + deadzone) > val_min: + """ 约束项已限制写入范围 """ + list_case_relate.append((val_min - 2 * abs(deadzone), val_min - 2 * abs(deadzone), True)) + list_case_late.append((val_min - testzone, val_min - testzone, False)) + list_case_late.append((val_min, val_min, True)) + list_case_late.append((val_min + testzone, val_min + testzone, True)) + val_min = val_relate + deadzone + else: + """ 约束项未限制写入范围 """ + val_relate = val_min + list_case_relate.append((val_relate, val_relate, True)) + list_case_late.append((val_relate + deadzone - testzone, val_relate + deadzone - testzone, False)) + list_case_late.append((val_relate + deadzone, val_relate + deadzone, True)) + list_case_late.append((val_relate + deadzone + testzone, val_relate + deadzone + testzone, True)) + list_case_normal.append((val_min - testzone, val_min - testzone, False)) + list_case_normal.append((val_min, val_min, True)) + list_case_normal.append((val_min + testzone, val_min + testzone, True)) + list_case_normal.append((val_max + testzone, val_max + testzone, False)) + list_case_normal.append((val_max, val_max, True)) + list_case_normal.append((val_max - testzone, val_max - testzone, True)) + + print(f"Param Case:\taddr={display_hex(addr_param)}") + + last_value = frame_read(device, addr_param, info_param) + for case_test in list_case_normal: + print(f"\tnormal case={case_test}") + result = frame_write(device, addr_param, info_param, case_test[0]) + assert result == case_test[2] + current_value = frame_read(device, addr_param, info_param) + if current_value is None: + raise Exception("Param Read Fail") + elif result: + if type(current_value) is float: + if abs(current_value - case_test[1]) > accuracy: + raise Exception("Param Check Fail") + else: + if current_value != case_test[1]: + raise Exception("Param Check Fail") + elif (not result) and current_value != last_value: + raise Exception("Param Check Fail") + last_value = current_value + + if list_case_normal and list_case_normal[0][1] != last_value: + """ 为参数写入首个测试用例数据(一般为参数默认值), 避免影响后续参数测试 """ + case_test = list_case_normal[0] + result = frame_write(device, addr_param, info_param, case_test[0]) + assert result == case_test[2] + last_value = frame_read(device, addr_param, info_param) + + if addr_relate: + """ 存在关联测试项 """ + for case_relate in list_case_relate: + print(f"\trelate state: addr={display_hex(addr_relate)}, value={case_relate[0]}") + result = frame_write(device, addr_relate, info_param, case_relate[0]) + if result == case_relate[2]: + for case_test in list_case_late: + print(f"\t\tstate case={case_test}") + result = frame_write(device, addr_param, info_param, case_test[0]) + assert result == case_test[2] + current_value = frame_read(device, addr_param, info_param) + if current_value is None: + raise Exception("Param Read Fail") + elif result: + if type(current_value) is float: + if abs(current_value - case_test[1]) > accuracy: + raise Exception("Param Check Fail") + else: + if current_value != case_test[1]: + raise Exception("Param Check Fail") + elif (not result) and current_value != last_value: + raise Exception("Param Check Fail") + last_value = current_value + + if list_case_normal and list_case_normal[0][1] != last_value: + """ 为参数写入首个测试用例数据(一般为参数默认值), 避免影响后续参数测试 """ + case_test = list_case_normal[0] + result = frame_write(device, addr_param, info_param, case_test[0]) + assert result == case_test[2] def main(): mode_config = { "Log": {'com_name': None, # 'addr_645': [0x01, 0x00, 0x00, 0x00, 0x00, 0x40], }, - "Debug": {'com_name': 'COM5', + "Debug": {'com_name': 'COM3', # 'addr_645': [0x01, 0x02, 0x03, 0x04, 0x05, 0x06], - # 'frame_print': True, + 'frame_print': None, 'time_out': 0.5, 'retry': 3}, } @@ -146,46 +185,47 @@ def main(): # 0 - 正常写入数据序列; [(写入数据, 读取数据)] # 1 - 范围限制测试; (最小值, 最大值) # 2 - 相关大小限制测试; ((0-等于, 1-小于, 2-大于), 相关值地址, 死区范围) - 0x60: {0: [(0, 0), (1, 1), (2, 1), (0xFF, 1)]}, - 0x61: {0: [(60.0, 60.0)], 1: (40, 60), 2: (1, 0x62, 0.5)}, - 0x62: {0: [(440.0, 440.0)], 1: (350, 560), 2: (2, 0x61, 0.5)}, - 0x63: {}, - 0x64: {}, - 0x65: {}, - 0x66: {}, - 0x67: {}, - 0x68: {}, - 0x69: {}, - 0x6A: {}, - 0x6C: {}, - 0x6E: {}, - 0x70: {}, - 0x71: {}, - 0x72: {}, - 0x73: {}, - 0x74: {}, - 0x75: {}, - 0x76: {}, - 0x78: {}, - 0x7A: {}, - 0x7B: {}, - 0x7C: {}, - 0x7D: {}, - 0x7E: {}, - 0x7F: {}, - 0x80: {}, - 0x81: {}, - 0x82: {}, - 0x83: {}, - 0x84: {}, - 0x85: {}, - 0x86: {}, - 0x88: {}, - 0x8A: {}, - 0x8B: {}, - 0x170: {}, - 0x180: {}, - 0x190: {}, + 0x60: {0: [(0, '0x0000'), (1, '0x0001'), + (2, '0x0001'), (0xFF, '0x0001'), (0xFFFF, '0x0001')]}, # 整机运行使能 + 0x61: {0: [(60.0, 60.0)], 1: (40, 100), 2: (1, 0x62, 0.5)}, # 最小启动允许输入电压 + 0x62: {0: [(440.0, 440.0)], 1: (350, 560), 2: (2, 0x61, 0.5)}, # 最大启动允许输入电压 + 0x63: {0: [(58, 58.0)], 1: (38, 98), 2: (1, 0x64, 0.5)}, # 最小停机输入电压 + 0x64: {0: [(442, 442.0)], 1: (352, 562), 2: (2, 0x63, 0.5)}, # 最大停机输入电压 + 0x65: {0: [(41, 41.0)], 1: (30, 60), 2: (1, 0x66, 0.5)}, # 最小启动允许输出电压 + 0x66: {0: [(57, 57.0)], 1: (50, 80), 2: (2, 0x65, 0.5)}, # 最大启动允许输出电压 + 0x67: {0: [(40, 40.0)], 1: (28, 58), 2: (1, 0x68, 0.5)}, # 最小停止允许输出电压 + 0x68: {0: [(58, 58.0)], 1: (52, 82), 2: (2, 0x67, 0.5)}, # 最大停止允许输出电压 + 0x69: {0: [(0.1, 0.1)], 1: (0, 5), 2: (1, 0x6A, 1.0)}, # 最小MPPT电流限值 + 0x6A: {0: [(22, 22.0)], 1: (5, 30), 2: (2, 0x69, 1.0)}, # 最大MPPT电流限值 + 0x6C: {0: [(6000, 6000)], 1: (3000, 7999.999),2: (0, 0x6E, 0.0)}, # 最大功率限值(由于转换误差, 无法写入8000W) + 0x6E: {0: [(6000, 6000)], 1: (3000, 7999.999), }, # 最大功率限值存储值(由于转换误差, 无法写入8000W) + 0x70: {0: [(500, 500)], 1: (400, 800), }, # Boost输入过压保护值 + 0x71: {0: [(460, 460)], 1: (300, 600), }, # Boost输出过压保护值 + 0x72: {0: [(60, 60)], 1: (40, 80), 2: (2, 0x73, 0.5)}, # LLC输出过压保护值 + 0x73: {0: [(40, 40)], 1: (20, 50), 2: (1, 0x72, 0.5)}, # LLC输出欠压保护值 + 0x74: {0: [(20, 20)], 1: (6, 30), }, # Boost电感过流保护值 + 0x75: {0: [(20, 20)], 1: (10, 30), }, # LLC输出电流均值保护值 + 0x76: {0: [(20, 20)], 1: (10, 30), }, # LLC输出电流峰值保护值 + 0x78: {0: [(6200, 6200)], 1: (4500, 9000), }, # 过载保护值 + 0x7A: {0: [(105, 105)], 1: (30, 150), 2: (2, 0x7B, 1.0)}, # 过温故障值 + 0x7B: {0: [(95, 95)], 1: (20, 150), 2: (1, 0x7A, 1.0)}, # 过温告警值 + 0x7C: {0: [(85, 85)], 1: (0, 120), 2: (1, 0x7A, 1.0)}, # 过温恢复值 + 0x7D: {0: [(10, 10)], 1: (0, 60), }, # 输出继电器故障判断差值 + 0x7E: {0: [(55, 55)], 1: (35, 60), }, # LLC输出电压给定值 + 0x7F: {0: [(420, 420)], 1: (320, 460), }, # Boost输出电压给定值 + 0x80: {0: [(56, 56)], 1: (10, 80), }, # 三点法中间阈值 + 0x81: {0: [(57, 57)], 1: (10, 80), }, # 浮充电压 + 0x82: {0: [(56, 56)], 1: (10, 80), }, # 恒压充电电压 + 0x83: {0: [(380, 380)], 1: (0, 450), }, # llc软起开始电压 + 0x84: {0: [(395, 395)], 1: (0, 450), 2: (1, 0x85, 0.5)}, # boost开始运行电压 + 0x85: {0: [(410, 410)], 1: (0, 450), 2: (2, 0x84, 0.5)}, # boost停止运行电压 + 0x86: {0: [(15000, 15000)], 1: (0, 30000), }, # 绝缘检测正阻抗限值 + 0x88: {0: [(15000, 15000)], 1: (0, 30000), }, # 绝缘检测负阻抗限值 + 0x8A: {0: [(123, 123), (137, 137)], 1: (50, 200), 2: (1, 0x8B, 0.2)}, # 抖动频率下限(精度误差严重, 难以正常测试) + 0x8B: {0: [(137, 137), (123, 123)], 1: (50, 200), 2: (2, 0x8A, -0.2)}, # 抖动频率上限(精度误差严重, 难以正常测试) + 0x170: {0: [(b'TTE0102DX20241001120001', 'TTE0102DX20241001120001\x00\x00\x00\x00\x00\x00\x00\x00\x00')]}, # 设备序列号 + 0x180: {0: [([0x24, 0x10, 0x01, 0x12, 0x00, 0x01], '$\x10\x01\x12\x00\x01' + 26 * '\x00')]}, # 设备MES码 + 0x190: {0: [(b'241001120001', '241001120001' + 20 * '\000')]}, # 出厂日期批次 } dev_lamina = LaminaController(**mode_config['Debug']) test_parameters(dev_lamina, ParamMap_LaminaController, TestCase)