from tester import * from modbus import Modbus from digital_io import IO_Digital from serial import Serial import colorama from colorama import Fore from mb_registers import * class DIO_Tester(Tester): def __init__(self, dut_debug_port, mb_port, tester_addr=1, dut_address=2): super().__init__(dut_debug_port) serial_port = Serial(mb_port, 115200, timeout=0.05, parity='N', xonxoff=False) self.modbus_tester = Modbus(serial_port, tester_addr) self.modbus_dut = Modbus(serial_port, dut_address) self.tester = IO_Digital(self.modbus_tester) self.dut = IO_Digital(self.modbus_dut) def startup(self): """Предварительная настройка tester, dut""" self.tester.set_outputs_state(0b1111_1111) # Подача питания на DUT self.tester.set_output(1, 0) time.sleep(0.3) self.tester.set_output(1, 1) time.sleep(0.3) # Отключаем безопасные режимы self.tester.sys.set_save_mode(0) # self.dut.sys.set_save_mode(0) def test_di(self): """Тест цифровых вхдов""" print('[Тестер] Установка выхода 2 --> 0') self.tester.set_output(2, 0) time.sleep(0.5) ret = self.dut.get_inputs_bit() even_inputs = ret[::2] # четные odd_inputs = ret[1::2] # нечетные if odd_inputs != '1111': print(Fore.RED + f'Нечетные входы не замкнуты [{odd_inputs}]. ERROR.') else: print(Fore.GREEN + 'Нечетные входы замкнуты. OK.') if even_inputs != '0000': print(Fore.RED + f'Четные входы не разомкнуты [{even_inputs}]. ERROR.') else: print(Fore.GREEN + 'Четные входы разомкнуты. OK.') print('[Тестер] Установка выхода 2 --> 1') self.tester.set_output(2, 1) time.sleep(0.5) ret = self.dut.get_inputs_bit() even_inputs = ret[::2] # четные odd_inputs = ret[1::2] # нечетные if odd_inputs != '0000': print(Fore.RED + f'Нечетные входы не разомкнуты [{odd_inputs}]. ERROR.') else: print(Fore.GREEN + 'Нечетные входы разомкнуты. OK.') if even_inputs != '1111': print(Fore.RED + f'Четные входы не замкнуты [{even_inputs}]. ERROR.') else: print(Fore.GREEN + 'Четные входы замкнуты. OK.') def test_do(self, do_number=1): """Проверка выхода""" self.tester.set_output(4, 1) self.dut.set_outputs_state(0b1111_1111) time.sleep(0.5) self.dut.set_outputs(0b1111_1111) time.sleep(0.5) # Разомкнуть нужный выход DUT self.dut.set_output(do_number, 0) time.sleep(1) ret = self.dut.get_loads_bit() if ret[-do_number] != '0': print(Fore.RED + f'Нагрузка к выходу {do_number} не подключена {ret}. ERROR.') return self.tester.set_output(4, 0) time.sleep(0.5) ret = self.dut.get_loads_bit() if ret[-do_number] == '0': print(Fore.RED + f'Датчик обрыва назгрузки выхода {do_number} не работает {ret}. ERROR.') return print(Fore.GREEN + f'Датчик обрыва нагрузки выхода {do_number}. OK.') def test_all_do(self): for i in range(1, 9): self.test_do(i) time.sleep(0.3) def test_rtc(self): """Проверка часов, батарейки и переключателя modbus адреса""" print("[Tester] Установка времени на DUT") self.dut.sys.set_rtc() # Снимаем питание с DUT self.tester.set_output(1, 0) print(Fore.YELLOW + "Переключите адрес на DUT в положение 'все переключатели вверх'.") print(Fore.YELLOW + "Затем нажмите 'Enter'") input() # Подаем питание на DUT self.tester.set_output(1, 1) time.sleep(3) # Меняем modbus-адрес DUT self.modbus_dut.address = 15 dut_time = self.dut.sys.get_rtc() print("Время DUT", dut_time) print(time.time() + self.dut.sys.utc_offset, dut_time/1000.0) print(abs(dut_time/1000.0 - (time.time() + self.dut.sys.utc_offset))) if abs(dut_time/1000.0 - (time.time() + self.dut.sys.utc_offset)) > 1: print(Fore.RED + f'Время не соответствует реальному. ERROR.') else: print(Fore.GREEN + 'Тест RTC и переключателя адреса. OK.') print(Fore.YELLOW + "Установите modbus адрес в значение 2 и нажмите 'Enter'.") input() def test_led(self): print("[Тест... Проверка LED") # Зеленые LED индикациии входов print(Fore.YELLOW + "Посмотрите на зеленые светодиоды индикации входов") self.tester.set_output(2, 1) time.sleep(1) self.tester.set_output(2, 0) time.sleep(1) self.tester.set_output(2, 1) time.sleep(1) self.tester.set_output(2, 0) print("Нажмите 'Enter'") input() # Зеленые LED индикации print(Fore.YELLOW + "Посмотрите на зеленые светодиоды индикации выходов") time.sleep(2) # включаем все выходы self.dut.set_outputs_state(0b1111_1111) for i in range(1, 9): self.dut.set_output(i, 1) time.sleep(1) for i in range(8, 0, -1): self.dut.set_output(i, 0) time.sleep(1) print("Нажмите 'Enter'") input() # Красные LED индикации нагрузки/аварии выходов print(Fore.YELLOW + "Посмотрите на красные светодиоды индикации аварий") time.sleep(2) self.dut.set_outputs_state(0b0000_0000) time.sleep(2) for i in range(1, 9): self.dut.set_output_state(i, 1) time.sleep(1) for i in range(8, 0, -1): self.dut.set_output_state(i, 0) time.sleep(1) print("Нажмите 'Enter'") input() def test_battery_voltage(self): print("[Тест... Проверка схемы измерения напряжения батарейки CR2032]") bat_voltage = self.dut.sys.get_bat_votage()/1000.0 if bat_voltage < 3.1: print(Fore.RED + f' Результат: Напряжение батареи слишком низкое {bat_voltage}. ERROR.') else: print(Fore.GREEN + f' Результат: Напряжение батареи в норме: {bat_voltage}. OK') def test_wdt(self): print("[Тест... Проверка WDT]") old_uptime = self.dut.sys.get_uptime() time.sleep(4) self.dut.sys.wdt_stop() time.sleep(2) new_uptime = self.dut.sys.get_uptime() if new_uptime > old_uptime: print(Fore.RED + ' Результат: Ошибка работы WDT [Error]') else: print(Fore.GREEN + f' Результат: WDT работает. OK') def set_sys_params(self): print("Введите серийный номер устройства и нажмите 'Enter'") print('SN: ', end='') sn = input() # Отправка пароля для разблокирования доступа к системным настройкам self.dut.modbus.write_holding_register(SysReg.PASSWORD.value, 1234) time.sleep(0.1) # Актуальная дата производства prod_time = int(time.time()) - time.timezone self.dut.modbus.write_uint32(SysReg.PRODATE.value, prod_time) # Серийный номер self.dut.modbus.write_uint32(SysReg.SN.value, int(sn)) # Статус тестирования self.dut.modbus.write_holding_register(SysReg.TEST_STATUS.value, 0x0001) # Команда сохранения системных настроек self.dut.modbus.write_holding_register(SysReg.SAVE_SYS.value, 0x0001) def test_all(self): pass def foo(self): print(self.modbus_dut.address) print(self.modbus_tester.address) self.modbus_dut.address = 15 print(self.modbus_dut.address) def menu(self): self.tester.set_output(1, 1) self.startup() questions = [ inquirer.List('action', message="Тестирование MDIO_88", choices=['Прошить IAP и FW', 'Прочитать системные настройки', 'Записать системные настройки', 'Полный тест', 'Тест цифровых входов', 'Тест цифровых выходов', 'Тест RTC', 'Тест LED', 'Тест напряжения батареи CR2032', 'Тест WDT', 'Завершить'], ), ] while True: answers = inquirer.prompt(questions) if answers['action'] == 'Прошить IAP и FW': self.write_iap_fw('bin_dio/fw.bin', 'bin_iap/iap.bin') elif answers['action'] == 'Прочитать системные настройки': self.dut.sys.get_system_vars() elif answers['action'] == 'Полный тест': print('Запуск цикла тестирования...') self.test_all() elif answers['action'] == 'Записать системные настройки': self.set_sys_params() elif answers['action'] == 'Тест цифровых входов': self.test_di() elif answers['action'] == 'Тест цифровых выходов': self.test_all_do() elif answers['action'] == 'Тест RTC': self.test_rtc() elif answers['action'] == 'Тест LED': self.test_led() elif answers['action'] == 'Тест напряжения батареи CR2032': self.test_battery_voltage() elif answers['action'] == 'Тест WDT': self.test_wdt() elif answers['action'] == 'Завершить': return def main(): tester = DIO_Tester('COM3', 'COM11', 1, 2) tester.menu() # tester.foo() # tester.dut_powerup() if __name__ == '__main__': main()