diff options
Diffstat (limited to 'sensors.py')
| -rw-r--r-- | sensors.py | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/sensors.py b/sensors.py new file mode 100644 index 0000000..d454a13 --- /dev/null +++ b/sensors.py @@ -0,0 +1,151 @@ +import os +import json +import time +import threading +from flask import Flask, jsonify, request, render_template +from dotenv import load_dotenv +from datetime import datetime + +load_dotenv() + +app = Flask(__name__) + +# Создаем папку для логов при запуске +UPLOAD_FOLDER = 'data/battery_logs' +os.makedirs(UPLOAD_FOLDER, exist_ok=True) + +# Глобальная переменная для хранения данных +cached_data = {} + +def file_read(filename, interval=1.0): + """Функция для постоянного чтения файла в отдельном потоке""" + global cached_data + while True: + try: + with open(filename, 'r', encoding='utf-8') as file: + cached_data = json.load(file) + except FileNotFoundError: + print(f"Файл {filename} не найден. Ожидание...") + except json.JSONDecodeError as e: + print(f"Ошибка декодирования JSON в файле {filename}: {e}") + except Exception as e: + print(f"Неожиданная ошибка при чтении файла {filename}: {e}") + + time.sleep(interval) + +@app.route('/upload', methods=['POST']) +def upload_file(): + """ + Принимаем CSV файл от ESP32-C3 + """ + try: + device_id = request.headers.get('X-Device-ID', 'unknown') + file_name = request.headers.get('X-File-Name', 'log.csv') + + csv_data = request.get_data(as_text=True) + + if not csv_data: + return jsonify({'error': 'No data received'}), 400 + + device_folder = os.path.join(UPLOAD_FOLDER, device_id) + os.makedirs(device_folder, exist_ok=True) + + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') + safe_filename = f"{timestamp}_{file_name}" + file_path = os.path.join(device_folder, safe_filename) + + with open(file_path, 'w', encoding='utf-8') as f: + f.write(csv_data) + + print(f"✅ Получен файл от {device_id}: {len(csv_data)} байт") + print(f" Сохранен как: {file_path}") + + return jsonify({ + 'status': 'success', + 'message': 'File saved', + 'filename': safe_filename, + 'size': len(csv_data) + }), 200 + + except Exception as e: + print(f"❌ Ошибка: {e}") + return jsonify({'error': str(e)}), 500 + +@app.route('/', methods=['POST']) +def receive_string(): + """Прием простой текстовой строки""" + text_data = request.data.decode('utf-8') + clean_list = [item.strip() for item in text_data.split(',')] + + if not cached_data: + return '*no data*' + + result_values = [] + for key in clean_list: + if key in cached_data: + strValue = str(cached_data[key]) + if '_' in strValue: + result_values.append(strValue[:strValue.index('_')]) + else: + result_values.append(strValue) + else: + result_values.append(f'? {key} ?') + + return '*' + '*'.join(result_values) + '*' + + +@app.route('/', methods=['GET']) +def sample(): + global cached_data + if cached_data: + return jsonify(cached_data) + else: + test_data = { + "Temp": 23.5, + "Hum": 45, + "Pres": 750, + "status": "no_file" + } + return jsonify(test_data) + +@app.route('/sensors', methods=['GET']) +def get_sensors(): + """Красивое отображение данных датчиков в браузере""" + global cached_data + + # Если запрошен JSON формат + if request.args.get('format') == 'json': + if cached_data: + return jsonify(cached_data) + else: + test_data = { + "Temp": 23.5, + "Hum": 45, + "Pres": 750, + "status": "no_data" + } + return jsonify(test_data) + + # Иначе возвращаем красивую HTML страницу + return render_template('sensors.html', data=cached_data) + +if __name__ == '__main__': + filename = os.getenv('FILE_CACHE_JSON_NAME') + + if not filename: + print("❌ Ошибка: переменная FILE_CACHE_JSON_NAME не задана в .env") + filename = 'sensors_cache.json' + + print(f"📁 Файлы будут сохраняться в: {os.path.abspath(UPLOAD_FOLDER)}") + print("🌐 Доступ по адресу: http://localhost:5000") + print("📤 Endpoint для загрузки: http://localhost:5000/upload") + print("📊 Endpoint для датчиков: http://localhost:5000/sensors") + print("-" * 50) + + data_thread = threading.Thread(target=file_read, args=(filename, 2), daemon=True) + data_thread.start() + + host = os.getenv('SERVER_IP', '0.0.0.0') + port = int(os.getenv('PORT_HTTP', 5000)) + + app.run(host=host, port=port) |
