"""Elmer Web UI — Flask-приложение для локального тестирования. Заодно прототип будущего серверного API. Запуск: DEEPSEEK_API_KEY=sk-... python web/app.py Открыть: http://localhost:5005 """ import sys from pathlib import Path # Добавляем корень проекта в PYTHONPATH sys.path.insert(0, str(Path(__file__).parent.parent)) from flask import Flask, jsonify, render_template, request from elmer.config import load from elmer.db import Database from elmer.diagnose import Diagnoser from elmer.elm import ELM327 from elmer.prompts import SYSTEM_PROMPT, build_user_prompt app = Flask(__name__) config = load() @app.route("/") def index(): """Главная страница.""" return render_template("index.html") @app.route("/api/diagnose", methods=["POST"]) def diagnose(): """Подключается к ELM327, читает данные, отправляет в LLM, возвращает результат.""" elm_cfg = config["elm327"] # ── 1. ELM327 ──────────────────────────────── try: elm = ELM327(port=elm_cfg["port"], baudrate=elm_cfg["baudrate"]) except Exception as e: return jsonify({"error": f"Не удалось открыть порт {elm_cfg['port']}: {e}"}), 500 if not elm.init(): elm.close() return jsonify({"error": "ELM327 не ответил на ATZ"}), 500 # ── 2. VIN ────────────────────────────────── vin = elm.read_vin() if not vin: elm.close() return jsonify({"error": "Не удалось прочитать VIN (режим 09 не поддерживается?)"}), 500 # ── 3. Ошибки ─────────────────────────────── dtc_codes = elm.read_dtc_codes("03") + elm.read_dtc_codes("07") # ── 4. Параметры ──────────────────────────── parameters = elm.read_all_pids(config.get("pids")) elm.close() # ── 5. DeepSeek ───────────────────────────── api_key = config["deepseek"]["api_key"] if not api_key: return jsonify({"error": "DEEPSEEK_API_KEY не задан"}), 500 diagnoser = Diagnoser( api_key=api_key, model=config["deepseek"].get("model", "deepseek-chat"), ) user_prompt = build_user_prompt(vin, dtc_codes, parameters) answer = diagnoser.diagnose(SYSTEM_PROMPT, user_prompt) # ── 6. SQLite ─────────────────────────────── db = Database() car_id = db.get_or_create_car(vin) token_id = db.create_token(car_id) for dtc in dtc_codes: db.add_dtc(token_id, dtc["code"], dtc.get("description", ""), dtc["status"]) for p in parameters: db.add_parameter(token_id, p["pid_code"], p["name"], p["value"], p["unit"]) db.add_llm_message(token_id, "user", user_prompt) db.add_llm_message(token_id, "assistant", answer) return jsonify({ "vin": vin, "dtc_codes": dtc_codes, "parameters": parameters, "diagnosis": answer, "token_id": token_id, }) if __name__ == "__main__": print(f"🌐 Elmer Web: http://localhost:5005") app.run(host="0.0.0.0", port=5005, debug=False)