Forum: Haus & Smart Home PHP Programmierung Webseite; Heizungssteuerung, ESP8266


von superflex (Gast)


Lesenswert?

Hallo liebe Community,
ich habe entsprechend dieser Vorlage 
(https://github.com/coolibre/thermomat) alte Heizungssthermostate mit 
ESP8266 smarthome-fähig gemacht.
Das funktioniert auch wunderbar. Die Steuerung erledige ich über eine 
Webseite (auf der die Temperatur eingestellt werden kann), welche eine 
txt-Datei ausspuckt, die entsprechend von den ESP's abgerufen wird.

Im Rahmen einer Erweiterung der Einstellungsmöglichkeiten auf der 
Webseite stoße ich auf folgendes Problem:
Wie kann ich eine eingegebene Uhrzeit (hier Beginn & Ende der Heizzeit) 
mit der aktuellen Uhrzeit vergleichen, um entsprechend den Wert der 
Heiztemperatur oder Nachtabsenkung in die txt-Datei zu schreiben? Meine 
diesbezüglichen Zeilen lauten so:

Einstellen des Beginnes der Heizzeit:
1
<!DOCTYPE html>
2
<html>
3
<head>
4
<body>
5
<form method="post">
6
 Heizzeit: von&nbsp;&nbsp;<input type="time" name="anfang"
7
 value="<?php echo file_get_contents('anfang.txt'); ?>">
8
 <input type="submit" name="submit" value="ändern">
9
</form>
10
<body>

Der nachfolgende Code sollte eigentlich, die eingegebene Zeit mit der 
aktuellen vergleichen und anschließend entsprechend die eine oder andere 
Temperatur in die Txt-Datei schreiben:
1
<?php
2
if (($_POST['anfang']< date ("H:i")) and ($_POST['ende']> date ("H:i")))
3
{ $data=$_POST['warm'];
4
  $fp = fopen('wohnzimmer.txt', 'w');
5
  fwrite($fp, $data);
6
  fclose($fp);
7
  header("Refresh:0");  
8
  }
9
else
10
{ $data=$_POST['kalt'];
11
  $fp = fopen('wohnzimmer.txt', 'w');
12
  fwrite($fp, $data);
13
  fclose($fp);
14
  header("Refresh:0");  
15
  }
16
?>
Leider funktioniert dies jedoch nicht. Da dies nun meine erste 
Programmierung mit html etc. ist, komme ich leider von selbst nicht mehr 
weiter.
Wo liegt mein Fehler?
Vielen Dank für eure Hilfe

LG
Superlex

von Hmmm (Gast)


Lesenswert?

superflex schrieb:
> Wo liegt mein Fehler?

Uhrzeiten kannst Du nicht so einfach vergleichen.

Da es hier nur um Stunden und Minuten geht, einfach alles in Minuten 
umrechnen (also 60*hh+mm) und damit rechnen.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Und dann vor allem gleich mal das Thema Sicherheit erschlagen. 
Ungefilterte Eingaben aus $_POST zu irgendwas zu verwenden ist totaler 
Mist, da kann Dir jeder alles schicken, was Du dann ungefiltert in die 
Datei reinschreibst.

von Sascha W. (sascha-w)


Lesenswert?

@superflex,

dein Konzept scheint mir fragwürdig.
Sollte solche Vergleiche nicht der Thermostat selbst machen? Und wenn's 
nur um die Konfigdatei geht, wieso dann ein Vergleich mit der aktuellen 
Uhrzeit?

Sascha

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Hmmm schrieb:
> superflex schrieb:
>> Wo liegt mein Fehler?
>
> Uhrzeiten kannst Du nicht so einfach vergleichen.
>
> Da es hier nur um Stunden und Minuten geht, einfach alles in Minuten
> umrechnen (also 60*hh+mm) und damit rechnen.

Muss man noch nicht mal von Hand machen, dass gibt es in PHP schon 
fertig:
- https://www.php.net/manual/de/book.datetime.php
1
$date1 = new DateTime("2020-04-01 22:22:22");
2
$date2 = new DateTime("2020-01-01 11:11:11");
3
if ($date1 > $date2)
4
...

von Εrnst B. (ernst)


Lesenswert?

Weitere Fehler(Quellen):

Du verwendest mal "anfang.txt" und mal "wohnzimmer.txt". Sollte das 
dieselbe Datei sein?

und, dein

"if (($_POST['anfang']< date ("H:i")) and ($_POST['ende']> date 
("H:i")))"

