"""REST API – board webhook receiver and JSON relay control.""" from datetime import datetime from flask import Blueprint, request, jsonify, abort from app import db, socketio from app.models.board import Board from app.services import workflow_engine api_bp = Blueprint("api", __name__) # ── webhook endpoint (boards POST input events here) ────────────────────────── @api_bp.route("/webhook/", methods=["POST"]) def webhook(board_id: int): board = db.session.get(Board, board_id) if board is None: abort(404) data = request.get_json(silent=True) or {} input_num = data.get("input") state = data.get("state") if input_num is None or state is None: return jsonify({"error": "missing input or state"}), 400 # Update cached input state states = board.input_states states[f"input_{input_num}"] = bool(state) board.input_states = states board.is_online = True board.last_seen = datetime.utcnow() db.session.commit() # Let the workflow engine decide what to do workflow_engine.process_input_event(board_id, int(input_num), bool(state)) # Push live update to all connected clients immediately socketio.emit("board_update", { "board_id": board_id, "is_online": True, "input_states": board.input_states, "relay_states": board.relay_states, }) return jsonify({"status": "ok"}) # ── JSON relay status ───────────────────────────────────────────────────────── @api_bp.route("/boards//relays") def relay_states(board_id: int): board = db.get_or_404(Board, board_id) return jsonify({ "board_id": board.id, "name": board.name, "is_online": board.is_online, "relay_states": board.relay_states, "input_states": board.input_states, }) # ── JSON board list ─────────────────────────────────────────────────────────── @api_bp.route("/boards") def board_list(): boards = Board.query.order_by(Board.name).all() return jsonify([ { "id": b.id, "name": b.name, "board_type": b.board_type, "host": b.host, "port": b.port, "is_online": b.is_online, "last_seen": b.last_seen.isoformat() if b.last_seen else None, "relay_states": b.relay_states, "input_states": b.input_states, } for b in boards ])