Проблема со сценарием регистрации данных: частичные данные сохранены в формате CSVPython

Программы на Python
Anonymous
Проблема со сценарием регистрации данных: частичные данные сохранены в формате CSV

Сообщение Anonymous »


Я разработал скрипт Python для регистрации данных с использованием связи Modbus. Основная цель сценария — сбор данных с устройства, подключенного к Modbus, таких как частота вращения, крутящий момент, температура и давление, с высокой частотой, примерно каждые 6–9 миллисекунд. Эти данные затем сохраняются в файл CSV для последующего анализа.

Я временно сохраняю его во фрейме данных pandas, чтобы уменьшить задержку чтения, а затем записываю его в CSV в конце

Поначалу скрипт работает хорошо; однако, когда я запускаю его в течение длительного периода времени, например, на один час, он не оправдывает моих ожиданий. Вместо непрерывной регистрации данных с заданной скоростью сбор данных прекращается примерно через первые 10 минут, в результате чего в файле CSV остается всего около 117 000 строк. Это не соответствует ожидаемой скорости сбора данных, в результате чего за час должен получиться значительно больший набор данных.

Я предоставил скрипт Python, отвечающий за регистрацию данных. Он использует библиотеку pymodbus для связи Modbus и библиотеку pandas для хранения данных. Скрипт подключается к устройству Modbus, получает данные с нужной скоростью и записывает их в файл CSV.

класс Data_Logger: TIME_FORMAT = "%d-%m-%Y %H:%M:%S.%f" def __init__(я, клиент, ip): self.IP = IP self.REG_start = 380 self.RPM = [] self.timestamps = [] self.client = клиент self.start_time = datetime.datetime.now() self.headers = ['Метка времени', 'RPM', «МОМЕНТ», «PS», «DY RPM», «ТЕМП. ЗАГЛУШКИ», «ТЕМП. МАСЛА», «ДАВЛЕНИЕ АТМ», «МОМЕНТ ДВИГАТЕЛЯ», «РАСХОД ТОПЛИВА», «ВЛАЖНАЯ ТЕМП.», «СУХАЯ ТЕМП.», «ТЕМП. НА ВПУСКЕ», «ДАВЛЕНИЕ МАСЛА»] self.data = pd.DataFrame(columns=self.headers) защита read_reg (сам): ответ = self.client.read_holding_registers(self.REG_start, 49) self.RPM = ответ.регистры def timestamp_update(self): время = tt.timeit(self.read_reg, число=1) * 1000,0 self.start_time += datetime.timedelta(миллисекунды=float(время)) row_data = [self.start_time.strftime(self.TIME_FORMAT)] + [self.RPM для i в диапазоне (0,49,4)] new_data = pd.DataFrame([row_data], columns=self.headers) self.data = pd.concat([self.data, new_data], ignore_index=True) защита Clear_data (сам): self.RPM = [] self.timestamps = [] self.data = pd.DataFrame(columns=self.headers) # Повторно инициализировать DataFrame защита check_connection_quality (сам): пытаться: ответ = self.client.read_holding_registers(self.REG_start, 1) # Чтение известного регистра если ответ: return True # Успешное чтение, соединение активно кроме исключения как e: print(f"Ошибка проверки качества соединения\n{e}\nПожалуйста, перезапустите приложение") return False # Невозможно прочитать реестр, проблема с подключением защита сохранения (сам): date = datetime.datetime.now().strftime("%d-%m-%Y") file_name = f"{date} Данные стенда для испытаний двигателя.csv" если os.path.exists(имя_файла): номер_файла = 1 в то время как os.path.exists(f"{file_name} ({file_number}).csv"): номер_файла += 1 self.data.to_csv(f"{file_name} ({file_number}).csv") еще: self.data.to_csv(имя_файла) Защитный сюжет (сам): plt.plot(self.data['RPM']) # Скрыть метки оси X plt.xticks([]) # Установите метки и заголовок plt.xlabel('Отметка времени (мс)') plt.ylabel('RPM') plt.title('RPM vs. Временная метка') #Показать сюжет plt.show() защита запуска (сам): self.timestamp_update() классное приложение: защита __init__(сам): #объекты графического интерфейса self.interrupt = Ложь защитаquality_check(self): пытаться: для меня в диапазоне (5): self.client.read(380) вернуть истину кроме AttributeError как e: messagebox.showerror("Ошибка чтения", "Невозможно прочитать регистр устройства, перезапустите регистратор") вернуть ложь защита подключения (сам): ip = self.ip_entry.get() пытаться: # Подтвердите введенный IP-адрес ipaddress.IPv4Address(ip) self.client = ModbusTcpClient(ip, debug=True) self.logger = Data_Logger(client=self.client, ip=ip) self.quality_check() если self.client.connect(): self.log("ПЛК подключен") self.status.config(text="ПЛК подключен", передний план='#00FB28') self.start.configure(state="нормальный") self.connect_button.configure(state="отключено") self.ip_entry.delete(0, 'конец') время.сон(2) еще: self.log("Ошибка подключения к ПЛК") кроме (ipaddress.AddressValueError, ValueError): messagebox.showerror("Неверный IP-адрес", "Пожалуйста, введите действительный адрес IPv4.") кроме исключения как e: messagebox.showerror("Ошибка соединения", str(e)) защита start_log (сам): self.console.delete(0,'конец') self.p_bar.start() self.log("Журналирование начато") self.start.configure(state="отключено") self.stop.configure(state="нормальный") пытаться: пока не self.interrupt: self.logger.run() кроме AttributeError как e: messagebox.showerror("Исключение ввода-вывода Modbus",f"\nПерезапустите регистратор\n{e}") защита thread_helper (сам): поток = Тема (цель = self.start_log) поток.start() защита stop_log (сам): self.interrupt = Истина self.p_bar.stop() self.log("Журналирование остановлено") self.log("Сохранение данных") self.p_bar.start() save_thread=Thread(target=self.logger.save) save_thread.start() self.log("Данные сохранены") self.p_bar.stop() self.start.configure(state="нормальный") self.stop.configure(state="отключено") self.logger.plot() self.logger.clear_data() защита button_init (сам): self.connect_button = tk.ttk.Button(self.connect_frame, команда=self.connect, text="Connect", ширина=20) self.start = tk.ttk.Button(self.control_frame, команда=self.thread_helper, text="Start", state="disabled", width=22) self.stop = tk.ttk.Button(self.control_frame, команда=self.stop_log, text="Stop", state="disabled", width=23) защита запуска (сам): self.main.mainloop() Данные и среда:

