Moin,
vielleicht könnt ihr mir helfen, ich verzweifel langsam. Ich möchte einen Webserver auf Verfügbarkeit prüfen. Es geht speziell um den http Dienst, der auf unterschiedlichen ports läuft, also ein ping reicht nicht.
Im Prinzip möchte ich wissen ob z.B. 192.168.10.24:8080 den Webdienst bereitstellt.
Mein Ansatz war mit Curl die Seite zu laden. Der Return Code von Curl wenn die Seite erreichbar ist, ist 0. Es gibt aber immer nur -1 aus. Vollkommen egal was in system() steht. Gibt es nen anderen Befehl der mir die Return codes richtig übergibt? Oder gibts einen kompett anderen Ansatz?
define Webservice.status at +*00:00:10 {\
my $ret = system("/usr/bin/curl --silent -o /dev/null http://10.0.78.201:32400");;\
if ($ret > 0){\
$ret = "OFFLINE";;\
} else {\
$ret = "ONLINE";;\
}\
fhem("set PrPLEX $ret");;\
}
Vielen Dank
Petz
Zitat von: Meister_Petz am 10 Januar 2018, 09:44:57
Gibt es nen anderen Befehl der mir die Return codes richtig übergibt?
qx() ist dein Freund -> https://forum.fhem.de/index.php/topic,77991.0.html
Hatte ich auch schon getestet...
define Webservice.status at +*00:00:10 {\
my $ret = qx("/usr/bin/curl --silent -o /dev/null http://10.0.78.201:32400");;\
fhem("set Webservice $ret");;\
}
das generiert folgenden Eintrag im Log:
Webservice.status: no set value specified
sieht für mich aus, als ob qx nichts ausspuckt
Hi,
qx gibt die Standardausgabe zurück, die Du aber mit -o /dev/null "abgeschaltet" hast. Das, was Du willst, dürfte eher mit system gehen. Wenn das -1 zurückgibt, dann laut perldoc:
Zitat
Return value of -1 indicates a failure to start the program or an error of the wait(2) system call (inspect $! for the reason).
...am besten, Du schaust Dir also mal an, was in $! steht.
Gruß,
Thorsten
oder nutze ein httpmod device. da kannst du zb den header checken. ist ausserdem non blocking.
Moin,
in $! steht "Keine Kind-Prozesse". Es ist mir aber extrem Schleierhaft, was das zu bedeuten hat. Wenn ich ein kleines perl script im terminal ausführe mit folgendem Inhalt klappt alles ohne Probleme:
$ret = system("curl --silent -o /dev/null http://10.0.78.201:32400");
print "$ret\n";
in perl klappt das selbe in dieser form nicht
define PrPLEX.getstatus at +*00:00:10 {\
my $ret = system("/usr/bin/curl --silent -o /dev/null http://10.0.78.201:32400");;\
fhem("set PrPLEX $ret");;\
}
httpmod hab ich auch schon angeschaut, da muss ich aber gestehen, dass ich das noch nicht ganz verstehe.
kann mir vielleicht jemand mit httpmod weiterhelfen?
So weit komm ich ;-)
define testHTTP HTTPMOD http://10.0.78.201:32400/web/index.html 10
lädt auch brav eine seite, aber wie bekomme ich einen header in das reading?
Gruß und vielen Dank
Petz
reading01Name header
reading01Regex (?s)(.*)
mit diesen attributen bekommst du ein reading mit namen header, in dem alles erscheint.
du musst die regex entsprechend anpassen, um nur bestimmte teile zu bekommen. oder auch auf mehrere readings verteilen.
ok, einen Schritt weiter. Jetzt hab ich aber das Problem, dass sich der Wert nicht ändert, wenn der Webserver gar nicht antwortet
zb hiermit:
Zitatreplacing reading values when they have not been updated / the device did not respond
If a device does not respond then the values stored in readings will keep the same and only their timestamp shows that they are outdated. If you want to modify reading values that have not been updated for a number of seconds, you can use the attributes
(reading|get)[0-9]*(-[0-9]+)?MaxAge
(reading|get)[0-9]*(-[0-9]+)?MaxAgeReplacementMode
(reading|get)[0-9]*(-[0-9]+)?MaxAgeReplacement
Every time the module tries to read from a device, it will also check if readings have not been updated for longer than the MaxAge attributes allow. If readings are outdated, the MaxAgeReplacementMode defines how the affected reading values should be replaced. MaxAgeReplacementMode can be text, expression or delete.
MaxAge specifies the number of seconds that a reading should remain untouched before it is replaced.
MaxAgeReplacement contains either a static text that is used as replacement value or a Perl expression that is evaluated to give the replacement value. This can be used for example to replace a temperature that has not bee updated for more than 5 minutes with the string "outdated - was 12":
attr PM readingMaxAge 300
attr PM readingMaxAgeReplacement "outdated - was " . $val
attr PM readingMaxAgeReplacementMode expression
The variable $val contains the value of the reading before it became outdated.
If the mode is delete then the reading will be deleted if it has not been updated for the defined time.
If you want to replace or delete a reading immediatley if a device doid not respond, simply set the maximum time to a number smaller than the update interval. Since the max age is checked after a HTTP request was either successful or it failed, the reading will always contain the read value or the replacement after a failed update.
und/oder setze attr showError und werte das reading/event LAST_ERROR aus.
Hi,
ich habe da irgendwo mal so einen simplen Statusmonitor gefunden. Als Sub in 99_myUtils
ServiceMonitor($$)
{
my ($host, $port) = @_;
my $status;
# Create a new ping object
my $p = Net::Ping->new("syn");
$p->port_number($port);
$p->ping($host,10);
# perform the ping
if ( $p->ack ) {
$status = 1;
}
else{
$status = 0;
}
# close our ping handle
$p->close();
return $status;
}
Das Ganze als Presence Device define ServerStatus PRESENCE function {ServiceMonitor("FQDN","Portnummer")}
Da hat man natürlich nur "vorhanden" geprüft und keinen Inhalt.
Gruß Otto
So, nun hab ichs! Vielen Dank an alle!
Anbei die finale Lösung, vielleicht hilft es ja mal jemandem:
Ich suche alle 5 Minuten im HTTP Code nach "HTTP" bzw. reduziere auf "HTTP" mit (?s)(.*?)/
Das ist der Anfang des HTTP Codes:
HTTP/1.1 200 OK Cache-Control: no-cache Accept-Ranges: bytes Connection: close Content-Length: 4154 Content-Type: text
Wenn "HTTP" vorhanden, setze ich das userreading Presence auf ONLINE, sonst OFFLINE
Und hier das komplette Device
define CHECKSERVER HTTPMOD http://www.webserver.de/index.html 300
attr CHECKSERVER userattr reading01MaxAge reading01Name reading01Regex
attr CHECKSERVER userReadings Presence
attr CHECKSERVER reading01MaxAge 10
attr CHECKSERVER reading01Name header
attr CHECKSERVER reading01Regex (?s)(.*?)/
define CHECKSERVERchange notify CHECKSERVER.header:.* {\
my $hdr = ReadingsVal("CHECKSERVER","header",0);;\
my $status;;\
if ($hdr eq "HTTP"){\
$status = "ONLINE";;\
} else {\
$status = "OFFLINE";;\
}\
fhem("setreading CHECKSERVER Presence $status");;\
}
userreadings solltest du dir aber mal richtig anschauen. ;)
dein konstrukt ist eher "von-hinten-durch-die-brust-ins-auge".
sicher, dass das funktioniert?
ausserdem würde ich die "200" überwachen, um andere fehler ebenfalls zu berücksichtigen.
Zitat von: frank am 11 Januar 2018, 17:04:37
userreadings solltest du dir aber mal richtig anschauen. ;)
dein konstrukt ist eher "von-hinten-durch-die-brust-ins-auge".
stimmt :) , @Meister_Petz das notify ist überflüssig du kannst das alles leicht im userreading presence selbst unterbringen :
attr CHECKSERVER userReadings Presence {return (ReadingsVal($NAME,"header","") eq "HTTP") ? "ONLINE" : "OFFLINE";}
Moin folks,
also es funktioniert. Aber ich werde die Vereinfachung gleich noch reinbasteln.
Danke!
Sodala, also nun so:
define CHECKSERVER HTTPMOD http://www.webserver.de/index.html 300
attr CHECKSERVER userattr reading01MaxAge reading01Name reading01Regex
attr CHECKSERVER userReadings Presence
attr CHECKSERVER reading01MaxAge 10
attr CHECKSERVER reading01Name header
attr CHECKSERVER reading01Regex (?s)(.*?)/
attr CHECKSERVER userReadings Presence {return (ReadingsVal($NAME,"header","") eq "HTTP") ? "ONLINE" : "OFFLINE";;}
das hab ich noch eingefügt, damit Nachrichten nur kommen, wenn sich was ändert, oder geht das auch einfacher?
attr CHECKSERVER event-on-change-reading Presence
Hallo
leider habe ich hier ein Problem.
2019.11.13 07:50:34.361 4 : P_ESP_TOR_WEB: GetUpdate called (update)
2019.11.13 07:50:34.365 4 : P_ESP_TOR_WEB: update timer modified: will call GetUpdate in 50.0 seconds at 2019-11-13 07:51:24
2019.11.13 07:50:34.366 4 : P_ESP_TOR_WEB: AddToQueue adds update, initial queue len: 0
2019.11.13 07:50:34.366 5 : P_ESP_TOR_WEB: AddToQueue adds type update to URL http://192.168.0.143, no data, no headers, retry 0
2019.11.13 07:50:34.367 5 : P_ESP_TOR_WEB: HandleSendQueue called, qlen = 1
2019.11.13 07:50:34.368 4 : P_ESP_TOR_WEB: HandleSendQueue sends request type update to URL http://192.168.0.143, No Data, No Header timeout 2
2019.11.13 07:50:34.368 5 : HttpUtils url=http://192.168.0.143
2019.11.13 07:50:34.369 3 : P_ESP_TOR_WEB: Read callback: Error: http://192.168.0.143: malformed or unsupported URL
2019.11.13 07:50:34.369 4 : P_ESP_TOR_WEB: Read callback: request type was update retry 0, body empty
2019.11.13 07:50:34.369 5 : P_ESP_TOR_WEB: ExtractSid called, context reading, num
2019.11.13 07:50:34.369 5 : P_ESP_TOR_WEB: MaxAge: check reading Presence
2019.11.13 07:50:34.369 5 : P_ESP_TOR_WEB: MaxAge: reading Presence doesn't come from a -Name attr -> skipping
2019.11.13 07:50:34.370 4 : P_ESP_TOR_WEB: CheckAuth decided no authentication required
defmod P_ESP_TOR_WEB HTTPMOD http://192.168.0.143 50
attr P_ESP_TOR_WEB userattr reading01MaxAge reading01Name reading01Regex
attr P_ESP_TOR_WEB oldreadings state
attr P_ESP_TOR_WEB reading01MaxAge 10
attr P_ESP_TOR_WEB reading01Name header
attr P_ESP_TOR_WEB reading01Regex (?s)(.*?)/
attr P_ESP_TOR_WEB userReadings Presence {return (ReadingsVal($NAME,"header","") =~ "HTTP") ? "ONLINE" : "OFFLINE";;}
Wie kann ich denn die website Antwort überprüfen?
curl -ivs http://192.168.0.143
* Rebuilt URL to: http://192.168.0.143/
* Trying 192.168.0.143...
* TCP_NODELAY set
* Connected to 192.168.0.143 (192.168.0.143) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.0.143
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 302
HTTP/1.1 302
< Location: /login
Location: /login
* Connection #0 to host 192.168.0.143 left intact
Danke VG T