first commit
This commit is contained in:
236
models.py
Normal file
236
models.py
Normal file
@@ -0,0 +1,236 @@
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List, Dict, Any, Literal
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
class SensorType(str, Enum):
|
||||
ENERGY = "energy"
|
||||
CO2 = "co2"
|
||||
TEMPERATURE = "temperature"
|
||||
HUMIDITY = "humidity"
|
||||
HVAC = "hvac"
|
||||
LIGHTING = "lighting"
|
||||
SECURITY = "security"
|
||||
|
||||
class SensorStatus(str, Enum):
|
||||
ONLINE = "online"
|
||||
OFFLINE = "offline"
|
||||
ERROR = "error"
|
||||
MAINTENANCE = "maintenance"
|
||||
|
||||
class CO2Status(str, Enum):
|
||||
GOOD = "good"
|
||||
MODERATE = "moderate"
|
||||
POOR = "poor"
|
||||
CRITICAL = "critical"
|
||||
|
||||
class OccupancyLevel(str, Enum):
|
||||
LOW = "low"
|
||||
MEDIUM = "medium"
|
||||
HIGH = "high"
|
||||
|
||||
# Base Models
|
||||
class SensorReading(BaseModel):
|
||||
"""Individual sensor reading model"""
|
||||
sensor_id: str = Field(..., description="Unique sensor identifier")
|
||||
room: Optional[str] = Field(None, description="Room where sensor is located")
|
||||
sensor_type: SensorType = Field(..., description="Type of sensor")
|
||||
timestamp: int = Field(..., description="Unix timestamp of reading")
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow, description="Record creation timestamp")
|
||||
|
||||
# Sensor values
|
||||
energy: Optional[Dict[str, Any]] = Field(None, description="Energy reading with value and unit")
|
||||
co2: Optional[Dict[str, Any]] = Field(None, description="CO2 reading with value and unit")
|
||||
temperature: Optional[Dict[str, Any]] = Field(None, description="Temperature reading with value and unit")
|
||||
humidity: Optional[Dict[str, Any]] = Field(None, description="Humidity reading with value and unit")
|
||||
motion: Optional[Dict[str, Any]] = Field(None, description="Motion detection reading")
|
||||
|
||||
# Metadata
|
||||
metadata: Optional[Dict[str, Any]] = Field(default_factory=dict, description="Additional sensor metadata")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat()
|
||||
}
|
||||
|
||||
class LegacySensorReading(BaseModel):
|
||||
"""Legacy sensor reading format for backward compatibility"""
|
||||
sensor_id: str = Field(..., alias="sensorId")
|
||||
timestamp: int
|
||||
value: float
|
||||
unit: str
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
class SensorMetadata(BaseModel):
|
||||
"""Sensor configuration and metadata"""
|
||||
sensor_id: str = Field(..., description="Unique sensor identifier")
|
||||
name: str = Field(..., description="Human-readable sensor name")
|
||||
sensor_type: SensorType = Field(..., description="Type of sensor")
|
||||
room: Optional[str] = Field(None, description="Room assignment")
|
||||
status: SensorStatus = Field(default=SensorStatus.OFFLINE, description="Current sensor status")
|
||||
|
||||
# Physical location and installation details
|
||||
location: Optional[str] = Field(None, description="Physical location description")
|
||||
floor: Optional[str] = Field(None, description="Floor level")
|
||||
building: Optional[str] = Field(None, description="Building identifier")
|
||||
|
||||
# Technical specifications
|
||||
model: Optional[str] = Field(None, description="Sensor model")
|
||||
manufacturer: Optional[str] = Field(None, description="Sensor manufacturer")
|
||||
firmware_version: Optional[str] = Field(None, description="Firmware version")
|
||||
hardware_version: Optional[str] = Field(None, description="Hardware version")
|
||||
|
||||
# Network and connectivity
|
||||
ip_address: Optional[str] = Field(None, description="IP address if network connected")
|
||||
mac_address: Optional[str] = Field(None, description="MAC address")
|
||||
connection_type: Optional[str] = Field(None, description="Connection type (wifi, ethernet, zigbee, etc.)")
|
||||
|
||||
# Power and maintenance
|
||||
battery_level: Optional[float] = Field(None, description="Battery level percentage")
|
||||
last_maintenance: Optional[datetime] = Field(None, description="Last maintenance date")
|
||||
next_maintenance: Optional[datetime] = Field(None, description="Next scheduled maintenance")
|
||||
|
||||
# Operational settings
|
||||
sampling_rate: Optional[int] = Field(None, description="Data sampling rate in seconds")
|
||||
calibration_date: Optional[datetime] = Field(None, description="Last calibration date")
|
||||
|
||||
# Capabilities
|
||||
monitoring_capabilities: List[str] = Field(default_factory=list, description="List of monitoring capabilities")
|
||||
control_capabilities: List[str] = Field(default_factory=list, description="List of control capabilities")
|
||||
|
||||
# Timestamps
|
||||
installed_at: Optional[datetime] = Field(None, description="Installation timestamp")
|
||||
last_seen: Optional[datetime] = Field(None, description="Last communication timestamp")
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow, description="Record creation timestamp")
|
||||
updated_at: datetime = Field(default_factory=datetime.utcnow, description="Record update timestamp")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat() if v else None
|
||||
}
|
||||
|
||||
class RoomMetrics(BaseModel):
|
||||
"""Aggregated room-level metrics"""
|
||||
room: str = Field(..., description="Room identifier")
|
||||
timestamp: int = Field(..., description="Metrics calculation timestamp")
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow, description="Record creation timestamp")
|
||||
|
||||
# Sensor inventory
|
||||
sensor_count: int = Field(0, description="Total number of sensors in room")
|
||||
active_sensors: List[str] = Field(default_factory=list, description="List of active sensor IDs")
|
||||
sensor_types: List[SensorType] = Field(default_factory=list, description="Types of sensors present")
|
||||
|
||||
# Energy metrics
|
||||
energy: Optional[Dict[str, Any]] = Field(None, description="Energy consumption metrics")
|
||||
# Format: {"current": float, "total": float, "average": float, "peak": float, "unit": str}
|
||||
|
||||
# Environmental metrics
|
||||
co2: Optional[Dict[str, Any]] = Field(None, description="CO2 level metrics")
|
||||
# Format: {"current": float, "average": float, "max": float, "min": float, "status": CO2Status, "unit": str}
|
||||
|
||||
temperature: Optional[Dict[str, Any]] = Field(None, description="Temperature metrics")
|
||||
# Format: {"current": float, "average": float, "max": float, "min": float, "unit": str}
|
||||
|
||||
humidity: Optional[Dict[str, Any]] = Field(None, description="Humidity metrics")
|
||||
# Format: {"current": float, "average": float, "max": float, "min": float, "unit": str}
|
||||
|
||||
# Occupancy and usage
|
||||
occupancy_estimate: OccupancyLevel = Field(default=OccupancyLevel.LOW, description="Estimated occupancy level")
|
||||
motion_detected: bool = Field(default=False, description="Recent motion detection status")
|
||||
|
||||
# Time-based metrics
|
||||
last_activity: Optional[datetime] = Field(None, description="Last detected activity timestamp")
|
||||
daily_usage_hours: Optional[float] = Field(None, description="Estimated daily usage in hours")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat() if v else None
|
||||
}
|
||||
|
||||
class SystemEvent(BaseModel):
|
||||
"""System events and alerts"""
|
||||
event_id: str = Field(..., description="Unique event identifier")
|
||||
event_type: str = Field(..., description="Type of event")
|
||||
severity: Literal["info", "warning", "error", "critical"] = Field(..., description="Event severity")
|
||||
timestamp: int = Field(..., description="Event timestamp")
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow, description="Record creation timestamp")
|
||||
|
||||
# Event details
|
||||
title: str = Field(..., description="Event title")
|
||||
description: str = Field(..., description="Event description")
|
||||
source: Optional[str] = Field(None, description="Event source (sensor_id, system component, etc.)")
|
||||
|
||||
# Context
|
||||
sensor_id: Optional[str] = Field(None, description="Related sensor ID")
|
||||
room: Optional[str] = Field(None, description="Related room")
|
||||
|
||||
# Event data
|
||||
data: Optional[Dict[str, Any]] = Field(default_factory=dict, description="Additional event data")
|
||||
|
||||
# Status tracking
|
||||
acknowledged: bool = Field(default=False, description="Whether event has been acknowledged")
|
||||
resolved: bool = Field(default=False, description="Whether event has been resolved")
|
||||
acknowledged_by: Optional[str] = Field(None, description="Who acknowledged the event")
|
||||
resolved_by: Optional[str] = Field(None, description="Who resolved the event")
|
||||
acknowledged_at: Optional[datetime] = Field(None, description="Acknowledgment timestamp")
|
||||
resolved_at: Optional[datetime] = Field(None, description="Resolution timestamp")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat() if v else None
|
||||
}
|
||||
|
||||
class DataQuery(BaseModel):
|
||||
"""Data query parameters for historical data retrieval"""
|
||||
sensor_ids: Optional[List[str]] = Field(None, description="Filter by sensor IDs")
|
||||
rooms: Optional[List[str]] = Field(None, description="Filter by rooms")
|
||||
sensor_types: Optional[List[SensorType]] = Field(None, description="Filter by sensor types")
|
||||
|
||||
# Time range
|
||||
start_time: Optional[int] = Field(None, description="Start timestamp (Unix)")
|
||||
end_time: Optional[int] = Field(None, description="End timestamp (Unix)")
|
||||
|
||||
# Aggregation
|
||||
aggregate: Optional[str] = Field(None, description="Aggregation method (avg, sum, min, max)")
|
||||
interval: Optional[str] = Field(None, description="Aggregation interval (1m, 5m, 1h, 1d)")
|
||||
|
||||
# Pagination
|
||||
limit: int = Field(default=100, description="Maximum number of records to return")
|
||||
offset: int = Field(default=0, description="Number of records to skip")
|
||||
|
||||
# Sorting
|
||||
sort_by: str = Field(default="timestamp", description="Field to sort by")
|
||||
sort_order: Literal["asc", "desc"] = Field(default="desc", description="Sort order")
|
||||
|
||||
class DataResponse(BaseModel):
|
||||
"""Response model for data queries"""
|
||||
data: List[Dict[str, Any]] = Field(default_factory=list, description="Query results")
|
||||
total_count: int = Field(0, description="Total number of matching records")
|
||||
query: DataQuery = Field(..., description="Original query parameters")
|
||||
execution_time_ms: float = Field(..., description="Query execution time in milliseconds")
|
||||
|
||||
class HealthCheck(BaseModel):
|
||||
"""Health check response model"""
|
||||
status: str = Field(..., description="Overall system status")
|
||||
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
# Database status
|
||||
mongodb_connected: bool = Field(..., description="MongoDB connection status")
|
||||
redis_connected: bool = Field(..., description="Redis connection status")
|
||||
|
||||
# Data statistics
|
||||
total_sensors: int = Field(0, description="Total number of registered sensors")
|
||||
active_sensors: int = Field(0, description="Number of active sensors")
|
||||
total_readings: int = Field(0, description="Total sensor readings in database")
|
||||
|
||||
# System metrics
|
||||
uptime_seconds: float = Field(..., description="System uptime in seconds")
|
||||
memory_usage_mb: Optional[float] = Field(None, description="Memory usage in MB")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat()
|
||||
}
|
||||
Reference in New Issue
Block a user