summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdeploy.sh7
-rwxr-xr-xmake_photo4
-rwxr-xr-xplot.py165
-rw-r--r--plot_new.py128
-rwxr-xr-xread_dht11.py39
-rwxr-xr-xread_sensors.py79
6 files changed, 204 insertions, 218 deletions
diff --git a/deploy.sh b/deploy.sh
index 3fffd76..6d7a19a 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -1,4 +1,7 @@
#!/bin/bash
set -e
-scp plot_new.py read_dht11.py water_the_plant create_backup make_photo index.html history.html *.png robert@waterpi:
-ssh robert@waterpi -C 'sudo cp index.html history.html *.png /var/www/html; sudo chown www-data:www-data /var/www/html/*.html /var/www/html/*.png; sudo cp plot_new.py read_dht11.py create_backup make_photo plot.py read_temperature.py water_the_plant /usr/local/bin'
+scp plot.py read_sensors.py water_the_plant create_backup make_photo index.html history.html *.png robert@waterpi:
+ssh robert@waterpi -C '\
+ sudo cp index.html history.html *.png /var/www/html; \
+ sudo chown www-data:www-data /var/www/html/*.html /var/www/html/*.png; \
+ sudo cp plot.py read_sensors.py create_backup make_photo plot.py read_temperature.py water_the_plant /usr/local/bin'
diff --git a/make_photo b/make_photo
index 76c9918..cf37ed5 100755
--- a/make_photo
+++ b/make_photo
@@ -8,6 +8,6 @@ rpicam-still -o $image
#add date string
convert $image -resize 1024x768 -gravity SouthEast -font DejaVu-Sans -pointsize 50 -stroke black -undercolor black -fill "rgba(255,255,255,0.5)" -annotate +30+30 "$(date +\\'%Y-%m-%d %H:%M\')" $image
#read cpu temp
-read_dht11.py
+read_sensors.py
#plot cpu temp
-plot_new.py $image $image
+plot.py $image $image
diff --git a/plot.py b/plot.py
index b58cf7a..ea80b03 100755
--- a/plot.py
+++ b/plot.py
@@ -1,47 +1,30 @@
#!/usr/bin/python3
+import sys
+import sqlite3
import matplotlib.pyplot as plt
import numpy as np
-from PIL import Image
-import argparse
from datetime import datetime, timedelta
import matplotlib.dates as mdates
+from PIL import Image
-import sqlite3
-
+# Funktion zum Lesen von Temperatur-, Luftfeuchtigkeits- und Zeitstempeldaten aus der SQLite-Datenbank
def read_data_from_db(db_name):
- """
- Liest alle gespeicherten Temperatur- und Zeitstempeldaten aus der SQLite-Datenbank.
-
- :param db_name: Name der SQLite-Datenbankdatei
- :return: Liste von Tupeln mit (timestamp, temperature)
- """
try:
- # Verbindung zur Datenbank herstellen
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
-
- # Abfrage zum Abrufen aller Daten aus der Tabelle
- cursor.execute("SELECT timestamp, temperature FROM cpu_temperature")
- data = cursor.fetchall() # Alle Ergebnisse abrufen
-
- conn.close() # Verbindung schließen
+ cursor.execute("SELECT timestamp, temperature, humidity, moisture FROM sensor_data")
+ data = cursor.fetchall()
+ conn.close()
return data
except sqlite3.Error as e:
print(f"Fehler beim Lesen aus der Datenbank: {e}")
return []
-
-
-# Funktion zum Erstellen des Temperaturdiagramms mit Achsenbeschriftungen und Transparenz
-def create_temperature_plot_with_labels(output_filename):
- db_name = "/var/www/html/cpu_temperature.db"
- records = read_data_from_db(db_name)
-
- if records:
- for timestamp, temperature in records:
- print(f"Zeit: {timestamp}, Temperatur: {temperature}°C")
- else:
+# Funktion zum Erstellen eines Diagramms für Temperatur und Luftfeuchtigkeit (800x200 Pixel)
+def create_temperature_humidity_plot(records, output_filename):
+ if not records:
print("Keine Daten gefunden.")
+ return
# Aktuelle Zeit und Filterzeitraum (letzte 24 Stunden)
now = datetime.now()
@@ -49,55 +32,83 @@ def create_temperature_plot_with_labels(output_filename):
# Filtern der Datensätze nach den letzten 24 Stunden
filtered_records = [
- (datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S"), temperature)
- for timestamp, temperature in records
+ (datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S"), temperature, humidity, moisture)
+ for timestamp, temperature, humidity, moisture in records
if datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S") >= last_24_hours
]
if not filtered_records:
print("Keine Daten in den letzten 24 Stunden gefunden.")
return
- # Extrahieren von Zeitstempeln und Temperaturen aus den gefilterten Datensätzen
- times = [timestamp for timestamp, _ in filtered_records]
- temperatures = [temperature for _, temperature in filtered_records]
-
- # Grenzen für die y-Achse basierend auf den Temperaturdaten
- min_temp = np.floor(min(temperatures) / 5) * 5 # Abrunden auf das nächste Vielfache von 5
- max_temp = np.ceil(max(temperatures) / 5) * 5 # Aufrunden auf das nächste Vielfache von 5
-
- # Temperaturdiagramm zeichnen
- plt.figure(figsize=(8, 2), dpi=100) # Größe des Diagramms: 800x100 Pixel
- plt.plot(times, temperatures, color='yellow', linewidth=2, label='Temperatur')
- plt.ylim(min_temp, max_temp) # Y-Achse auf den Bereich der Daten begrenzen
- plt.xlabel('Uhrzeit', color='white') # X-Achsenbeschriftung
- plt.ylabel('CPU Temp in °C', color='white') # Y-Achsenbeschriftung
- plt.xticks(color='white') # X-Achse beschriften (automatisch), gedreht für bessere Lesbarkeit
- plt.yticks(np.arange(min_temp, max_temp + 1, 5), color='white') # Y-Achse in Schritten von 5 beschriften
- plt.grid(color='white', linestyle='--', linewidth=0.5, alpha=0.7)
- plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
- plt.tight_layout()
-
- # Diagramm mit transparentem Hintergrund speichern
+ # Extrahieren von Zeitstempeln, Temperaturen, Luftfeuchtigkeit und Feuchtigkeit
+ times = [timestamp for timestamp, _, _, _ in filtered_records]
+ temperatures = [temperature for _, temperature, _, _ in filtered_records]
+ humidities = [humidity for _, _, humidity, _ in filtered_records]
+ moistures = [moisture for _, _, _, moisture in filtered_records]
+
+ # Grenzen für die y-Achsen basierend auf den Daten
+ min_temp = np.floor(min(temperatures) / 5) * 5
+ max_temp = np.ceil(max(temperatures) / 5) * 5
+ min_humidity = np.floor(min(humidities) / 10) * 10
+ max_humidity = np.ceil(max(humidities) / 10) * 10
+ min_moisture = np.floor(min(moistures) / 10) * 10
+ max_moisture = np.ceil(max(moistures) / 10) * 10
+
+ # Diagramm zeichnen (800x200 Pixel)
+ fig, ax1 = plt.subplots(figsize=(8, 2), dpi=100)
+
+ # Temperaturplot (linke Y-Achse)
+ ax1.set_xlabel('Uhrzeit', color='white')
+ ax1.set_ylabel('Temperatur (°C)', color='tab:red')
+ ax1.plot(times, temperatures, color='tab:red', label='Temperatur')
+ ax1.tick_params(axis='y', labelcolor='tab:red')
+ ax1.tick_params(axis='x', colors='white')
+ ax1.set_ylim(min_temp, max_temp)
+ ax1.spines['top'].set_color('white')
+ ax1.spines['bottom'].set_color('white')
+ ax1.spines['left'].set_color('white')
+ ax1.spines['right'].set_color('white')
+
+
+ # Luftfeuchtigkeitsplot (rechte Y-Achse)
+ ax2 = ax1.twinx()
+ ax2.set_ylabel('Luftfeuchtigkeit (%)', color='tab:blue')
+ ax2.plot(times, humidities, color='tab:blue', label='Luftfeuchtigkeit')
+ ax2.tick_params(axis='y', labelcolor='tab:blue')
+ ax2.set_ylim(min_humidity, max_humidity)
+ ax2.tick_params(axis='x', colors='white')
+ ax2.spines['top'].set_color('white')
+ ax2.spines['bottom'].set_color('white')
+ ax2.spines['left'].set_color('white')
+ ax2.spines['right'].set_color('white')
+
+ # Feuchtigkeitsplot (dritte Y-Achse)
+ ax3 = ax1.twinx()
+ ax3.spines['right'].set_position(('outward', 60)) # Platz für die dritte Achse schaffen
+ ax3.set_ylabel('Feuchtigkeit (16-32k)', color='tab:green')
+ ax3.plot(times, moistures, color='tab:green', label='Feuchtigkeit')
+ ax3.tick_params(axis='y', labelcolor='tab:green')
+ ax3.set_ylim(min_moisture, max_moisture)
+ ax3.tick_params(axis='x', colors='white')
+ ax3.spines['top'].set_color('white')
+ ax3.spines['bottom'].set_color('white')
+ ax3.spines['left'].set_color('white')
+ ax3.spines['right'].set_color('white')
+
+ # X-Achse formatieren
+ ax1.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
+
+ # Layout anpassen und Diagramm speichern
+ fig.tight_layout()
plt.savefig(output_filename, transparent=True, bbox_inches='tight')
plt.close()
-# Funktion zum Laden und Überprüfen des Basisbildes
-def load_and_check_base_image(image_path):
- try:
- base_image = Image.open(image_path)
- if base_image.size != (1024, 768):
- raise ValueError("Das Basisbild muss eine Größe von 1024x768 Pixeln haben.")
- return base_image
- except Exception as e:
- print(f"Fehler beim Laden des Basisbildes: {e}")
- return None
# Funktion zum Überlagern des Diagramms auf das Basisbild
def overlay_plot_on_image(base_image_path, plot_image_path, output_image_path):
try:
base_image = Image.open(base_image_path)
-
- plot_image = Image.open(plot_image_path)
+ plot_image = Image.open(plot_image_path).resize((800, 200)) # Größe des Plots anpassen
# Überlagern des Diagramms auf das Basisbild (mit Transparenz)
base_image.paste(plot_image, (112, 0), plot_image) # Zentrieren: (1024 - 800) / 2 = 112
@@ -110,21 +121,27 @@ def overlay_plot_on_image(base_image_path, plot_image_path, output_image_path):
# Hauptfunktion
def main():
- parser = argparse.ArgumentParser(description="Overlay transparentes Temperaturdiagramm auf ein Bild.")
- parser.add_argument("image", help="Pfad zum Basisbild (1024x768 Pixel)")
- parser.add_argument("output", help="Pfad zum kombinierten Ausgabebild")
- args = parser.parse_args()
+ if len(sys.argv) != 3:
+ print("Bitte geben Sie den Pfad zum Basisbild und den Pfad zum Ausgabebild an.")
+ sys.exit(1)
- base_image_path = args.image
- output_image_path = args.output
+ base_image_path = sys.argv[1]
+ output_image_path = sys.argv[2]
+
+ db_name = "/var/www/html/sensor_data.db"
+
+ # Daten aus der Datenbank lesen
+ records = read_data_from_db(db_name)
- # Temporäre Datei für das transparente Temperaturdiagramm
- plot_filename = "temperature_plot_with_labels.png"
+ # Temporäre Datei für das transparente Temperatur- und Feuchtigkeitsdiagramm
+ plot_filename = "temperature_humidity_plot.png"
+
+ # Diagramm erstellen und speichern
+ create_temperature_humidity_plot(records, plot_filename)
- # Schritte ausführen: Diagramm erstellen und überlagern
- create_temperature_plot_with_labels(plot_filename)
+ # Basisbild laden und Diagramm überlagern
overlay_plot_on_image(base_image_path, plot_filename, output_image_path)
if __name__ == "__main__":
- main()
+ main()
diff --git a/plot_new.py b/plot_new.py
deleted file mode 100644
index 4a6ee16..0000000
--- a/plot_new.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/python3
-import sys
-import sqlite3
-import matplotlib.pyplot as plt
-import numpy as np
-from datetime import datetime, timedelta
-import matplotlib.dates as mdates
-from PIL import Image
-
-# Funktion zum Lesen von Temperatur-, Luftfeuchtigkeits- und Zeitstempeldaten aus der SQLite-Datenbank
-def read_data_from_db(db_name):
- try:
- conn = sqlite3.connect(db_name)
- cursor = conn.cursor()
- cursor.execute("SELECT timestamp, temperature, humidity FROM sensor_data")
- data = cursor.fetchall()
- conn.close()
- return data
- except sqlite3.Error as e:
- print(f"Fehler beim Lesen aus der Datenbank: {e}")
- return []
-
-# Funktion zum Erstellen eines Diagramms für Temperatur und Luftfeuchtigkeit (800x200 Pixel)
-def create_temperature_humidity_plot(records, output_filename):
- if not records:
- print("Keine Daten gefunden.")
- return
-
- # Aktuelle Zeit und Filterzeitraum (letzte 24 Stunden)
- now = datetime.now()
- last_24_hours = now - timedelta(hours=24)
-
- # Filtern der Datensätze nach den letzten 24 Stunden
- filtered_records = [
- (datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S"), temperature, humidity)
- for timestamp, temperature, humidity in records
- if datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S") >= last_24_hours
- ]
- if not filtered_records:
- print("Keine Daten in den letzten 24 Stunden gefunden.")
- return
-
- # Extrahieren von Zeitstempeln, Temperaturen und Luftfeuchtigkeit
- times = [timestamp for timestamp, _, _ in filtered_records]
- temperatures = [temperature for _, temperature, _ in filtered_records]
- humidities = [humidity for _, _, humidity in filtered_records]
-
- # Grenzen für die y-Achsen basierend auf den Daten
- min_temp = np.floor(min(temperatures) / 5) * 5
- max_temp = np.ceil(max(temperatures) / 5) * 5
- min_humidity = np.floor(min(humidities) / 10) * 10
- max_humidity = np.ceil(max(humidities) / 10) * 10
-
- # Diagramm zeichnen (800x200 Pixel)
- fig, ax1 = plt.subplots(figsize=(8, 2), dpi=100)
-
- # Temperaturplot (linke Y-Achse)
- ax1.set_xlabel('Uhrzeit', color='white')
- ax1.set_ylabel('Temperatur (°C)', color='tab:red')
- ax1.plot(times, temperatures, color='tab:red', label='Temperatur')
- ax1.tick_params(axis='y', labelcolor='tab:red')
- ax1.tick_params(axis='x', colors='white')
- ax1.set_ylim(min_temp, max_temp)
- ax1.spines['top'].set_color('white')
- ax1.spines['bottom'].set_color('white')
- ax1.spines['left'].set_color('white')
- ax1.spines['right'].set_color('white')
-
- # Luftfeuchtigkeitsplot (rechte Y-Achse)
- ax2 = ax1.twinx()
- ax2.set_ylabel('Luftfeuchtigkeit (%)', color='tab:blue')
- ax2.plot(times, humidities, color='tab:blue', label='Luftfeuchtigkeit')
- ax2.tick_params(axis='y', labelcolor='tab:blue')
- ax2.set_ylim(min_humidity, max_humidity)
- ax2.spines['top'].set_color('white')
- ax2.spines['bottom'].set_color('white')
- ax2.spines['left'].set_color('white')
- ax2.spines['right'].set_color('white')
-
- # X-Achse formatieren
- ax1.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
- fig.tight_layout()
-
- # Diagramm speichern (transparent)
- plt.savefig(output_filename, transparent=True, bbox_inches='tight')
- plt.close()
-
-# Funktion zum Überlagern des Diagramms auf das Basisbild
-def overlay_plot_on_image(base_image_path, plot_image_path, output_image_path):
- try:
- base_image = Image.open(base_image_path)
- plot_image = Image.open(plot_image_path).resize((800, 200)) # Größe des Plots anpassen
-
- # Überlagern des Diagramms auf das Basisbild (mit Transparenz)
- base_image.paste(plot_image, (112, 0), plot_image) # Zentrieren: (1024 - 800) / 2 = 112
-
- # Kombiniertes Bild speichern
- base_image.save(output_image_path)
- print(f"Kombiniertes Bild gespeichert als {output_image_path}")
- except Exception as e:
- print(f"Fehler beim Überlagern des Diagramms: {e}")
-
-# Hauptfunktion
-def main():
- if len(sys.argv) != 3:
- print("Bitte geben Sie den Pfad zum Basisbild und den Pfad zum Ausgabebild an.")
- sys.exit(1)
-
- base_image_path = sys.argv[1]
- output_image_path = sys.argv[2]
-
- db_name = "/var/www/html/sensor_data.db"
-
- # Daten aus der Datenbank lesen
- records = read_data_from_db(db_name)
-
- # Temporäre Datei für das transparente Temperatur- und Feuchtigkeitsdiagramm
- plot_filename = "temperature_humidity_plot.png"
-
- # Diagramm erstellen und speichern
- create_temperature_humidity_plot(records, plot_filename)
-
- # Basisbild laden und Diagramm überlagern
- overlay_plot_on_image(base_image_path, plot_filename, output_image_path)
-
-if __name__ == "__main__":
- main()
-
diff --git a/read_dht11.py b/read_dht11.py
index 524fdba..e560a8a 100755
--- a/read_dht11.py
+++ b/read_dht11.py
@@ -3,10 +3,22 @@ import sqlite3
from datetime import datetime
import adafruit_dht
import board
+import busio
+import adafruit_ads1x15.ads1115 as ADS
+from adafruit_ads1x15.analog_in import AnalogIn
# GPIO-Pin für den DHT11-Sensor
DHT_SENSOR = adafruit_dht.DHT11(board.D26)
+# Initialize the I2C interface
+i2c = busio.I2C(board.SCL, board.SDA)
+
+# Create an ADS1115 object
+ads = ADS.ADS1115(i2c)
+
+# Define the analog input channel
+channel = AnalogIn(ads, ADS.P0)
+
# Funktion zur Initialisierung der SQLite-Datenbank
def init_db(db_name):
conn = sqlite3.connect(db_name)
@@ -17,30 +29,32 @@ def init_db(db_name):
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT NOT NULL,
temperature REAL NOT NULL,
- humidity REAL NOT NULL
+ humidity REAL NOT NULL,
+ moisture REAL NOT NULL
)
""")
conn.commit()
return conn
# Funktion zum Einfügen von Daten in die Datenbank
-def insert_data(conn, timestamp, temperature, humidity):
+def insert_data(conn, timestamp, temperature, humidity, moisture):
cursor = conn.cursor()
cursor.execute("""
- INSERT INTO sensor_data (timestamp, temperature, humidity)
- VALUES (?, ?, ?)
- """, (timestamp, temperature, humidity))
+ INSERT INTO sensor_data (timestamp, temperature, humidity, moisture)
+ VALUES (?, ?, ?, ?)
+ """, (timestamp, temperature, humidity, moisture))
conn.commit()
# Funktion zum Lesen von Temperatur und Luftfeuchtigkeit vom DHT11-Sensor
def read_dht11():
humidity = DHT_SENSOR.humidity
temperature = DHT_SENSOR.temperature
+ moisture = channel.value
if humidity is not None and temperature is not None:
- return round(temperature, 1), round(humidity, 1)
+ return round(temperature, 1), round(humidity, 1), moisture
else:
- print("Fehler beim Lesen des Sensors. Versuche erneut...")
- return None, None
+ print("Fehler beim Lesen der Sensoren. Versuche erneut...")
+ return None, None, None
# Hauptfunktion
def main():
@@ -48,14 +62,15 @@ def main():
conn = init_db(db_name)
# Ruft Temperatur und Luftfeuchtigkeit ab
- temperature, humidity = read_dht11()
+ temperature, humidity, moisture = read_dht11()
+
- if temperature is not None and humidity is not None:
+ if temperature is not None and humidity is not None and moisture is not None:
# Holt das aktuelle Datum und die Uhrzeit
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Speichert die Daten in der Datenbank
- insert_data(conn, timestamp, temperature, humidity)
- print(f"Gespeichert: {timestamp} - Temperatur: {temperature}°C - Luftfeuchtigkeit: {humidity}%")
+ insert_data(conn, timestamp, temperature, humidity, moisture)
+ print(f"Gespeichert: {timestamp} - Temperatur: {temperature}°C - Luftfeuchtigkeit: {humidity}% - Bodenfeutigkeit {moisture}")
conn.close()
diff --git a/read_sensors.py b/read_sensors.py
new file mode 100755
index 0000000..e560a8a
--- /dev/null
+++ b/read_sensors.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python3
+import sqlite3
+from datetime import datetime
+import adafruit_dht
+import board
+import busio
+import adafruit_ads1x15.ads1115 as ADS
+from adafruit_ads1x15.analog_in import AnalogIn
+
+# GPIO-Pin für den DHT11-Sensor
+DHT_SENSOR = adafruit_dht.DHT11(board.D26)
+
+# Initialize the I2C interface
+i2c = busio.I2C(board.SCL, board.SDA)
+
+# Create an ADS1115 object
+ads = ADS.ADS1115(i2c)
+
+# Define the analog input channel
+channel = AnalogIn(ads, ADS.P0)
+
+# Funktion zur Initialisierung der SQLite-Datenbank
+def init_db(db_name):
+ conn = sqlite3.connect(db_name)
+ cursor = conn.cursor()
+ # Erstellt eine Tabelle, falls sie noch nicht existiert
+ cursor.execute("""
+ CREATE TABLE IF NOT EXISTS sensor_data (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ timestamp TEXT NOT NULL,
+ temperature REAL NOT NULL,
+ humidity REAL NOT NULL,
+ moisture REAL NOT NULL
+ )
+ """)
+ conn.commit()
+ return conn
+
+# Funktion zum Einfügen von Daten in die Datenbank
+def insert_data(conn, timestamp, temperature, humidity, moisture):
+ cursor = conn.cursor()
+ cursor.execute("""
+ INSERT INTO sensor_data (timestamp, temperature, humidity, moisture)
+ VALUES (?, ?, ?, ?)
+ """, (timestamp, temperature, humidity, moisture))
+ conn.commit()
+
+# Funktion zum Lesen von Temperatur und Luftfeuchtigkeit vom DHT11-Sensor
+def read_dht11():
+ humidity = DHT_SENSOR.humidity
+ temperature = DHT_SENSOR.temperature
+ moisture = channel.value
+ if humidity is not None and temperature is not None:
+ return round(temperature, 1), round(humidity, 1), moisture
+ else:
+ print("Fehler beim Lesen der Sensoren. Versuche erneut...")
+ return None, None, None
+
+# Hauptfunktion
+def main():
+ db_name = "/var/www/html/sensor_data.db"
+ conn = init_db(db_name)
+
+ # Ruft Temperatur und Luftfeuchtigkeit ab
+ temperature, humidity, moisture = read_dht11()
+
+
+ if temperature is not None and humidity is not None and moisture is not None:
+ # Holt das aktuelle Datum und die Uhrzeit
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ # Speichert die Daten in der Datenbank
+ insert_data(conn, timestamp, temperature, humidity, moisture)
+ print(f"Gespeichert: {timestamp} - Temperatur: {temperature}°C - Luftfeuchtigkeit: {humidity}% - Bodenfeutigkeit {moisture}")
+
+ conn.close()
+
+if __name__ == "__main__":
+ main()
+