Campbell Logger Commander ========================= **Document version**: |version| .. toctree:: :maxdepth: 2 :caption: Contents: self mqtt cli mqtt-settings sources/modules genindex modindex Introduction ------------ The purpose of this project is to simplify the remote control of Campbell data loggers via MQTT commands. This is done by using Python code to interface with the existing MQTT `Command & Control `_ API that exists on data loggers already. Each logger subscribes to a few topics for receiving commands and responds by publishing the results on another topic. By tracking sending a payload to the command topic and listening for a response, a reliable method of remotely administering loggers at no cost is achievable. How it's Implemented --------------------- The Codebase is split into a few parts. * MQTT Broker Connections * Campbell Commands * Command Executors MQTT Broker Connections ^^^^^^^^^^^^^^^^^^^^^^^ There is a common interface for handling connections to MQTT brokers such that the specific implementation of each connection client isn't relevent to the rest of the codebase. Each client supports commands to publish/subscribe to topic, handle connections, disconnections, etc. Currently supported clients are: * **Paho:** A generic Python based MQTT client that supports password authentication. * **AWSCRT:** An MQTT client developed by AWS that supports a wide range of security methods such as asymetric keys. Campbell MQTT Commands ^^^^^^^^^^^^^^^^^^^^^^ There are a wide range of commands available to run on loggers in the MQTT API that won't be detailed on this page but include tasks such as firmware/script updates, rebooting, or talking to sensors. All of the available commands have been adapted into Python classes to serve a few purposes. The command classes must be instantiated with a base topic and serial number used by the logger who will receive the command. Once instantiated, the class can generate relevant topics, a payload, and a handler to process the logger's response to the command. The topics are: * **Payload:** Where the logger subscribes to for receiving the command. * **Response:** Where the logger publishes data in reponse to most commands. * **State:** Where the logger publishes state data. A JSON payload can generated by executing the `payload()` or `json_payload()` methods with the required arguments. Using a client object, the payload can be sent to the Payload topic to submit the command to the target logger and elicit a response. Each command as has a `handler()` method that must be registerd to the client to handle the response published by the logger after the command runs. .. note:: The command classes are not responsible for the flow of publishing payloads and awaiting responses, that is handled by the command executors. Command Executors ^^^^^^^^^^^^^^^^^ The command executors are responsible for handling the process of generating the payload for a command, submitting it to a logger, and awaiting the response to report success or failure. Because the MQTT clients have different workflows for listening for messages and registering the `_on_message()` callback, there too is a command executor for each of the client types. The executor is instantiated with an MQTT client and the `send_message()` method is called with a command, and additional arguments that are forwarded to the command to generate a payload. The executor then connects to the client, subscribes to a response topic, and sends the payload. Once sent, it will wait for a reponse on the response topic until one is received, or the request times out. How to Use ---------- .. code-block:: python from campbellcontrol.control import PahoCommandHandler from campbellcontrol.connection.generic import PahoConnection from campbellcontrol.commands import commands base_topic = "cs/v2" serial = "1234" file_to_delete = "myfile.CR1X" # Create a MQTT client using Paho client = PahoConnection("test.mosquitto.org", 1883) # Instanticating a command handler command_handler = PahoCommandHandler(client) # Create a command targeted to the desired logger command = commands.DeleteFile(base_topic, serial) # Send the command and wait for a response response = command_handler.send_command(command, file_to_delete) print(response)