diff --git a/software/backend/backend_database.db b/software/backend/backend_database.db index 3cbd3b5..d17c698 100644 Binary files a/software/backend/backend_database.db and b/software/backend/backend_database.db differ diff --git a/software/backend/data_functions.py b/software/backend/data_functions.py index f6a556b..d1e5cb6 100644 --- a/software/backend/data_functions.py +++ b/software/backend/data_functions.py @@ -29,16 +29,15 @@ def data_sensordata(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, my try: robot.delete_order(drive_data) + mydatabase.insert_measurement_data(plant_id=payload['PlantID'], + sensordata_temp=payload['AirTemperature'], + sensordata_humidity=payload['AirHumidity'], + sensordata_soil_moisture=payload['SoilMoisture'], + sensordata_brightness=payload['Brightness']) + logging.debug("Inserted to data base: " + json.dumps(payload)) except Exception as e: logging.error("Could not delete order: " + str(e)) - mydatabase.insert_measurement_data(plant_id=payload['PlantID'], - sensordata_temp=payload['AirTemperature'], - sensordata_humidity=payload['AirHumidity'], - sensordata_soil_moisture=payload['SoilMoisture'], - sensordata_brightness=payload['Brightness']) - logging.debug("Inserted to data base: " + json.dumps(payload)) - def data_position(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot): logging.info("ROBOT_DATA_POSITION Received data: " + json.dumps(message.payload.decode("UTF-8"))) @@ -60,6 +59,22 @@ def data_battery(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot client.publish(Topics['BACKEND_DATA_BATTERY'], json.dumps(battery_data)) +def data_error(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot): + robot.store_last_error(message.payload.decode("UTF-8")) + logging.error("ROBOT_DATA_ERROR new error received from Robot: " + robot.get_last_error()) + client.publish(Topics['BACKEND_DATA_ERROR'], message.payload.decode("UTF-8")) + + +def data_robotready(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot): + robot.change_robot_status(message.payload.decode("UTF-8") == 'True') + if robot.get_robot_status() is True and robot.get_order_number() >= 1: + client.publish(Topics['ROBOT_ACTION_DRIVE'], json.dumps(robot.get_next_order())) + logging.info("Waiting Order send to Robot") + + logging.info("ROBOT_DATA_ROBOTREADY status updated: " + str(robot.get_robot_status())) + client.publish(Topics['BACKEND_DATA_ROBOTREADY'], message.payload.decode("UTF-8")) + + # FrontEnd Channel Reactions def action_drive(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase, @@ -86,8 +101,31 @@ def action_drive(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydat def action_driveall(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase, robot: Robot): + plant_names = mydatabase.get_plant_names() + plant_ids = [] + print(plant_names) - client.publish(Topics['ROBOT_ACTION_DRIVEALL']) + for names in plant_names: + _id = mydatabase.get_plant_id(names) + plant_ids.append(_id) + + action_id = str(uuid.uuid4()) + drive_data = { + "PlantID": plant_ids, + "ActionID": action_id + } + print(drive_data) + if robot.get_order_number() < 6 and robot.get_robot_status() is True: + robot.add_order(drive_data) + client.publish(Topics['ROBOT_ACTION_DRIVEALL'], json.dumps(plant_ids)) + logging.info("BACKEND_ACTION_DRIVEALL Drive Command published: " + json.dumps(drive_data)) + else: + if robot.get_order_number() < 6: + robot.add_order(drive_data) + logging.info("BACKEND_ACTION_DRIVEALL New data added to order list: " + str(drive_data)) + elif robot.get_order_number() >= 6: + client.publish(Topics['BACKEND_DATA_ERROR'], "Could not add Order to list. Order discarded") + logging.error("Could not add Order to list. Order discarded") def action_getposition(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase): @@ -98,13 +136,19 @@ def action_getposition(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, def action_getbattery(client: mqtt.Client, userdata, message: mqtt.MQTTMessage): client.publish(Topics['ROBOT_ACTION_GETBATTERY']) logging.info("BACKEND_ACTION_GETBATTERY message forwarded to Robot") + battery_data = { + "Battery": 66, + "Timestamp": str(datetime.now()) + } + print(battery_data) + client.publish(Topics['BACKEND_DATA_BATTERY'], json.dumps(battery_data)) def action_getalldata(client: mqtt.Client, userdata, message: Union[mqtt.MQTTMessage, list], mydatabase: PlantDataBase): plant_names = mydatabase.get_plant_names() alldata = [] for i in plant_names: - alldata.append(mydatabase.get_latest_data(plant_name=i[0])) + alldata.append(mydatabase.get_latest_data(plant_name=i)) client.publish(Topics['BACKEND_DATA_SENSORDATAALL'], json.dumps(alldata)) logging.info("BACKEND_DATA_SENSORDATAALL got data from database:" + str(alldata)) @@ -148,19 +192,3 @@ def action_countplants(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, } client.publish(Topics["BACKEND_DATA_PLANTCOUNT"], json.dumps(count_payload)) logging.info("BACKEND_DATA_PLANTCOUNT forwarded plant count to FrontEnd: " + str(count_payload)) - - -def data_error(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot): - robot.store_last_error(message.payload.decode("UTF-8")) - logging.error("ROBOT_DATA_ERROR new error received from Robot: " + robot.get_last_error()) - client.publish(Topics['BACKEND_DATA_ERROR'], message.payload.decode("UTF-8")) - - -def data_robotready(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot): - robot.change_robot_status(message.payload.decode("UTF-8") == 'True') - if robot.get_robot_status() is True and robot.get_order_number() >= 1: - client.publish(Topics['ROBOT_ACTION_DRIVE'], json.dumps(robot.get_next_order())) - logging.info("Waiting Order send to Robot") - - logging.info("ROBOT_DATA_ROBOTREADY status updated: " + str(robot.get_robot_status())) - client.publish(Topics['BACKEND_DATA_ROBOTREADY'], message.payload.decode("UTF-8")) diff --git a/software/backend/dev_test_examples/mqtt_publisher.py b/software/backend/dev_test_examples/mqtt_publisher.py index 42aeb26..f5a8e1d 100644 --- a/software/backend/dev_test_examples/mqtt_publisher.py +++ b/software/backend/dev_test_examples/mqtt_publisher.py @@ -1,7 +1,7 @@ import paho.mqtt.client as mqtt import software.backend.defines -from software.backend.defines import MQTT_BROKER_LOCAL +from software.backend.defines import MQTT_BROKER_GLOBAL from random import randrange, uniform import time import json @@ -19,14 +19,14 @@ def on_connect(client, userdata, flags, rc): client = mqtt.Client() client.on_connect = on_connect -client.connect("mqtt://192.168.137.197", 1883) +client.connect(MQTT_BROKER_GLOBAL, 1883) plantdata = { - "Battery": 10 + "PlantName": "Ipne" } print(type(PLANTDATA)) -client.publish(Topics['ROBOT_DATA_BATTERY'], json.dumps(plantdata)) +client.publish(Topics['BACKEND_ACTION_DRIVE'], json.dumps(plantdata)) print(json.dumps(plantdata)) time.sleep(2) diff --git a/software/backend/main.py b/software/backend/main.py index 476f68b..fe6491d 100644 --- a/software/backend/main.py +++ b/software/backend/main.py @@ -46,7 +46,13 @@ def on_connect(_client: mqtt.Client, _userdata, _flags, _rc, _mydatabase, _robot _client.message_callback_add(Topics['ROBOT_DATA_BATTERY'], lambda client, userdata, message: data_functions. data_battery(client, userdata, message, _robot)) - # client.subscribe('Robot/Data/Picture') + _client.subscribe(Topics['ROBOT_DATA_ERROR']) + _client.message_callback_add(Topics['ROBOT_DATA_ERROR'], lambda client, userdata, message: data_functions. + data_error(client, userdata, message, _robot)) + + _client.subscribe(Topics['ROBOT_DATA_ROBOTREADY']) + _client.message_callback_add(Topics['ROBOT_DATA_ROBOTREADY'], lambda client, userdata, message: data_functions. + data_robotready(client, userdata, message, _robot)) # From FrontEnd: _client.subscribe(Topics['BACKEND_ACTION_DRIVE']) @@ -85,13 +91,6 @@ def on_connect(_client: mqtt.Client, _userdata, _flags, _rc, _mydatabase, _robot _client.message_callback_add(Topics['BACKEND_ACTION_PLANTCOUNT'], lambda client, userdata, message: data_functions. action_countplants(client, userdata, message, _mydatabase)) - _client.subscribe(Topics['ROBOT_DATA_ERROR']) - _client.message_callback_add(Topics['ROBOT_DATA_ERROR'], lambda client, userdata, message: data_functions. - data_error(client, userdata, message, _robot)) - - _client.subscribe(Topics['ROBOT_DATA_ROBOTREADY']) - _client.message_callback_add(Topics['ROBOT_DATA_ROBOTREADY'], lambda client, userdata, message: data_functions. - data_robotready(client, userdata, message, _robot)) # END TOPIC SUBSCRIPTIONS else: print("connection failed") @@ -101,7 +100,7 @@ def main(): robot = Robot() my_database = PlantDataBase(database_name=DATABASE_NAME) my_database.create_tables() - mqttclient = mqtt.Client(BACKEND_CLIENT_ID, transport="websockets") + mqttclient = mqtt.Client(BACKEND_CLIENT_ID) mqttclient.on_connect = lambda client, userdata, flags, rc: on_connect(_client=client, _userdata=userdata, _flags=flags, diff --git a/software/backend/plantdatabase.py b/software/backend/plantdatabase.py index 9229cbd..0e5b97b 100644 --- a/software/backend/plantdatabase.py +++ b/software/backend/plantdatabase.py @@ -2,6 +2,7 @@ import sqlite3 from typing import Optional import logging +from itertools import chain class PlantDataBase: @@ -139,7 +140,7 @@ class PlantDataBase: def get_plant_names(self) -> list: try: self.cur.execute("SELECT PlantName FROM plants") - return self.cur.fetchall() + return [row[0] for row in self.cur.fetchall()] except Exception as e: logging.error("Could not get plant names: " + str(e))