log_reader.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. from modbus import Modbus
  2. from mb_registers import reg_table, LOG_REGS
  3. from colorama import Fore
  4. from random import randint
  5. from time import sleep
  6. import time
  7. import colorama
  8. import struct
  9. from datetime import datetime, timedelta, timezone
  10. ARCHIVE_ENTRY = 0x06
  11. LOG_ENTRY = 0x07
  12. class Parser:
  13. utc_offset = 10800
  14. def __init__(self) -> None:
  15. t = datetime.now(timezone.utc).astimezone()
  16. self.utc_offset = t.utcoffset() // timedelta(seconds=1)
  17. class LogParser(Parser):
  18. events = {1: 'Включение питания/перезагрузка ',
  19. 2: 'Перевод времени ',
  20. 3: 'Обновление ПО ',
  21. 4: 'Самодиагностика/системная ошибка',
  22. 5: 'Изменение конфигурации ',
  23. 6: 'Диагностика выходов ',
  24. 7: 'Срабатывание уставок ',
  25. 8: 'Переход в безопасный режим ',
  26. 9: 'Очистка журнала/архива '}
  27. @staticmethod
  28. def print_entry(entry: tuple, index: int):
  29. timestamp = time.ctime(entry[0]/1000 - LogParser.utc_offset)
  30. ans = f"[LOG] {index:05}: {LogParser.events[entry[1]]}, {timestamp}, state: {entry[2]}, channel: {entry[3]}, value: {entry[4]}"
  31. print(Fore.CYAN + ans)
  32. class ArchiveParser(Parser):
  33. @staticmethod
  34. def print_entry(entry: tuple, channel: int, index: int):
  35. timestamp = time.ctime(entry[0]/1000 - LogParser.utc_offset)
  36. ans = f"[ARCHIVE] {index:05}: {timestamp}, value: {entry[1]}"
  37. print(Fore.CYAN + ans)
  38. class LogReader:
  39. COM_LOG_CLEAR = 0x0002
  40. COM_ARCHIVE_CLEAR = 0x0003
  41. def __init__(self, modbus: Modbus):
  42. self.modbus = modbus
  43. self.log_capacity = 0
  44. self.log_entries_number = 0
  45. self.archive_capacity = 0
  46. self.archive_entries_number = 0
  47. self.archive_period = []
  48. colorama.init(autoreset=True)
  49. def get_archive(self):
  50. print("LogReader")
  51. def get_log_info(self):
  52. data = self.modbus.read_holding_registers(reg_table['log_info'], 19)
  53. self.log_capacity = data[0]
  54. self.log_entries_number = data[1]
  55. self.archive_capacity = data[2]
  56. self.archive_entries_number = data[3:11]
  57. self.archive_period = data[12:21]
  58. print(Fore.CYAN + "Log and archive params:\n")
  59. print('Log capacity :', Fore.CYAN + str(self.log_capacity))
  60. print('Log entries number :', Fore.CYAN + str(self.log_entries_number))
  61. print('Archive capacity :', Fore.CYAN + str(self.archive_capacity))
  62. print('Archive entries number :', Fore.CYAN + str(self.archive_entries_number))
  63. print('Archive period :', Fore.CYAN + str(self.archive_period), end='\n')
  64. def set_archive_period(self, value, channel):
  65. self.modbus.write_holding_register(LOG_REGS['arch_per'] + channel, value)
  66. def log_clear(self):
  67. self.modbus.write_holding_register(reg_table['param_manager'], self.COM_LOG_CLEAR)
  68. def archive_clear(self):
  69. self.modbus.write_holding_register(reg_table['param_manager'], self.COM_ARCHIVE_CLEAR)
  70. class DigitalLogReader(LogReader):
  71. def __init__(self, modbus: Modbus):
  72. super().__init__(modbus)
  73. def get_archive(self):
  74. print("DigitalLogReader")
  75. def get_archive_entry(self, channel, index):
  76. data = self.modbus.read_file_record(ARCHIVE_ENTRY, channel, index, 1)
  77. return struct.unpack('<QBB', data[5:15])
  78. def get_random_archive_entry(self):
  79. data = self.modbus.read_file_record(ARCHIVE_ENTRY, randint(0, 8), randint(1, self.archive_entries_number), 1)
  80. entry = struct.unpack('<QBB', data[5:15])
  81. print(Fore.CYAN + str(entry))
  82. def get_log_entry(self, index):
  83. data = self.modbus.read_file_record(LOG_ENTRY, 0, index, 1)
  84. return struct.unpack('<QBBBfB', data[5:21])
  85. def print_log_entry(self, index):
  86. data = self.modbus.read_file_record(LOG_ENTRY, 0, index, 1)
  87. LogParser.print_entry(struct.unpack('<QBBBfB', data[5:21]), index)
  88. def print_archive_entry(self, channel, index):
  89. data = self.modbus.read_file_record(ARCHIVE_ENTRY, channel, index, 1)
  90. ArchiveParser.print_entry(struct.unpack('<QBB', data[5:15]), channel, index)
  91. def get_random_log_entry(self):
  92. data = self.modbus.read_file_record(LOG_ENTRY, 0, randint(1, self.log_entries_number), 1)
  93. entry = struct.unpack('<QBBBfB', data[5:21])
  94. print(Fore.CYAN + str(entry))
  95. def get_random_entries(self):
  96. '''Читаем лог и архив'''
  97. print(Fore.CYAN + "\nEntries:\n")
  98. while (1):
  99. self.get_random_archive_entry()
  100. sleep(0.1)
  101. self.get_random_log_entry()
  102. sleep(0.1)
  103. def get_all_archive(self):
  104. self.get_log_info()
  105. for channel in range(0, len(self.archive_entries_number)):
  106. if (self.archive_entries_number[channel]):
  107. print(Fore.LIGHTGREEN_EX + f"Archive channel: {channel}")
  108. for i in range(0, self.archive_entries_number[channel]):
  109. self.print_archive_entry(channel, i + 1)
  110. def get_all_log(self):
  111. self.get_log_info()
  112. for i in range(1, self.log_entries_number + 1):
  113. self.print_log_entry(i)
  114. sleep(0.01)
  115. class AnalogInputLogReader(LogReader):
  116. def __init__(self, modbus: Modbus):
  117. super().__init__(modbus)
  118. def get_archive(self):
  119. print("AnalogInputLogReader")
  120. def main():
  121. module = DigitalLogReader('COM24', 115200, 15)
  122. # module.get_log_info()
  123. # module.get_archive()
  124. # module.set_archive_period(10)
  125. return
  126. # for i in range(500):
  127. while (1):
  128. module.get_random_archive_entry()
  129. sleep(0.1)
  130. module.get_random_log_entry()
  131. sleep(0.1)
  132. if __name__ == '__main__':
  133. main()