import asyncio import json import logging from datetime import datetime, timezone import aiomqtt logger = logging.getLogger(__name__) class BaseBot: interval: int = 30 # seconds between publishes def __init__(self) -> None: self._scenario: str | None = None self._scenario_step: int = 0 def get_topic(self) -> str: raise NotImplementedError def get_payload(self) -> dict: raise NotImplementedError def set_scenario(self, name: str | None) -> None: self._scenario = name self._scenario_step = 0 logger.info(f"{self.__class__.__name__} scenario → {name or 'NORMAL'}") async def run(self, client: aiomqtt.Client) -> None: while True: try: payload = self.get_payload() payload["timestamp"] = datetime.now(timezone.utc).isoformat() await client.publish(self.get_topic(), json.dumps(payload), qos=0) self._scenario_step += 1 except Exception as e: logger.error(f"{self.__class__.__name__} publish error: {e}") await asyncio.sleep(self.interval)