def command_GETLOG(): """ Запрос журнала событий RTU. """ # Определяем тип команды type_command = 'GETLOG' # Формируем команду Nsect = b'\x00\x00\x00\x01' ## id события - вот тут надо доставать последнее событие из журнала --> test_get_maxlogid() Id = b'\x00\x00\x00\x01' Num = b'\x00\x01' data = Nsect + Id + Num command = FormCommand(type_command=type_command, data=data).command # Запускаем answer = Setup(command=command).answer data_bytes_list = [] normal_answer = Constructor_Answer(data_bytes=data) # ПОЛУЧИЛИ ОТВЕТ - ТЕПЕРЬ ЕГО МОЖНО СРАВНИВАТЬ total_assert(answer_uspd=answer, answer_normal=normal_answer) # --------------------------------------------------------------------------------------------------------------------- # command_GETLOG()
def command_SETTIME(time_correct: int = 60): """ Тест на команду изменения времени """ from work_with_device import get_right_hex import ctypes # # Итак - Сначала переводим в стандарт int16 # time_correct_ctypes = ctypes.c_int16(time_correct) # # # ПОСЛЕ ЧЕГО ИМЕННО ЕГО - в байты # time_correct_bytes = bytes(time_correct_ctypes) # # # В начале надо сгенерировать команду для запроса версии # # # # # # Достраиваем нашу команду до нужной длины # time_correct_bytes = time_correct_bytes + (b'\x00' * (4 - len(time_correct_bytes))) time_correct_bytes = time_correct.to_bytes(4, byteorder='little', signed=True) print('bytes', time_correct_bytes) # Определяем тип команды type_command = 'SETTIME' # Формируем command = FormCommand(type_command=type_command, data=time_correct_bytes).command # ПОЛУЧАЕМ ВРЕМЯ ДО изменений unix_time_before = get_sys_time() # Запускаем # command = b'\x02\x00\r\x01\x00\x00\x00\x00\x00\x00\x00\x73\x59\x00\x00\xe5x' answer = Setup(command=command).answer # Генерируем предпологаемый ответ data_bytes_list = b'' normal_answer = Constructor_Answer(data_bytes=data_bytes_list) # ПОЛУЧИЛИ ОТВЕТ - ТЕПЕРЬ ЕГО МОЖНО СРАВНИВАТЬ total_assert(answer_uspd=answer, answer_normal=normal_answer) # Теперь проверяем записанное время # Получаем системное время unix_time_after = get_sys_time() unix_time_expected = unix_time_before + time_correct # Теперь конвертируем это в нормальный дата тайм from datetime import datetime # date_time = datetime.fromtimestamp(unix_time_dec_int) # print(date_time) # Сравниваем assert abs(unix_time_after - unix_time_expected) < 20, 'НЕ КОРЕКТНОЕ ВРЕМЯ \n' + \ '\nВремя что на устройстве ДО коррекции\n' + \ str(datetime.fromtimestamp(unix_time_before)) + \ '\nВремя что на устройстве ПОСЛЕ коррекции\n' + \ str(datetime.fromtimestamp(unix_time_after)) + \ '\nОжидаемое время после коррекции\n' + \ str(datetime.fromtimestamp(unix_time_expected))
def command_GETTIME(): """ Тест на команду запроса времени """ # В начале надо сгенерировать команду для запроса версии type_command = 'GETTIME' # Составляем наш список корректной команды command = FormCommand(type_command=type_command, data=None).command # Теперь отправляем нашу команду answer = Setup(command=command).answer # ТЕПЕРЬ НА ОСНОВЕ ДАННОГО ВРЕМЕНИ ФОРМИРУЕМ ПРЕДПОЛООГАЕМУЮ КОМАНДУ data_bytes_list = b'' for i in range(len(answer['answer_data'])): # ДЕЛАЕМ БАЙТ ИЗ HEX data_bytes_list = data_bytes_list + bytes.fromhex(answer['answer_data'][i]) # отправляем в конструктор normal_answer = Constructor_Answer(data_bytes=data_bytes_list) # ПОЛУЧИЛИ ОТВЕТ - ТЕПЕРЬ ЕГО МОЖНО СРАВНИВАТЬ total_assert(answer_uspd=answer, answer_normal=normal_answer) # ПОЛУЧИЛИ ОТВЕТ - ТЕПЕРЬ ЕГО МОЖНО СРАВНИВАТЬ # ТЕПЕРЬ - НАДО ПРОВЕРИТЬ САМО ВРЕМЯ - # реверсируем список answer['answer_data'].reverse() # слепливаем нормальное число unix_time_hex = '' for i in range(len(answer['answer_data'])): unix_time_hex = unix_time_hex + answer['answer_data'][i] # Получаем числов 10 системе unix_time_dec_int = int(unix_time_hex, 16) # Получаем системное время unix_time_sys = get_sys_time() # Теперь конвертируем это в нормальный дата тайм from datetime import datetime # date_time = datetime.fromtimestamp(unix_time_dec_int) # print(date_time) # Сравниваем assert abs(unix_time_sys - unix_time_dec_int) < 10, 'НЕ КОРЕКТНОЕ ВРЕМЯ \n' + \ '\nВремя что вернули командой\n' + \ str(datetime.fromtimestamp(unix_time_dec_int)) + \ '\nВремя что на устройстве\n' + \ str(datetime.fromtimestamp(unix_time_sys))
def command_GETMAXLOGID(): """ Получение максимального идентификатора секции журнала событий RTU. Максимальный идентификатор (максимальный номер события) может быть использован для проверки переполнения или очистки журнала событий RTU. """ # Определяем тип команды type_command = 'GETMAXLOGID' # Формируем data = b'\x01' command = FormCommand(type_command=type_command, data=data).command # Запускаем answer = Setup(command=command).answer data_bytes_list = [] normal_answer = Constructor_Answer(data_bytes=data) # ПОЛУЧИЛИ ОТВЕТ - ТЕПЕРЬ ЕГО МОЖНО СРАВНИВАТЬ total_assert(answer_uspd=answer, answer_normal=normal_answer)
def command_GETMTRLOG(RecordTypeId: list = [ "ElJrnlPwr", "ElJrnlTimeCorr", "ElJrnlReset", "ElJrnlOpen", "ElJrnlPwrA", "ElJrnlPwrB", "ElJrnlPwrC" ], count_timestamp: int = 11): """ Получение значений ЖУРНАЛОВ Крайне важная штука НЕОБХОДИМО ЗАДАТЬ ОДИН ЖУРНАЛ """ # Определяем тип команды type_command = 'GETMTRLOG' # ПРОВЕРЯЕМ ТИП ДАННЫХ ДА assert ('ElJrnlPwr' in RecordTypeId) or ('ElJrnlTimeCorr' in RecordTypeId) or ('ElJrnlReset' in RecordTypeId) or \ ('ElJrnlOpen' in RecordTypeId) or \ ('ElJrnlPwrA' in RecordTypeId) or ('ElJrnlPwrB' in RecordTypeId) or ('ElJrnlPwrC' in RecordTypeId), \ 'НЕ ВЕРНО ЗАДАН ТИП ДАННЫХ ' # Первое что делаем - генерируем необходимые нам данные from Service.Generator_Data import GenerateGETMTRLOG ElectricEnergyValues = GenerateGETMTRLOG(Count_timestamp=count_timestamp, RecordTypeId=RecordTypeId) # получаем данные Generate_data_dict = deepcopy(ElectricEnergyValues.GETMTRLOG) Serial = deepcopy(ElectricEnergyValues.Serial) # Формируем команду from Service.Service_function import get_form_NSH, decode_data_to_GETMTRLOG, code_data_to_GETMTRLOG, \ form_data_to_GETMTRLOG # ---------- ФОРМИРУЕМ ДАННЫЕ ДЛЯ КОМАНДЫ ЗАПРОСА ---------- # БЕРЕМ ТАЙМШТАМП # print('----->', Generate_data_dict) Timestamp = [] for i in Generate_data_dict: Timestamp = Timestamp + sorted(Generate_data_dict[i].keys()) print('Timestamp', len(Timestamp), Timestamp) # print(' из них уникальных', len(set(Timestamp)), set(Timestamp)) Timestamp = min(Timestamp) # print('Timestamp --->', Timestamp) # NSH Номер счетчика BCD5 NSH = get_form_NSH(Serial=Serial) # Запросить события с отметками времени больше Tstart TIME_T Tstart = int(Timestamp).to_bytes(length=4, byteorder='little') # Максимальное кол-во запрашиваемых событий INT16 Cnt = count_timestamp * len(RecordTypeId) print('Cnt', Cnt) Cnt = int(Cnt).to_bytes(length=2, byteorder='little', signed=True) # ---------- ФОРМИРУЕМ КОМАНДУ ---------- data_request = NSH + Tstart + Cnt command = FormCommand(type_command=type_command, data=data_request).command # ---------- ФОРМИРУЕМ ПРЕДПОЛАГАЕМЫЙ ОТВЕТ ---------- answer_data_expected = form_data_to_GETMTRLOG(Generate_data_dict) # Формируем байтовую строку нагрузочных байтов data = code_data_to_GETMTRLOG(answer_data_expected) # Формируем предполагаемый ответ Answer_expected = Constructor_Answer(data) # ---------- ОТПРАВЛЯЕМ КОМАНДУ ---------- Answer = Setup(command=command).answer # ---------- ТЕПЕРЬ ДЕКОДИРУЕМ ДАННЫЕ ОТВЕТА ---------- # # # ДЕКОДИРУЕМ ПОЛЕ ДАТА Answer['answer_data'] = decode_data_to_GETMTRLOG( answer_data=Answer['answer_data']) # БЕРЕМ ДАННЫЕ В НОРМАЛЬНОМ ВИДЕ Answer_expected['answer_data'] = answer_data_expected # -------------------> print('Answer_expected', Answer_expected['answer_data']) print('Answer', Answer['answer_data']) # -------------------> # ТЕПЕРЬ СРАВНИВАЕМ НАШИ ДАННЫЕ - ЦЕ ВАЖНО assert_answer_data(answer_data_expected=Answer_expected['answer_data'], answer_data=Answer['answer_data']) # ТЕПЕРЬ ПРОВОДИМ ТОТАЛЬНОЕ СРАВНИВАНИЕ total_assert(answer_uspd=Answer, answer_normal=Answer_expected)
def command_GETPOK(Ap: bool = True, Am: bool = True, Rp: bool = True, Rm: bool = True, count_timestamp: int = 1, RecordTypeId: list = ['ElDayEnergy']): """ Получение Профиля мощности ПО сумме тарифов за КОНКРЕТНЫЙ таймшитамп сюда можно пихать 'ElMomentEnergy', 'ElDayEnergy', 'ElMonthEnergy' """ import struct # Определяем тип команды type_command = 'GETPOK' # 'ElMomentEnergy', 'ElDayEnergy', 'ElMonthEnergy' assert ('ElMomentEnergy' in RecordTypeId) or ('ElDayEnergy' in RecordTypeId) or ('ElMonthEnergy' in RecordTypeId), \ 'НЕ ВЕРНО ЗАДАН ТИП ДАННЫХ ' # Первое что делаем - генерируем необходимые нам данные from Service.Generator_Data import GenerateGETPOK ElectricEnergyValues = GenerateGETPOK(Count_timestamp=count_timestamp, RecordTypeId=RecordTypeId) # получаем данные Generate_data_SHPRM_dict = deepcopy(ElectricEnergyValues.GETPOK) Serial = deepcopy(ElectricEnergyValues.Serial) # # print('->',Generate_data_SHPRM_dict) # print('->',Serial) # Формируем команду from Service.Service_function import get_form_NSH, decode_data_to_GETPOK, code_data_to_GETPOK # ---------- ФОРМИРУЕМ ДАННЫЕ ДЛЯ КОМАНДЫ ЗАПРОСА ---------- # БЕРЕМ ТАЙМШТАМП Timestamp = 0 for i in Generate_data_SHPRM_dict: Timestamp = Generate_data_SHPRM_dict[i].get('Timestamp') print('Timestamp --->', Timestamp) # NSH Номер счетчика BCD5 NSH = get_form_NSH(Serial=Serial) # Формируем Признаки заказываемых измерений. Chnl = str(int(Rm)) + str(int(Rp)) + str(int(Am)) + str(int(Ap)) print(Chnl) # # Признаки заказываемых измерений. INT8 Chnl = int(str(Chnl), 2).to_bytes(length=1, byteorder='little') # Время запроса показаний счетчика TIME_T Time = int(Timestamp).to_bytes(length=4, byteorder='little') # ---------- ФОРМИРУЕМ КОМАНДУ ---------- data_request = NSH + Chnl + Time command = FormCommand(type_command=type_command, data=data_request).command # ---------- ФОРМИРУЕМ ПРЕДПОЛАГАЕМЫЙ ОТВЕТ ---------- answer_data_expected = { 'Rm': None, 'Rp': None, 'Am': None, 'Ap': None, } if Rm: answer_data_expected['Rm'] = Generate_data_SHPRM_dict.get( Timestamp).get('Rm') if Rp: answer_data_expected['Rp'] = Generate_data_SHPRM_dict.get( Timestamp).get('Rp') if Am: answer_data_expected['Am'] = Generate_data_SHPRM_dict.get( Timestamp).get('Am') if Ap: answer_data_expected['Ap'] = Generate_data_SHPRM_dict.get( Timestamp).get('Ap') # Формируем байтовую строку нагрузочных байтов data = code_data_to_GETPOK(answer_data_expected) # Формируем предполагаемый ответ Answer_expected = Constructor_Answer(data) # ---------- ОТПРАВЛЯЕМ КОМАНДУ ---------- Answer = Setup(command=command).answer # ---------- ТЕПЕРЬ ДЕКОДИРУЕМ ДАННЫЕ ОТВЕТА ---------- # ДЕКОДИРУЕМ ПОЛЕ ДАТА Answer['answer_data'] = decode_data_to_GETPOK( answer_data=Answer['answer_data'], Chnl={ "Rm": Rm, "Rp": Rp, "Am": Am, "Ap": Ap, }) # БЕРЕМ ДАННЫЕ В НОРМАЛЬНОМ ВИДЕ Answer_expected['answer_data'] = answer_data_expected # -------------------> print('Answer_expected', Answer_expected['answer_data']) print('Answer', Answer['answer_data']) # -------------------> # ТЕПЕРЬ СРАВНИВАЕМ НАШИ ДАННЫЕ - ЦЕ ВАЖНО assert_answer_data(answer_data_expected=Answer_expected['answer_data'], answer_data=Answer['answer_data']) # ТЕПЕРЬ ПРОВОДИМ ТОТАЛЬНОЕ СРАВНИВАНИЕ total_assert(answer_uspd=Answer, answer_normal=Answer_expected)
def command_GETAUTOREAD(Kanal: str = 'Ap'): """ Получение Профиля мощности ПО сумме тарифов за КОНКРЕТНЫЙ таймшитамп сюда можно пихать 'ElMomentEnergy', 'ElDayEnergy', 'ElMonthEnergy' """ import struct # Определяем тип команды type_command = 'GETAUTOREAD' # 'ElMomentEnergy', 'ElDayEnergy', 'ElMonthEnergy' RecordTypeId: list = ['ElDayEnergy', 'ElMonthEnergy'] count_timestamp: int = 3 Kk = 1 # assert ('ElMomentEnergy' in RecordTypeId) or ('ElDayEnergy' in RecordTypeId) or ('ElMonthEnergy' in RecordTypeId), \ # 'НЕ ВЕРНО ЗАДАН ТИП ДАННЫХ ' # Первое что делаем - генерируем необходимые нам данные from Service.Generator_Data import GenerateGETAUTOREAD ElectricEnergyValues = GenerateGETAUTOREAD(Count_timestamp=count_timestamp, RecordTypeId=RecordTypeId) # получаем данные Generate_data_dict_full = deepcopy(ElectricEnergyValues.GETAUTOREAD) Serial = deepcopy(ElectricEnergyValues.Serial) # Формируем команду from Service.Service_function import get_form_NSH, decode_data_to_GETAUTOREAD, form_data_to_GETAUTOREAD, \ code_data_to_GETAUTOREAD # выбираем все типы данных которые у нас есть data_type = set() for Idx in Generate_data_dict_full: data_type.add(Generate_data_dict_full[Idx].get('RecordTypeId')) # Теперь выбираем этот тип данных data_type = list(data_type) from random import randint RecordTypeId = data_type[randint(0, (len(data_type)- 1))] # и вытаскиваем ТОЛЬКО ЭТОТ ТИП ДАННЫХ Generate_data_dict = {} for Idx in Generate_data_dict_full: if Generate_data_dict_full[Idx].get('RecordTypeId') == RecordTypeId : Generate_data_dict.update({Generate_data_dict_full[Idx].get('Timestamp') : Generate_data_dict_full[Idx]}) # ---------- ФОРМИРУЕМ ДАННЫЕ ДЛЯ КОМАНДЫ ЗАПРОСА ---------- # БЕРЕМ ТАЙМШТАМП Timestamp = [] for i in Generate_data_dict: Timestamp.append(Generate_data_dict[i].get('Timestamp')) # print('ЧТО ЕСТЬ ',Timestamp) Timestamp.remove(max(Timestamp)) Timestamp.remove(min(Timestamp)) Timestamp = Timestamp.pop() # print('Данные ',Generate_data_dict.get(Timestamp)) print('Timestamp --->', Timestamp) # Serial = '39902651' print('Serial', Serial) # NSH Номер счетчика BCD5 NSH = get_form_NSH(Serial=Serial) # print_bytes(string='NSH ===>', byte_string=NSH) # Формируем Признаки заказываемых измерений. Kanal_dict = \ { 'Rm': 4, 'Rp': 3, 'Am': 2, 'Ap': 1, } if type(Kanal) != int: Kanal = Kanal_dict.get(Kanal) # ---------- ФОРМИРУЕМ ПРЕДПОЛАГАЕМЫЙ ОТВЕТ ---------- answer_data_expected = form_data_to_GETAUTOREAD(answer_data=Generate_data_dict.get(Timestamp), Serial=Serial, Kanal=Kanal) # Формируем байтовую строку нагрузочных байтов data = code_data_to_GETAUTOREAD(answer_data_expected) # Формируем предполагаемый ответ Answer_expected = Constructor_Answer(data) # Время запроса показаний счетчика TIME_T Tday = Timestamp - 1 Tday = int(Tday).to_bytes(length=4, byteorder='little') # # Признаки заказываемых измерений. INT8 Kanal = int(Kanal).to_bytes(length=1, byteorder='little', signed=True) Kk = int(Kk).to_bytes(length=1, byteorder='little', signed=True) # ---------- ФОРМИРУЕМ КОМАНДУ ---------- data_request = NSH + Tday + Kanal + Kk command = FormCommand(type_command=type_command, data=data_request).command # # Формируем предполагаемый ответ Answer_expected = Constructor_Answer(data) # ---------- ОТПРАВЛЯЕМ КОМАНДУ ---------- Answer = Setup(command=command).answer # ---------- ТЕПЕРЬ ДЕКОДИРУЕМ ДАННЫЕ ОТВЕТА ---------- # print(Answer) # # ДЕКОДИРУЕМ ПОЛЕ ДАТА Answer['answer_data'] = decode_data_to_GETAUTOREAD(answer_data=Answer['answer_data'], ) # БЕРЕМ ДАННЫЕ В НОРМАЛЬНОМ ВИДЕ Answer_expected['answer_data'] = answer_data_expected # -------------------> print('Answer_expected',Answer_expected['answer_data']) # print(Answer) print('Answer',Answer['answer_data']) # -------------------> # ТЕПЕРЬ СРАВНИВАЕМ НАШИ ДАННЫЕ - ЦЕ ВАЖНО assert_answer_data(answer_data_expected=Answer_expected['answer_data'], answer_data=Answer['answer_data']) # ТЕПЕРЬ ПРОВОДИМ ТОТАЛЬНОЕ СРАВНИВАНИЕ total_assert(answer_uspd=Answer, answer_normal=Answer_expected)
def command_GETLP(Qp: bool = True, Qm: bool = True, Pp: bool = True, Pm: bool = True, Kk: int = 1): """ Получение Профиля мощности? """ # Определяем тип команды type_command = 'GETLP' cTime = 30 # Первое что делаем - генерируем необходимые нам данные from Service.Generator_Data import GenerateGETLP ElectricPowerValues = GenerateGETLP(Count_timestamp=Kk, cTime=cTime) # получаем данные Generate_data_GETLP_dict = deepcopy(ElectricPowerValues.GETLP) Serial = deepcopy(ElectricPowerValues.Serial) # ---------- ФОРМИРУЕМ ДАННЫЕ ДЛЯ КОМАНДЫ ЗАПРОСА ---------- from Service.Service_function import get_form_NSH, decode_data_to_GETLP, code_data_to_GETLP, form_data_to_GETLP Timestamp_list = [] for i in Generate_data_GETLP_dict: Timestamp_list.append(Generate_data_GETLP_dict[i].get('Timestamp')) Timestamp = min(Timestamp_list) print('-->Timestamp--->', Timestamp) # NSH Номер счетчика BCD5 NSH = get_form_NSH(Serial=Serial) # Формируем Признаки заказываемых измерений. Kanal = str(int(Qm)) + str(int(Qp)) + str(int(Pm)) + str(int(Pp)) # # Признаки заказываемых измерений. INT8 Kanal = int(str(Kanal), 2).to_bytes(length=1, byteorder='little') # Время запроса показаний счетчика TIME_T Tstart = int(Timestamp).to_bytes(length=4, byteorder='little') # Время запроса показаний счетчика TIME_T Kk = int(Kk).to_bytes(length=2, byteorder='little') # ---------- ФОРМИРУЕМ КОМАНДУ ---------- data_request = NSH + Kanal + Tstart + Kk command = FormCommand(type_command=type_command, data=data_request).command # ---------- ФОРМИРУЕМ ПРЕДПОЛАГАЕМЫЙ ОТВЕТ ---------- answer_data_expected = form_data_to_GETLP( answer_data=Generate_data_GETLP_dict, Kanal={ "Qp": Qp, "Qm": Qm, "Pm": Pm, "Pp": Pp, }) # Формируем байтовую строку нагрузочных байтов data = code_data_to_GETLP(answer_data=answer_data_expected, Kanal={ "Qp": Qp, "Qm": Qm, "Pm": Pm, "Pp": Pp, }, cTime=cTime) # Формируем предполагаемый ответ Answer_expected = Constructor_Answer(data) # ---------- ОТПРАВЛЯЕМ КОМАНДУ ---------- Answer = Setup(command=command).answer # ---------- ТЕПЕРЬ ДЕКОДИРУЕМ ДАННЫЕ ОТВЕТА ---------- # ТЕПЕРЬ ДЕКОДИРУЕМ ДАННЫЕ ОТВЕТА Answer['answer_data'] = decode_data_to_GETLP( answer_data=Answer['answer_data'], Kanal={ "Qp": Qp, "Qm": Qm, "Pm": Pm, "Pp": Pp, }, cTime=cTime) # БЕРЕМ ДАННЫЕ В НОРМАЛЬНОМ ВИДЕ Answer_expected['answer_data'] = answer_data_expected # -------------------> print('Answer_expected', Answer_expected['answer_data']) print('Answer', Answer['answer_data']) # -------------------> # ТЕПЕРЬ СРАВНИВАЕМ НАШИ ДАННЫЕ - ЦЕ ВАЖНО assert_answer_data(answer_data_expected=Answer_expected['answer_data'], answer_data=Answer['answer_data']) # ТЕПЕРЬ ПРОВОДИМ ТОТАЛЬНОЕ СРАВНИВАНИЕ total_assert(answer_uspd=Answer, answer_normal=Answer_expected)