hat ein "else", was auch ausgeführt wird, wenn garkein "$_POST" gesetzt 
ist, also z.B. beim "GET", und überschreibt dir dann immer deine 
Datei, ggfs. eben mit nix.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Das könnte so gewollt sein, er überschreibt ja auch jedes Mal den alten 
Inhalt der Datei, ist also kein Logdatei... naja, keine Ahnung was das 
werden soll, aber noch hat sich der TE ja nicht wieder gemeldet.

von superflex (Gast)


Lesenswert?

Hmmm schrieb:
> Da es hier nur um Stunden und Minuten geht, einfach alles in Minuten
> umrechnen (also 60*hh+mm) und damit rechnen.

okay, danke - da liegt wohl der Hauptfehler.

Sascha W. schrieb:
> dein Konzept scheint mir fragwürdig.
> Sollte solche Vergleiche nicht der Thermostat selbst machen? Und wenn's
> nur um die Konfigdatei geht, wieso dann ein Vergleich mit der aktuellen
> Uhrzeit?

nein, das Thermostat (elektrisches Heizkörperventil) soll lediglich die 
eingestellte Temperatur im Raum halten. Der Vergleich mit der Uhrzeit 
erfolgt, damit der ESP sehr lange in den deepsleep kann und lediglich 
kurz seinen Auftrag (entsprechende Temperatur, die er gerade 
einzustellen hat) in Empfang nehmen kann.

Irgend W. schrieb:
> Muss man noch nicht mal von Hand machen, dass gibt es in PHP schon
> fertig:
> - https://www.php.net/manual/de/book.datetime.php

das muss ich mir nochmals näher anschauen =), danke !

Ben B. schrieb:
> Das könnte so gewollt sein, er überschreibt ja auch jedes Mal den alten
> Inhalt der Datei, ist also kein Logdatei

tatsächlich, das ist so gewollt. Es wird eine Heiz-, eine 
Absenkungstemperatur sowie ein Heizbeginn und Endzeit eingestellt, 
jeweils entsprechend dieser Programmierung:


superflex schrieb:
> Einstellen des Beginnes der Heizzeit:<!DOCTYPE html>
> <html>
> <head>
> <body>
> <form method="post">
>  Heizzeit: von&nbsp;&nbsp;<input type="time" name="anfang"
>  value="<?php echo file_get_contents('anfang.txt'); ?>">
>  <input type="submit" name="submit" value="ändern">
> </form>
> <body>
(sorry die Zitierung hat nicht wirklich funktioniert, vgl. bitte ersten 
Beitrag, 1. genannter Code)


Nun soll in einer txt datei die Temperatur ausgespuckt werden, welche 
nun der ESP des Heizkörperventils abruft, und entsprechend die richtige 
Temperatur einstellt.
Die verschiedenen txt-Dateien ('anfang', 'ende', 'warm', 'kalt') sind 
wohl meiner Unwissenheit bzw. Ungeschicklichkeit geschuldet, da ich 
dieses Modell einer anderen Programmierung abkupfern konnte :D, wenn es 
andere einfachere Wege gibt den value entsprechend vorzubesetzen, ohne 
eine txt-Datei zu erzeugen ... Mir schien das erstmal das einfachste für 
mich persönlich zu sein.

Ich habe nun den ersten Tip versucht umzusetzen. Herausgekommen ist 
folgendes:
1
  $date1 = (explode(":",$_POST['anfang']));  
