Antworten
Mai 29, 2017 - 14:37
1. Darstellung in der App, was zur Zeit läuft bzw laufen wird
Um die Daten darstellen zu können muss ich die Daten extern aufbereiten und ein Webseiten-Element im NEO zu Hilfe nehmen.
Auf meiner NAS läuft ein Web-Server, in dem ich ein entsprechendes PHP-Script ablegen kann. Je nach Webserver liegen die Scripte an unterschiedlichen Stellen - muss man schauen, was machbar ist.
Ich habe an dieser Stelle PHP verwendet, weil es in diesem Umfeld weit verbreitet ist und gut mit URL-Aufrufen sowie JSON umgehen kann.
Der Trick ist, das der Output des Scriptes den HTML-Code produziert, der dargestelt werden soll. Den HTML-Code, den ich erzeuge, ist sicherlich für einen HTML-Fachmann ein Graus, da bin ich nicht ganz so Zuhause.
Das Script ist etwas länglich, weil ich die Daten nach verschiedenen Kriterien aufbereite, ich nehme aber an, da kann jeder sich das auf das wesentlich reudzieren.
Die URL ist die komplette URL zu dem Script, also "https:///hydrawise_today.php"
Und so sieht es aus ...
Um die Daten darstellen zu können muss ich die Daten extern aufbereiten und ein Webseiten-Element im NEO zu Hilfe nehmen.
Auf meiner NAS läuft ein Web-Server, in dem ich ein entsprechendes PHP-Script ablegen kann. Je nach Webserver liegen die Scripte an unterschiedlichen Stellen - muss man schauen, was machbar ist.
Ich habe an dieser Stelle PHP verwendet, weil es in diesem Umfeld weit verbreitet ist und gut mit URL-Aufrufen sowie JSON umgehen kann.
Der Trick ist, das der Output des Scriptes den HTML-Code produziert, der dargestelt werden soll. Den HTML-Code, den ich erzeuge, ist sicherlich für einen HTML-Fachmann ein Graus, da bin ich nicht ganz so Zuhause.
Das Script ist etwas länglich, weil ich die Daten nach verschiedenen Kriterien aufbereite, ich nehme aber an, da kann jeder sich das auf das wesentlich reudzieren.
$api_key = "xxxx-xxxx-xxxx-xxxx";
$url = "https://app.hydrawise.com/api/v1/statusschedule.php?api_key=$api_key";
# Sortierfunkion: nach nächstem geplantem Vorgang
# Format des Zeitstempels: "Tue, 30th May 11:00am"
function cmp_relays_nextrun($a, $b)
{
$tm = date_create_from_format("D, j* F g:ia", $a->nicetime);
if ( $tm )
$a_nextrun = $tm->format('U');
else
$a_nextrun = 0;
$tm = date_create_from_format("D, j* F g:ia", $b->nicetime);
if ( $tm )
$b_nextrun = $tm->format('U');
else
$b_nextrun = 0;
if ($a_nextrun != $b_nextrun)
return ($a_nextrun < $b_nextrun) ? -1 : 1;
$a_relay = $a->relay;
$b_relay = $b->relay;
if ($a_relay == $b_relay)
return 0;
return ($a_relay < $b_relay) ? -1 : 1;
}
# Sortierfunkion: nach letztem durchgeführtem Vorgang
# Format des Zeitstempels: "6 hours 22 minutes ago"
function cmp_relays_lastrun($a, $b)
{
$a_lastrun = strtotime($a->lastwater);
$b_lastrun = strtotime($b->lastwater);
if ($a_lastrun != $b_lastrun)
return ($a_lastrun < $b_lastrun) ? -1 : 1;
$a_relay = $a->relay;
$b_relay = $b->relay;
if ($a_relay == $b_relay)
return 0;
return ($a_relay < $b_relay) ? -1 : 1;
}
# Sekunden in lesbares Format umwandeln
function calc_duration($sec)
{
$duration = "";
if ( $sec > 3600 ) {
$duration .= sprintf("%dh", floor($sec / 3600));
$sec = $sec % 3600;
}
if ( $sec > 60 ) {
$duration .= sprintf("%dm", floor($sec / 60));
$sec = $sec % 60;
}
if ( $sec > 0 ) {
$duration .= sprintf("%ds", $sec);
$sec = floor($sec);
}
return $duration;
}
# Zeitzone setzen
date_default_timezone_set("Europe/Berlin");
# URL holen
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$cdata = curl_exec($ch);
curl_close($ch);
# HTML-Seite beginnen
echo "\n";
echo " \n";
echo "!\n";
echo " \n";
echo "!\n";
if ($cdata) {
# JSON decodieren
$jdata = json_decode($cdata);
if ($jdata) {
# Daten des Controllers
$controller_id = $jdata->controller_id;
$customer_id = $jdata->customer_id;
$user_id = $jdata->user_id;
$nextpoll = $jdata->nextpoll;
$message = $jdata->message;
$obs_rain = $jdata->obs_rain;
$obs_rain_week = $jdata->obs_rain_week;
$obs_maxtemp = $jdata->obs_maxtemp;
$obs_rain_upgrade = $jdata->obs_rain_upgrade;
$obs_rain_text = $jdata->obs_rain_text;
$obs_currenttemp = $jdata->obs_currenttemp;
$watering_time = $jdata->watering_time;
$water_saving = $jdata->water_saving;
$last_contact = $jdata->last_contact;
$status = $jdata->status;
$name = $jdata->name;
# HTML-Ausgabe
$now = date('d.m. H:i', time());
echo "Stand: $now, Status: $status
\n";
# eventuelle Sensoren
$sensors = $jdata->sensors;
if ( count($sensors) > 0 ) {
foreach ($sensors as $i => $value) {
$input = $sensors[$i]->input;
$type = $sensors[$i]->type;
$mode = $sensors[$i]->mode;
$relays = $sensors[$i]->relays;
$relay_ids = "";
foreach ($relays as $j => $v) {
$id = $relays[$i]->id;
if ( $relay_ids != "" ) {
$relay_ids .= ",";
}
$relay_ids .= $id;
}
}
}
# Wettervorschau
$forecast = $jdata->forecast;
if ( count($forecast) > 0 ) {
foreach ($forecast as $i => $value) {
$temp_hi = $forecast[$i]->temp_hi;
$temp_lo = $forecast[$i]->temp_lo;
$conditions = $forecast[$i]->conditions;
$day = $forecast[$i]->day;
$pop = $forecast[$i]->pop;
$humidity = $forecast[$i]->humidity;
$wind = $forecast[$i]->wind;
}
}
# Namen der Zonen/Ventile (relay) merken
$relay2name = "";
$relays = $jdata->relays;
if ( count($relays) > 0 ) {
foreach ($relays as $i => $value) {
$relay2name[$relays[$i]->relay_id] = $relays[$i]->name;
}
}
# aktuell durchgeführte Bewässerung
$relay2running = "";
$running = $jdata->running;
if ( count($running) > 0 ) {
$b = 0;
foreach ($running as $i => $value) {
$relay_id = $running[$i]->relay_id;
$relay = $running[$i]->relay;
$time_left = $running[$i]->time_left;
$run = $running[$i]->run;
$water = $running[$i]->water;
$water_int = $running[$i]->water_int;
$water_unit = $running[$i]->water_unit;
$duration = calc_duration($time_left);
$name = $relay2name[$relay_id];
$relay2running[$relay_id] = 1;
if ( ! $b ) {
# HTML-Ausgabe: Titel, Kopf der Tabelle
echo "derzeitige Bewässerung\n";
echo "\n";
# Spaltenbreite der letzten / beiden letzten Spalten (siehe oben '#spalte_rest' ...)
echo " \n";
echo " \n";
# Spaltenüberschriften
echo "\n";
echo "\n";
echo "Bezeichnung \n";
echo "Restdauer \n";
echo " \n";
echo "\n";
echo "\n";
$b = 1;
}
# HTML-Ausgabe: Datenzeilen der Tabelle
echo "\n";
echo "$name \n";
echo "$duration \n";
echo " \n";
}
if ( $b ) {
# HTML-Ausgabe: Ende der Tabelle
echo " \n";
echo "
\n";
}
}
# Status der Zonen (relays)
$relays = $jdata->relays;
if ( count($relays) > 0 ) {
# was kommt heute noch?
$b = 0;
usort($relays, "cmp_relays_nextrun");
foreach ($relays as $i => $value) {
$relay_id = $relays[$i]->relay_id;
$relay = $relays[$i]->relay;
$name = $relays[$i]->name;
$lastwater = $relays[$i]->lastwater;
$time = $relays[$i]->time;
$type = $relays[$i]->type;
$run = $relays[$i]->run;
$run_seconds = $relays[$i]->run_seconds;
$nicetime = $relays[$i]->nicetime;
$suspended = $relays[$i]->suspended;
$message = $relays[$i]->message;
$nextrun = "";
$nextrun_date = "";
$is_today = 0;
$tm = date_create_from_format("D, j* F g:ia", $nicetime);
if ( $tm ) {
$nextrun = $tm->format('d.m.Y H:i');
$nextrun_time = $tm->format('H:i');
if ( $tm->format('d.m.Y') == date('d.m.Y', time()) )
$is_today = 1;
}
if ( ! $is_today )
continue;
if ( ! $b ) {
echo "heute noch geplante Bewässerung\n";
echo "\n";
echo " \n";
echo " \n";
echo " \n";
echo "\n";
echo "\n";
echo "Bezeichnung \n";
echo "Zeit \n";
echo "Dauer \n";
echo " \n";
echo "\n";
echo "\n";
$b = 1;
}
$duration = calc_duration($run_seconds);
echo "\n";
echo "$name \n";
echo "$nextrun_time \n";
echo "$duration \n";
echo " \n";
}
if ( $b ) {
echo " \n";
echo "
\n";
}
# was war heute?
$b = 0;
usort($relays, "cmp_relays_lastrun");
foreach ($relays as $i => $value) {
$relay_id = $relays[$i]->relay_id;
$relay = $relays[$i]->relay;
$name = $relays[$i]->name;
$lastwater = $relays[$i]->lastwater;
$time = $relays[$i]->time;
$type = $relays[$i]->type;
$run = $relays[$i]->run;
$run_seconds = $relays[$i]->run_seconds;
$nicetime = $relays[$i]->nicetime;
$suspended = $relays[$i]->suspended;
$message = $relays[$i]->message;
$lastrun = "";
$lastrun_time = "";
$is_today = 0;
$ts = strtotime($lastwater);
if ( $ts ) {
$lastrun = date('d.m.Y H:i', $ts);
$lastrun_time = date('H:i', $ts);
if ( date('d.m.Y', $ts) == date('d.m.Y', time()) )
$is_today = 1;
}
if ( ! $is_today )
continue;
$is_running = $relay2running[$relay_id];
if ( $is_running )
continue;
if ( ! $b ) {
echo "heute bereits durchgeführte Bewässerung\n";
echo "\n";
echo " \n";
echo " \n";
echo " \n";
echo "\n";
echo "\n";
echo "Bezeichnung \n";
echo "Zeit \n";
echo "Dauer \n";
echo " \n";
echo "\n";
echo "\n";
$b = 1;
}
$duration = calc_duration($run_seconds);
echo "\n";
echo "$name \n";
echo "$lastrun_time \n";
echo "$duration \n";
echo " \n";
}
if ( $b ) {
echo " \n";
echo "
\n";
}
# was kommt in den nächsten Tagen
$b = 0;
usort($relays, "cmp_relays_nextrun");
foreach ($relays as $i => $value) {
$relay_id = $relays[$i]->relay_id;
$relay = $relays[$i]->relay;
$name = $relays[$i]->name;
$lastwater = $relays[$i]->lastwater;
$time = $relays[$i]->time;
$type = $relays[$i]->type;
$run = $relays[$i]->run;
$run_seconds = $relays[$i]->run_seconds;
$nicetime = $relays[$i]->nicetime;
$suspended = $relays[$i]->suspended;
$message = $relays[$i]->message;
$nextrun = "";
$nextrun_date = "";
$is_today = 0;
$tm = date_create_from_format("D, j* F g:ia", $nicetime);
if ( $tm ) {
$nextrun = $tm->format('d.m.Y H:i');
$nextrun_date = $tm->format('d.m. H:i');
if ( $tm->format('d.m.Y') == date('d.m.Y', time()) )
$is_today = 1;
}
if ( $is_today )
continue;
if ( ! $b ) {
echo "demnächst geplante Bewässerung\n";
echo "\n";
echo " \n";
echo " \n";
echo " \n";
echo "\n";
echo "\n";
echo "Bezeichnung \n";
echo "Zeitpunkt \n";
echo "Dauer \n";
echo " \n";
echo "\n";
echo "\n";
$b = 1;
}
$duration = calc_duration($run_seconds);
echo "\n";
echo "$name \n";
echo "$nextrun_date \n";
echo "$duration \n";
echo " \n";
}
if ( $b ) {
echo " \n";
echo "
\n";
}
}
}
}
echo "
\n";
echo " \n";
echo " \n";
exit(0);
In dem ist das Webseiten-Element eingebaut (mit maximaler Größe)Die URL ist die komplette URL zu dem Script, also "https://
Und so sieht es aus ...
Mai 29, 2017 - 14:47
2. Überwachung, ob der Server läuft.
Hierzu habe ich eine Gateway-Variable "Hydrawise_Status" angelegt
Dann haben ich im Automation Manager ein Script geschrieben. Hier wird JavaScript verwendet - ist etwas anders, aber man kann die Ähnlichkeiten erkennen.
In Abhängigkeit von dem ermittelten Daten wird die Gateway-Systemvariable "Hydrawise_Status" gesetzt.
Und dann haben ich im Blockeditor den Aufruf des Scriptes realisiert und die Abfrage der Variable "Hydrawise_Status"
Ich habe den Fehlerfall (noch) nicht provoziert, aber sollte klappen. Die Variable wird auf jeden Fall richtig gesetzt und wird in dem o.g. Screnn angezeigt.
Das ist ein einfaches Feld
mit der Variablen-Zuweisung
und einer Status-Regel
Hierzu habe ich eine Gateway-Variable "Hydrawise_Status" angelegt
Dann haben ich im Automation Manager ein Script geschrieben. Hier wird JavaScript verwendet - ist etwas anders, aber man kann die Ähnlichkeiten erkennen.
In Abhängigkeit von dem ermittelten Daten wird die Gateway-Systemvariable "Hydrawise_Status" gesetzt.
var api_key = "xxxx-xxxx-xxxx-xxxx";
var url = "https://app.hydrawise.com/api/v1/statusschedule.php?api_key=" + api_key;
var http = require('https');
var req = http.get(url, function(res) {
var body = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
body += String(chunk);
});
res.on('end', function() {
var jsObject = JSON.parse( body );
var status = jsObject.status;
if (status == "All good!") {
executeDeviceCommand(
"Gateway",
"Hydrawise_Status",
{"value":"setValue","ext":"ok"},
function(err) {
err && console.error(err);
});
} else {
executeDeviceCommand(
"Gateway",
"Hydrawise_Status",
{"value":"setValue","ext":"fail"},
function(err) {
err && console.error(err);
});
}
});
});
Und dann haben ich im Blockeditor den Aufruf des Scriptes realisiert und die Abfrage der Variable "Hydrawise_Status"
Ich habe den Fehlerfall (noch) nicht provoziert, aber sollte klappen. Die Variable wird auf jeden Fall richtig gesetzt und wird in dem o.g. Screnn angezeigt.
Das ist ein einfaches Feld
mit der Variablen-Zuweisung
und einer Status-Regel
Von
Sieht schon gut aus :)
Neuen Kommentar hinzufügen