Artikel 3 – Navigation und Visualisierung stabilisieren: Wie die Gebäudedaten‑App zuverlässig zwischen Screens wechselt und Diagramme erzeugt

Die Gebäudedaten‑App lebt von ihrer klaren Navigation und der Fähigkeit, Sensordaten zuverlässig zu visualisieren. In diesem Artikel tauchst du tief in die Mechanik der Navigation ein und lernst, wie die App zwischen den verschiedenen Screens wechselt, wie der AppState dabei eine zentrale Rolle spielt und wie der Diagramm‑Screen die Messwerte eines Sensors in ein Matplotlib‑Diagramm verwandelt.

Dieser Artikel ist bewusst praxisnah aufgebaut: Du erfährst nicht nur, wie die Navigation funktioniert, sondern auch, warum sie so implementiert wurde und wie sie sich im Zusammenspiel mit der Visualisierung verhält. Am Ende wirst du verstehen, warum die App so stabil läuft und wie du sie später erweitern kannst, ohne die bestehende Struktur zu gefährden.

1. Die Navigation als Rückgrat der App

Die Navigation ist das zentrale Element, das alle Screens miteinander verbindet. Ohne eine saubere Navigation wäre die App schwer zu bedienen und fehleranfällig. Die Gebäudedaten‑App nutzt den ScreenManager von Kivy, um zwischen den verschiedenen Screens zu wechseln. Jeder Screen hat einen eindeutigen Namen, und die App wechselt zwischen ihnen, indem sie self.manager.current setzt.

Beispiel:

self.manager.current = "sensors"

Das klingt einfach — und das ist es auch. Aber die wahre Stärke liegt in der Kombination mit dem AppState. Der AppState speichert alle Informationen, die für die Navigation wichtig sind: die aktuelle Zone, den aktuellen Raum, den ausgewählten Sensor und den vorherigen Screen. Dadurch müssen die Screens nicht direkt miteinander kommunizieren, sondern greifen alle auf denselben Zustand zu.

Warum ist das wichtig?

Stell dir vor, der Diagramm‑Screen müsste wissen, welcher Sensor gerade ausgewählt wurde. Ohne AppState müsstest du diese Information beim Wechsel des Screens übergeben. Das wäre fehleranfällig und würde die Screens enger miteinander verknüpfen.

Mit dem AppState ist das viel einfacher:

  • Der SensorScreen setzt current_sensor_id und current_sensor_name.
  • Der DiagrammScreen liest diese Werte aus.
  • Der RoomScreen setzt current_room_id und current_room_name.
  • Der SensorScreen liest diese Werte aus.

So entsteht eine lose Kopplung, die die App flexibel macht.

2. Der SensorScreen – das Bindeglied zwischen Raum und Diagramm

Der SensorScreen ist einer der wichtigsten Screens der App. Er zeigt alle Sensoren eines Raums an und ermöglicht es dem Benutzer, einen Sensor auszuwählen, um dessen Messwerte zu visualisieren. Die Logik ist klar strukturiert und leicht verständlich.

Der SensorScreen lädt die Sensoren eines Raums über die Datenbankabfrage:

sensors = get_sensors_by_room(room_id)

Für jeden Sensor wird ein Button erzeugt. Wenn der Benutzer auf einen Button klickt, passiert Folgendes:

  1. Der AppState wird aktualisiert: sm.state.current_sensor_id = sid sm.state.current_sensor_name = sname
  2. Der vorherige Screen wird gespeichert: sm.state.previous_screen = sm.current
  3. Die App wechselt zum Diagramm‑Screen: sm.current = "diagrams"

Der Code sieht so aus:

def refresh_sensors(self):
    sensors = get_sensors_by_room(room_id)
    for sensor_id, name, sensor_type in sensors:
        btn = Button(...)
        def on_release(...):
            sm.state.current_sensor_id = sid
            sm.state.current_sensor_name = sname
            sm.state.previous_screen = sm.current
            sm.current = "diagrams"

Warum ist diese Struktur so effektiv?

  • Die Buttons werden dynamisch erzeugt.
  • Die Navigation ist klar und nachvollziehbar.
  • Der AppState hält alle relevanten Informationen bereit.
  • Der Diagramm‑Screen muss keine Parameter entgegennehmen.

Diese Struktur ist robust und leicht erweiterbar.


3. Der Diagramm‑Screen – Visualisierung der Messwerte

Der Diagramm‑Screen ist das Herzstück der Visualisierung. Er lädt die Messwerte eines Sensors aus der Datenbank und erzeugt ein Diagramm mit Matplotlib. Die Logik ist bewusst einfach gehalten, damit du sie leicht verstehen und später erweitern kannst.

