import asyncio import configparser import logging import sys import aiomqtt from odoo_rpc import OdooRPCClient from mqtt_service import handle_incoming_messages, poll_and_publish def setup_logging(): """Configures the root logger.""" logging.basicConfig( stream=sys.stdout, level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s' ) async def main(): """Main function to set up and run the service.""" setup_logging() logger = logging.getLogger(__name__) config = configparser.ConfigParser() try: config.read_file(open('config.ini')) except FileNotFoundError: logger.error("Error: config.ini not found. Please create it.") return odoo_cfg = config['odoo'] mqtt_cfg = config['mqtt'] app_cfg = config['app'] odoo_url = f"{odoo_cfg['protocol']}://{odoo_cfg['host']}" poll_interval = app_cfg.getfloat('poll_interval', 2.0) try: logger.info(f'odooa b url:{odoo_url}') # 1. Login to Odoo odoo = OdooRPCClient( url=odoo_url, db=odoo_cfg['db'], username=odoo_cfg['user'], password=odoo_cfg['password'] ) # 2. Connect to MQTT and run tasks async with aiomqtt.Client( hostname=mqtt_cfg['host'], port=int(mqtt_cfg['port']), identifier=mqtt_cfg['client_id'], username=mqtt_cfg['username'], password=mqtt_cfg['password'] ) as client: logger.info(f"Connected to MQTT broker at {mqtt_cfg['host']}:{mqtt_cfg['port']}") # Parse reply topics from config reply_topics = ['iot/service/deviceid'] # Run message handling and publishing tasks concurrently await asyncio.gather( handle_incoming_messages(client, odoo, reply_topics), poll_and_publish(client, odoo, poll_interval) ) except aiomqtt.MqttError as e: logger.error(f"MQTT connection error: {e}") except Exception as e: logger.error(f"A critical error occurred: {e}", exc_info=True) finally: logger.info("Cleaned up resources and shutting down.") if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: logging.getLogger(__name__).info("Process interrupted by user.")