========================================== CMSW Main Application (cmsw_main_app.py) ========================================== Overview ======== The CMSW main application is responsible for launching: 1. All asynchronous CMSW background tasks (polling, safety checks, etc.) 2. Optionally, the CMSW REST API (FastAPI + Uvicorn) 3. A unified shutdown mechanism for the tasks and the API It uses an asynchronous event loop to run multiple cooperative tasks and supports clean shutdown via: - ``Ctrl+C`` (SIGINT) - ``SIGTERM`` (service stop) - ``POST /shutdown`` (if the API is enabled) Usage ===== - Set up the virtual environment with all required dependencies by following the instructions in :doc:`installation`. - Activate the virtual environment and run the CMSW main application: .. code-block:: bash source .venv/bin/activate cd src/ska-low-sps-cabinet-cmsw python cmsw_main_app.py Command-Line Arguments ====================== The application may be started in two modes: **1. Standard Mode (API Enabled)** This is the default behavior. Run: .. code-block:: bash python cmsw_main_app.py This launches: - CMSW tasks (PDU sensor polling, cooling system sensor polling, safety model, fault detection, low power mode) - The REST API defined in ``cmsw_api.py`` **2. Headless Mode (No API)** To run CMSW without the API: .. code-block:: bash python cmsw_main_app.py --no-api In this mode: - Only background CMSW tasks are started - No FastAPI/Uvicorn server is launched - Shutdown must be triggered by ``Ctrl+C`` or external SIGTERM Argument Summary ---------------- +---------------------+-----------------------------------------+ | Argument | Description | +=====================+=========================================+ | ``--no-api`` | Disable REST API server | +---------------------+-----------------------------------------+ | ``--placeholder`` | Force-enable the REST API | +---------------------+-----------------------------------------+ Background Tasks ================ The following asynchronous CMSW tasks are launched at runtime: - ``pdu_task`` - ``cooling_task`` - ``safety_task`` - ``fault_task`` - ``low_power_task`` Each task runs periodically using the intervals defined in ``config.yaml``: .. code-block:: yaml cmsw: polling_intervals: sensor_polling: 5 safety_model: 10 fault_detection: 20 low_power_mode: 30 These tasks run concurrently inside the asyncio event loop and share state via ``shared_state.py``. For detailed information about sensor polling capabilities, see :doc:`sensor_polling`. API Integration =============== If API mode is enabled, Uvicorn and FastAPI are launched inside the same event loop as CMSW tasks. This ensures immediate access to live CMSW data via HTTP. API configuration is stored in ``config.yaml``: .. code-block:: yaml cmsw: api: host: "0.0.0.0" port: 8082 API calls supported currently: - Get readings_dict (use -s option for silent output without progress bar): .. code-block:: bash curl -s :/readings - Shutdown CMSW (-X option is for specifying API request type, e.g. POST. Default is GET.): .. code-block:: bash curl -X POST http://:/shutdown Shutdown Behaviour ================== The application shuts down cleanly when: - ``Ctrl+C`` is pressed - ``SIGTERM`` is received - ``shutdown_event`` is triggered by the API Shutdown sequence: 1. API server is stopped (if active) 2. All tasks are cancelled 3. All asyncio tasks are awaited for proper cleanup 4. Event loop exits This ensures that Modbus, SNMP, and other future subsystems can perform safe teardown. Design Notes ============ - The application runs with ``asyncio.run`` to ensure isolation of the event loop. - Shutdown is coordinated using a global ``shutdown_event`` imported from ``shared_state.py``. - Running the API and the CMSW task engine in the same process avoids synchronization problems and maintains consistency.