Der Diagramm‑Screen liest die Sensorinformationen aus dem AppState:

sensor_id = state.current_sensor_id
sensor_name = state.current_sensor_name or "Diagramm"

Wenn kein Sensor ausgewählt wurde, wird kein Diagramm angezeigt.

Das Laden des Diagramms

Der Diagramm‑Screen ruft den diagram_service auf:

path = create_sensor_diagram(sensor_id, sensor_name)

Wenn ein Fehler auftritt, wird das Diagramm zurückgesetzt:

except Exception as e:
    self.ids.diagram_image.source = ""
    return

Anschließend wird das Bild neu geladen:

self.ids.diagram_image.source = path
self.ids.diagram_image.reload()

4. Der DiagrammService – Matplotlib in Kivy integrieren

Der DiagrammService ist für die Erstellung der Diagramme verantwortlich. Er verwendet Matplotlib, um ein einfaches Liniendiagramm zu erzeugen. Die Diagramme werden transparent gespeichert, damit sie sich gut in das UI einfügen.

Der Code sieht so aus:

fig, ax = plt.subplots(figsize=(6, 3), dpi=100)
ax.plot(timestamps, values, color=color, linewidth=1.8)
fig.savefig(path, transparent=True)

Warum transparente Diagramme?

  • Sie passen sich dem Hintergrund an.
  • Sie wirken moderner und leichter.
  • Sie lassen sich besser in dunkle Themes integrieren.

Farbwahl basierend auf dem Sensortyp

Der DiagrammService wählt die Farbe basierend auf dem Sensornamen:

color = "blue" if "feuchte" in sensor_name.lower() else "red"

Das ist eine einfache, aber effektive Methode, um die Diagramme visuell zu unterscheiden.

5. Die Rolle des AppState im Diagramm‑Screen

Der AppState spielt im Diagramm‑Screen eine zentrale Rolle. Er sorgt dafür, dass der Diagramm‑Screen immer weiß, welcher Sensor gerade ausgewählt wurde. Ohne den AppState müsstest du die Sensorinformationen beim Wechsel des Screens übergeben — das wäre fehleranfällig und würde die Screens enger miteinander verknüpfen.

Mit dem AppState ist das viel einfacher:

  • Der SensorScreen setzt die Sensorinformationen.
  • Der DiagrammScreen liest sie aus.
  • Der OutdoorScreen setzt die Zone.
  • Der RoomScreen liest sie aus.

Diese Struktur ist robust und leicht erweiterbar.

6. Fehlerbehandlung im Diagramm‑Screen

Die Fehlerbehandlung im Diagramm‑Screen ist bewusst einfach gehalten. Wenn ein Fehler auftritt, wird das Diagramm zurückgesetzt:

except Exception as e:
    self.ids.diagram_image.source = ""
    return

Das ist wichtig, weil die Diagrammerstellung fehlschlagen kann, wenn:

  • keine Messwerte vorhanden sind
  • der Sensor keine Daten hat
  • die Datenbank leer ist

Durch die einfache Fehlerbehandlung bleibt die App stabil und reagiert vorhersehbar.

7. Die Navigation zurück – previous_screen

Der previous_screen im AppState sorgt dafür, dass du jederzeit zurückspringen kannst. Der Diagramm‑Screen verwendet ihn, um den vorherigen Screen wiederherzustellen:

prev = self.manager.state.previous_screen
if prev:
    self.manager.current = prev

Das ist eine einfache, aber effektive Methode, um eine konsistente Navigation zu gewährleisten.

8. Warum diese Struktur so stabil ist

Die Kombination aus:

  • ScreenManager
  • AppState
  • klaren Datenbankabfragen
  • sauberer Trennung von Logik und Layout
  • einfacher Fehlerbehandlung
  • dynamischer UI‑Erzeugung

macht die App extrem stabil. Du kannst sie problemlos erweitern, ohne die bestehende Struktur zu gefährden.

Fazit: Die Navigation und Visualisierung sind bereit für die nächsten Schritte

Nach diesem Artikel verstehst du:

  • wie die Navigation funktioniert
  • wie der SensorScreen aufgebaut ist
  • wie der DiagrammScreen Diagramme erzeugt
  • wie der DiagrammService arbeitet
  • wie der AppState alle Screens verbindet
  • warum die App so stabil läuft

Damit bist du perfekt vorbereitet für Artikel 4, in dem du die Außensensoren und die Zonenlogik im Detail betrachtest.

Veröffentlicht in Uncategorized.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Mit der Nutzung dieses Formulars erklärst du dich mit der Speicherung und Verarbeitung deiner Daten durch die Website einverstanden.