<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true"> | |||||
<data-source source="LOCAL" name="backend_database.db" uuid="a5aefbe2-75a1-4a5e-ae27-5f87ff08045a"> | |||||
<driver-ref>sqlite.xerial</driver-ref> | |||||
<synchronize>true</synchronize> | |||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver> | |||||
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/software/backend/backend_database.db</jdbc-url> | |||||
<working-dir>$ProjectFileDir$</working-dir> | |||||
</data-source> | |||||
</component> | |||||
</project> |
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="SqlDialectMappings"> | |||||
<file url="file://$PROJECT_DIR$/software/backend/plantdatabase.py" dialect="GenericSQL" /> | |||||
<file url="PROJECT" dialect="SQLite" /> | |||||
</component> | |||||
</project> |
""" | |||||
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 | |||||
""" |
""" | |||||
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" |
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) | |||||
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() |
""" | |||||
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() |
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)""" |
# 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() |