summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Scheibe <rob.scheibe@gmail.com>2024-12-22 15:52:40 +0100
committerRobert Scheibe <rob.scheibe@gmail.com>2024-12-22 15:52:40 +0100
commitbd0a388682dae9da9146a9d37ebfd4d2c2527b6e (patch)
tree6a555b1347dbfab3a956a4b6ede508c1559628b5
parent44a4a65f8c7244244d9b9102193d682ba89d3048 (diff)
added history.html and cpu temperature plotting
-rw-r--r--README.txt5
-rwxr-xr-xcreate_backup2
-rwxr-xr-xdeploy.sh4
-rw-r--r--history.html152
-rw-r--r--index.html2
-rwxr-xr-xmake_photo8
-rwxr-xr-xplot.py65
-rwxr-xr-xread_temperature.py61
-rwxr-xr-xwater_the_plant22
9 files changed, 309 insertions, 12 deletions
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..9e7834e
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,5 @@
+#> sudo crontab -e
+
+*/15 * * * * /usr/local/bin/make_photo
+02 12 * * * /usr/local/bin/create_backup
+29 08 * * * /usr/local/bin/water_the_plant
diff --git a/create_backup b/create_backup
new file mode 100755
index 0000000..a166395
--- /dev/null
+++ b/create_backup
@@ -0,0 +1,2 @@
+#!/bin/bash
+cp /mnt/ramdisk/12_00.jpg /var/www/html/waterpi_12h_images/$(date +'%Y-%m-%d')_12_00.jpg
diff --git a/deploy.sh b/deploy.sh
index 2f2b6e7..5032c15 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -1,4 +1,4 @@
#!/bin/bash
set -e
-scp index.html *.png robert@waterpi:
-ssh robert@waterpi -C 'sudo cp index.html *.png /var/www/html; sudo chown www-data:www-data /var/www/html/index.html'
+scp water_the_plant create_backup make_photo *.py 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 create_backup make_photo plot.py read_temperature.py water_the_plant /usr/local/bin'
diff --git a/history.html b/history.html
new file mode 100644
index 0000000..f48e9fe
--- /dev/null
+++ b/history.html
@@ -0,0 +1,152 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title> waterpi </title>
+ <meta http-equiv="refresh" content="60">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <style>
+.gallery {
+ max-width: 800px;
+ margin: 0 auto;
+ text-align: center;
+}
+
+.main-image {
+ margin-bottom: 20px;
+}
+
+.main-image img {
+ width: 100%;
+ height: auto;
+ display: block;
+ margin: 0 auto;
+ object-fit: contain;
+}
+
+.controls {
+ display: flex;
+ justify-content: center;
+ gap: 20px;
+ align-items: center;
+}
+
+.nav-button {
+ padding: 10px 20px;
+ font-size: 24px;
+ cursor: pointer;
+ border: none;
+ background-color: #f0f0f0;
+ border-radius: 5px;
+ transition: background-color 0.3s;
+}
+
+.now-button {
+ padding: 12px 24px;
+ font-size: 16px;
+ font-weight: bold;
+ cursor: pointer;
+ border: none;
+ background-color: #4CAF50;
+ color: white;
+ border-radius: 5px;
+ transition: background-color 0.3s;
+}
+
+.now-button:hover {
+ background-color: #45a049;
+}
+
+.nav-button:hover {
+ background-color: #e0e0e0;
+}
+
+.nav-button:disabled, .now-button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+</style>
+ </head>
+
+ <body>
+<div class="gallery">
+ <div class="main-image">
+ <img id="featured" src="" alt="Hauptbild" onerror="this.src='error.png'">
+ </div>
+ <div class="controls">
+ <button onclick="jumpDays(-7)" class="nav-button"><img src="fbck.png"></button>
+ <button onclick="jumpDays(-1)" class="nav-button"><img src="bck.png"></button>
+ <button onclick="jumpToCurrent()" class="now-button"><img src="stop.png"></button>
+ <button onclick="jumpDays(1)" class="nav-button"><img src="fwd.png"></button>
+ <button onclick="jumpDays(7)" class="nav-button"><img src="ffwd.png"></button>
+ </div>
+</div>
+<a href="index.html">go to current day</a>
+ </body>
+</html>
+
+<script>
+let currentDate = new Date();
+
+function formatDateString(date) {
+ const year = date.getFullYear();
+ const month = (date.getMonth() + 1).toString().padStart(2, '0');
+ const day = date.getDate().toString().padStart(2, '0');
+ return `${year}-${month}-${day}_12_00`;
+}
+
+function updateGallery() {
+ // Setze die Uhrzeit auf 12:00
+ currentDate.setHours(12, 0, 0, 0);
+ updateImage();
+ updateButtons();
+}
+
+function jumpDays(days) {
+ const newDate = new Date(currentDate);
+ newDate.setDate(newDate.getDate() + days);
+ const today = new Date();
+ today.setHours(12, 0, 0, 0);
+
+ // Prüfe ob das neue Datum nicht in der Zukunft liegt
+ if (newDate <= today) {
+ currentDate = newDate;
+ updateImage();
+ updateButtons();
+ }
+}
+
+function jumpToCurrent() {
+ const today = new Date();
+ today.setHours(12, 0, 0, 0);
+ currentDate = today;
+ updateImage();
+ updateButtons();
+}
+
+function updateImage() {
+ const dateString = formatDateString(currentDate);
+ const img = document.getElementById('featured');
+ img.src = `waterpi_12h_images/${dateString}.jpg`;
+}
+
+function updateButtons() {
+ const today = new Date();
+ today.setHours(12, 0, 0, 0);
+
+ const buttons = document.querySelectorAll('.nav-button');
+
+ // Deaktiviere Vorwärts-Buttons wenn aktueller Tag erreicht
+ buttons[2].disabled = currentDate.getTime() + 24 * 60 * 60 * 1000 > today.getTime();
+ buttons[3].disabled = currentDate.getTime() + 7 * 24 * 60 * 60 * 1000 > today.getTime();
+
+ // Deaktiviere den Heute-Button wenn bereits der aktuelle Tag angezeigt wird
+ document.querySelector('.now-button').disabled =
+ currentDate.getTime() === today.getTime();
+}
+
+// Initial gallery setup
+updateGallery();
+
+// Aktualisiere die Galerie jede Sekunde
+//setInterval(updateGallery, 1000);
+</script>
diff --git a/index.html b/index.html
index 6686788..048d8d7 100644
--- a/index.html
+++ b/index.html
@@ -80,7 +80,7 @@
<button onclick="jumpTime(60)" class="nav-button"><img src="ffwd.png"></button>
</div>
</div>
-
+<a href="history.html">go to 12:00 images</a>
</body>
</html>
diff --git a/make_photo b/make_photo
index 3c27888..e214f3b 100755
--- a/make_photo
+++ b/make_photo
@@ -1,10 +1,12 @@
#!/bin/bash
export LC_TIME=de_DE.utf-8
image=/mnt/ramdisk/$(date +'%H_%M').jpg
-#image_small=/mnt/ramdisk/$(date +'%H_%M')_thumb.jpg
-
+#take photo
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
-#convert $image -resize 200x150 $image_small
+#read cpu temp
+read_temperature.py
+#plot cpu temp
+plot.py $image $image
diff --git a/plot.py b/plot.py
index 55b6ef3..b58cf7a 100755
--- a/plot.py
+++ b/plot.py
@@ -3,11 +3,63 @@ 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
+
+import sqlite3
+
+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
+ 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):
- times = np.arange(0, 24, 0.5) # Zeitpunkte (alle halbe Stunde)
- temperatures = 20 + 10 * np.sin(times / 24 * 2 * np.pi) # Beispielhafte Sinuskurve für Temperaturen
+ 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:
+ print("Keine Daten gefunden.")
+
+ # 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)
+ for timestamp, temperature 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
@@ -15,13 +67,14 @@ def create_temperature_plot_with_labels(output_filename):
# Temperaturdiagramm zeichnen
plt.figure(figsize=(8, 2), dpi=100) # Größe des Diagramms: 800x100 Pixel
- plt.plot(times, temperatures, color='yellow', linewidth=5, label='Temperatur')
+ 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('Temperatur in °C', color='white') # Y-Achsenbeschriftung
- plt.xticks(np.arange(0, 25, 4), color='white') # X-Achse in 4-Stunden-Schritten beschriften
+ 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='gray', linestyle='--', linewidth=0.5, alpha=0.7)
+ 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
diff --git a/read_temperature.py b/read_temperature.py
new file mode 100755
index 0000000..0d9249e
--- /dev/null
+++ b/read_temperature.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python3
+import sqlite3
+import subprocess
+from datetime import datetime
+
+# Funktion zur Messung der CPU-Temperatur
+def get_cpu_temperature():
+ try:
+ # Führt den Befehl vcgencmd aus, um die CPU-Temperatur zu messen
+ output = subprocess.run(['vcgencmd', 'measure_temp'], stdout=subprocess.PIPE)
+ temp_str = output.stdout.decode('utf-8')
+ # Extrahiert die Temperatur als Float-Wert
+ temp = float(temp_str.split('=')[1].split("'")[0])
+ return temp
+ except Exception as e:
+ print(f"Fehler beim Abrufen der CPU-Temperatur: {e}")
+ return None
+
+# 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 cpu_temperature (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ timestamp TEXT NOT NULL,
+ temperature REAL NOT NULL
+ )
+ """)
+ conn.commit()
+ return conn
+
+# Funktion zum Einfügen von Daten in die Datenbank
+def insert_data(conn, timestamp, temperature):
+ cursor = conn.cursor()
+ cursor.execute("""
+ INSERT INTO cpu_temperature (timestamp, temperature)
+ VALUES (?, ?)
+ """, (timestamp, temperature))
+ conn.commit()
+
+# Hauptfunktion
+def main():
+ db_name = "/var/www/html/cpu_temperature.db"
+ conn = init_db(db_name)
+
+ # Ruft die aktuelle CPU-Temperatur ab
+ temperature = get_cpu_temperature()
+ if temperature 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)
+ print(f"Gespeichert: {timestamp} - {temperature}°C")
+
+ conn.close()
+
+if __name__ == "__main__":
+ main()
+
diff --git a/water_the_plant b/water_the_plant
new file mode 100755
index 0000000..bdfed4d
--- /dev/null
+++ b/water_the_plant
@@ -0,0 +1,22 @@
+#!/usr/bin/python3
+import RPi.GPIO as GPIO
+import time
+
+# GPIO-Modus auf BCM setzen
+GPIO.setmode(GPIO.BCM)
+
+# GPIO4 als Ausgang konfigurieren
+GPIO.setup(4, GPIO.OUT)
+
+try:
+ # GPIO4 einschalten
+ GPIO.output(4, GPIO.LOW)
+ # 1 Sekunde warten
+ time.sleep(4)
+ # GPIO4 ausschalten
+ GPIO.output(4, GPIO.HIGH)
+finally:
+ # Ressourcen freigeben
+ GPIO.cleanup()
+
+