From 9396c59e86c622d739a674b3289b8a537069ff7c Mon Sep 17 00:00:00 2001 From: caliskanbi Date: Wed, 19 Apr 2023 02:47:49 +0200 Subject: [PATCH] new backend files added: main created and plantdatabase files from Makeathon extracted --- .idea/dataSources.xml | 12 +++ .idea/sqldialects.xml | 7 ++ software/backend/backend_database.db | Bin 0 -> 16384 bytes software/backend/data_handling_functions.py | 6 ++ software/backend/defines.py | 8 ++ .../dev_test_examples/mqtt_publisher.py | 16 ++++ .../dev_test_examples/mqtt_subscriber.py | 18 ++++ software/backend/main.py | 54 ++++++++++++ software/backend/mqtt_client_basic.py | 29 ------- software/backend/plantdatabase.py | 77 ++++++++++++++++++ 10 files changed, 198 insertions(+), 29 deletions(-) create mode 100644 .idea/dataSources.xml create mode 100644 .idea/sqldialects.xml create mode 100644 software/backend/backend_database.db create mode 100644 software/backend/data_handling_functions.py create mode 100644 software/backend/defines.py create mode 100644 software/backend/dev_test_examples/mqtt_publisher.py create mode 100644 software/backend/dev_test_examples/mqtt_subscriber.py create mode 100644 software/backend/main.py delete mode 100644 software/backend/mqtt_client_basic.py create mode 100644 software/backend/plantdatabase.py diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..36085a8 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + sqlite.xerial + true + org.sqlite.JDBC + jdbc:sqlite:$PROJECT_DIR$/software/backend/backend_database.db + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..5d33860 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/software/backend/backend_database.db b/software/backend/backend_database.db new file mode 100644 index 0000000000000000000000000000000000000000..406143c784e401cdad9950ac830c009c0ef1ca90 GIT binary patch literal 16384 zcmeI#O>5gg5C&k$4#_E`H!8GTTzO6Fli0=^MeFi*|xSUjU(D8-EkX%q$nKb+E?n36w{_rZ`W z4a87-GETLzD$S|Om1Qsx)D=B{(wEekgdx8Yt%GCf4@O>|DDE!kR&_lxIx~yaOj#9K z%|*DszPA;8D$;ls+n0mHe6=XDS+twaxs@o+9@ib&c#*xWlf?6_+|X9OHL9I9+HH4QvYTbXhv>-YWudbNz4ut(0pCkDGnH!I z?6PIuv&QA6``Rf>ZkF8KYdZz@o2mBq&iA2tZb*vn(%Wn$vM;$V1FiMhoDcmN5P$## zAOHafKmY;|fB*y_009Ubu>j8hNBnWIH3&ce0uX=z1Rwwb2tWV=5P-lx0i6HwD?k7O W5P$##AOHafKmY;|fB*!JU*InU!piXg literal 0 HcmV?d00001 diff --git a/software/backend/data_handling_functions.py b/software/backend/data_handling_functions.py new file mode 100644 index 0000000..a495826 --- /dev/null +++ b/software/backend/data_handling_functions.py @@ -0,0 +1,6 @@ +""" +created by caliskan at 19.04.2023 + +This file contains all functions, which handle the different cases. +Every function should return json format with the wanted data from the database +""" \ No newline at end of file diff --git a/software/backend/defines.py b/software/backend/defines.py new file mode 100644 index 0000000..2574007 --- /dev/null +++ b/software/backend/defines.py @@ -0,0 +1,8 @@ +""" +created by caliskan at 19.04.2023 + +contains all constants for the backend architecture of the smart garden project +""" + +MQTT_BROKER_LOCAL = "" +MQTT_BROKER_GLOBAL = "mqtt.eclipseprojects.io" diff --git a/software/backend/dev_test_examples/mqtt_publisher.py b/software/backend/dev_test_examples/mqtt_publisher.py new file mode 100644 index 0000000..e005f0b --- /dev/null +++ b/software/backend/dev_test_examples/mqtt_publisher.py @@ -0,0 +1,16 @@ + +import paho.mqtt.client as mqtt +from random import randrange, uniform +import time + +mqttBroker ="mqtt.eclipseprojects.io" + +client = mqtt.Client("Temperature_Inside") +client.connect(mqttBroker) + +while True: + randNumber = uniform(20.0, 21.0) + client.publish("planttest", randNumber) + print("Just published " + str(randNumber) + " to topic TEMPERATURE") + time.sleep(0.5) + diff --git a/software/backend/dev_test_examples/mqtt_subscriber.py b/software/backend/dev_test_examples/mqtt_subscriber.py new file mode 100644 index 0000000..3eed0c6 --- /dev/null +++ b/software/backend/dev_test_examples/mqtt_subscriber.py @@ -0,0 +1,18 @@ +import paho.mqtt.client as mqtt +import time + +def on_message(client, userdata, message): + print("received message: " ,str(message.payload.decode("utf-8"))) + +mqttBroker ="mqtt.eclipseprojects.io" + +client = mqtt.Client("Smartphone") +client.connect(mqttBroker) + +client.loop_start() + +client.subscribe("TEMPERATURE") +client.on_message=on_message + +time.sleep(30) +client.loop_stop() \ No newline at end of file diff --git a/software/backend/main.py b/software/backend/main.py new file mode 100644 index 0000000..40a9505 --- /dev/null +++ b/software/backend/main.py @@ -0,0 +1,54 @@ +""" +created by caliskan at 19.04.2023 + +This file contains the main script for the backend server of smart garden project +It has the task to be a bridge between the frontend and robot. +It also contains a database with the current plant data +Used protocol for interaction: mqtt (paho-mqtt module) +""" + +# imports +import paho.mqtt.client as mqtt +from defines import MQTT_BROKER_LOCAL, MQTT_BROKER_GLOBAL +from plantdatabase import PlantDataBase + +def on_message(client, userdata, message): + print(f'message received! {message.topic}') + + +def on_connect(client, userdata, flags, rc): + if rc == 0: + print("connected") + + # TOPIC SUBSCRIPTIONS + client.subscribe("planttest") + # Robot topics + client.subscribe("Robot/Data/SensorData") + client.subscribe("Robot/Data/Position") + client.subscribe("Robot/Data/Battery") + client.subscribe("Robot/Data/Picture") + + # FrontEnd topics + client.subscribe("BackEnd/Data/SensorData") + client.subscribe("BackEnd/Data/SensorDataAll") + client.subscribe("BackEnd/Data/Position") + client.subscribe("BackEnd/Data/Battery") + client.subscribe("BackEnd/Data/Picture") + + # END TOPIC SUBSCRIPTIONS + else: + print("connection failed") + + +def main(): + mydatabase = PlantDataBase() + mydatabase.create_table() + client = mqtt.Client() + client.on_connect = on_connect + client.on_message = on_message + client.connect(MQTT_BROKER_GLOBAL) + client.loop_forever() + + +if __name__ == "__main__": + main() diff --git a/software/backend/mqtt_client_basic.py b/software/backend/mqtt_client_basic.py deleted file mode 100644 index 56652d0..0000000 --- a/software/backend/mqtt_client_basic.py +++ /dev/null @@ -1,29 +0,0 @@ -import paho.mqtt.client as mqtt - - -def on_connect(_client, userdata, flags, rc): - print("Connected with result code " + str(rc)) - client.subscribe("test/topic") - - -def on_message(_client, userdata, msg): - print(msg.topic + " " + str(msg.payload)) - - -client = mqtt.Client() -client.on_connect = on_connect -client.on_message = on_message - -client.connect("localhost", 1883, 60) - -client.loop_forever() - -"""In this example, we create a new instance of the mqtt.Client class and set up the on_connect and on_message -callback functions. The on_connect function is called when the client successfully connects to the broker, -and the on_message function is called when a message is received on a subscribed topic. - -Then, we call the connect method to connect to the MQTT broker running on the local machine on port 1883, and set the -keepalive value to 60 seconds. - -Finally, we call the loop_forever method to start the client and begin processing incoming messages. This method -blocks the program execution and runs the client loop in a loop until the client is disconnected. (ChatGPT)""" diff --git a/software/backend/plantdatabase.py b/software/backend/plantdatabase.py new file mode 100644 index 0000000..3a8b27c --- /dev/null +++ b/software/backend/plantdatabase.py @@ -0,0 +1,77 @@ +# file to create a database via python script +import sqlite3 + + +class PlantDataBase: + """ + Class to create Makeathon database + """ + def __init__(self): + self.db_file = 'backend_database.db' + self.conn = None + try: + self.conn = sqlite3.connect(self.db_file, check_same_thread=False) + print(sqlite3.version) + except sqlite3.Error as e: + print(e) + self.cur = self.conn.cursor() + + def create_table(self): + table_config = "CREATE TABLE IF NOT EXISTS plants " \ + "(plant_ID INTEGER PRIMARY KEY AUTOINCREMENT," \ + " gps TEXT," \ + " plant_type TEXT)" + self.cur.execute(table_config) + + table_config = "CREATE TABLE IF NOT EXISTS measurement_values " \ + "(measurement_id INTEGER PRIMARY KEY AUTOINCREMENT," \ + "Timestamp DATETIME DEFAULT CURRENT_TIMESTAMP," \ + "plant_ID INTEGER, " \ + "sensordata_temp REAL," \ + "sensordata_humidity REAL," \ + "sensordata_ground_humidity REAL," \ + "pest_infestation INTEGER," \ + "light_intensity REAL," \ + "FOREIGN KEY (plant_ID)" \ + " REFERENCES plants (plant_ID) )" + self.cur.execute(table_config) + + def insert_plant(self, gps: str, plant_type: str): + self.cur.execute(f"INSERT INTO plants (gps, plant_type) VALUES ({gps}, {plant_type})") + self.conn.commit() + + def insert_measurement_data(self, plant_id, + sensordata_temp, + sensordata_humidity, + sensordata_ground_humidity, + pest_infestation, + light_intensity): + self.cur.execute(f"INSERT INTO measurement_values (plant_ID, sensordata_temp, sensordata_humidity," + f" sensordata_ground_humidity, pest_infestation, light_intensity) VALUES " + f"({plant_id}, {sensordata_temp}, {sensordata_humidity}, {sensordata_ground_humidity}, {pest_infestation}" + f", {light_intensity})") + self.conn.commit() + + def get_latest_data(self, plant_id) -> dict: + """ + Gets the newest parameter of specific plant and returns all parameters in json format + :param plant_id: + :return: + """ + self.cur.execute(f"SELECT * FROM measurement_values where plant_ID = {plant_id} ORDER BY Timestamp DESC LIMIT 1") + data = self.cur.fetchone() + json_file = { + "measurement_id": data[0], + "plant_id": data[2], + "timestamp": data[1], + "sensordata_temp": data[3], + "sensordata_humidity": data[4], + "sensordata_ground_humidity": data[5], + "pest_infestation": data[6], + "light_intensity": data[7] + } + return json_file + + def delete_data(self, table_name): + self.cur.execute(f"DELETE FROM {table_name}") + self.conn.commit()