2
  $date2 = (explode(":",$_POST['ende']));
3
  $date3 = date("H:i");
4
  $date4 = (explode (":",$date3));
5
  $zeitaktuell = $date4[0] + ($date4[1] *60);
6
  $zeitanfang = $date1[0] + ($date1[1] * 60);
7
  $zeitende = $date2[0] + ($date2[1] * 60);
8
  
9
    if (($zeitanfang < $zeitaktuell) and ($zeitende > $zeitaktuell))
10
{     $data=$_POST['warm'];
11
    $fp = fopen('wohnzimmer.txt', 'w');
12
    fwrite($fp, $data);
13
    fclose($fp);
14
    header("Refresh:0");  
15
  }
16
else
17
{     $data=$_POST['kalt'];
18
    $fp = fopen('wohnzimmer.txt', 'w');
19
    fwrite($fp, $data);
20
    fclose($fp);
21
    header("Refresh:0");  
22
  }
23
  
24
    
25
?>
Leider habe ich wohl noch nicht alle Fehler gefunden.
LG Superflex

von Ein T. (ein_typ)


Lesenswert?

superflex schrieb:
> Leider habe ich wohl noch nicht alle Fehler gefunden.

Worin äußern sich denn die Fehler? Und was sagt das Error-Log des 
Webservers dazu?

von Ein T. (ein_typ)


Lesenswert?

superflex schrieb:
>     if (($zeitanfang < $zeitaktuell) and ($zeitende > $zeitaktuell))
> {     $data=$_POST['warm'];
>     $fp = fopen('wohnzimmer.txt', 'w');
>     fwrite($fp, $data);
>     fclose($fp);
>     header("Refresh:0");
>   }
> else
> {     $data=$_POST['kalt'];
>     $fp = fopen('wohnzimmer.txt', 'w');
>     fwrite($fp, $data);
>     fclose($fp);
>     header("Refresh:0");
>   }
>
>
> ?>
> [/code]

Ach so, was mir gerade beim schnellen Überfliegen noch aufgefallen ist, 
Du verletzt das DRY-Prinzip (Don't Repeat Yourself). Etwas 
übersichtlicher könnte der Code sein, wenn Du ihn so schreibst:
1
$fp = fopen('wohnzimmer.txt', 'w');
2
if (($zeitanfang < $zeitaktuell) and ($zeitende > $zeitaktuell)) {
3
    $data = $_POST['warm'];
4
  } else {
5
    $data = $_POST['kalt'];
6
  }
7
fwrite($fp, $data);
8
fclose($fp);
9
header("Refresh:0");  
10
?>

Ansonsten sind die Vorschläge anderer Beiträge sehr sinnvoll, also 
erstens die Eingaben zu validieren (!) und zweitens die Klasse DateTime 
zu benutzen. Was mir ebenfalls aufgefallen ist: Deine Daten stehen in 
den Feldern "warm" oder "kalt", aber ist denn garantiert, in welcher der 
POST-Felder die Daten stehen, wenn Deine if-Bedingung zutrifft? Und 
warum stehen die überhaupt in unterschiedlichen Feldern, reicht da nicht 
ein einzelnes Feld? Das erscheint mir ein wenig... suboptimal. ;-)

von Zeno (Gast)


Lesenswert?

Irgend W. schrieb:
> Muss man noch nicht mal von Hand machen, dass gibt es in PHP schon
> fertig:
> - https://www.php.net/manual/de/book.datetime.php1$date1 = new
> DateTime("2020-04-01 22:22:22");
> 2$date2 = new DateTime("2020-01-01 11:11:11");
> 3if ($date1 > $date2)
> 4...

Das ist auch genau der richtige Ansatz. Das DateTime-Object liefert ja 
eine Zahl und die kann man gut vergleichen.

Du solltest Dir mal das Manual zu DateTime anschauen - Google liefert da 
viele Quellen wo es erklärt wird.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.