from flask import Flask, request from llama_cpp import Llama import requests from bs4 import BeautifulSoup ENV_URL = "http://192.168.4.1/" # your Station AP page llm = Llama(model_path="model/llama-3.2-1b-Q4_K_M.gguf") app = Flask(__name__) def fetch_envpro_values(): r = requests.get(ENV_URL, timeout=3) soup = BeautifulSoup(r.text, "html.parser") text = soup.get_text() def extract(label): start = text.find(label) if start == -1: return None value = text[start+len(label):].split("\n")[0].strip() return value return { "temp": extract("Temp:"), "hum": extract("Hum:"), "press": extract("Press:"), "gas": extract("Gas:"), "co2": extract("CO2eq:"), "voc": extract("VOCeq:"), "iaq": extract("IAQ accuracy:") } @app.route("/interpret") def interpret(): data = fetch_envpro_values() prompt = ( "ENV PRO DATA:\n" f"Temp: {data['temp']}\n" f"Hum: {data['hum']}\n" f"Press: {data['press']}\n" f"Gas: {data['gas']}\n" f"CO2eq: {data['co2']}\n" f"VOCeq: {data['voc']}\n" f"IAQ accuracy: {data['iaq']}\n\n" "Context: Indoor environment. Do not assume cooking unless the sensor values indicate it.\n" "Instruction: Base your interpretation ONLY on the ENV PRO DATA values above.\n" "Do NOT invent activities.\n" "Do NOT infer smells that are not supported by the data.\n" "The environment may be a bedroom, living room, hallway, kitchen or any indoor space.\n\n" "Task: Output exactly ONE short sentence.\n" "Rules:\n" "1. The sentence MUST start with one of these words: smell, activity, mood, doing\n" "2. The sentence MUST NOT exceed 100 characters.\n" "3. Do NOT output examples.\n" "4. Do NOT output lists.\n" "5. Do NOT explain anything.\n" "6. Output exactly ONE short sentence.\n\n" "Now output the sentence:\n" ) out = llm(prompt, max_tokens=160) return out["choices"][0]["text"] # ⭐ NEW: Manual input mode (works inside Docker Desktop) @app.route("/manual", methods=["POST"]) def manual(): data = request.json prompt = ( "ENV PRO DATA:\n" f"Temp: {data['temp']}\n" f"Hum: {data['hum']}\n" f"Press: {data['press']}\n" f"Gas: {data['gas']}\n" f"CO2eq: {data['co2']}\n" f"VOCeq: {data['voc']}\n" f"IAQ accuracy: {data['iaq']}\n\n" "Context: Indoor environment. Do not assume cooking unless the sensor values indicate it.\n" "Instruction: Base your interpretation ONLY on the ENV PRO DATA values above.\n" "Do NOT invent activities.\n" "Do NOT infer smells that are not supported by the data.\n" "The environment may be a bedroom, living room, hallway, kitchen or any indoor space.\n\n" "Task: Output exactly ONE short sentence.\n" "Rules:\n" "1. The sentence MUST start with one of these words: smell, activity, mood, doing\n" "2. The sentence MUST NOT exceed 100 characters.\n" "3. Do NOT output examples.\n" "4. Do NOT output lists.\n" "5. Do NOT explain anything.\n" "6. Output exactly ONE short sentence.\n\n" "Now output the sentence:\n" ) out = llm(prompt, max_tokens=160) return out["choices"][0]["text"] app.run(host="0.0.0.0", port=8000)