Zitat von: Wernieman am 30 Januar 2020, 08:21:20
Wen ich wirklich die Werte meines Haussystemes in FHEM brauche, mache ich auch kein Pull sondern mittlerweile ein Push, d.h. der Server sendet die Daten von sich aus. Hat noch den Vorteil, das dieses "Push" Script mit einer angepassten Userberechtigung läuft und wirklich keine Befehle entgegen nimmt ...
Zitat von: mumpitzstuff am 30 Januar 2020, 08:48:05
Gibt es dafür vielleicht irgend etwas fertiges irgendwo? Ich möchte eigentlich nur ein paar wenige Dinge überwachen und sowas wie Grafana oder Prometheus wäre für mich mit Kanonen auf Spatzen schiessen.
Zitat von: CoolTux am 30 Januar 2020, 11:16:52
###############################################################################
#
# Developed with Kate
#
# (c) 2019 Copyright: Marko Oldenburg (marko.oldenburg at araneaconsult dot de)
# All rights reserved
#
#
# This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# any later version.
#
# The GNU General Public License can be found at
# http://www.gnu.org/copyleft/gpl.html.
# A copy is found in the textfile GPL.txt and important notices to the license
# from the author is found in LICENSE.txt distributed with these scripts.
#
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
###############################################################################
use strict;
use warnings;
use POSIX;
use IO::Socket::INET;
##################################################
# Forward declarations
#
sub deconzDaemonSystemctl($$);
sub deconzDaemonState($);
sub sendStateToFHEM();
sub deconzDaemonCpuLast();
##################################################
# Variables:
my $self = {};
$self->{daemons} = ['deconz','deconz-wifi'];
###################################################
# Start the program
my ($arg,$debug,$acount);
return 'Usage status|restart' unless ( scalar(@ARGV) > 0 );
$arg = shift @ARGV;
$debug = 0;
if ( $arg eq 'restart' ) {
deconzDaemonSystemctl('restart',$self->{daemons}->[0]);
deconzDaemonSystemctl('stop',$self->{daemons}->[1]);
}
$acount = 0;
foreach ( @{ $self->{daemons} } ) {
deconzDaemonState($self->{daemons}->[$acount]);
$acount++;
}
deconzDaemonCpuLast() if ( $arg eq 'restart' or $arg eq 'status' );
sendStateToFHEM();
sub deconzDaemonSystemctl($$) {
my ( $ctlCmd, $daemon ) = @_;
system('systemctl ' . $ctlCmd . ' ' . $daemon);
return 0;
}
sub deconzDaemonState($) {
my $daemon = shift;
$self->{daemons}->[$acount] = { daemon => $daemon };
if ( open( STATE, "systemctl status $daemon 2>&1 |" ) ) {
while ( my $line = <STATE> ) {
chomp($line);
print qq($line\n) if ( $debug == 1 );
if ( $line =~ m#^\s+Loaded:\s(\S+)# ) {
$self->{daemons}->[$acount]->{loaded} = $1;
}
elsif ( $line =~ m#^^\s+Active:\s(\S+\s\S+)\s\S+\s(\S+\s\S+\s\S+\s\S+);\s(\S+)# ) {
$self->{daemons}->[$acount]->{active} = $1;
$self->{daemons}->[$acount]->{timestamp} = $2;
$self->{daemons}->[$acount]->{timeago} = $3;
}
}
close(STATE);
}
else {
die "Couldn't use STATE: $!\n";
$self->{daemons}->[$acount]->{error} = 'Couldn\'t use STATE: ' . $;;
return 1;
}
return 0;
}
sub deconzDaemonCpuLast() {
if ( open( STATE, 'ps uax 2>&1 |' ) ) {
while ( my $line = <STATE> ) {
chomp($line);
print qq($line\n) if ( $debug == 1 );
if ( $line =~ m#^marko\s+\d+\s+(\d+.\d*).+\/usr\/bin\/deCONZ# ) {
$self->{daemons}->[0]->{cpuLast} = $1;
}
}
close(STATE);
}
else {
die "Couldn't use STATE: $!\n";
$self->{daemons}->[0]->{error} = 'Couldn\'t use STATE: ' . $;;
return 1;
}
return 0;
}
sub sendStateToFHEM() {
my $fhemDummy = 'dummyDeconzDaemonState';
my $HOSTNAME = "p-fhem02.tuxnet.lan";
my $HOSTPORT = "7072";
my $socket = IO::Socket::INET->new('PeerAddr' => $HOSTNAME,'PeerPort' => $HOSTPORT,'Proto' => 'tcp')
or die 'Cant\'t connect to FHEM Instance';
$acount = 0;
foreach ( @{ $self->{daemons} } ) {
while ( my ( $r, $v ) = each %{$self->{daemons}->[$acount]} ) {
print $socket 'setreading ' . $fhemDummy . ' ' . $self->{daemons}->[$acount]->{daemon} . '_' . $r . ' ' . $v ."\n" if ( $v ne $self->{daemons}->[$acount]->{daemon} );
print $socket 'setreading ' . $fhemDummy . ' state ' . $v ."\n" if ( $r eq 'active' and $self->{daemons}->[$acount]->{daemon} eq 'deconz' );
}
$acount++;
}
$socket->close;
}
Hier mal ein kleines Beispielscript wie man Systemüberwachung an FHEM per Push senden kann.
Sieht in FHEM dann so aus.
Internals:
FUUID 5c645655-f33f-b39c-204e-0043ce79d972bc47
NAME dummyDeconzDaemonState
NR 64
STATE active (running)
TYPE dummy
READINGS:
2019-11-12 20:06:02 deconz-wifi_active active (running)
2019-11-12 20:06:02 deconz-wifi_loaded loaded
2019-11-12 20:06:02 deconz-wifi_timeago 4h
2019-11-12 20:06:02 deconz-wifi_timestamp Tue 2019-11-12 15:21:30 CET
2019-11-12 20:06:02 deconz_active active (running)
2019-11-12 20:06:02 deconz_cpuLast 4.1
2019-11-12 20:06:02 deconz_loaded loaded
2019-11-12 20:06:02 deconz_timeago 6min
2019-11-12 20:06:02 deconz_timestamp Tue 2019-11-12 19:59:04 CET
2019-11-12 20:06:02 state active (running)
Attributes:
alias deCONZ Service Status
event-on-change-reading state,deconz-wifi_active,deconz_cpuLast,.*_timestamp
group deCONZ
room EDV
setList restart:noArg
Oh cool. Sehr schön. Danke!
Habe bei mir ein bash-Script laufen.
Bitte alles mit <...> anpassen. Habe allerdings für diesen Zugang ein eigenes SSL-Telnet-Device mit Passwort angelegt.
Doing:
Zuerst wird alles in der Variablen "fhem" gesammelt, um dann im 2. Stepp alles zu FHEM zu puschen. TimeOut 4 Sekunden, um nicht zu sehr zu blockieren.
Hier im beispiel werden PI Daten gesammelt (CPU Temperatur und SD-Nutzung)
#!/bin/bash
logfile="/var/log/mrtg/daten.log"
# Serverangabe
server="<TollerFhemServer>"
server_port="<TollerFhemPort>"
#Zuerst muss Passwort
fhem="<TollesPasswort>"
#CPU Temperatur
fhem="${fhem}\nsetreading PI Temp $(echo "scale=1; $(cat /sys/class/thermal/thermal_zone0/temp) / 1000" | bc -l)"
# Speicherverbrauch (Bis jetzt sda) auslesen
while read line
do
Device=$(echo ${line} | awk '{print $1}' | sed -e "s/^.*\///g" -e "s/ //g")
Proz=$(echo ${line} | awk '{print $5}' | sed -e "s/%//g" -e "s/ //g")
Benutzt=$(echo ${line} | awk '{print $3}')
fhem="${fhem}\nsetreading PI ${Device}_Prozent ${Proz}"
fhem="${fhem}\nsetreading PI ${Device}_Benutzt ${Benutzt}"
done < <(df -m | grep -v -e tmpfs -e Filesystem -e ":" | tail -n +2)
# Daten an FHEM übergeben
if ping $server -c1 >/dev/null 2>&1
then
echo -en "${fhem}\nquit\n" | /usr/bin/ncat -w5 -4 --ssl $server $server_port >/dev/null
if [ ! "$?" = "0" ]
then
echo "$(date "+%Y-%m-%d/%H:%M:%S") - Fehler beim Datenuebertragen an FHEM-Server $server" >>/var/log/mrtg/daten.log
fi
else
echo "$(date "+%Y-%m-%d/%H:%M:%S") - Kein FHEM-Server $server pingbar" >>/var/log/mrtg/daten.log
fi
irgendwo hatte Otto mal ein Script, um Daten über die Webschnittstelle zu puschen ...
Edit:
Wer suchet der findet
http://heinz-otto.blogspot.com/2019/02/fhem-http-client.html (http://heinz-otto.blogspot.com/2019/02/fhem-http-client.html)
was auch gut geht ist mqtt :)
In der Art als Einzeiler:
while [ true ] ; do mosquitto_pub -h raspib2 -i COMPUTER -t CPU/$(hostname)/temperature -m $(($(</sys/class/thermal/thermal_zone0/temp)/1000)) ; sleep 30 ; done
Gruß Otto
Kann man in MQTT auch mehrere Daten "im Rutsch" Transferieren, oder muß man jedes mal eine Neue Verbindung öffnen?
Btw: 30 Sec. ist für Temperatur des Rechners doch relativ schnell .. würde auf 1m oder länger gehen ...
Klar, der payload kann json sein. Die Werte werden dann in k/v Paare gesteckt. Das mqtt2_device kann beliebig flexibel die Werte entgegen nehmen
Zitat von: Wernieman am 30 Januar 2020, 18:29:12
Btw: 30 Sec. ist für Temperatur des Rechners doch relativ schnell .. würde auf 1m oder länger gehen ...
War doch nur ein Test 8)
Lass mal die Klima im rz ausfallen. da können 30 Sekunden viel sein 🤪
Jörg: es war nur ein Funktionstest - ;D
Die eine Seite ist die Ermittlung des Problems, die andere Seite die Übertragung. Ich wollte nur sagen: Die Übertragung geht mit netcat und Telnet, es geht HTTP und es geht auch mqtt :) :) :)
Und klar per Json geht alles in einem Rutsch :)
Dann würde ich aber die Steuerung auf dem gleichen Rechner machen und weniger als 30 Sec ;o)
So besser? Alle 2 sec aber nur bei Änderung senden :D
Edit: Mit Schwellwert und wahlweise als json
# Schwellwert in c
# oder ohne Schwellwert einfach die Bedingung anders if (( $a != $b ))
c=8
# Strings für mqtt setzen
h="raspib2" #mqtt Server
i="COMPUTER" #CID
r="temperature" #Readingname für json
t="raspi/$(hostname)/temperature" #Topic
# Vergleichswert initialisieren
b=0
while [ true ] ; do
a=$(($(</sys/class/thermal/thermal_zone0/temp)/100))
if (( $a > $(($b+$c)) )) || (( $a < $(($b-$c)) ))
then
# temperature wert direkt
m=$(($a/10))
# oder als json String
#m=$(echo {\"$r\":\"$m\"})
mosquitto_pub -h $h -i $i -t $t -m $m
b=$a
fi
sleep 2
done
Gruß
Otto
*griins* wir werden richtig Gut .. kannst Du die Schwellwerte nicht in FHEM verwalten?
*DuckUndWeg*
Da reicht doch doch ein mqtt2 device