FHEM Forum

FHEM - Hardware => Server - Linux => Thema gestartet von: CoolTux am 30 Januar 2020, 12:20:01

Titel: Daten zu FHEM pusche
Beitrag von: CoolTux am 30 Januar 2020, 12:20:01
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

Titel: Antw:Daten zu FHEM pusche
Beitrag von: mumpitzstuff am 30 Januar 2020, 12:31:59
Oh cool. Sehr schön. Danke!
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Wernieman am 30 Januar 2020, 14:13:11
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
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Wernieman am 30 Januar 2020, 15:31:10
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)
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Otto123 am 30 Januar 2020, 17:10:42
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
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Wernieman am 30 Januar 2020, 18:29:12
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 ...
Titel: Antw:Daten zu FHEM pusche
Beitrag von: herrmannj am 30 Januar 2020, 21:30:49
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
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Otto123 am 30 Januar 2020, 21:31:52
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)
Titel: Antw:Daten zu FHEM pusche
Beitrag von: herrmannj am 30 Januar 2020, 21:49:10
Lass mal die Klima im rz ausfallen. da können 30 Sekunden viel sein 🤪
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Otto123 am 30 Januar 2020, 21:53:18
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 :)
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Wernieman am 30 Januar 2020, 21:53:32
Dann würde ich aber die Steuerung auf dem gleichen Rechner machen und weniger als 30 Sec ;o)
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Otto123 am 31 Januar 2020, 12:08:16
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
Titel: Antw:Daten zu FHEM pusche
Beitrag von: Wernieman am 31 Januar 2020, 19:46:30
*griins* wir werden richtig Gut .. kannst Du die Schwellwerte nicht in FHEM verwalten?
*DuckUndWeg*
Titel: Antw:Daten zu FHEM pusche
Beitrag von: herrmannj am 31 Januar 2020, 20:35:07
Da reicht doch doch ein mqtt2 device