Browse Source

Functions excluded out of mainProg, added defines.py to raspy

master
Luis Waldhauser 1 year ago
parent
commit
ae1e67f204

+ 119
- 0
software/roboter/raspy/defines.py View File

@@ -0,0 +1,119 @@
"""
created by caliskan at 19.04.2023

contains all constants for the backend architecture of the smart garden project
"""

MQTT_BROKER_LOCAL = "lorem ipsum"
MQTT_BROKER_GLOBAL = "mqtt.eclipseprojects.io"
RASPI_CLIENT_ID = "smart_farming_raspi"
BACKEND_CLIENT_ID = "smart_farming_server"

# Topics:
Topics = {
"ROBOT_ACTION_DRIVE": "ROBOT/ACTION/DRIVE",
"ROBOT_ACTION_GETPOSITION": "ROBOT/ACTION/GETPOSITION",
"ROBOT_ACTION_GETBATTERY": "ROBOT/ACTION/GETBATTERY",

"ROBOT_DATA_SENSORDATA": "ROBOT/DATA/SENSORDATA",
"ROBOT_DATA_BATTERY": "ROBOT/DATA/BATTERY",
"ROBOT_DATA_POSITION": "ROBOT/DATA/POSITION",
"ROBOT_DATA_PICTURE": "ROBOT/DATA/PICTURE",

"BACKEND_ACTION_DRIVE": "BACKEND/ACTION/DRIVE",
"BACKEND_ACTION_GETPOSITION": "BACKEND/ACTION/GETPOSITION",
"BACKEND_ACTION_GETBATTERY": "BACKEND/ACTION/GETBATTERY",
"BACKEND_ACTION_GETALLDATA": "BACKEND/ACTION/GETALLDATA",

"BACKEND_DATA_SENSORDATA": "BACKEND/DATA/SENSORDATA",
"BACKEND_DATA_SENSORDATAALL": "BACKEND/DATA/SENSORDATA_ALL",
"BACKEND_DATA_POSITION": "BACKEND/DATA/POSITION",
"BACKEND_DATA_BATTERY": "BACKEND/DATA/BATTERY",
"BACKEND_DATA_PICTURE": "BACKEND/DATA/PICTURE"

}


# MQTT Messages:

# region Robot -> Backend
SENSORDATA = {
"AirTemperature": 0.0,
"AirHumidity" : 0.0,
"SoilMoisture" : 0.0,
"Brightness" : 0,
"PlantID": 0,
"ActionID": 0
}

# TODO When sensor is available
POSITION = {
"Position": ""
}

BATTERY = {
"Battery": 0.0
}

# endregion

# region Backend -> Robot

DRIVE = {
"PlantID": 0,
"ActionID": 0
}

# GETPOSITION -> no message needed

# GETBATTERY -> no message needed

# endregion

# region Backend -> Frontend

PLANTDATA = {
"AirTemperature": 0.0,
"AirHumidity" : 0.0,
"SoilMoisture" : 0.0,
"Brightness" : 0,
"PlantID": 0,
"Timestamp": "",
"MeasurementID": 0
}

ALLPLANTDATA = [
PLANTDATA,
PLANTDATA,
PLANTDATA,
PLANTDATA,
PLANTDATA,
PLANTDATA
]

# TODO When sensor is available
POSITION = {
"Position": "",
"Timestamp": ""
}

BATTERY = {
"Battery": 0.0,
"Timestamp": ""
}

# endregion

# region Frontend -> Backend

DRIVE = {
"PlantID": 0
}

# GETPOSITION -> no message needed

# GETBATTERY -> no message needed

# GETALLDATA -> no message needed

# endregion

+ 120
- 0
software/roboter/raspy/functions.py View File

@@ -0,0 +1,120 @@
import paho.mqtt.client as mqtt
import json
import threading
import os
import raspy_sensors as RaspySensors
from defines import Topics

def measure_send_data(plantID, actionID, client: mqtt.Client):
"""
Reads all sensors and publishes data via MQTT

Args:
plantID (_type_): plant to measure
actionID (_type_): current ID of driving action
client (mqtt.Client): current mqtt client for publishing
"""
sensor = RaspySensors()
sensorData = sensor.readSensors()
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
"""
os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/plant_{plantID}.py')

print("Measuring Sensors")

#FIXME Sensor not working
# measure_send_data(plantID, actionID, client)

print("Robot driving home")
if plantID % 2 == 0:
leftRight = -50 #rotating left
else:
leftRight = 50 #rotating right
os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/drive_back.py {leftRight}')
print("Robot home")

#TODO decide about robot occupied message
#client.publish("ROBOT/DATA/OCCUPIED", "false")


#region MQTT callbacks

#Testing
def send_data_json(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
strIn = str(message.payload.decode("UTF-8"))
dataDict = json.loads(strIn)
print("Received data: ", json.dumps(dataDict))


def drive_plant(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
"""
Function to drive to plant according to request
Starting Drive in Thread

