backend code fully commented
This commit is contained in:
parent
90235a73f1
commit
22bcf7310f
@ -3,6 +3,7 @@ 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
|
||||
The functions are called, when data is received on the according channel
|
||||
"""
|
||||
import paho.mqtt.client as mqtt
|
||||
from plantdatabase import PlantDataBase
|
||||
@ -19,8 +20,21 @@ from robot import Robot
|
||||
|
||||
def data_sensordata(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase,
|
||||
robot: Robot):
|
||||
"""
|
||||
This function is used to store received data from the robot inside the plant_database
|
||||
USAGE FOR DATA OF ONE PLANT
|
||||
:param client: mqtt client
|
||||
:param userdata:
|
||||
:param message: received data
|
||||
:param mydatabase: database information
|
||||
:param robot: robot object
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Load the message and convert to json
|
||||
str_in = str(message.payload.decode("UTF-8"))
|
||||
payload = json.loads(str_in)
|
||||
|
||||
logging.info("ROBOT_DATA_SENSORDATA Received data: " + json.dumps(payload))
|
||||
drive_data = {
|
||||
"PlantID": [payload['PlantID']],
|
||||
@ -28,39 +42,54 @@ def data_sensordata(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, my
|
||||
}
|
||||
|
||||
try:
|
||||
print(drive_data)
|
||||
print(robot.order_handler)
|
||||
# Delete order from order list
|
||||
robot.delete_order(drive_data)
|
||||
# Save data in database
|
||||
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))
|
||||
|
||||
# Send received data to frontend
|
||||
action_getalldata(client, userdata, message, mydatabase)
|
||||
except Exception as e:
|
||||
logging.error("Could not delete order: " + str(e))
|
||||
|
||||
|
||||
def data_sensordataall(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase,
|
||||
robot: Robot):
|
||||
"""
|
||||
This function is used to store received data from the robot inside the plant_database
|
||||
USAGE FOR DATA OF ALL PLANTS
|
||||
:param client:
|
||||
:param userdata:
|
||||
:param message:
|
||||
:param mydatabase:
|
||||
:param robot:
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Load the message and convert to json
|
||||
str_in = str(message.payload.decode("UTF-8"))
|
||||
payload = json.loads(str_in)
|
||||
logging.info("ROBOT_DATA_SENSORDATAALL Received data: " + json.dumps(payload))
|
||||
|
||||
# Create list of plant_ids and create dataset
|
||||
plant_ids = []
|
||||
|
||||
for i in payload['SensorData']:
|
||||
plant_ids.append(i["PlantID"])
|
||||
print("Plant Names:", str(plant_ids))
|
||||
drive_data = {
|
||||
"PlantID": plant_ids,
|
||||
"ActionID": payload['ActionID']
|
||||
}
|
||||
|
||||
try:
|
||||
print(robot.order_handler)
|
||||
print(drive_data)
|
||||
# Delete order from order list
|
||||
robot.delete_order(drive_data)
|
||||
|
||||
# Insert all received data files in plant_database
|
||||
for i in payload['SensorData']:
|
||||
mydatabase.insert_measurement_data(plant_id=i['PlantID'],
|
||||
sensordata_temp=i['AirTemperature'],
|
||||
@ -68,46 +97,96 @@ def data_sensordataall(client: mqtt.Client, userdata, message: mqtt.MQTTMessage,
|
||||
sensordata_soil_moisture=i['SoilMoisture'],
|
||||
sensordata_brightness=i['Brightness'])
|
||||
logging.debug("Inserted to data base: " + json.dumps(payload))
|
||||
|
||||
# Send all the plant data to the frontend
|
||||
action_getalldata(client, userdata, message, mydatabase)
|
||||
except Exception as e:
|
||||
logging.error("Could not delete order: " + str(e))
|
||||
|
||||
|
||||
|
||||
def data_position(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot):
|
||||
"""
|
||||
This function is used to receive the robot position and insert it in the robot object
|
||||
:param client: mqtt client
|
||||
:param userdata:
|
||||
:param message: received data
|
||||
:param robot: robot object to store position
|
||||
:return: none
|
||||
"""
|
||||
|
||||
logging.info("ROBOT_DATA_POSITION Received data: " + json.dumps(message.payload.decode("UTF-8")))
|
||||
|
||||
# Store received position data in robot object
|
||||
robot.store_position(json.loads(message.payload.decode("UTF-8"))["Position"])
|
||||
position_data = {
|
||||
"Position": robot.get_position(),
|
||||
"Timestamp": str(datetime.now())
|
||||
}
|
||||
# Send the position as a json object to the frontend channel
|
||||
client.publish(Topics['BACKEND_DATA_POSITION'], json.dumps(position_data))
|
||||
|
||||
|
||||
def data_battery(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot):
|
||||
"""
|
||||
This function is used to receive the robot position and insert it in the robot object
|
||||
:param client: mqtt client object
|
||||
:param userdata:
|
||||
:param message: received data
|
||||
:param robot: robot object to store the received information
|
||||
:return: none
|
||||
"""
|
||||
|
||||
logging.info("ROBOT_DATA_BATTERY Received data: " + str(json.dumps(message.payload.decode("UTF-8"))))
|
||||
# Store battery status in robot object
|
||||
robot.store_battery(json.loads(message.payload.decode("UTF-8"))["Battery"])
|
||||
battery_data = {
|
||||
"Battery": robot.get_battery(),
|
||||
"Timestamp": str(datetime.now())
|
||||
}
|
||||
# Send Battery status and Robot-Ready Status as json objects to frontend
|
||||
client.publish(Topics['BACKEND_DATA_BATTERY'], json.dumps(battery_data))
|
||||
client.publish(Topics['BACKEND_DATA_ROBOTREADY'], str(robot.get_robot_status()))
|
||||
|
||||
|
||||
def data_error(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot):
|
||||
"""
|
||||
This function is called when the robot sends an error message and forwards it to the frontend
|
||||
:param client: mqtt client
|
||||
:param userdata:
|
||||
:param message: received error message
|
||||
:param robot: robot objectg
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Store last error in robot object
|
||||
robot.store_last_error(message.payload.decode("UTF-8"))
|
||||
# Write error into server log
|
||||
logging.error("ROBOT_DATA_ERROR new error received from Robot: " + robot.get_last_error())
|
||||
# Send error data to FrontEnd Channel to display it to the user
|
||||
client.publish(Topics['BACKEND_DATA_ERROR'], message.payload.decode("UTF-8"))
|
||||
|
||||
|
||||
def data_robotready(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot):
|
||||
"""
|
||||
This function is used to update the Robot-Ready Status of the Robot and inform the FrontEnd about it
|
||||
:param client: mqtt client
|
||||
:param userdata:
|
||||
:param message: received data
|
||||
:param robot: robot object
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Update the robot status
|
||||
robot.change_robot_status(message.payload.decode("UTF-8") == 'True')
|
||||
|
||||
# If possible send new waiting order to the robot
|
||||
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()))
|
||||
|
||||
# Send new robot-ready status to frontend channel
|
||||
client.publish(Topics['BACKEND_DATA_ROBOTREADY'], str(robot.get_robot_status()))
|
||||
|
||||
|
||||
@ -115,43 +194,72 @@ def data_robotready(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, ro
|
||||
|
||||
def action_drive(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase,
|
||||
robot: Robot):
|
||||
"""
|
||||
This function is called when a drive command from the FrontEnd is received and forwards the order to the robot or
|
||||
stores it in the order list.
|
||||
:param client: mqtt client object
|
||||
:param userdata:
|
||||
:param message: information of plant to drive to
|
||||
:param mydatabase: plant_database
|
||||
:param robot: robot object
|
||||
:return: none
|
||||
"""
|
||||
# Get PlantID from received PlantName
|
||||
plant_id = mydatabase.get_plant_id(plant_name=json.loads(str(message.payload.decode("UTF-8"))))
|
||||
print(str(plant_id))
|
||||
|
||||
# Generate a new ActionID
|
||||
action_id = str(uuid.uuid4())
|
||||
drive_data = {
|
||||
"PlantID": plant_id,
|
||||
"ActionID": action_id
|
||||
}
|
||||
|
||||
# Store order in order list or discard if list already contains 5 orders
|
||||
if robot.get_order_number() < 6 and robot.get_robot_status() is True:
|
||||
robot.add_order({"PlantID": [plant_id], "ActionID": action_id})
|
||||
# Send order to robot, if robot is available
|
||||
client.publish(Topics['ROBOT_ACTION_DRIVE'], json.dumps(drive_data))
|
||||
logging.info("BACKEND_ACTION_DRIVE Drive Command published: " + json.dumps(drive_data))
|
||||
else:
|
||||
if robot.get_order_number() < 6:
|
||||
# Add to order list if robot not available
|
||||
robot.add_order(drive_data)
|
||||
logging.info("BACKEND_ACTION_DRIVE New data added to order list: " + str(drive_data))
|
||||
elif robot.get_order_number() >= 6:
|
||||
# Discard order if list full
|
||||
logging.error("Could not add Order to list. Order discarded")
|
||||
client.publish(Topics['BACKEND_DATA_ERROR'], "Could not add Order to list. Order discarded")
|
||||
|
||||
|
||||
def action_driveall(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase,
|
||||
robot: Robot):
|
||||
"""
|
||||
This function is called when the frontend sends a drive_all command which lets the robot drive to all registered plants.
|
||||
Same as action_drive(), but for all plants.
|
||||
:param client:
|
||||
:param userdata:
|
||||
:param message:
|
||||
:param mydatabase:
|
||||
:param robot:
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Get all plantnames from the database and extract the id from them
|
||||
plant_names = mydatabase.get_plant_names()
|
||||
plant_ids = []
|
||||
print(plant_names)
|
||||
|
||||
for names in plant_names:
|
||||
_id = mydatabase.get_plant_id(names[0])
|
||||
plant_ids.append(_id)
|
||||
|
||||
# Create a new order number
|
||||
action_id = str(uuid.uuid4())
|
||||
drive_data = {
|
||||
"PlantID": plant_ids,
|
||||
"ActionID": action_id
|
||||
}
|
||||
print(drive_data)
|
||||
|
||||
# Send drive command to Robot if possible (same as action_drive())
|
||||
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(drive_data))
|
||||
@ -166,64 +274,153 @@ def action_driveall(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, my
|
||||
|
||||
|
||||
def action_getposition(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
"""
|
||||
This function is called when the frontend demands the robots position from the backend. It forwards the command to
|
||||
the robot.
|
||||
:param client: mqtt client object
|
||||
:param userdata:
|
||||
:param message:
|
||||
:param mydatabase:
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Send command to robot
|
||||
client.publish(Topics['ROBOT_ACTION_GETPOSITION'])
|
||||
logging.info("BACKEND_ACTION_GETPOSITION message forwarded to Robot")
|
||||
|
||||
|
||||
def action_getbattery(client: mqtt.Client, userdata, message: mqtt.MQTTMessage):
|
||||
"""
|
||||
This function is called when the frontend demands the robots battery status from the backend. It forwards the
|
||||
command to the robot to get new information.
|
||||
:param client: mqtt client object
|
||||
:param userdata:
|
||||
:param message:
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Send command to robot
|
||||
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):
|
||||
"""
|
||||
This function is called when the frontend demands the last data of the registered plants. It gets the last data from
|
||||
the local database and forwards it to the frontend
|
||||
:param client: mqtt client object
|
||||
:param userdata:
|
||||
:param message:
|
||||
:param mydatabase: database object, where the plant data is stored
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# get the all PlantNames
|
||||
plant_names = mydatabase.get_plant_names()
|
||||
print("SUIII" + str(plant_names))
|
||||
alldata = []
|
||||
|
||||
# Get the latest data from all registered plant names by using the plant names
|
||||
for i in plant_names:
|
||||
alldata.append(mydatabase.get_latest_data(plant_name=i[0]))
|
||||
|
||||
# Send the data as a list to the frontends channel
|
||||
client.publish(Topics['BACKEND_DATA_SENSORDATAALL'], json.dumps(alldata))
|
||||
logging.info("BACKEND_DATA_SENSORDATAALL got data from database:" + str(alldata))
|
||||
|
||||
|
||||
def action_newplant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
"""
|
||||
This function is called when the frontend wants to register a new plant. The information of the new plant is
|
||||
delivered from the frontend and used to register the plant
|
||||
:param client: mqtt client object
|
||||
:param userdata:
|
||||
:param message: data from the frontend
|
||||
:param mydatabase: local database
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Load the plant data as json
|
||||
plant_data = json.loads(message.payload.decode("UTF-8"))
|
||||
|
||||
# Insert the plant in the database
|
||||
mydatabase.insert_plant(plantname=plant_data["PlantName"], plant_id=plant_data["PlantID"])
|
||||
|
||||
# Insert a first measurement value in the database
|
||||
mydatabase.insert_measurement_data(plant_id=plant_data["PlantID"],
|
||||
sensordata_temp=plant_data["AirTemperature"],
|
||||
sensordata_humidity=plant_data["AirHumidity"],
|
||||
sensordata_soil_moisture=plant_data["SoilMoisture"],
|
||||
sensordata_brightness=plant_data["Brightness"])
|
||||
logging.info("BACKEND_ACTION_NEWPLANT new plant data received and inserted: " + str(plant_data))
|
||||
|
||||
# Send all new plant data to the frontend to update it
|
||||
action_getalldata(client, userdata, message, mydatabase)
|
||||
|
||||
|
||||
def action_configureplant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
"""
|
||||
This function is called when a parameter of a plant is changed by the frontend. It updates the information in the
|
||||
database and sends the updated data to the frontend
|
||||
:param client: mqtt client object
|
||||
:param userdata:
|
||||
:param message: received data from frontend
|
||||
:param mydatabase: local database
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Load the received data as json
|
||||
plant_data = json.loads(message.payload.decode("UTF-8"))
|
||||
|
||||
# Update the plant in the database
|
||||
mydatabase.configure_plant(plant_id=plant_data["PlantID"], plantname=plant_data["PlantName"])
|
||||
# Insert measurement_data into the database (from frontend)
|
||||
mydatabase.insert_measurement_data(plant_id=plant_data["PlantID"],
|
||||
sensordata_temp=plant_data["AirTemperature"],
|
||||
sensordata_humidity=plant_data["AirHumidity"],
|
||||
sensordata_soil_moisture=plant_data["SoilMoisture"],
|
||||
sensordata_brightness=plant_data["Brightness"])
|
||||
logging.info("BACKEND_ACTION_CONFIGUREPLANT configure plant data received and inserted: " + str(plant_data))
|
||||
|
||||
# Update the frontend with the current data
|
||||
action_getalldata(client, userdata, message, mydatabase)
|
||||
|
||||
|
||||
def action_deleteplant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
"""
|
||||
This function is called when the frontend wants to delete a registered plant from the database.
|
||||
:param client:
|
||||
:param userdata:
|
||||
:param message: Received data from the frontend
|
||||
:param mydatabase: local database object
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Load the Plant-Name from the message
|
||||
delete_plant = json.loads(message.payload.decode("UTF-8"))
|
||||
|
||||
# Delete the plant
|
||||
mydatabase.delete_plant(plant_id=delete_plant)
|
||||
logging.info("BACKEND_ACTION_DELETEPLANT delete plant data received and deleted: " + str(delete_plant))
|
||||
|
||||
# Send current data to frontend to update it
|
||||
action_getalldata(client, userdata, message, mydatabase)
|
||||
|
||||
|
||||
def action_countplants(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
"""
|
||||
This function is called when the frontend requires the count of the currently registerd plants. It sends the number
|
||||
and maximal possible plant number to the frontend as a json object
|
||||
:param client: mqtt client object
|
||||
:param userdata:
|
||||
:param message:
|
||||
:param mydatabase: local database
|
||||
:return: none
|
||||
"""
|
||||
|
||||
# Count plants
|
||||
count = mydatabase.plant_count()
|
||||
|
||||
# Create Object and send to the FrontEnd
|
||||
count_payload = {
|
||||
"CurrentCount": count,
|
||||
"MaxCount": MAX_PLANT_COUNT
|
||||
|
@ -1,7 +1,8 @@
|
||||
"""
|
||||
created by caliskan at 19.04.2023
|
||||
|
||||
contains all constants for the backend architecture of the smart garden project
|
||||
contains all constants for the backend architecture of the smart garden project. This file contains no executable script
|
||||
and is only for documentation purpose
|
||||
"""
|
||||
|
||||
MQTT_BROKER_LOCAL = "192.168.0.102"
|
||||
|
@ -21,13 +21,13 @@ def on_connect(_client: mqtt.Client, _userdata, _flags, _rc, _mydatabase, _robot
|
||||
"""
|
||||
This method gets called, when it connects to a mqtt broker.
|
||||
It is used to subscribe to the specific topics
|
||||
:param _robot:
|
||||
:param _mydatabase:
|
||||
:param _robot: robot object for
|
||||
:param _mydatabase: object, that contains the custom plant database and methods for its usage
|
||||
:param _client: mqtt client object
|
||||
:param _userdata:
|
||||
:param _flags:
|
||||
:param _rc: connection flag
|
||||
:return:
|
||||
:return: none
|
||||
"""
|
||||
if _rc == 0:
|
||||
print("connected")
|
||||
@ -100,10 +100,15 @@ def on_connect(_client: mqtt.Client, _userdata, _flags, _rc, _mydatabase, _robot
|
||||
|
||||
|
||||
def main():
|
||||
# Create Robot Object
|
||||
robot = Robot()
|
||||
|
||||
# Connect to Plant_Database and create tables if database did not exist
|
||||
my_database = PlantDataBase(database_name=DATABASE_NAME)
|
||||
my_database.create_tables()
|
||||
mqttclient = mqtt.Client(BACKEND_CLIENT_ID, transport="websockets")
|
||||
|
||||
# Create MQTT Client and connect to local broker
|
||||
mqttclient = mqtt.Client(BACKEND_CLIENT_ID, transport="websockets") # transport websockets required for local broker
|
||||
mqttclient.on_connect = lambda client, userdata, flags, rc: on_connect(_client=client,
|
||||
_userdata=userdata,
|
||||
_flags=flags,
|
||||
@ -111,10 +116,14 @@ def main():
|
||||
_mydatabase=my_database,
|
||||
_robot=robot)
|
||||
mqttclient.connect(MQTT_BROKER_LOCAL)
|
||||
|
||||
# Initialize logger and save in server.log file
|
||||
logging.basicConfig(filename="server.log", filemode="a", encoding="utf-8", level=logging.DEBUG,
|
||||
format='%(asctime)s %(name)s %(levelname)s %(message)s',
|
||||
datefmt="%d-%m-%Y %H:%M:%S")
|
||||
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
|
||||
|
||||
# Starting mqttclient infinite loop
|
||||
mqttclient.loop_forever()
|
||||
|
||||
|
||||
|
@ -6,25 +6,43 @@ import logging
|
||||
|
||||
class PlantDataBase:
|
||||
"""
|
||||
Class to create Makeathon database
|
||||
Class of a PlantDataBase Object. It contains functions specifically for the plantdatabase.
|
||||
Usage:
|
||||
- First declare object
|
||||
- Then use create_tables() to create the tables (NECESSARY !!)
|
||||
- After that use the methods of this class
|
||||
"""
|
||||
|
||||
def __init__(self, database_name: str):
|
||||
self.db_file = database_name # 'backend_database.db'
|
||||
"""
|
||||
Only Constructor of the Class. Pass name of database to connect to. If not available it will create a new one.
|
||||
:param database_name: Name of the SQLITE database file system
|
||||
"""
|
||||
self.db_file = database_name # 'backend_database.db' usually used name
|
||||
self.conn = None
|
||||
try:
|
||||
# connect or create new database if not available
|
||||
self.conn = sqlite3.connect(self.db_file, check_same_thread=False)
|
||||
except sqlite3.Error as e:
|
||||
logging.error("Database init error: " + str(e))
|
||||
|
||||
# cursor on the database
|
||||
self.cur = self.conn.cursor()
|
||||
|
||||
def create_tables(self):
|
||||
"""
|
||||
Use this method to create the plants and measurement_values tables. Call this function before using the data
|
||||
handling methods below
|
||||
:return: True if successfully, False if not
|
||||
"""
|
||||
try:
|
||||
# Create plants table if not already existing
|
||||
table_config = "CREATE TABLE IF NOT EXISTS plants " \
|
||||
"(PlantID INTEGER PRIMARY KEY," \
|
||||
"PlantName TEXT)"
|
||||
self.cur.execute(table_config)
|
||||
|
||||
# Create measurement_values_table if not already existing
|
||||
table_config = "CREATE TABLE IF NOT EXISTS measurement_values " \
|
||||
"(measurementID INTEGER PRIMARY KEY," \
|
||||
"Timestamp DATETIME DEFAULT (datetime('now', 'localtime'))," \
|
||||
@ -42,6 +60,12 @@ class PlantDataBase:
|
||||
return False
|
||||
|
||||
def insert_plant(self, plantname: str, plant_id: int) -> bool:
|
||||
"""
|
||||
Insert a new plant with an id and a plantname
|
||||
:param plantname: name of plant
|
||||
:param plant_id: id of plant (position in the bed, must be unique!!)
|
||||
:return: True if successfully, False if not
|
||||
"""
|
||||
try:
|
||||
self.cur.execute("INSERT INTO plants (PlantName, PlantID) VALUES (?,?)", (plantname, plant_id))
|
||||
self.conn.commit()
|
||||
@ -51,6 +75,12 @@ class PlantDataBase:
|
||||
return False
|
||||
|
||||
def configure_plant(self, plant_id: int, plantname: str) -> bool:
|
||||
"""
|
||||
Change a plants parameters in the database by using its PlantID as a search criteria
|
||||
:param plant_id: id of plant
|
||||
:param plantname: name of plant
|
||||
:return: True if successfully, False if not
|
||||
"""
|
||||
try:
|
||||
self.cur.execute("UPDATE plants SET PlantID = ?, PlantName = ? WHERE PlantID= ?",
|
||||
(plant_id, plantname, plant_id))
|
||||
@ -61,6 +91,11 @@ class PlantDataBase:
|
||||
return False
|
||||
|
||||
def delete_plant(self, plant_id):
|
||||
"""
|
||||
Delete a plant from the database
|
||||
:param plant_id: PlantID of plant to delete
|
||||
:return: True if successfully, False if not
|
||||
"""
|
||||
try:
|
||||
self.cur.execute('DELETE FROM plants WHERE PlantID = ?', (plant_id,))
|
||||
self.conn.commit()
|
||||
@ -74,6 +109,15 @@ class PlantDataBase:
|
||||
sensordata_humidity,
|
||||
sensordata_soil_moisture,
|
||||
sensordata_brightness) -> bool:
|
||||
"""
|
||||
Insert a measurement value of plantID
|
||||
:param plant_id: plantID of plant
|
||||
:param sensordata_temp: Temperature
|
||||
:param sensordata_humidity: Air Humidity value
|
||||
:param sensordata_soil_moisture: Soil Moisture value
|
||||
:param sensordata_brightness: brightness value
|
||||
:return: True if successfully, False if not
|
||||
"""
|
||||
try:
|
||||
self.cur.execute(f"INSERT INTO measurement_values (PlantID, AirTemperature, AirHumidity,"
|
||||
f"SoilMoisture, Brightness) VALUES "
|
||||
@ -87,10 +131,11 @@ class PlantDataBase:
|
||||
|
||||
def get_latest_data(self, plant_name: Optional[str] = None, plant_id: Optional[int] = None):
|
||||
"""
|
||||
Gets the newest parameter of specific plant and returns all parameters in json format
|
||||
:param plant_id:
|
||||
:param plant_name:
|
||||
:return:
|
||||
Gets the newest parameter of specific plant and returns all parameters in json format.
|
||||
Either pass plant_name OR plant_id, BOTH passed -> ERROR
|
||||
:param plant_id: PlantID of plant
|
||||
:param plant_name: Name of Plant
|
||||
:return: JSON with data if successfully, else none
|
||||
"""
|
||||
try:
|
||||
if plant_name is not None and plant_id is None:
|
||||
@ -118,6 +163,11 @@ class PlantDataBase:
|
||||
logging.error("Could not get measurement values: " + str(e))
|
||||
|
||||
def delete_data(self, table_name):
|
||||
"""
|
||||
Delete all data from a specific tabel
|
||||
:param table_name: tabel you want to delete
|
||||
:return: True if successfully, False if not
|
||||
"""
|
||||
try:
|
||||
self.cur.execute(f'DELETE FROM {table_name}')
|
||||
self.conn.commit()
|
||||
@ -128,7 +178,7 @@ class PlantDataBase:
|
||||
def plant_count(self) -> int:
|
||||
"""
|
||||
returns the number of plants registered in the database
|
||||
:return:
|
||||
:return: Count of registered plants as int
|
||||
"""
|
||||
try:
|
||||
self.cur.execute("SELECT COUNT(*) FROM plants")
|
||||
@ -137,6 +187,10 @@ class PlantDataBase:
|
||||
logging.error("Could not count plants: " + str(e))
|
||||
|
||||
def get_plant_names(self) -> list:
|
||||
"""
|
||||
Use this method to get a list of the Names of all registered plants
|
||||
:return: list containing plantNames
|
||||
"""
|
||||
try:
|
||||
self.cur.execute("SELECT PlantName FROM plants")
|
||||
return self.cur.fetchall()
|
||||
@ -144,6 +198,11 @@ class PlantDataBase:
|
||||
logging.error("Could not get plant names: " + str(e))
|
||||
|
||||
def get_plant_id(self, plant_name: str) -> int:
|
||||
"""
|
||||
Use this method to get the PlantID of a registered plant by its name
|
||||
:param plant_name: name of registered plant
|
||||
:return: ID of plant as int
|
||||
"""
|
||||
try:
|
||||
self.cur.execute("SELECT PlantID FROM plants WHERE PlantName=?", (plant_name,))
|
||||
return self.cur.fetchone()[0]
|
||||
@ -151,4 +210,7 @@ class PlantDataBase:
|
||||
logging.error("Could not get plant id: " + str(e))
|
||||
|
||||
def __del__(self):
|
||||
"""
|
||||
Destructor of Class. Disconnects from database.
|
||||
"""
|
||||
self.conn.close()
|
||||
|
@ -1,7 +1,7 @@
|
||||
class Robot:
|
||||
"""
|
||||
This class contains the features of the robot. It is used as an interface for the main to avoid global variables and
|
||||
store them instead in an instance of this robot object
|
||||
store them instead an instance of this robot object. It saves the orders and some basic information of the robots status
|
||||
"""
|
||||
def __init__(self):
|
||||
self.robot_ready = True
|
||||
|
Loading…
x
Reference in New Issue
Block a user