Diese Seite ist Teil des Projekts Automatische Gewächshauslüftung.

Die Android App habe ich mit App Inventor entwickelt. App Inventor ist ein vom MIT entwickeltes grafisches Online-Entwicklungssystem. Der Vorteil ist: App Inventor ist ein grafisches Online-Entwicklungssystem, der Nachteil ist: App Inventor ist ein grafisches Online-Entwicklungssystem. Im Prinzip wird eine App-Oberfläche aus den angebotenen Komponenten zusammengeklickt. Zu den benutzten Komponenten müssen dann die betreffenden Ereignisroutinen (Eventhandler) ebenfalls zusammengeklickt werden.

Die wichtigsten Gründe für die Entscheidung für App Inventor waren:

Bei der Arbeit mit dem App Inventor hat sich ergeben:

Das App Inventor-Projekt und das erstellte Android Application Package können hier heruntergeladen werden.


Konzept

Eine Applikation die keinen Programmfluss kennt, sondern immer nur auf Ereignisse reagiert, wie es bei einer Android App der Fall ist, entwickelt man am besten, indem man sich ein Screen-Layout entwirft und dessen Verhalten über einen endlichen Automaten (state machine) festlegt.

Die Applikation soll:

Screen-Layout
Zustandsautomat
Applikation


Screen-Layout

Die Struktur des Bildschirmaufbaus spiegelt die im Abschnitt Konzept gemachten Anforderungen wieder. Er besteht aus drei Blöcken:

Titel der App
Verbindungsstatus
Anzeige der aktuellen Werte
Anzeige und Eingabe der Steuerparameter
Moduseinstellung / manuelle Lüftersteuerung
Screenshots
Screenshot der App
 Zustand "Connected"
Screenshot der App
 Zustand "Disconnected"

Der Block zur Zustandsanzeige besteht aus 6 Komponenten:

Zustandsblock  
Zustandsblock

Die HorizontalArrangement-Komponente haConnection fasst diesen Block zusammen.

Die beiden Label Spacer1 und Spacer2 jeweils links und rechts haben beide die Width Fill Parent und zentrieren die drei Image-Komponenten. Damit sie unsichtbar sind, ist TextColor auf None eingestellt.

Das linke Image imgSmartphone und das rechte imgGreenhouse sind fix. Das mittlere Image imgConnection wird jeweils an den aktuellen Status angepasst und ist animiert.

Die Anzeige der aktuellen Werte besteht aus einer Überschrift und vier Blöcken für die einzelnen Werte für aktuelle Temperatur, Luftfeuchtigkeit, Modus und Lüfterstatus:

Block 'Aktuelle Werte'  
Block 'Aktuelle Werte'

Für jeden Wert gibt es eine HorizontalArrangement-Komponente ha..., die den Block zusammenfasst.

Die Blöcke für die numerischen Werte bestehen jeweils aus drei Labeln zur Anzeige des Namens (txt...), des aktuellen Werten (dsp...) und zur Anzeige der Maßeinheit (txt...Unit).

Die Blöcke für die nominalen Werte bestehen jeweils ebenfalls aus drei Labeln zur Anzeige des Namens (txt...), einem Spacer zur Ausrichtung (Spacer...) und zur Anzeige des Zustands (dsp...).

Der Bereich zur Anzeige und Anpassung der Parameter für die Lüftersteuerung besteht aus einer Überschriftenzeile, fünf Blöcken für die numerischen Parameter mit einem Slider zur Anzeige und Einstellung und einem Block mit drei Schaltflächen für die Einstellung des Modus und des Lüfterstatus.

Block 'Steuerparameter' Block 'Steuerparameter'

Für jeden Wert gibt es eine HorizontalArrangement-Komponente ha..., die den Block zusammenfasst.

Die Blöcke für die numerischen Werte bestehen jeweils aus einem Labeln zur Anzeige des Namens (txt...), einem Slider zur Anzeige und Einstellung des aktuellen Werten (sl...) und ein Label zur Anzeige des aktuellen Wertes in numerischer Form (dsp...).

Block 'Steuerparameter' Block 'Steuerparameter' Die drei Schaltflächen werden jeweils durch ein Label getrennt. Diese haben die Width Fill Parent und sorgen für die Zentrierung der Schaltflächen.

Zustandsautomat

Eine ereignisgesteuerte Applikation steuert man am besten durch einen Zustandsautomaten. Zwei Zustände "Disconnected" und "Connected" sind auf Grund des oben gesagten relativ klar. Der dritte Zustand "UpdatePending" sammelt die Anpassungen der Steuerparameter  und sendet alle nach Ablauf einer Latenzzeit geschlossen in einem Block an die Lüftersteuerung. Würde man jede Änderung der Slider übertragen, würden während des Schiebens mehrmals eine Anpassung versandt. Dies ist zum einen unnötig, weil nur die Übertragung des Endstands des Slider übertragen werden muss und zum anderen kann die Steuerung die schnellen Änderungsanforderungen gar nicht verarbeiten. Schließlich müssen die Daten ins EEPROM übertragen werden. 

