|
@@ -2,24 +2,59 @@ import asyncio
|
|
|
import logging
|
|
import logging
|
|
|
from typing import Dict, List
|
|
from typing import Dict, List
|
|
|
from datetime import datetime
|
|
from datetime import datetime
|
|
|
-from models.battery import Battery
|
|
|
|
|
|
|
+import json
|
|
|
|
|
+from models.cell import Cell
|
|
|
from models.device import Device
|
|
from models.device import Device
|
|
|
from services.i2c_service import I2CService
|
|
from services.i2c_service import I2CService
|
|
|
from services.http_service import HTTPService
|
|
from services.http_service import HTTPService
|
|
|
-from utils.health_calculator import calculate_health
|
|
|
|
|
|
|
+from services.mqtt_service import MQTTService
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
class MeasurementController:
|
|
class MeasurementController:
|
|
|
"""Controls the measurement process for multiple devices and slots."""
|
|
"""Controls the measurement process for multiple devices and slots."""
|
|
|
|
|
|
|
|
- def __init__(self, config: dict, i2c_service: I2CService, http_service: HTTPService):
|
|
|
|
|
|
|
+ def __init__(self, config: dict, i2c_service: I2CService, http_service: HTTPService, mqtt_service: MQTTService):
|
|
|
self.config = config
|
|
self.config = config
|
|
|
self.i2c_service = i2c_service
|
|
self.i2c_service = i2c_service
|
|
|
self.http_service = http_service
|
|
self.http_service = http_service
|
|
|
|
|
+ self.mqtt_service = mqtt_service
|
|
|
|
|
+
|
|
|
self.active_measurements: Dict[str, Dict[int, asyncio.Task]] = {}
|
|
self.active_measurements: Dict[str, Dict[int, asyncio.Task]] = {}
|
|
|
|
|
+
|
|
|
|
|
+ devices_config = config['devices']
|
|
|
|
|
+ self.devices = {id: Device(id, config) for id, config in enumerate(devices_config)}
|
|
|
|
|
|
|
|
- async def start_measurement(self, device_id: str, slot: int, cell_id: int):
|
|
|
|
|
|
|
+ self.topic_prefix = self.config['mqtt']['topic_prefix']
|
|
|
|
|
+ for device_id in self.devices.keys():
|
|
|
|
|
+ self.setup_mqtt_subscription(device_id)
|
|
|
|
|
+
|
|
|
|
|
+ def setup_mqtt_subscription(self, device_id):
|
|
|
|
|
+ """Setup MQTT subscriptions for each device."""
|
|
|
|
|
+ topic = f"{self.topic_prefix}/{device_id}"
|
|
|
|
|
+ self.mqtt_service.add_message_handler(topic, lambda client, userdata, msg, dev_id=device_id: self._handle_cell_insertion(client, userdata, msg, dev_id))
|
|
|
|
|
+
|
|
|
|
|
+ def _handle_cell_insertion(self, client, userdata, message: str, device_id: int):
|
|
|
|
|
+ """Handle MQTT message for cell insertion."""
|
|
|
|
|
+ try:
|
|
|
|
|
+ data = json.loads(message.payload)
|
|
|
|
|
+ slot = data.get('slot')
|
|
|
|
|
+ cell_id = data.get('cell_id')
|
|
|
|
|
+
|
|
|
|
|
+ if slot is None or cell_id is None:
|
|
|
|
|
+ logger.error(f"Invalid message format: {message.payload}")
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ # Create and schedule the measurement task
|
|
|
|
|
+ asyncio.create_task(self.start_measurement(device_id, slot, cell_id))
|
|
|
|
|
+ logger.info(f"Initiated measurement for device {device_id}, slot {slot}, cell {cell_id}")
|
|
|
|
|
+
|
|
|
|
|
+ except json.JSONDecodeError:
|
|
|
|
|
+ logger.error(f"Invalid JSON in MQTT message: {message}")
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ logger.error(f"Error handling cell insertion: {str(e)}")
|
|
|
|
|
+
|
|
|
|
|
+ async def start_measurement(self, device_id: int, slot: int, cell_id: int):
|
|
|
"""Start measurement cycle for a specific slot."""
|
|
"""Start measurement cycle for a specific slot."""
|
|
|
if device_id not in self.active_measurements:
|
|
if device_id not in self.active_measurements:
|
|
|
self.active_measurements[device_id] = {}
|
|
self.active_measurements[device_id] = {}
|
|
@@ -35,10 +70,10 @@ class MeasurementController:
|
|
|
self.active_measurements[device_id][slot] = task
|
|
self.active_measurements[device_id][slot] = task
|
|
|
|
|
|
|
|
async def _measure_cycle(self, device_id: str, slot: int, cell_id: int):
|
|
async def _measure_cycle(self, device_id: str, slot: int, cell_id: int):
|
|
|
- """Execute measurement cycles for a battery."""
|
|
|
|
|
|
|
+ """Execute measurement cycles for a Cell."""
|
|
|
try:
|
|
try:
|
|
|
- # Get battery info from HTTP service
|
|
|
|
|
- battery_info = await self.http_service.get_cell_info(cell_id)
|
|
|
|
|
|
|
+ # Get Cell info from HTTP service
|
|
|
|
|
+ cell_info = await self.http_service.get_cell_info(cell_id)
|
|
|
|
|
|
|
|
measurements = []
|
|
measurements = []
|
|
|
cycles = self.config['measurement']['cycles']
|
|
cycles = self.config['measurement']['cycles']
|