|
@@ -1,4 +1,6 @@
|
|
|
-from modbus import Modbus, MBError, NoResponseError
|
|
|
+from modbus import Modbus
|
|
|
+from updater import Updater
|
|
|
+from sys_params import IO_SysParams
|
|
|
import colorama
|
|
|
from colorama import Fore
|
|
|
import time
|
|
@@ -6,90 +8,14 @@ import os
|
|
|
import struct
|
|
|
import random
|
|
|
|
|
|
-models = {0x100: 'MDIO_88', 0x200: 'MAO_8', 0x300: 'MAI_12'}
|
|
|
-
|
|
|
-MODEL_MDIO_88 = 0x0100
|
|
|
-MODEL_MAO_8 = 0x0200
|
|
|
-MODEL_MAI_12 = 0x0300
|
|
|
-
|
|
|
-SYS_TEST_OK = 0x0001
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-reg_table = {'in_bits': 0x0100, 'in_cnt': 0x0102, 'in_mode': 0x0120, 'in_norm': 0x0122, 'in_deb_start': 0x124,
|
|
|
- 'out_cur': 0x0200, 'out_mode': 0x0202, 'out_mode_save': 0x0203, 'pwm_duty': 0x0210,
|
|
|
- 'pwm_duty_save': 0x0220, 'pwm_per': 0x0230, 'pwm_per_save': 0x0240,
|
|
|
- 'rtc_unix': 0x0802, 'rtc_sinhro': 0x0804, 'uptime': 0x0800, 'log_info': 0x0900,
|
|
|
- 'log_ent': 0x0901, 'arch_cap': 0x0902, 'arch_ent': 0x0903,
|
|
|
- 'model': 0x0080, 'prod_date': 0x0081, 'serial_number': 0x0083, 'fw_ver': 0x0085,
|
|
|
- 'test_status': 0x0089, 'password': 0x008A}
|
|
|
-
|
|
|
-
|
|
|
-class IO_Module(Modbus):
|
|
|
- def __init__(self, tty: str, brate: int, address: int):
|
|
|
- super().__init__(tty, brate, address)
|
|
|
- self.update_segment_number = 0
|
|
|
-
|
|
|
- def iap_start(self):
|
|
|
- """Reboot device in IAP mode"""
|
|
|
- request = bytes((self.address, 0x41, 0x01))
|
|
|
- response = self.raw_communicate(request + self._crc(request))
|
|
|
-
|
|
|
- def write_fw_start(self, size: int):
|
|
|
- """Ask device to start update"""
|
|
|
- self.update_segment_number = 0
|
|
|
- request = bytes((self.address, 0x41, 0x01, 0xEF, 0xBE, 0xAD, 0xDE)) + size.to_bytes(4, 'big')
|
|
|
- response = self.raw_communicate(request + self._crc(request), 5)
|
|
|
- if len(response) == 0:
|
|
|
- raise NoResponseError('No response on WRITE_START command')
|
|
|
- if len(response) != 5:
|
|
|
- raise MBError('Incorrect response length')
|
|
|
- if response[:3] != bytes((self.address, 0x41, 0x01)):
|
|
|
- raise MBError('Incorrect response')
|
|
|
-
|
|
|
- def write_fw_part(self, data: bytes):
|
|
|
- """Write piece of FW data in IAP mode"""
|
|
|
- header = bytes((self.address, 0x41, 0x02))
|
|
|
- request = b''.join((header, self.update_segment_number.to_bytes(2, 'big'), data))
|
|
|
- response = self.raw_communicate(request + self._crc(request), 5)
|
|
|
- # self.print_hex(response)
|
|
|
- if len(response) != 5:
|
|
|
- raise MBError('Incorrect response length')
|
|
|
- if (response[:3]) != header:
|
|
|
- raise MBError('Incorrect response')
|
|
|
- self.update_segment_number += 1
|
|
|
-
|
|
|
- def iap_finish(self):
|
|
|
- """Complete FW transmission and check response"""
|
|
|
- header = request = bytes((self.address, 0x41, 0x03))
|
|
|
- response = self.raw_communicate(request + self._crc(request), 5)
|
|
|
- if len(response) != 5:
|
|
|
- raise MBError('Incorrect response length')
|
|
|
- if response[:3] != header:
|
|
|
- raise MBError('Incorrect response')
|
|
|
-
|
|
|
- def update(self, path):
|
|
|
- self.MB_TIMEOUT = 3
|
|
|
- size = os.path.getsize('fw.bin')
|
|
|
- print('Switch to IAP mode')
|
|
|
- self.iap_start()
|
|
|
- time.sleep(4)
|
|
|
- print(f'Start writing {size} bytes of FW')
|
|
|
- self.write_fw_start(size)
|
|
|
- time.sleep(2)
|
|
|
- print(f'Open FW file "{path}"...')
|
|
|
- with open(path, 'rb') as f:
|
|
|
- done = progress_cur = progress_pre = 0
|
|
|
- while True:
|
|
|
- buf = f.read(128)
|
|
|
- if len(buf):
|
|
|
- self.write_fw_part(buf)
|
|
|
- progress_cur = done / size
|
|
|
- else:
|
|
|
- break
|
|
|
- print('End of transmission')
|
|
|
- self.iap_finish()
|
|
|
|
|
|
+class IO_Module:
|
|
|
+ def __init__(self, modbus: Modbus):
|
|
|
+ self.modbus = modbus
|
|
|
+ self.updater = Updater(self.modbus)
|
|
|
+ self.sys = IO_SysParams(self.modbus)
|
|
|
+
|
|
|
+'''
|
|
|
# 0x0100 - текущее состояние входов
|
|
|
def get_inputs_bit(self) -> str:
|
|
|
data = self.read_holding_registers(reg_table['in_bits'], 1)
|
|
@@ -227,55 +153,10 @@ class IO_Module(Modbus):
|
|
|
|
|
|
def set_rtc(self, utc):
|
|
|
self.write_uint32(reg_table['rtc_sinhro'], utc)
|
|
|
+'''
|
|
|
|
|
|
|
|
|
-
|
|
|
-def set_system_vars(dev: IO_Module, password: int):
|
|
|
- # Отправка пароля для разблокирования доступа к системным настройкам
|
|
|
- dev.write_holding_register(reg_table['password'], password)
|
|
|
-
|
|
|
- # time.sleep(0.1)
|
|
|
- # Модель
|
|
|
- # dev.write_holding_register(reg_table['model'], SYS_MODEL_MDIO_88)
|
|
|
- # Дата производства
|
|
|
- # dev.write_holding_register(reg_table['prod_time'], int(time.time()) - 3600*24)
|
|
|
- # Серийный номер
|
|
|
- # dev.write_holding_register(reg_table['serial'], random.randint(10000, 1000000))
|
|
|
-
|
|
|
- # Статус тестирования
|
|
|
- # dev.write_holding_register(reg_table['test_status'], SYS_TEST_OK)
|
|
|
-
|
|
|
-
|
|
|
-def get_system_vars(dev: IO_Module):
|
|
|
- """Запрос системных настроек и параметров"""
|
|
|
- # Модель
|
|
|
- model = dev.read_holding_registers(reg_table['model'], 1)[0]
|
|
|
- print("Model: ", models[model])
|
|
|
-
|
|
|
- # Дата производства
|
|
|
- prod_date = dev.read_uint32_holding(reg_table['prod_date'])
|
|
|
- print("Prod date: ", prod_date)
|
|
|
-
|
|
|
- # Серийный номер
|
|
|
- serial_number = dev.read_uint32_holding(reg_table['serial_number'])
|
|
|
- print("SN: ", serial_number)
|
|
|
-
|
|
|
- # Версия ПО
|
|
|
- fw_bytes = b''
|
|
|
- data = dev.read_holding_registers(reg_table['fw_ver'], 4)
|
|
|
- fw_raw = list(data)
|
|
|
- fw_raw.reverse()
|
|
|
- for i in fw_raw:
|
|
|
- fw_bytes += i.to_bytes(2, 'little')
|
|
|
-
|
|
|
- fw = fw_bytes.decode('utf-8')
|
|
|
- print("FW version: ", fw)
|
|
|
-
|
|
|
- # Статус тестирования
|
|
|
- test_status = dev.read_holding_registers(reg_table['test_status'], 1)[0]
|
|
|
- print("Test status: ", test_status)
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
|
|
|
|
|
|
def main():
|
|
@@ -285,8 +166,6 @@ def main():
|
|
|
|
|
|
# dev.update('fw.bin')
|
|
|
|
|
|
- # Запрос системных параметров, установка времени
|
|
|
-
|
|
|
# print('Device uptime:', dev.get_uptime())
|
|
|
# unix_time = dev.get_rtc()
|
|
|
# print(f'RTC: {time.ctime(unix_time)}. Unix time stamp: {unix_time}')
|
|
@@ -296,9 +175,6 @@ def main():
|
|
|
# unix_time = dev.get_rtc()
|
|
|
# print(f'RTC: {time.ctime(unix_time)}. Unix time stamp: {unix_time}')
|
|
|
|
|
|
- set_system_vars(dev, 1234)
|
|
|
-
|
|
|
- # get_system_vars(dev)
|
|
|
|
|
|
return
|
|
|
|