Zustandsdiagramm
Disconnected
Eine Bluetooth-Verbindung zum Lüftungssteuerung besteht nicht
Symbol 
Auslöser  Initial oder nach einem Übertragungsfehler
GUI sämtliche Bedienelemente sind gesperrt
Entry Verbindung sicher schließen, Timer initialisieren
Do Verbindung herstellen (über Timer getriggert)
Exit -

Connected
Eine Bluetooth-Verbindung zum Lüftungssteuerung besteht
Symbol 
Auslöser  Die  BT-Verbindung wurde hergestellt
GUI sämtliche Bedienelemente sind freigegeben
Entry Timer initialisieren
Do Status abfragen und anzeigen (über Timer getriggert)
Exit -

UpdatePending
Geänderte Steuerparameter müssen übertragen werden
Symbol 
Auslöser  Über einen der Slider wurde ein Steuerparameter geändert
GUI sämtliche Bedienelemente sind freigegeben
Entry Statusabfrage stoppen, Timer initialisieren
Do Auf Ablauf des Timers warten, erneute Parameteränderung startet den Timer erneut
Exit Steuerparameter übertragen

 


Applikation

Im Folgenden wird die Implementierung des Zustandsautomaten und die Besonderheiten der Benutzeroberfläche beschrieben.

Zum Zustandsautomaten gehören

Zur Steuerung der Benutzeroberfläche gehören

Implementierung des Zustandsautomaten
Implementierung der GUI-Komponenten

Projekt-Übersicht

App Inventor Projektübersicht

Felder
GreenhouseMac MAC-Adresse des Bluetooth-Transceivers
State Speicherung des aktuellen Zustands
SlidersEnabled Unterdrückt die Behandlung von PositionChanged-Events der Slider
AnimatedPictures Zweidimensionale Liste zur Referenz auf die Animiation-Icons
AnimationCount Zustandszähler für die Animation
txtModeAuto Textkonstante für Modusanzeige
txtModeMan Textkonstante für Modusanzeige
txtFanOff Textkonstante für Zustandsanzeige Lüfter
txtFanOn Textkonstante für Zustandsanzeige Lüfter
Komponenten
Screen1 Hauptanzeige-Seite
btGreenHouse Bluetooth-Client zur Datenübertragung von und zu der Gewächshaussteuerung
clkDoState Timer zum Anstoßen der Zustandsaktivitäten
ntNotifier Notifier zur Anzeige unvorhergesehener Fehler
clkAnimate Timer zur Steuerung der Animation des Verbindungs-Icons
Eventhandler
Sreen1.Initialize Initialisierung des Zustandsautomaten
Screen1.BackPressed Applikations-Ende
Screen1.ErrorOccurred Fehlerbehandlung
clkDoState.Timer Anstoßen der Zustandsaktivitäten
clkAnimate.Timer  Bildwechsel durchführen
slMaxTemp.PositionChanged Einstellung der maximalen Temperatur wurde geändert
slMinTemp.PositionChanged Einstellung der minimalen Temperatur wurde geändert
slMaxHum.PositionChanged Einstellung der maximalen Luftfeuchtigkeit wurde geändert
slPhaseDuration.PositionChanged Einstellung der Phasendauer wurde geändert
slBtTimeout.PositionChanged Einstellung des Bluetooth-Verbindung-Timeout wurde geändert
btnFanOff.Click Schaltfläche "Lüfter Aus" gedrückt
btnFanOn.Click Schaltfläche "Lüfter An" gedrückt
btnAuto.Click Schaltfläche "Automatische Stuerung" gedrückt
Funktionen
enterConnected Zustand Connected einstellen
enterDisconnected Zustand Disconnected einstellen
enterUpdatePending Zustand UpdatePending einstellen
tryConnect Bluetooth-Verbindung zur Gewächshaussteuerung herstellen
UpdateState Zustandsdaten der Gewächshaussteuerung abrufen und anzeigen
ShowState Zustandsdaten der Gewächshaussteuerung anzeigen
SetSliderValue Position der Slider unter Berücksichtigung der Fließkommaeigenschaft einstellen
Delay Warteschleife
updateParamters Parameteränderungen zur Gewächshaussteuerung übertragen
handlePositionChanged Gemeinsamer Eventhandler für die Slieder

Implementierung des Zustandsautomaten
Implementierung der GUI-Komponenten

Das App Inventor-Projekt und das erstellte Android Application Package können hier heruntergeladen werden.