Add room and analytics services with CRUD API endpoints

- Implement RoomService for room management and metrics - Add
AnalyticsService for sensor data analytics and trends - Extend models
with Room, RoomCreate, RoomUpdate, RoomInfo - Add room CRUD endpoints to
FastAPI app - Add database connection logic for MongoDB and Redis -
Refactor sensor service logic into SensorService class
This commit is contained in:
rafaeldpsilva
2025-09-22 15:13:14 +01:00
parent 2008ea0e70
commit 02a0d54e14
6 changed files with 1285 additions and 7 deletions

View File

@@ -16,7 +16,8 @@ import json
from models import (
SensorReading, SensorMetadata, RoomMetrics, SystemEvent, DataQuery, DataResponse,
SensorType, SensorStatus, CO2Status, OccupancyLevel, HealthResponse
SensorType, SensorStatus, CO2Status, OccupancyLevel, HealthResponse,
Room, RoomCreate, RoomUpdate, RoomInfo
)
from database import connect_to_mongo, close_mongo_connection, get_database, connect_to_redis, get_redis
from sensor_service import SensorService
@@ -38,6 +39,12 @@ async def lifespan(app: FastAPI):
await connect_to_mongo()
await connect_to_redis()
# Initialize default rooms if none exist
db = await get_database()
redis_client = await get_redis()
room_service = RoomService(db, redis_client)
await room_service.initialize_default_rooms()
# Start background tasks
asyncio.create_task(redis_subscriber_task())
asyncio.create_task(room_metrics_aggregation_task())
@@ -250,6 +257,19 @@ async def delete_sensor(
raise HTTPException(status_code=500, detail="Internal server error")
# Room Management
@app.get("/rooms/names")
async def get_room_names(service: RoomService = Depends(get_room_service)):
"""Get simple list of room names for dropdowns"""
try:
room_names = await service.get_all_room_names()
return {
"rooms": room_names,
"count": len(room_names)
}
except Exception as e:
logger.error(f"Error getting room names: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@app.get("/rooms")
async def get_rooms(service: RoomService = Depends(get_room_service)):
"""Get all rooms with sensor counts and metrics"""
@@ -265,16 +285,16 @@ async def get_rooms(service: RoomService = Depends(get_room_service)):
@app.post("/rooms")
async def create_room(
room_data: dict,
room_data: RoomCreate,
service: RoomService = Depends(get_room_service)
):
"""Create a new room"""
try:
result = await service.create_room(room_data)
result = await service.create_room(room_data.dict())
return {
"message": "Room created successfully",
"room": room_data.get("name"),
"created_at": result.get("created_at")
"room": result["name"],
"created_at": result["created_at"]
}
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
@@ -282,6 +302,40 @@ async def create_room(
logger.error(f"Error creating room: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@app.put("/rooms/{room_name}")
async def update_room(
room_name: str,
room_data: RoomUpdate,
service: RoomService = Depends(get_room_service)
):
"""Update an existing room"""
try:
result = await service.update_room(room_name, room_data.dict(exclude_unset=True))
return {
"message": "Room updated successfully",
"room": result["name"],
"updated_at": result["updated_at"],
"modified": result["modified"]
}
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
except Exception as e:
logger.error(f"Error updating room {room_name}: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@app.delete("/rooms/{room_name}")
async def delete_room(room_name: str, service: RoomService = Depends(get_room_service)):
"""Delete a room"""
try:
result = await service.delete_room(room_name)
return {
"message": "Room deleted successfully",
**result
}
except Exception as e:
logger.error(f"Error deleting room {room_name}: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@app.get("/rooms/{room_name}")
async def get_room(room_name: str, service: RoomService = Depends(get_room_service)):
"""Get detailed room information"""