Use the Paho MQTT python library
Your TX54 device includes support for the Paho MQTT python library. MQTT is a lightweight messaging protocol used to communicate with various applications including cloud-based applications such as Amazon Web Services and Microsoft Azure. The following is example code that reads CPU and RAM usage on the device, updates the device firmware, then publishes information about DHCP clients and system information to the MQTT server at 192.168.1.100. The MQTT server IP is configurable.
""" MQTT client example: - Reporting some device metrics from runt - Reporting DHCP clients - Firmware update feature (simple implementation, read TODO in cmd_fwupdate) """ import sys import time import paho.mqtt.client as mqtt import json from acl import runt, config from http import HTTPStatus import urllib.request import tempfile import os from digidevice import cli POLL_TIME = 60 def cmd_reboot(params): print("Rebooting unit...") try: cli.execute("reboot", 10) except: print("Failed to run 'reboot' command") return HTTPStatus.INTERNAL_SERVER_ERROR return HTTPStatus.OK def cmd_fwupdate(params): try: fw_uri = params["uri"] except: print("Firmware file URI not passed") return HTTPStatus.BAD_REQUEST print("Request to update firmware with URI: {}".format(fw_uri)) try: fd, fname = tempfile.mkstemp() os.close(fd) try: urllib.request.urlretrieve(fw_uri, fname) except: print("Failed to download FW file from URI {}".format(fw_uri)) return HTTPStatus.NOT_FOUND try: ret = cli.execute("system firmware update file " + fname, 60) except: print("Failed to run firmware update command") return HTTPStatus.INTERNAL_SERVER_ERROR if not "Firmware update completed" in ret: print("Failed to update firmware") return HTTPStatus.INTERNAL_SERVER_ERROR finally: os.remove(fname) print("Firmware update finished") return HTTPStatus.OK CMD_HANDLERS = { "reboot": cmd_reboot, "fw-update": cmd_fwupdate } def send_cmd_reply(client, cmd_path, cid, cmd, status): if not status or not cid: return if cmd_path.startswith(PREFIX_CMD): path = cmd_path[len(PREFIX_CMD):] else: print("Invalid command path ({}), cannot send reply".format(cmd_path)) return reply = { "cmd": cmd, "status": status } client.publish(PREFIX_RSP + path + "/" + cid, json.dumps(reply, separators=(',',':'))) def on_connect(client, userdata, flags, rc): print("Connected to MQTT server") client.subscribe(PREFIX_CMD + "/system") def on_message(client, userdata, msg): """ Supporting only a single topic for now, no need for filters Expects the following message format: { "cid": "<client-id>", "cmd": "<command>", "params": { <optional_parameters> } } Supported commands: - "fw-update" params: - "uri": "<firmware_file_URL>" - "reboot" params: """ try: m = json.loads(msg.payload) cid = m["cid"] cmd = m["cmd"] try: payload = m["params"] except: payload = None except: print("Invalid command format: {}".format(msg.payload)) if not cid: # Return if client-ID not passed return None send_cmd_reply(client, msg.topic, cid, cmd, HTTPStatus.BAD_REQUEST) try: status = CMD_HANDLERS[cmd](payload) except: print("Invalid command: {}".format(cmd)) status = HTTPStatus.NOT_IMPLEMENTED send_cmd_reply(client, msg.topic, cid, cmd, status) def publish_dhcp_leases(): leases = [] try: with open('/etc/config/dhcp.leases', 'r') as f: for line in f: elems = line.split() if len(elems) != 5: continue leases.append({"mac": elems[1], "ip": elems[2], "host": elems[3]}) if leases: client.publish(PREFIX_EVENT + "/leases", json.dumps(leases, separators=(',',':'))) except: print("Failed to open DHCP leases file") def publish_system(): avg1, avg5, avg15 = runt.get("system.load_avg").split(', ') ram_used = runt.get("system.ram.per") disk_opt = runt.get("system.disk./opt.per") disk_config = runt.get("system.disk./etc/config.per") msg = json.dumps({ "load_avg": { "1min": avg1, "5min": avg5, "15min": avg15 }, "disk_usage": { "/opt": disk_opt, "/etc/config:": disk_config, "ram": ram_used } }) client.publish(PREFIX_EVENT + "/system", json.dumps(msg)) runt.start() serial = runt.get("system.serial") PREFIX = "router/" + serial PREFIX_EVENT = "event/" + PREFIX PREFIX_CMD = "cmd/" + PREFIX PREFIX_RSP = "rsp/" + PREFIX client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message try: client.connect("192.168.1.100", 1883, 60) client.loop_start() except: print("Failed to connect to MQTT server") sys.exit(1) while True: publish_dhcp_leases() publish_system() time.sleep(POLL_TIME)