Hühnerstall SmartHome Steuerung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
unique24
User
Beiträge: 65
Registriert: Donnerstag 5. Juli 2018, 14:51

Hallo,

nachdem ich hier einige Infos Zusammen getragen habe, starte ich nun mit der Software.

Was ich machen möchte
Einen Hühnerstall mit einem Raspberry und kleinen Modulen in ein SmartHome erweitern.
Folgende Funktionen sollen umgesetzt werden:
* automtisches Hühnerstall Türl
* öffnen/schließen des Türls mit der Dämmerung
* Automatische Innenbeleuchtung auf 6 Stufen, falls es nicht mind. 13h lang hell ist (Tageslänge berechnen)
* Temperatur im Stall
* Temperatur außen
* Temperatur des Trinkwassers
* Feuchtigkeit außen
* Feuchtigkeit im Stall
* Futtermittel nachfüllen erkennen
* Webserver um alles per Handy/Web bedienen zu können
* kleines Display am Raspi für div. Infos
* Rauchmelder im Stall
* 5MP 160° Kamera innen

Den Code stelle ich in Github ein und baue auf einer Arbeit eines anderen Github Projektes auf:
https://github.com/fohnbit/CoopControl
(Ich muss erst noch einige Änderungen vor nehmen und lade dann alles hoch)

Was ich bitte als Anfang benötige
Programm läuft in Python3 (logisch :-) )
Eventuelle Einstellungen während der Laufzeit und Programmsettings in je eine YAML Datei

* Webserver soll ich aber welchen einsetzen? Der Pythonserver hat einen TCP Socket, wo alle Infos als JSON abgerufen können (Tür Status, Sensoren, usw). Einstellungen in der Webseite sollen wieder zurück geschrieben werden.
Hier habe ich noch gar nichts ... womit beginnt man da?

Ich schreibe dann alle anfälligen Fragen in diesem Thread.

Vielen Dank für Eure Mithilfe!
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Zum Code server.py im verlinkten Repository: *-Importe sind böse, mit socket werden da so allgemeine Namen wie `close` oder `error` importiert, was zu seltsamen Effekten führen kann, wenn die schon anderweitig verwendet werden.
Der Unterstrich bei _thread zeigt schon deutlich, dass das nur für den internen Gebrauch gedacht ist und nicht verwendet werden sollte. Statt dessen nimmt man threading, was komischerweise an anderer Stelle auch getan wird.
/tmp ist nicht für log-Dateien gedacht und wenn da irgendwer so allgemeine Dateien wie log.log anlegt, kann das ein ziemliches Durcheinander geben.
Im Rumpf einer Klassendefinition sollte kein komplizierter Programm stehen. Dateien öffenen gehört da nicht rein. Zudem sollten Dateien auch wieder geschlossen werden, am besten mit dem with-Statement. Die Konfigurationen werden aus dem aktuellen Arbeitsverzeichnis gelesen; das ist ungewöhnlich und normalerweise nicht das, was man möchte. Bei yaml-Dateien gilt, immer das Encoding utf8 angeben.
In __init__ stehen eine IP-Adresse und ein Port mitten im Code. Komischerweise wird das nicht über yaml-Dateien gesetzt. Bei bind verwendet man üblicherweise als Adresse ANY also 0.0.0.0. __init__ ist dazu da, dass etwas initialisiert wird, nicht dass es ewig läuft. Die while-Schleife gehört da also nicht rein. Außerdem wird dafür gesorgt, dass sich das Programm nicht per Ctrl+C abbrechen läßt. Was soll das?
An einigen Stellen sind um die if-Bedingungen unnötige Klammern. Methoden werden wie Variablen komplett klein geschrieben. Einige Methoden verwenden `self` gar nicht. Da sollte man sich die Frage stellen, was das für eine Klasse ist und was da nicht rein gehört. Insgesamt scheint mir einfach alle sin eine Klasse gestopft zu sein. Das Design sollte man gründlich überdenken. Mit über 500 Zeilen ist die Klasse auch zu lang.
Benutze keine Abkürzungen. Wenn temperature gemeint ist, dann schreibt man das auch und nicht temp.
In einem Event-Callback sollte man möglichst wenig machen, buttonPress tut zu viel und da aus verschiedensten Threads auf die Steuerung zugegriffen wird, ist nicht garantiert, dass da nicht komische Sachen passieren. Bei Steuerungen sollte es immer eine Hauptschleife geben, aus der alles angesprochen wird. Die Kommandos kommen per Events in die Hauptschleife.
`handler` hat dann den üblichen Fehler, dass ein TCP-Stream als Nachrichtenbus falsch verstanden wird. Da es sich aber um einen Strom handelt, gibt es keine Nachrichtengrenzen, die muß man selbst programmieren, oder auf ein etabliertes Protokoll setzen.

Im Code ist viel vermischt was nicht zusammen gehört, es fehlt eine ordentliche Struktur. Viele Stücke wurden einfach so zusammenkopiert in der Hoffnung, dass es irgendwie funktionieren wird. Tut es meist leider auch, weil die Fehler nicht deterministisch auftreten, meist dann, wenn der Fuchs vor der Tür steht.

Statt also alles auf einmal zu wollen, solltest Du Dich Stück für Stück an Dein Problem herantasten und jedes neue Feature gut testen. Als erstes mach Dich mal mit Event-Handling in der Theorie vertraut. Wenn es nur eine Stelle gibt, die alles steuert, dann ist die Gefahr klein, dass man schwer zu entdeckende Fehler einbaut.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Zusaetzlich zu den richtigen Anmerkungen von Sirius3: GPIOs sollten nicht gepollt, sondern als Ereignisquellen behandelt werden. RPi.GPIO ist veraltet, und sollte durch gpiozero ersetzt werden. Das hat dann auch fuer bestimmte Funktionalitaeten fertige Loesungen, wie zB blinken. Logging sollte nicht hart-kodiert konfiguriert werden, du hast eine Konfigurations-Datei - benutzt die also.
unique24
User
Beiträge: 65
Registriert: Donnerstag 5. Juli 2018, 14:51

Danke für die Tipps .. ich werde mal alles überarbeiten.

Inzwischen ist auch ein cherrypy drinnen (statt des sockets).

Die Verbindung mit der Webseite klappt an sich, aber muss noch ausprogrammiert werden.
JamesS
User
Beiträge: 5
Registriert: Sonntag 1. August 2021, 11:55

Das Projekt ist interessant, deshalb würde mich interessieren ob es weiter geführt wurde oder gestorben ist?
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

und schon mal auf Github nachgeschaut?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
JamesS
User
Beiträge: 5
Registriert: Sonntag 1. August 2021, 11:55

Ja, 5 forks 4 davon sind seit jahre nicht angefasst worden und 1 ist vor 2 monaten bearbeitet worden. Das read me ist bei allen das Originale von vor 6 Jahren und steht nichts wirklich interessantes drin.
Antworten