repository to manage all files related to the makeathon farm bot project (Software + Documentation).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

plantdatabase.py 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. # file to create a database via python script
  2. import sqlite3
  3. from typing import Optional
  4. import logging
  5. from itertools import chain
  6. class PlantDataBase:
  7. """
  8. Class to create Makeathon database
  9. """
  10. def __init__(self, database_name: str):
  11. self.db_file = database_name # 'backend_database.db'
  12. self.conn = None
  13. try:
  14. self.conn = sqlite3.connect(self.db_file, check_same_thread=False)
  15. except sqlite3.Error as e:
  16. logging.error("Database init error: " + str(e))
  17. self.cur = self.conn.cursor()
  18. def create_tables(self):
  19. try:
  20. table_config = "CREATE TABLE IF NOT EXISTS plants " \
  21. "(PlantID INTEGER PRIMARY KEY," \
  22. "PlantName TEXT)"
  23. self.cur.execute(table_config)
  24. table_config = "CREATE TABLE IF NOT EXISTS measurement_values " \
  25. "(measurementID INTEGER PRIMARY KEY," \
  26. "Timestamp DATETIME DEFAULT (datetime('now', 'localtime'))," \
  27. "PlantID INTEGER, " \
  28. "AirTemperature REAL," \
  29. "AirHumidity REAL," \
  30. "SoilMoisture REAL," \
  31. "Brightness REAL," \
  32. "FOREIGN KEY (PlantID)" \
  33. "REFERENCES plants (PlantID) )"
  34. self.cur.execute(table_config)
  35. return True
  36. except sqlite3.Warning as e:
  37. logging.error("Could not create tables: " + str(e))
  38. return False
  39. def insert_plant(self, plantname: str, plant_id: int) -> bool:
  40. try:
  41. self.cur.execute("INSERT INTO plants (PlantName, PlantID) VALUES (?,?)", (plantname, plant_id))
  42. self.conn.commit()
  43. return True
  44. except Exception as e:
  45. logging.error("Could not insert plant: " + str(e))
  46. return False
  47. def configure_plant(self, plant_id: int, plantname: str) -> bool:
  48. try:
  49. self.cur.execute("UPDATE plants SET PlantID = ?, PlantName = ? WHERE PlantID= ?",
  50. (plant_id, plantname, plant_id))
  51. self.conn.commit()
  52. return True
  53. except Exception as e:
  54. logging.error("Could not configure plant: " + str(e))
  55. return False
  56. def delete_plant(self, plant_id):
  57. try:
  58. self.cur.execute('DELETE FROM plants WHERE PlantID = ?', (plant_id,))
  59. self.conn.commit()
  60. return True
  61. except Exception as e:
  62. logging.error("Could not delete plant: " + str(e))
  63. return False
  64. def insert_measurement_data(self, plant_id,
  65. sensordata_temp,
  66. sensordata_humidity,
  67. sensordata_soil_moisture,
  68. sensordata_brightness) -> bool:
  69. try:
  70. self.cur.execute(f"INSERT INTO measurement_values (PlantID, AirTemperature, AirHumidity,"
  71. f"SoilMoisture, Brightness) VALUES "
  72. f"({plant_id}, {sensordata_temp}, {sensordata_humidity}, {sensordata_soil_moisture}"
  73. f", {sensordata_brightness})")
  74. self.conn.commit()
  75. return True
  76. except Exception as e:
  77. logging.error("Could not insert measurement data: " + str(e))
  78. return False
  79. def get_latest_data(self, plant_name: Optional[str] = None, plant_id: Optional[int] = None):
  80. """
  81. Gets the newest parameter of specific plant and returns all parameters in json format
  82. :param plant_id:
  83. :param plant_name:
  84. :return:
  85. """
  86. try:
  87. if plant_name is not None and plant_id is None:
  88. self.cur.execute("SELECT PlantID FROM plants where PlantName = ?", (plant_name,))
  89. plant_id = self.cur.fetchone()[0]
  90. elif (plant_id is not None and plant_name is not None) or (plant_id is None and plant_name is None):
  91. raise TypeError("Can't pass plant_id and plant_name to the function. Just one allowed !")
  92. self.cur.execute("SELECT * FROM measurement_values where PlantID = ? ORDER BY Timestamp DESC LIMIT 1",
  93. (plant_id,))
  94. data = self.cur.fetchone()
  95. json_file = {
  96. "MeasurementID": data[0],
  97. "PlantID": data[2],
  98. "Timestamp": data[1],
  99. "AirTemperature": data[3],
  100. "AirHumidity": data[4],
  101. "SoilMoisture": data[5],
  102. "Brightness": data[6],
  103. "PlantName": plant_name
  104. }
  105. return json_file
  106. except Exception as e:
  107. logging.error("Could not get measurement values: " + str(e))
  108. def delete_data(self, table_name):
  109. try:
  110. self.cur.execute(f'DELETE FROM {table_name}')
  111. self.conn.commit()
  112. return True
  113. except Exception as e:
  114. logging.error("Could not delete data: " + str(e))
  115. def plant_count(self) -> int:
  116. """
  117. returns the number of plants registered in the database
  118. :return:
  119. """
  120. try:
  121. self.cur.execute("SELECT COUNT(*) FROM plants")
  122. return self.cur.fetchone()[0]
  123. except Exception as e:
  124. logging.error("Could not count plants: " + str(e))
  125. def get_plant_names(self) -> list:
  126. try:
  127. self.cur.execute("SELECT PlantName FROM plants")
  128. return [row[0] for row in self.cur.fetchall()]
  129. except Exception as e:
  130. logging.error("Could not get plant names: " + str(e))
  131. def get_plant_id(self, plant_name: str) -> int:
  132. try:
  133. self.cur.execute("SELECT PlantID FROM plants WHERE PlantName=?", (plant_name,))
  134. return self.cur.fetchone()[0]
  135. except Exception as e:
  136. logging.error("Could not get plant id: " + str(e))
  137. def __del__(self):
  138. self.conn.close()