Download backend/api/plant_control_controller.py from subhan07/hvac-agents: direct link, hf CLI and curl.
- Browser
- Download file 11 kB
-
https://huggingface.co/subhan07/hvac-agents/resolve/main/backend/api/plant_control_controller.py
- Command line
-
hf download hf://subhan07/hvac-agents/backend/api/plant_control_controller.py
-
curl -L -o plant_control_controller.py https://huggingface.co/subhan07/hvac-agents/resolve/main/backend/api/plant_control_controller.py
11 kB
| """ | |
| PlantControlController: FastAPI Router exposing all REST endpoints for | |
| Plant Control Parameter Optimizations: | |
| - O5: Duct Static Pressure Reset | |
| - O6–8: Unified Temperature Reset (HHW, CHW, CW modes) | |
| - O9: Electronic Expansion Valve Retrofit Assessment | |
| """ | |
| from fastapi import APIRouter, HTTPException, Query | |
| from typing import Dict, Any, List, Optional | |
| from pydantic import BaseModel | |
| from backend.services.plant_control_service import plant_control_service | |
| from backend.services.plant_control_telemetry_service import plant_control_telemetry_service | |
| from backend.services.plant_control_command_service import plant_control_command_service | |
| from backend.services.plant_control_verification_service import plant_control_verification_service | |
| from backend.services.plant_control_safety_service import plant_control_safety_service | |
| from backend.agents.plant_control.o6_8_temperature_reset.engine import o6_8_agent | |
| from backend.services.plant_control_provenance import stamp_plant_provenance | |
| def _reset_opportunity(mode: str) -> str: | |
| r_type = (mode or "CHW").upper().replace("_RESET", "") | |
| if r_type == "HHW": | |
| return "O6" | |
| if r_type == "CW": | |
| return "O8" | |
| return "O7" | |
| router = APIRouter(prefix="/api/agents/plant-control", tags=["Plant Control Parameter Optimizations"]) | |
| class CommandDispatchRequest(BaseModel): | |
| target_setpoint: float | |
| reset_type: Optional[str] = "CHW" | |
| context: Optional[Dict[str, Any]] = None | |
| # ------------------------------------------------------------- | |
| # High-Level Plant Control Fleet Endpoints | |
| # ------------------------------------------------------------- | |
| async def get_plant_control_state(): | |
| """Returns fleet-wide optimization state, total kW shed, and opportunity status.""" | |
| return plant_control_service.get_dashboard_state() | |
| async def get_all_plant_telemetry(): | |
| """Returns standardized telemetry points across all plant control equipment.""" | |
| return plant_control_telemetry_service.get_all_points() | |
| async def get_plant_activity(limit: int = Query(20, ge=1, le=100)): | |
| """Returns audit log history of plant control actions, safety checks, and verifications.""" | |
| return plant_control_service.get_activity_log(limit=limit) | |
| async def get_safety_guardrails(): | |
| """Returns definitions of all 10 deterministic safety guardrails.""" | |
| return plant_control_safety_service.get_guardrail_definitions() | |
| # ------------------------------------------------------------- | |
| # Opportunity 5: Duct Static Pressure Reset | |
| # ------------------------------------------------------------- | |
| async def get_o5_state(): | |
| """Returns live O5 Duct Static Pressure Reset state and candidate evaluation.""" | |
| return plant_control_service.get_o5_state() | |
| async def get_o5_telemetry(): | |
| """Returns all standardized telemetry points for AHUs and downstream VAV boxes.""" | |
| return plant_control_telemetry_service.get_opportunity_telemetry("O5") | |
| async def get_o5_decision(): | |
| """Returns active candidate recommendation and fan power savings prediction.""" | |
| state = plant_control_service.get_o5_state() | |
| return { | |
| "opportunity_code": "O5", | |
| "current_setpoint": state["current_setpoint"], | |
| "optimized_setpoint": state["optimized_setpoint"], | |
| "pressure_reduction": state["pressure_reduction"], | |
| "fan_power_shed_kw": state["power_shed_kw"], | |
| "confidence": state["confidence"], | |
| "safety_status": state["safety_status"], | |
| "decision": state["decision"] | |
| } | |
| async def get_o5_history(): | |
| """Returns 24-hour historical time-series for duct static pressure and fan power.""" | |
| return plant_control_service.get_o5_history() | |
| async def dispatch_o5_command(req: CommandDispatchRequest): | |
| """Dispatches an optimized duct static pressure setpoint via BMS Gateway.""" | |
| try: | |
| return plant_control_command_service.execute_command("O5", req.target_setpoint, req.context) | |
| except ValueError as exc: | |
| raise HTTPException(status_code=409, detail={"code": "DISPATCH_BLOCKED", "message": str(exc)}) | |
| async def verify_o5_response(): | |
| """Runs 15-minute M&V verification for O5 static pressure reset.""" | |
| return plant_control_verification_service.verify_opportunity("O5") | |
| async def rollback_o5(): | |
| """Rolls back O5 static pressure setpoint to design baseline.""" | |
| return plant_control_verification_service.rollback_opportunity("O5", "Manual Operator Rollback") | |
| # ------------------------------------------------------------- | |
| # Opportunity 6–8: Unified Temperature Reset (HHW, CHW, CW) | |
| # ------------------------------------------------------------- | |
| async def get_o6_8_state(mode: str = Query("CHW", description="Reset Mode: HHW, CHW, or CW")): | |
| """Returns normalized Temperature Reset state for selected mode (HHW, CHW, or CW).""" | |
| return stamp_plant_provenance(o6_8_agent.optimize_mode(mode), _reset_opportunity(mode)) | |
| async def get_o6_8_all_modes(): | |
| """Returns summary for all 3 temperature reset modes simultaneously.""" | |
| return o6_8_agent.get_all_modes_summary() | |
| async def get_o6_8_telemetry(mode: str = Query("CHW")): | |
| """Returns telemetry points for selected reset mode loop.""" | |
| r_type = mode.upper().replace("_RESET", "") | |
| opp_code = "O6" if r_type == "HHW" else ("O8" if r_type == "CW" else "O7") | |
| return plant_control_telemetry_service.get_opportunity_telemetry(opp_code) | |
| async def get_o6_8_decision(mode: str = Query("CHW")): | |
| """Returns normalized decision record for selected reset mode.""" | |
| res = o6_8_agent.optimize_mode(mode) | |
| return { | |
| "opportunity_id": "O6_8", | |
| "reset_type": res["reset_type"], | |
| "current_setpoint": res["current_setpoint"], | |
| "optimized_setpoint": res["optimized_setpoint"], | |
| "baseline_setpoint": res["baseline_setpoint"], | |
| "power_impact": res["power_impact"], | |
| "efficiency_impact": res["efficiency_impact"], | |
| "confidence": res["confidence"], | |
| "safety_status": res["status"], | |
| "reason": res["reason"] | |
| } | |
| async def dispatch_o6_8_command(req: CommandDispatchRequest): | |
| """Dispatches a temperature reset setpoint for HHW, CHW, or CW.""" | |
| r_type = (req.reset_type or "CHW").upper().replace("_RESET", "") | |
| opp_code = "O6" if r_type == "HHW" else ("O8" if r_type == "CW" else "O7") | |
| try: | |
| return plant_control_command_service.execute_command(opp_code, req.target_setpoint, req.context) | |
| except ValueError as exc: | |
| raise HTTPException(status_code=409, detail={"code": "DISPATCH_BLOCKED", "message": str(exc)}) | |
| async def verify_o6_8_response(mode: str = Query("CHW")): | |
| """Runs 15-minute M&V verification for temperature reset mode.""" | |
| r_type = mode.upper().replace("_RESET", "") | |
| opp_code = "O6" if r_type == "HHW" else ("O8" if r_type == "CW" else "O7") | |
| return plant_control_verification_service.verify_opportunity(opp_code) | |
| async def rollback_o6_8(mode: str = Query("CHW")): | |
| """Rolls back temperature reset to baseline design setpoint.""" | |
| r_type = mode.upper().replace("_RESET", "") | |
| opp_code = "O6" if r_type == "HHW" else ("O8" if r_type == "CW" else "O7") | |
| return plant_control_verification_service.rollback_opportunity(opp_code, f"Rollback for {mode} Temperature Reset") | |
| # ------------------------------------------------------------- | |
| # Backward-Compatibility Routes for O6, O7, O8 | |
| # ------------------------------------------------------------- | |
| async def get_o6_state(): | |
| return stamp_plant_provenance(o6_8_agent.optimize_mode("HHW"), "O6") | |
| async def get_o6_telemetry(): | |
| return plant_control_telemetry_service.get_opportunity_telemetry("O6") | |
| async def get_o6_decision(): | |
| return get_o6_8_decision("HHW") | |
| async def get_o6_history(): | |
| return plant_control_service.get_o6_history() | |
| async def get_o7_state(): | |
| return stamp_plant_provenance(o6_8_agent.optimize_mode("CHW"), "O7") | |
| async def get_o7_telemetry(): | |
| return plant_control_telemetry_service.get_opportunity_telemetry("O7") | |
| async def get_o7_decision(): | |
| return get_o6_8_decision("CHW") | |
| async def get_o7_history(): | |
| return plant_control_service.get_o7_history() | |
| async def get_o8_state(): | |
| return stamp_plant_provenance(o6_8_agent.optimize_mode("CW"), "O8") | |
| async def get_o8_telemetry(): | |
| return plant_control_telemetry_service.get_opportunity_telemetry("O8") | |
| async def get_o8_decision(): | |
| return get_o6_8_decision("CW") | |
| async def get_o8_history(): | |
| return plant_control_service.get_o8_history() | |
| # ------------------------------------------------------------- | |
| # Opportunity 9: Electronic Expansion Valve Retrofit | |
| # ------------------------------------------------------------- | |
| async def get_o9_assessment(): | |
| """Returns comprehensive thermodynamic and economic retrofit feasibility assessment.""" | |
| return plant_control_service.get_o9_assessment() | |
| async def get_o9_telemetry(): | |
| """Returns live suction, superheat, and evaporating state telemetry.""" | |
| return plant_control_telemetry_service.get_opportunity_telemetry("O9") | |
| async def get_o9_history(): | |
| """Returns superheat stability and hunting amplitude comparison curves.""" | |
| return plant_control_service.get_o9_history() | |
| async def recalculate_o9_feasibility(utility_rate: float = Query(0.12)): | |
| """Recalculates capital payback and ROI based on updated utility rates.""" | |
| from backend.agents.plant_control.o9_electronic_expansion_valve.engine import o9_agent | |
| return o9_agent.evaluate_retrofit_feasibility(utility_rate_per_kwh=utility_rate) | |