Files
bakery-ia/services/production/app/schemas/equipment.py

489 lines
17 KiB
Python
Raw Normal View History

2025-10-19 19:22:37 +02:00
# services/production/app/schemas/equipment.py
"""
Equipment schemas for Production Service
"""
from pydantic import BaseModel, Field, ConfigDict
from typing import Optional, List
from datetime import datetime
from uuid import UUID
2025-11-13 16:01:08 +01:00
from app.models.production import EquipmentType, EquipmentStatus, IoTProtocol, IoTConnectionStatus
class IoTConnectionConfig(BaseModel):
"""Schema for IoT connection configuration"""
protocol: str = Field(..., description="IoT protocol (rest_api, opc_ua, mqtt, modbus, custom)")
endpoint: str = Field(..., description="Connection endpoint (URL or IP address)")
port: Optional[int] = Field(None, description="Connection port")
username: Optional[str] = Field(None, description="Username for authentication")
password: Optional[str] = Field(None, description="Password for authentication")
api_key: Optional[str] = Field(None, description="API key for authentication")
token: Optional[str] = Field(None, description="Authentication token")
additional_config: Optional[dict] = Field(None, description="Additional protocol-specific configuration")
model_config = ConfigDict(
json_schema_extra={
"example": {
"protocol": "rest_api",
"endpoint": "https://connectedcooking.com/api/v1",
"port": 443,
"api_key": "your-api-key-here",
"additional_config": {"poll_interval": 30}
}
}
)
2025-10-19 19:22:37 +02:00
class EquipmentCreate(BaseModel):
"""Schema for creating new equipment"""
name: str = Field(..., min_length=1, max_length=255, description="Equipment name")
type: EquipmentType = Field(..., description="Equipment type")
model: Optional[str] = Field(None, max_length=100, description="Equipment model")
serial_number: Optional[str] = Field(None, max_length=100, description="Serial number")
location: Optional[str] = Field(None, max_length=255, description="Physical location")
2025-11-13 16:01:08 +01:00
manufacturer: Optional[str] = Field(None, max_length=100, description="Manufacturer")
firmware_version: Optional[str] = Field(None, max_length=50, description="Firmware version")
2025-10-19 19:22:37 +02:00
status: EquipmentStatus = Field(default=EquipmentStatus.OPERATIONAL, description="Equipment status")
# Installation and maintenance
install_date: Optional[datetime] = Field(None, description="Installation date")
last_maintenance_date: Optional[datetime] = Field(None, description="Last maintenance date")
next_maintenance_date: Optional[datetime] = Field(None, description="Next scheduled maintenance date")
maintenance_interval_days: Optional[int] = Field(None, ge=1, description="Maintenance interval in days")
# Performance metrics
efficiency_percentage: Optional[float] = Field(None, ge=0, le=100, description="Current efficiency percentage")
uptime_percentage: Optional[float] = Field(None, ge=0, le=100, description="Overall uptime percentage")
energy_usage_kwh: Optional[float] = Field(None, ge=0, description="Current energy usage in kWh")
# Specifications
power_kw: Optional[float] = Field(None, ge=0, description="Power consumption in kilowatts")
capacity: Optional[float] = Field(None, ge=0, description="Equipment capacity")
weight_kg: Optional[float] = Field(None, ge=0, description="Weight in kilograms")
# Temperature monitoring
current_temperature: Optional[float] = Field(None, description="Current temperature")
target_temperature: Optional[float] = Field(None, description="Target temperature")
2025-11-13 16:01:08 +01:00
# IoT Connectivity
iot_enabled: bool = Field(default=False, description="Enable IoT connectivity")
iot_protocol: Optional[str] = Field(None, description="IoT protocol")
iot_endpoint: Optional[str] = Field(None, description="IoT endpoint URL or IP")
iot_port: Optional[int] = Field(None, description="IoT connection port")
iot_config: Optional[dict] = Field(None, description="IoT configuration")
# Real-time monitoring
supports_realtime: bool = Field(default=False, description="Supports real-time monitoring")
poll_interval_seconds: Optional[int] = Field(None, ge=1, description="Polling interval in seconds")
# Sensor capabilities
temperature_zones: Optional[int] = Field(None, ge=1, description="Number of temperature zones")
supports_humidity: bool = Field(default=False, description="Supports humidity monitoring")
supports_energy_monitoring: bool = Field(default=False, description="Supports energy monitoring")
supports_remote_control: bool = Field(default=False, description="Supports remote control")
2025-10-19 19:22:37 +02:00
# Notes
notes: Optional[str] = Field(None, description="Additional notes")
2026-01-11 17:03:46 +01:00
# Support contact information
support_contact: Optional[dict] = Field(
None,
description="Support contact information for equipment maintenance",
json_schema_extra={
"example": {
"email": "support@ovenfactory.com",
"phone": "+1-800-555-1234",
"company": "OvenTech Support",
"contract_number": "SUP-2023-001",
"response_time_sla": 24
}
}
)
2025-10-19 19:22:37 +02:00
model_config = ConfigDict(
json_schema_extra={
"example": {
"name": "Horno Principal #1",
"type": "oven",
"model": "Miwe Condo CO 4.1212",
"serial_number": "MCO-2021-001",
"location": "Área de Horneado - Zona A",
"status": "operational",
"install_date": "2021-03-15T00:00:00Z",
"maintenance_interval_days": 90,
"efficiency_percentage": 92.0,
"uptime_percentage": 98.5,
"power_kw": 45.0,
"capacity": 24.0
}
}
)
class EquipmentUpdate(BaseModel):
"""Schema for updating equipment"""
name: Optional[str] = Field(None, min_length=1, max_length=255)
type: Optional[EquipmentType] = None
model: Optional[str] = Field(None, max_length=100)
serial_number: Optional[str] = Field(None, max_length=100)
location: Optional[str] = Field(None, max_length=255)
2025-11-13 16:01:08 +01:00
manufacturer: Optional[str] = Field(None, max_length=100)
firmware_version: Optional[str] = Field(None, max_length=50)
2025-10-19 19:22:37 +02:00
status: Optional[EquipmentStatus] = None
# Installation and maintenance
install_date: Optional[datetime] = None
last_maintenance_date: Optional[datetime] = None
next_maintenance_date: Optional[datetime] = None
maintenance_interval_days: Optional[int] = Field(None, ge=1)
# Performance metrics
efficiency_percentage: Optional[float] = Field(None, ge=0, le=100)
uptime_percentage: Optional[float] = Field(None, ge=0, le=100)
energy_usage_kwh: Optional[float] = Field(None, ge=0)
# Specifications
power_kw: Optional[float] = Field(None, ge=0)
capacity: Optional[float] = Field(None, ge=0)
weight_kg: Optional[float] = Field(None, ge=0)
# Temperature monitoring
current_temperature: Optional[float] = None
target_temperature: Optional[float] = None
2025-11-13 16:01:08 +01:00
# IoT Connectivity
iot_enabled: Optional[bool] = None
iot_protocol: Optional[str] = None
iot_endpoint: Optional[str] = None
iot_port: Optional[int] = None
iot_config: Optional[dict] = None
# Real-time monitoring
supports_realtime: Optional[bool] = None
poll_interval_seconds: Optional[int] = Field(None, ge=1)
# Sensor capabilities
temperature_zones: Optional[int] = Field(None, ge=1)
supports_humidity: Optional[bool] = None
supports_energy_monitoring: Optional[bool] = None
supports_remote_control: Optional[bool] = None
2025-10-19 19:22:37 +02:00
# Notes
notes: Optional[str] = None
2026-01-11 17:03:46 +01:00
# Support contact information
support_contact: Optional[dict] = None
2025-10-19 19:22:37 +02:00
# Status flag
is_active: Optional[bool] = None
model_config = ConfigDict(
json_schema_extra={
"example": {
"status": "maintenance",
"last_maintenance_date": "2024-01-15T00:00:00Z",
"next_maintenance_date": "2024-04-15T00:00:00Z",
"efficiency_percentage": 88.0
}
}
)
class EquipmentResponse(BaseModel):
"""Schema for equipment response"""
id: UUID
tenant_id: UUID
name: str
type: EquipmentType
model: Optional[str] = None
serial_number: Optional[str] = None
location: Optional[str] = None
2025-11-13 16:01:08 +01:00
manufacturer: Optional[str] = None
firmware_version: Optional[str] = None
2025-10-19 19:22:37 +02:00
status: EquipmentStatus
# Installation and maintenance
install_date: Optional[datetime] = None
last_maintenance_date: Optional[datetime] = None
next_maintenance_date: Optional[datetime] = None
maintenance_interval_days: Optional[int] = None
# Performance metrics
efficiency_percentage: Optional[float] = None
uptime_percentage: Optional[float] = None
energy_usage_kwh: Optional[float] = None
# Specifications
power_kw: Optional[float] = None
capacity: Optional[float] = None
weight_kg: Optional[float] = None
# Temperature monitoring
current_temperature: Optional[float] = None
target_temperature: Optional[float] = None
2025-11-13 16:01:08 +01:00
# IoT Connectivity
iot_enabled: bool = False
iot_protocol: Optional[str] = None
iot_endpoint: Optional[str] = None
iot_port: Optional[int] = None
iot_connection_status: Optional[str] = None
iot_last_connected: Optional[datetime] = None
iot_config: Optional[dict] = None
# Real-time monitoring
supports_realtime: bool = False
poll_interval_seconds: Optional[int] = None
# Sensor capabilities
temperature_zones: Optional[int] = None
supports_humidity: bool = False
supports_energy_monitoring: bool = False
supports_remote_control: bool = False
2025-10-19 19:22:37 +02:00
# Status
is_active: bool
notes: Optional[str] = None
2026-01-11 17:03:46 +01:00
# Support contact information
support_contact: Optional[dict] = None
2025-10-19 19:22:37 +02:00
# Timestamps
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class EquipmentListResponse(BaseModel):
"""Schema for paginated equipment list response"""
equipment: List[EquipmentResponse]
total_count: int
page: int
page_size: int
model_config = ConfigDict(
json_schema_extra={
"example": {
"equipment": [],
"total_count": 10,
"page": 1,
"page_size": 50
}
}
)
2025-10-29 06:58:05 +01:00
class EquipmentDeletionSummary(BaseModel):
"""Schema for equipment deletion summary"""
can_delete: bool = Field(..., description="Whether the equipment can be deleted")
warnings: List[str] = Field(default_factory=list, description="List of warnings about deletion")
production_batches_count: int = Field(default=0, description="Number of production batches using this equipment")
maintenance_records_count: int = Field(default=0, description="Number of maintenance records")
temperature_logs_count: int = Field(default=0, description="Number of temperature logs")
equipment_name: Optional[str] = Field(None, description="Equipment name")
equipment_type: Optional[str] = Field(None, description="Equipment type")
equipment_location: Optional[str] = Field(None, description="Equipment location")
model_config = ConfigDict(
json_schema_extra={
"example": {
"can_delete": True,
"warnings": ["3 production batch(es) are using this equipment"],
"production_batches_count": 3,
"maintenance_records_count": 5,
"temperature_logs_count": 120,
"equipment_name": "Horno Principal #1",
"equipment_type": "oven",
"equipment_location": "Área de Horneado"
}
}
)
2025-11-13 16:01:08 +01:00
# ================================================================
# IoT-SPECIFIC SCHEMAS
# ================================================================
class EquipmentSensorReadingResponse(BaseModel):
"""Schema for equipment sensor reading response"""
id: UUID
tenant_id: UUID
equipment_id: UUID
batch_id: Optional[UUID] = None
reading_time: datetime
# Temperature readings
temperature: Optional[float] = None
temperature_zones: Optional[dict] = None
target_temperature: Optional[float] = None
# Humidity
humidity: Optional[float] = None
target_humidity: Optional[float] = None
# Energy monitoring
energy_consumption_kwh: Optional[float] = None
power_current_kw: Optional[float] = None
# Equipment status
operational_status: Optional[str] = None
cycle_stage: Optional[str] = None
cycle_progress_percentage: Optional[float] = None
time_remaining_minutes: Optional[int] = None
# Process parameters
motor_speed_rpm: Optional[float] = None
door_status: Optional[str] = None
steam_level: Optional[float] = None
# Quality indicators
product_weight_kg: Optional[float] = None
moisture_content: Optional[float] = None
# Additional sensor data
additional_sensors: Optional[dict] = None
# Data quality
data_quality_score: Optional[float] = None
is_anomaly: bool = False
created_at: datetime
model_config = ConfigDict(from_attributes=True)
class EquipmentConnectionTestResponse(BaseModel):
"""Schema for IoT connection test response"""
success: bool = Field(..., description="Whether connection test succeeded")
status: str = Field(..., description="Connection status")
message: str = Field(..., description="Detailed message")
response_time_ms: Optional[int] = Field(None, description="Response time in milliseconds")
protocol_tested: str = Field(..., description="Protocol that was tested")
endpoint_tested: str = Field(..., description="Endpoint that was tested")
error_details: Optional[str] = Field(None, description="Error details if connection failed")
supported_features: Optional[List[str]] = Field(None, description="List of supported IoT features")
model_config = ConfigDict(
json_schema_extra={
"example": {
"success": True,
"status": "connected",
"message": "Successfully connected to equipment",
"response_time_ms": 145,
"protocol_tested": "rest_api",
"endpoint_tested": "https://connectedcooking.com/api/v1",
"supported_features": ["temperature", "humidity", "energy_monitoring"]
}
}
)
class RealTimeDataResponse(BaseModel):
"""Schema for real-time equipment data response"""
equipment_id: UUID
equipment_name: str
timestamp: datetime
connection_status: str
# Current readings
temperature: Optional[float] = None
temperature_zones: Optional[dict] = None
humidity: Optional[float] = None
energy_consumption_kwh: Optional[float] = None
power_current_kw: Optional[float] = None
# Status
operational_status: Optional[str] = None
cycle_stage: Optional[str] = None
cycle_progress_percentage: Optional[float] = None
time_remaining_minutes: Optional[int] = None
# Active batch
active_batch_id: Optional[UUID] = None
active_batch_name: Optional[str] = None
model_config = ConfigDict(
json_schema_extra={
"example": {
"equipment_id": "123e4567-e89b-12d3-a456-426614174000",
"equipment_name": "Horno Principal #1",
"timestamp": "2025-01-12T10:30:00Z",
"connection_status": "connected",
"temperature": 185.5,
"temperature_zones": {"zone1": 180, "zone2": 190, "zone3": 185},
"humidity": 65.0,
"operational_status": "running",
"cycle_stage": "baking",
"cycle_progress_percentage": 45.0,
"time_remaining_minutes": 12
}
}
)
class EquipmentIoTAlertResponse(BaseModel):
"""Schema for IoT alert response"""
id: UUID
tenant_id: UUID
equipment_id: UUID
batch_id: Optional[UUID] = None
# Alert information
alert_type: str
severity: str
alert_time: datetime
# Alert details
title: str
message: str
# Threshold information
threshold_value: Optional[float] = None
actual_value: Optional[float] = None
deviation_percentage: Optional[float] = None
# Status
is_active: bool
is_acknowledged: bool
acknowledged_by: Optional[UUID] = None
acknowledged_at: Optional[datetime] = None
is_resolved: bool
resolved_by: Optional[UUID] = None
resolved_at: Optional[datetime] = None
resolution_notes: Optional[str] = None
# Automated response
auto_resolved: bool
corrective_action_taken: Optional[str] = None
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class EquipmentSensorHistoryResponse(BaseModel):
"""Schema for sensor reading history response"""
equipment_id: UUID
equipment_name: str
start_time: datetime
end_time: datetime
total_readings: int
readings: List[EquipmentSensorReadingResponse]
model_config = ConfigDict(
json_schema_extra={
"example": {
"equipment_id": "123e4567-e89b-12d3-a456-426614174000",
"equipment_name": "Horno Principal #1",
"start_time": "2025-01-12T08:00:00Z",
"end_time": "2025-01-12T12:00:00Z",
"total_readings": 48,
"readings": []
}
}
)