import requests
import json
import time
import sys
import csv
import os
from datetime import datetime

class JSONMonitor:
    def __init__(self, url, interval, csv_filename="monitor_data.csv"):
        self.url = url
        self.interval = interval
        self.csv_filename = csv_filename
        self.csv_file = None
        self.csv_writer = None
        
    def decode_russian_text(self, text):
        """
        Декодирует русский текст из неправильно интерпретированной кодировки
        """
        if not text or not isinstance(text, str):
            return text
            
        try:
            # Пробуем декодировать как UTF-8 байты, которые были прочитаны как Latin-1
            encoded_bytes = text.encode('iso-8859-1')
            #decoded_text = encoded_bytes.decode('utf-8')
            decoded_text = encoded_bytes.decode('1251')
            return decoded_text
        except (UnicodeEncodeError, UnicodeDecodeError):
            # Если не получается декодировать, возвращаем оригинальный текст
            return text
    
    def decode_json_response(self, response):
        """
        Декодирует JSON ответ с русским текстом
        """
        # Получаем содержимое как байты
        content_bytes = response.content
        
        # Декодируем в строку с правильной кодировкой
        content_str = content_bytes.decode('utf-8')
        
        # Парсим JSON
        data = json.loads(content_str)
        
        # Декодируем русские текстовые поля
        text_fields = ['mess_loader', 'mess_unloader', 'mess_long', 'mess_state_prc', 'sweight']
        
        for field in text_fields:
            if field in data and data[field]:
                data[field] = self.decode_russian_text(data[field])
        
        return data
    
    def setup_csv(self):
        """Создает CSV файл с разделителем ; и записывает заголовок"""
        try:
            # Проверяем, существует ли файл
            file_exists = os.path.isfile(self.csv_filename)
            
            #self.csv_file = open(self.csv_filename, 'a', newline='', encoding='utf-8')
            self.csv_file = open(self.csv_filename, 'a', newline='', encoding='1251')
            self.csv_writer = csv.writer(self.csv_file, delimiter=';')
            
            # Записываем заголовок только если файл новый
            if not file_exists:
                headers = [
                    'timestamp',
                    'Уст. доза', 'Тек. доза', 'Остат. доза', 'Порог', 'Св. столб', 'Подача', 'Производ. уст.', 'Производ. тек.', 'Автомат процесса',
                    'Сум.вес.нсб', 'Сум.вес.сбр', 'Кол.порц.нсб', 'Кол.порц.сб',
                    'Вес индицируемый', 'Бес в граммах',
                    'mcu_runtime', 'call_get', 'call_post', 'timecycle',
                    'old_portion', 'Автомат подачи', 'Автомат разгрузки', 'Сообщение', 'Сообщение2',
                    'di', 'do'
                ]
                self.csv_writer.writerow(headers)
                print(f"Создан CSV файл с разделителем ';': {self.csv_filename}")
            
        except Exception as e:
            print(f"Ошибка при создании CSV файла: {e}")
            self.csv_file = None
            self.csv_writer = None
    
    def write_to_csv(self, data):
        """Записывает данные в CSV файл с разделителем ;"""
        if self.csv_writer is None:
            return
        
        try:
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            
            row = [
                timestamp,
                data.get('doze_end', ''),
                data.get('doze_curr', ''),
                data.get('drm', ''),
                data.get('compare', ''),
                data.get('freedrop', ''),
                data.get('spdrw', ''),                
                data.get('perfom_set', ''),
                data.get('perfom_curr', ''),
                data.get('pstate', ''),
                data.get('summ_w_nr', ''),
                data.get('summ_w_r', ''),
                data.get('summ_d_nr', ''),
                data.get('summ_d_r', ''),
                data.get('sweight', '').strip(),
                data.get('wbrutto_g', ''),
                data.get('mcu_runtime', ''),
                data.get('call_get', ''),
                data.get('call_post', ''),
                data.get('timecycle', ''),
                data.get('old_portion', ''),
                data.get('mess_loader', ''),
                data.get('mess_unloader', ''),
                data.get('mess_long', ''),
                data.get('mess_state_prc', ''),
                data.get('di', ''),
                data.get('do', '')
            ]
            
            self.csv_writer.writerow(row)
            self.csv_file.flush()
            #print(f"Данные записаны в CSV: {self.csv_filename}")
            
        except Exception as e:
            print(f"Ошибка записи в CSV: {e}")
    
    def parse_json_data(self):
        """
        Функция для периодического опроса URL и парсинга JSON данных
        """
        print(f"Начало мониторинга URL: {self.url}")
        print(f"Интервал опроса: {self.interval} секунд")
        print(f"CSV файл: {self.csv_filename} (разделитель: ';')")
        print("-" * 80)
        
        # Настраиваем CSV файл
        self.setup_csv()
        
        try:
            while True:
                try:
                    # Выполняем GET запрос
                    response = requests.get(self.url, timeout=10)
                    response.raise_for_status()
                    
                    # Декодируем JSON с русским текстом
                    data = self.decode_json_response(response)
                    
                    # Выводим текущее время
                    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    print(f"\n=== Данные от {current_time} ===")
                    
                    # Выводим распарсенные значения spdrw
                    print("\n")
                    print(f"  {data.get('mess_long', 'N/A')}")
                    print(f"  {data.get('sweight', 'N/A')}")
                    print(f"  Набор: {data.get('spdrw', 'N/A')} т/час")
                    print(f"  Порог: {data.get('compare', 'N/A')}")
                    print(f"  Остаток: {data.get('drm', 'N/A')}")
                    #print(f"  wbrutto_g: {data.get('wbrutto_g', 'N/A')}")
                    print(f"  Вся доза: {data.get('doze_end', 'N/A')}")
                    print(f"  Отв. доза: {data.get('doze_curr', 'N/A')}")
                    print(f"  Прошлая порция: {data.get('old_portion', 'N/A')}")
                    print(f"  Свободный столб: {data.get('freedrop', 'N/A')}")

                    print("\n")
                    #print("\nДискретные входы/выходы:")
                    #print(f"              76543210")
                    print(f"               НВД НВВ")
                    print(f"               ЗЗВДЗЗЗ")
                    print(f"               ОПУПЗОЗ")
                    print(f"  di: {data.get('di', 'N/A')}")
                    print(f"  do: {data.get('do', 'N/A')}")
                    print(f"              АР  НВНВ")
                    print(f"                  ЗЗОО")	
                    
                    print("\nСтатистика весов:")
                    print(f"  summ_w_nr: {data.get('summ_w_nr', 'N/A')}")
                    print(f"  summ_w_r: {data.get('summ_w_r', 'N/A')}")
                    print(f"  summ_d_nr: {data.get('summ_d_nr', 'N/A')}")
                    print(f"  summ_d_r: {data.get('summ_d_r', 'N/A')}")
                    print(f"  perfom_set: {data.get('perfom_set', 'N/A')}")
                    print(f"  perfom_curr: {data.get('perfom_curr', 'N/A')}")
                    
                    #print("\nСтатистика работы:")
                    #print(f"  mcu_runtime: {data.get('mcu_runtime', 'N/A')}")
                    #print(f"  call_get: {data.get('call_get', 'N/A')}")
                    #print(f"  call_post: {data.get('call_post', 'N/A')}")
                    #print(f"  timecycle: {data.get('timecycle', 'N/A')}")
                    
                    print("\nСообщения системы:")
                    print(f"  ВЗ: {data.get('mess_loader', 'N/A')}")
                    print(f"  НЗ: {data.get('mess_unloader', 'N/A')}")
                    print(f"  ПР: {data.get('mess_long', 'N/A')}")
                    print(f"  :{data.get('mess_state_prc', 'N/A')}")
                    print(f"  pstate: {data.get('pstate', 'N/A')}")     
                    
                    # Записываем данные в CSV
                    self.write_to_csv(data)
                    
                    #print("-" * 80)
                    
                except requests.exceptions.RequestException as e:
                    print(f"Ошибка при запросе: {e}")
                    error_data = {'mess_long': f'Ошибка запроса: {e}'}
                    self.write_to_csv(error_data)
                except json.JSONDecodeError as e:
                    print(f"Ошибка парсинга JSON: {e}")
                except KeyboardInterrupt:
                    print("\nМониторинг остановлен пользователем")
                    break
                except Exception as e:
                    print(f"Неожиданная ошибка: {e}")
                
                time.sleep(self.interval)
                
        except KeyboardInterrupt:
            print("\nМониторинг остановлен пользователем")
        finally:
            if self.csv_file:
                self.csv_file.close()
                print(f"CSV файл закрыт: {self.csv_filename}")

def main():
    url = "http://192.168.0.50/get_json.js"
    interval = 1
    csv_filename = "monitor_data.csv"
    
    if len(sys.argv) > 1:
        try:
            interval = int(sys.argv[1])
        except ValueError:
            print("Ошибка: интервал должен быть числом. Используется значение по умолчанию: 5 сек")
    
    if len(sys.argv) > 2:
        csv_filename = sys.argv[2]
    
    print("Программа мониторинга JSON данных с записью в CSV")
    print("Разделитель CSV: ';'")
    print("Автоматическое декодирование русского текста")
    print("Для остановки нажмите Ctrl+C")
    print(f"Данные будут сохраняться в: {csv_filename}")
    
    monitor = JSONMonitor(url, interval, csv_filename)
    monitor.parse_json_data()

if __name__ == "__main__":
    main()