489 lines
17 KiB
Python
489 lines
17 KiB
Python
# 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
|
|
|
|
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}
|
|
}
|
|
}
|
|
)
|
|
|
|
|
|
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")
|
|
manufacturer: Optional[str] = Field(None, max_length=100, description="Manufacturer")
|
|
firmware_version: Optional[str] = Field(None, max_length=50, description="Firmware version")
|
|
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")
|
|
|
|
# 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")
|
|
|
|
# Notes
|
|
notes: Optional[str] = Field(None, description="Additional notes")
|
|
|
|
# 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
|
|
}
|
|
}
|
|
)
|
|
|
|
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)
|
|
manufacturer: Optional[str] = Field(None, max_length=100)
|
|
firmware_version: Optional[str] = Field(None, max_length=50)
|
|
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
|
|
|
|
# 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
|
|
|
|
# Notes
|
|
notes: Optional[str] = None
|
|
|
|
# Support contact information
|
|
support_contact: Optional[dict] = None
|
|
|
|
# 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
|
|
manufacturer: Optional[str] = None
|
|
firmware_version: Optional[str] = None
|
|
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
|
|
|
|
# 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
|
|
|
|
# Status
|
|
is_active: bool
|
|
notes: Optional[str] = None
|
|
|
|
# Support contact information
|
|
support_contact: Optional[dict] = None
|
|
|
|
# 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
|
|
}
|
|
}
|
|
)
|
|
|
|
|
|
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"
|
|
}
|
|
}
|
|
)
|
|
|
|
|
|
# ================================================================
|
|
# 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": []
|
|
}
|
|
}
|
|
)
|