import asyncio import logging import signal import threading from meshbot import config from meshbot.database import Database from meshbot.bot import MeshBot from meshbot.scheduler import Scheduler from meshbot.webserver import WebServer, WebSocketManager logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", ) logger = logging.getLogger(__name__) async def main(): logger.info("Starting %s v%s", config.get("bot.name"), config.get("version")) # Database db = Database(config.get("database.path", "meshdd.db")) await db.connect() # WebSocket Manager ws_manager = WebSocketManager() # Bot loop = asyncio.get_event_loop() bot = MeshBot(db, loop) bot.ws_manager = ws_manager # Scheduler scheduler = Scheduler(bot, ws_manager) # Webserver webserver = WebServer(db, ws_manager, bot, scheduler) runner = await webserver.start(config.get("web.host", "0.0.0.0"), config.get("web.port", 8080)) # Connect Meshtastic in a thread (blocking call) connect_thread = threading.Thread(target=bot.connect, daemon=True) connect_thread.start() # Watch config for changes asyncio.create_task(config.watch()) # Scheduler tasks asyncio.create_task(scheduler.watch()) asyncio.create_task(scheduler.run()) # Wait for shutdown stop_event = asyncio.Event() def _signal_handler(): logger.info("Shutdown signal received") stop_event.set() for sig in (signal.SIGINT, signal.SIGTERM): loop.add_signal_handler(sig, _signal_handler) try: await stop_event.wait() finally: logger.info("Shutting down...") bot.disconnect() await ws_manager.close_all() await runner.cleanup() await db.close() logger.info("Shutdown complete") if __name__ == "__main__": asyncio.run(main())