CalejoControl/src/main.py

137 lines
4.3 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
Calejo Control Adapter - Main Application
Multi-protocol integration adapter for municipal wastewater pump stations
with comprehensive safety and security framework.
"""
import asyncio
import signal
import structlog
from typing import Dict, Any
from config.settings import Settings
from src.database.client import DatabaseClient
from src.core.auto_discovery import AutoDiscovery
from src.core.security import SecurityManager
from src.core.safety import SafetyLimitEnforcer
from src.core.plan_to_setpoint import PlanToSetpointEngine
from src.monitoring.watchdog import DatabaseWatchdog
from src.monitoring.alerts import AlertManager
from src.protocols.opc_ua_server import OPCUAServer
from src.protocols.modbus_server import ModbusServer
from src.protocols.rest_api import RESTAPIServer
logger = structlog.get_logger()
class CalejoControlAdapter:
"""Main application class for Calejo Control Adapter."""
def __init__(self, settings: Settings):
self.settings = settings
self.running = False
# Initialize components
self.db_client = DatabaseClient(settings.database_url)
self.auto_discovery = AutoDiscovery(self.db_client)
self.security_manager = SecurityManager()
self.safety_enforcer = SafetyLimitEnforcer(self.db_client)
self.plan_engine = PlanToSetpointEngine(self.db_client, self.safety_enforcer)
self.alert_manager = AlertManager(settings)
self.watchdog = DatabaseWatchdog(
self.db_client, self.alert_manager, settings.safety_timeout_seconds
)
# Protocol servers
self.opc_ua_server = OPCUAServer(settings.opc_ua_endpoint, self.plan_engine)
self.modbus_server = ModbusServer(settings.modbus_port, self.plan_engine)
self.rest_api = RESTAPIServer(settings.rest_api_port, self.plan_engine)
async def start(self):
"""Start the Calejo Control Adapter."""
logger.info("starting_calejo_control_adapter", version="2.0.0")
try:
# Connect to database
await self.db_client.connect()
# Load safety limits
await self.safety_enforcer.load_safety_limits()
# Auto-discover pump stations and pumps
await self.auto_discovery.discover()
# Start protocol servers
await asyncio.gather(
self.opc_ua_server.start(),
self.modbus_server.start(),
self.rest_api.start(),
)
# Start monitoring
await self.watchdog.start()
self.running = True
logger.info("calejo_control_adapter_started")
# Keep application running
while self.running:
await asyncio.sleep(1)
except Exception as e:
logger.error("failed_to_start_adapter", error=str(e))
await self.stop()
raise
async def stop(self):
"""Stop the Calejo Control Adapter gracefully."""
logger.info("stopping_calejo_control_adapter")
self.running = False
# Stop protocol servers
await asyncio.gather(
self.opc_ua_server.stop(),
self.modbus_server.stop(),
self.rest_api.stop(),
return_exceptions=True
)
# Close database connection
await self.db_client.disconnect()
logger.info("calejo_control_adapter_stopped")
def handle_shutdown(signum, frame):
"""Handle shutdown signals gracefully."""
logger.info("received_shutdown_signal", signal=signum)
# Signal handling will be implemented in the async context
async def main():
"""Main application entry point."""
# Load settings
settings = Settings()
# Set up signal handlers
signal.signal(signal.SIGINT, handle_shutdown)
signal.signal(signal.SIGTERM, handle_shutdown)
# Create and start adapter
adapter = CalejoControlAdapter(settings)
try:
await adapter.start()
except KeyboardInterrupt:
logger.info("keyboard_interrupt_received")
except Exception as e:
logger.error("unexpected_error", error=str(e))
raise
finally:
await adapter.stop()
if __name__ == "__main__":
asyncio.run(main())