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: print(str(e)) # TODO Error message MQTT sensorData["PlantID"] = plantID sensorData["ActionID"] = actionID client.publish(Topics["ROBOT_DATA_SENSORDATA"], json.dumps(sensorData, indent=4)) 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}') # TODO Error Message if errorCode != 0: logging.error(f"Robot Error {errorCode} occurred") logging.error("Drive Plant aborted, Robot at starting position") 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}') # TODO Error Message if errorCode != 0: logging.error(f"Robot Error {errorCode} occurred") logging.error(f"Drive Home aborted, Robot at plant {plantID}") return logging.info("Robot home") #TODO decide about robot occupied message #client.publish("ROBOT/DATA/OCCUPIED", "false") #region MQTT callbacks def drive_plant(clients: 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"))) plantID = dictMessage["PlantID"] actionID = dictMessage["ActionID"] logging.info(f"Received Drive-request to plant {plantID}, ActionID: {actionID}") thread = threading.Thread(target= drive_plant_thread, args=(plantID, actionID, clients), 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 """ # TODO Write GPS Sensor Function position = { "Position": "" } clients.publish(Topics["ROBOT_DATA_POSITION"], json.dumps(position, indent=4)) def get_BatteryStatus(clients: 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") #TODO Error Message return batteryLevel = round(batteryLevel / 1000000, 2) # Voltage batteryLevel = batteryLevel - 5 batteryLevel = round(batteryLevel / 3.5, 3) *100 # Percentage battery = { "Battery": batteryLevel } clients.publish(Topics["ROBOT_DATA_BATTERY"], json.dumps(battery, indent=4)) #endregion