Args:
clients (mqtt.Client): current mqtt client
userdata (_type_): _description_
message (mqtt.MQTTMessage): received message
"""
dictMessage = json.loads(str(message.payload.decode("UTF-8")))
plantID = dictMessage["PlantID"]
actionID = dictMessage["ActionID"]

print(f"received drive to plant {plantID}")
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

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

Args:
clients (mqtt.Client): current mqtt client
userdata (_type_): _description_
message (mqtt.MQTTMessage): received message
"""

battery = {
"Battery": 0.0
}

#TODO read Battery
clients.publish(Topics["ROBOT_DATA_BATTERY"], json.dumps(battery, indent=4))

#endregion

+ 6
- 144
software/roboter/raspy/mainProg.py View File

@@ -9,71 +9,10 @@ Interaction with the EV3 via SSH
"""

import paho.mqtt.client as mqtt
import json
import threading
import os
import time
import functions
from raspy_sensors import RaspySensors
from defines import Topics, RASPI_CLIENT_ID, MQTT_BROKER_GLOBAL

from software.defines import Topics, RASPI_CLIENT_ID, MQTT_BROKER_GLOBAL



#region global Varaibles

# FIXME Sensor not working
#sensors: RaspySensors


#endregion

#region global functions

# TODO auslagern
def measure_send_data(plantID, actionID, client: mqtt.Client):
"""
Reads all sensors and publishes data via MQTT

Args:
plantID (_type_): plant to measure
actionID (_type_): current ID of driving action
client (mqtt.Client): current mqtt client for publishing
"""
sensorData = sensors.readSensors()
sensorData["PlantID"] = plantID
sensorData["ActionID"] = actionID
client.publish(Topics["ROBOT_DATA_SENSORDATA"], json.dumps(sensorData, indent=4))

# TODO auslagern
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
"""
os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/plant_{plantID}.py')
#CHECK if working properly

print("Measuring Sensors")

#FIXME Sensor not working
# measure_send_data(plantID, actionID, client)

print("Robot driving home")
if plantID % 2 == 0:
leftRight = -50 #rotating left
else:
leftRight = 50 #rotating right
os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/drive_back.py {leftRight}')
print("Robot home")

#TODO decide about robot occupied message
#client.publish("ROBOT/DATA/OCCUPIED", "false")

def on_connect(client: mqtt.Client, userdata, flags, rc):
"""
@@ -88,10 +27,10 @@ def on_connect(client: mqtt.Client, userdata, flags, rc):
"""
if rc == 0:
#Add callbacks
client.message_callback_add("ROBOT/DATA", send_data_json) #Testing
client.message_callback_add(Topics["ROBOT_ACTION_DRIVE"], drive_plant)
client.message_callback_add(Topics["ROBOT_ACTION_GETPOSITION"], get_position)
client.message_callback_add(Topics["ROBOT_ACTION_GETBATTERY"], get_BatteryStatus)
client.message_callback_add("ROBOT/DATA", functions.send_data_json) #Testing
client.message_callback_add(Topics["ROBOT_ACTION_DRIVE"], functions.drive_plant)
client.message_callback_add(Topics["ROBOT_ACTION_GETPOSITION"], functions.get_position)
client.message_callback_add(Topics["ROBOT_ACTION_GETBATTERY"], functions.get_BatteryStatus)

#Subscribe to topics
client.subscribe("ROBOT/DATA") #Testing
@@ -102,89 +41,12 @@ def on_connect(client: mqtt.Client, userdata, flags, rc):
print("MQTT initialized")

#endregion

# TODO auslagern
#region MQTT callbacks

#Testing
def send_data_json(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
strIn = str(message.payload.decode("UTF-8"))
dataDict = json.loads(strIn)
print("Received data: ", json.dumps(dataDict))


# CHECK if working properly
def drive_plant(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
"""
Function to drive to plant according to request
Starting Drive in Thread

Args:
clients (mqtt.Client): current mqtt client
userdata (_type_): _description_
message (mqtt.MQTTMessage): received message
"""
dictMessage = json.loads(str(message.payload.decode("UTF-8")))
plantID = dictMessage["PlantID"]
actionID = dictMessage["ActionID"]

print(f"received drive to plant {plantID}")
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

Args:
clients (mqtt.Client): current mqtt client
userdata (_type_): _description_
message (mqtt.MQTTMessage): received message
"""
# TODO Write 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

Args:
clients (mqtt.Client): current mqtt client
userdata (_type_): _description_
message (mqtt.MQTTMessage): received message
"""

battery = {
"Battery": 0.0
}

#TODO read Battery
clients.publish(Topics["ROBOT_DATA_BATTERY"], json.dumps(battery, indent=4))

#endregion



def main():
"""
Initialises MQTT and Sensors
Runs forever and controlls all robot functions
"""
# CHECK if global
# FIXME Sensor not working
# global sensors
# sensors = RaspySensors()
client = mqtt.Client(RASPI_CLIENT_ID)
client.on_connect = on_connect
client.connect(MQTT_BROKER_GLOBAL)

+ 2
- 0
software/roboter/raspy/raspy_sensors.py View File

@@ -57,6 +57,8 @@ class RaspySensors:
#read TSL2561
self.sensorData["Brightness"] = round(self.tsl2561.lux, 2)

#TODO SoilMoisture Sensor

return self.sensorData
#TODO - take picture function

Loading…
Cancel
Save