import os import base64 import uuid import datetime import sys import json from flask import Flask, request, jsonify from pymongo import MongoClient from APIs import generate, EdamamAPI from APIs.mqtt import send_command from microwaveCookPlanner import MicrowaveCookPlanner sys.path.insert(0, '..') try: from shared import config except ImportError: from ..shared import config app = Flask(__name__) # --------------------------------------------------------- # Configuration & Setup # --------------------------------------------------------- # Configure MongoDB connection MONGO_URI = os.getenv("MONGO_URI", "mongodb://localhost:27017/") client = MongoClient(MONGO_URI) db = client["microwave_network_db"] cooking_collection = db["cooking_parameters"] telemetry_collection = db["telemetry_data"] # Ensure the camera image storage directory exists when the app starts CAMERA_IMAGE_DIR = "storage/dishCameraImages" os.makedirs(CAMERA_IMAGE_DIR, exist_ok=True) # --------------------------------------------------------- # Classes # --------------------------------------------------------- microwave_cook_planner = MicrowaveCookPlanner() # --------------------------------------------------------- # Routes # --------------------------------------------------------- @app.route("/") def hello_world(): gen = generate(prompt="Say Hello, to the user !") print(gen) return f"

{gen}

" @app.route("/cooking-params", methods=["POST"]) def cooking_params(): data = request.get_json() if not data: return jsonify({"error": "Invalid or missing JSON payload"}), 400 # Extract user or device parameters (with fallback defaults) height_cm = float(data.get("dish_height", 4.0)) initial_temp_c = float(data.get("ir_initial_temp", 20.0)) # e.g., 4.0 for fridge, -18.0 for freezer microwave_wattage = int(data.get("microwave_wattage", 900)) # e.g., 900W defrost_mode = bool(data.get("defrost_mode", False)) # True for defrost, False for cook/reheat print("Parsed parameters - Height (cm):", height_cm, "Initial Temp (C):", initial_temp_c, "Microwave Wattage:", microwave_wattage, "Defrost Mode:", defrost_mode) # 1. Handle the Camera Image camera_image_b64 = data.get("camera_image") filepath = None if camera_image_b64: filename = f"dish_{uuid.uuid4().hex}.jpg" filepath = os.path.join(CAMERA_IMAGE_DIR, filename) try: with open(filepath, "wb") as f: f.write(base64.b64decode(camera_image_b64)) data["camera_image"] = filepath except Exception as e: return jsonify({"error": f"Failed to save camera image: {str(e)}"}), 500 else: return jsonify({"error": "Missing required field 'camera_image'"}), 400 # 2. Run the Cook Planning Engine try: cook_plan = microwave_cook_planner.generate_plan( image_path=filepath, height_cm=height_cm, initial_temp_c=initial_temp_c, microwave_wattage=microwave_wattage, defrost_mode=defrost_mode ) except Exception as e: return jsonify({"error": f"Failed to compute cooking plan: {str(e)}"}), 500 # 3. Attach cooking parameters to database record data["analysis_results"] = cook_plan # 4. Save to MongoDB try: cooking_collection.insert_one(data) data.pop("_id", None) except Exception as e: return jsonify({"error": f"Database error: {str(e)}"}), 500 # 5. Return complete output return jsonify(cook_plan), 201 @app.route("/telemetry", methods=["POST"]) def telemetry(): data = request.get_json() if data is None: return jsonify({"error": "Invalid or missing JSON payload"}), 400 # If the payload was double-encoded as a string, deserialize it if isinstance(data, str): try: data = json.loads(data) except (json.JSONDecodeError, TypeError): return jsonify({"error": "String payload could not be parsed as JSON"}), 400 if not isinstance(data, dict): return jsonify({"error": "Expected a JSON object/dictionary"}), 400 # Stamp UTC timestamp for Node-RED queries data["received_at"] = datetime.datetime.now(datetime.timezone.utc).isoformat() try: telemetry_collection.insert_one(data) return jsonify({"status": "success", "message": "Telemetry saved"}), 200 except Exception as e: return jsonify({"error": f"Database error: {str(e)}"}), 500 @app.route("/debug", methods=["GET"]) def debug(): # Construct external HTTP endpoint dynamically based on incoming request host telemetry_url = f"{request.host_url.rstrip('/')}/telemetry" cmd_payload = { "action": "request_telemetry", "endpoint": telemetry_url } try: send_command(topic="cmd/all", payload=cmd_payload) return jsonify({ "status": "Telemetry command sent to cmd/all", "published_payload": cmd_payload }), 200 except Exception as e: return jsonify({"error": f"Failed to publish MQTT command: {str(e)}"}), 500 if __name__ == "__main__": app.run(debug=getattr(config, "DEBUG", True))