Операционная система: Windows 10 Версия Python: Python 3.9.16 Соответствующие библиотеки: pymodbus, matplotlib, pandas. Источник данных: связь Modbus с ПЛК (программируемый логический контроллер)

[*]Я протестировал сценарий на нескольких машинах, чтобы исключить проблемы, связанные с оборудованием. Проблема сохраняется при различных конфигурациях оборудования, что указывает на то, что проблема, скорее всего, не связана с конкретным компьютером или конфигурацией системы. [*]В качестве шага по устранению неполадок я протестировал альтернативный подход с использованием базы данных SQL для хранения данных. этот метод успешно записывает данные с желаемой скоростью в течение всего часа.
Ожидания: При запуске сценария регистрации данных Python я ожидаю, что данные будут последовательно записываться с высокой частотой, примерно каждые 6–9 миллисекунд. Я ожидаю, что в течение часа в файле CSV появится значительный набор данных с сотнями тысяч строк.

Фактические результаты: Фактические результаты не соответствуют моим ожиданиям. Хотя сценарий первоначально регистрирует данные, как и предполагалось, он по необъяснимым причинам прекращает сбор данных через первые 10 минут. В результате набор данных оказывается гораздо меньшим, чем ожидалось: через час в файле CSV будет всего около 117 000 строк.

Дополнительно - в тесте продолжительностью 2-3 часа файл csv был пуст и содержал только заголовки. -Ошибок или исключений не обнаружено

Вернуться в «Python»