import paho.mqtt.client as mqtt import json import threading import os import logging import raspy_sensors as Sensors from defines import Topics, SENSORDATA def measure_send_data(plantID, actionID, client: mqtt.Client): """ Reads all sensors and publishes data via MQTT in form of SENSORDATA Args: plantID (_type_): plant to measure actionID (_type_): current ID of driving action client (mqtt.Client): current mqtt client for publishing """ sensorData = SENSORDATA try: sensorData = Sensors.readSensors() except Exception as e: logging.error(str(e)) # TODO Error message MQTT client.publish(Topics["ROBOT_DATA_ERROR"], str(e), qos=1) sensorData["PlantID"] = plantID sensorData["ActionID"] = actionID client.publish(Topics["ROBOT_DATA_SENSORDATA"], json.dumps(sensorData, indent=4), qos=1) def drive_plant_thread(plantID, actionID, client: mqtt.Client): """ Function to drive to plant according to number from MQTT message in thread Meassure and publish data via MQTT Drive home to starting point Args: plantID (_type_): plant to measure actionID (_type_): current ID of driving action client (mqtt.Client): current mqtt client for publishing """ # FIXME Change to color code driving errorCode = os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/plant_{plantID}.py') # errorCode = os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/drive_plant.py {plantID}') if errorCode != 0: logging.error(f"Robot Error {errorCode} occurred") logging.info("Drive Plant aborted, Robot at starting position") client.publish(Topics["ROBOT_DATA_ERROR"], "Drive Plant aborted, Robot at starting position", qos=1) #TODO decide about robot occupied message client.publish(Topics["ROBOT_DATA_ROBOTREADY"], "True", qos=1) return logging.info("Measuring Sensors") measure_send_data(plantID, actionID, client) logging.info("Robot driving home") errorCode = os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/drive_back.py {plantID}') if errorCode != 0: logging.error(f"Robot Error {errorCode} occurred") logging.info(f"Drive Home aborted, Robot at plant {plantID}") client.publish(Topics["ROBOT_DATA_ERROR"], f"Drive Home aborted, Robot at plant {plantID}", qos=1) #TODO decide about robot occupied message client.publish(Topics["ROBOT_DATA_ROBOTREADY"], "True", qos=1) return logging.info("Robot home") #TODO decide about robot occupied message client.publish(Topics["ROBOT_DATA_ROBOTREADY"], "True", qos=1) #region MQTT callbacks def drive_plant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage): """ Function to drive to plant according to request Starting Drive in Thread to not block main programm Args: clients (mqtt.Client): current mqtt client userdata (_type_): _description_ message (mqtt.MQTTMessage): received DRIVE message with PlantID and ActionID """ dictMessage = json.loads(str(message.payload.decode("UTF-8"))) print(dictMessage) plantID = dictMessage["PlantID"] actionID = dictMessage["ActionID"] logging.info(f"Received Drive-request to plant {plantID}, ActionID: {actionID}") #TODO decide about robot occupied message client.publish(Topics["ROBOT_DATA_ROBOTREADY"], "False", qos=1) thread = threading.Thread(target= drive_plant_thread, args=(plantID, actionID, client), daemon=True) thread.start() def get_position(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage): """ Callback function for GPS position request Function to send actual GPS position via MQTT in form of POSITION Args: clients (mqtt.Client): current mqtt client userdata (_type_): _description_ message (mqtt.MQTTMessage): received message """ logging.info("Received position request") # TODO Write GPS Sensor Function position = { "Position": "" } clients.publish(Topics["ROBOT_DATA_POSITION"], json.dumps(position, indent=4), qos=1) def get_BatteryStatus(client: mqtt.Client, userdata, message: mqtt.MQTTMessage): """ Callback function for battery status request Function to read battery status from ev3 and send via MQTT in form of BATTERY 8,5V -> 100% 5V -> 0% Args: clients (mqtt.Client): current mqtt client userdata (_type_): _description_ message (mqtt.MQTTMessage): received message """ logging.info("Received battery status request") try: batteryLevel = int(os.popen('sshpass -p maker ssh robot@ev3dev.local cat /sys/devices/platform/battery/power_supply/lego-ev3-battery/voltage_now').read()) except: logging.error("Robot not connected") client.publish(Topics["ROBOT_DATA_ERROR"], "Robot not connected", qos=1) return batteryLevel = round(batteryLevel / 1000000, 2) # Voltage batteryLevel = batteryLevel - 5 batteryLevel = round(batteryLevel / 3.5, 3) *100 # Percentage battery = { "Battery": batteryLevel } client.publish(Topics["ROBOT_DATA_BATTERY"], json.dumps(battery, indent=4), qos=1) #endregion