from fastapi import FastAPI, Path, HTTPException, status from fastapi.responses import RedirectResponse, FileResponse from projectorpi.cli import ProjectorSerial, ExtronSerial from pydantic import BaseModel from time import sleep from typing import Optional import sentry_sdk sentry_sdk.init( dsn="https://8dce3a0f69f643c0a3547b8baf19d00b@sentry.marijndoeve.nl/3", # Set traces_sample_rate to 1.0 to capture 100% # of transactions for performance monitoring. # We recommend adjusting this value in production, traces_sample_rate=1.0, ) app = FastAPI() extron = ExtronSerial() projector = ProjectorSerial() class Response(BaseModel): status: str error: Optional[str] = None @app.get("/") async def index() -> RedirectResponse: return FileResponse("projectorpi_web/index.html") # return RedirectResponse("/docs", HTTPStatus.MOVED_PERMANENTLY) @app.post("/sleep", response_model=Response) async def sleep_post() -> Response: extron.sleep() projector.power_off() return Response(status="ok") @app.post("/select/{input_id}", response_model=Response) async def select( input_id: int = Path(title="The input to select", ge=1, le=4), ) -> Response: if extron.is_sleeping(): extron.wake() sleep(1) extron.change_input(input_id) if not projector.is_on(): projector.power_on() return Response(status="ok") @app.post("/control/{direction}", response_model=Response) async def control(direction: str) -> Response: directions = { "vol_up": extron.volume_up, "vol_down": extron.volume_down, "up": extron.menu_up, "right": extron.menu_right, "down": extron.menu_down, "left": extron.menu_left, "enter": extron.menu_enter, "menu": extron.menu_toggle, } runnable = directions.get(direction) if not runnable: raise HTTPException(status.HTTP_400_BAD_REQUEST, "invalid control") runnable() return Response(status="ok")