Presence Funktion für Mikrotik/RouterOS (SNMP) und TP-Link Geräte (WEB)

Begonnen von pipp37, 01 September 2016, 00:52:58

Vorheriges Thema - Nächstes Thema

pipp37

Hallo Markus Bloch.
Ich nutzte das Presence Modul seit einiger Zeit und teile meine Netzwerkerfahrungen gerne hier.

Es wäre super, die SNMP Erkennung in das Presence Modul einzubauen.  Auch die Statuspage eines TP-Link Powerline-Wireless Repeater TL-WPA4220 kann eventuell Einzug in das Modul finden.
Dazu die passenden Attribute für mehrere Hosts wie z.B.:

  • snmp_community
  • snmp_version
  • snmp_host

Mein Code darf gerne dazu verwendet werden.


SNMP Erkennung
Mikrotik unterstützt bei den Geräten SNMP mit MIB´s.
http://www.mikrotik.com/

Die folgende Funktion testet per SNMP die Wireless-Registration-Tables der Devices.
Auch bietet das RouterOS den CAPSMAN an. http://wiki.mikrotik.com/wiki/Manual:CAPsMAN
Damit können mehrere MT-Geräte zentral verwaltet werden. Bei der Abfrage werden beide Tabellen berücksichtigt.
Den initialen Code dafür habe ich aus dem WIKI http://www.fhemwiki.de/wiki/Anwesenheitserkennung.

In der neuen Funktion snmpCheck2 wird auch die DHCP Überwachung der Airport Basestation berücksichtigt.  Ich konnte dies leider nicht testen, weil ich keine besitze.

Bei beiden Funktionen kann ein letzer, optionaler Parameter LOGLEVEL hinzugefügt werden. Standard ist der Level 4.

Zuerst ist folgender Code in 99_myUtils.pl einzufügen:

Hilfsfunktionen:

#########################################################################################################################
# hex mac address (AA:BB:CC:DD:EE:FF) to pointed  decimal values
sub HexMacToDec($)
    {
    my ($in) = @_;
    my @elements=split(/:/,$in);
    my $element;
    my $ret;
    for  $element  (@elements)
        {
        # print ".".hex($element);
        $ret.=hex($element) . "." ;
        }

    chop($ret);
    #{Log 3, ("hexMacToDec:Parameter=@_" . "<".$ret.">")};
    #print("$rethex\n");

    return $ret;
    }

#########################################################################################################################
# hex mac address (AA:BB:CC:DD:EE:FF) to hex value (0x...)
sub HexMacToHex($)
    {
    my ($in) = @_;
    my @elements=split(/:/,$in);
    my $element;
    my $rethex="0x";

    for  $element  (@elements)
        {
        $rethex .= lc($element);
        }

    #print("$rethex\n");

    return $rethex;
    }




define PR_iPhoneSNMP PRESENCE function { snmpCheck2("iPhone-Armin", "192.168.27.254", 1, "public", "3C:07:71:B3:B6:71" ) } 30 120
Dann die neue SNMP Funktion:

#########################################################################################################################
# Function for checking mac addresses with snmp
# Use with presence modul
# (c) armin@pipp.at  8/2016
#
# Syntax: snmpCheck2 <NAME> <HOST> <OID-Index> <COMMUNITY> <AA:BB:CC:DD:EE:FF>  [LOGLEVEL]
# Returns 1 if found
#   <NAME>             Human readable Name only for logs
#   <HOST>             SNMP Host
#   <OID-Index>         0-2
#                  $oidindex
#                  0 = Mikrotik wireless mac table:    .1.3.6.1.4.1.14988.1.1.1.2.1.1
#                  1 = Mikrotik capsman mac table:     .1.3.6.1.4.1.14988.1.1.1.5.1.1
#                  2 = Apple Airport DHCP table:       .1.3.6.1.2.1.3.1.1.2
#   <COMMUNITY>       SNMP read community string (standard=public)
#   <AA:BB:CC:DD:EE:FF> Client MAC Address for the search
#   [LOGLEVEL]         optional / Loglevel (standard=4)
#
# Fhem PRESENCE: define PR_iPhoneSNMP PRESENCE function { snmpCheck2("iPhone-Armin", "192.168.27.254", 1, "public", "3C:07:71:B3:B6:71" ) } 30 120
#
use Net::SNMP;
sub snmpCheck2($$$$$;$)
    {
    my ($NAME,$host,$oidindex,$community,$clientMac,$loglevel)=@_;
   my $log=4;
   if (defined($loglevel))   {$log=$loglevel};
   
    my @oidarray = (".1.3.6.1.4.1.14988.1.1.1.2.1.1", ".1.3.6.1.4.1.14988.1.1.1.5.1.1", ".1.3.6.1.2.1.3.1.1.2");
    #my $community = "public";
    #my $host = $airport;
    #my $oid = ".1.3.6.1.2.1.3.1.1.2";
    #my $oid = ".1.3.6.1.2.1.3.1.1.2.25.1.10.0.1";

    #capsman                              last digit
                                             #1=mac
                                             #3=uptime
    #my $oid = ".1.3.6.1.4.1.14988.1.1.1.5.1.1";

    my $client = HexMacToHex($clientMac);
    my $oid = $oidarray[$oidindex];

   #Log3 $name, 5, "snmpCheck2a ($name)"
    Log $log, ("snmpCheck2: $NAME: Parameter=@_");
   Log $log, ("snmpCheck2: $NAME: Vars: OID-Index=$oidindex / OID=$oid / CheckMacHex=$client");
   
   #print("Host=$host / SNMP-com=$community\n");
    #print("OID-Index=$oidindex / OID=$oid CheckMac=$client\n");
    #print("DezimalMac=" . HexMacToDec($clientMac) . "\n");
    #print("MacToHex=" . HexMacToHex($clientMac) . "\n");

    my ( $session, $error ) = Net::SNMP->session(
        -hostname => $host,
        -community => $community,
        -port => 161,
        -version => 1
        );

    if( !defined($session) ) {
        return 0;
        return "Can't connect to host $host.";
        }

    my @snmpoids = ();

    my $response = $session->get_next_request($oid);
    my @nextid = keys %$response;
    while ( @nextid && $nextid[0] && $nextid[0] =~ m/^$oid/ ) {
        push( @snmpoids, $nextid[0] );
        #print ("$nextid[0]\n");
        $response = $session->get_next_request( $nextid[0] );
        @nextid = keys %$response;
        }

    if ( !defined($response = $session->get_request( @snmpoids ) ) ) {
        return 0;
        }

    foreach my $value (values %$response) {
        #print (" $value:$client\n");
      Log $log, ("snmpCheck2: $NAME: Check-Mac: $value=$client");
      Log $log, ("snmpCheck2: $NAME: Mac $clientMac FOUND in $host") if( $value eq $client );
        return 1 if( $value eq $client )
        }
   Log $log, ("snmpCheck2: $NAME: Mac $clientMac NOT found in $host");
    return 0;
}
### end sub




TP-Link WEB Page Statuserkennung

Die nächste Funktion testet die Statusseite eines TP-LINK Powerline Wireless Adapters  TL-WPA4220.
http://www.tp-link.de/products/details/TL-WPA4220.html
Es wird einfach die Website ausgelesen und per REGEX nach der MAC Adresse gesucht.
Hier ist der Link zum RegEx-Test:
http://fiddle.re/ppkvka


Auch andere TP-Link Modelle sollten funktionieren.

define PR_iPhoneTPLINK PRESENCE function { chkTplinkClient("iPhone-Armin", "http://192.168.27.241/userRpm/WlanStationRpm.htm", "admin:admin", "3C:07:71:B3:B6:71", 3 ) } 30 120




#########################################################################################################################
# Function to check if mac address is registered at wireless tplink status page
# Testet with Powerline-Wireless Repeater TL-WPA4220    (Mac format in TPLINK Status Page: AA-BB-CC-DD-EE-FF
#                                                      (MAC format in CALL:               AA:BB:CC:DD:EE:FF)
# (c) armin@pipp.at  8/2016
#
# Syntax: chkTplinkClient <NAME> <URL> <user:pass> <AA:BB:CC:DD:EE::FF>  [LOGLEVEL]
# Returns 1 if found
#
#   <NAME> Human readable Name only for logs
#   <URL>  Full URL to website incl. http://
#   <user:pass>         User and Password for auth. (standard=admin:admin)
# <AA:BB:CC:DD:EE:FF> Client MAC Address for the search
# [LOGLEVEL] optional / Loglevel (standard=4)
#
#
# Sub needs Perl Curl::Easy
# Debian/Ubuntu: apt-get install libwww-curl-perl
#
# Fhem PRESENCE: define PR_iPhoneTPLINK PRESENCE function { chkTplinkClient("iPhone-Armin", "http://192.168.27.241/userRpm/WlanStationRpm.htm", "admin:admin", "3C:07:71:B3:B6:71", 3 ) } 30 120
sub chkTplinkClient($$$$;$)
    {
use WWW::Curl::Easy;
        my ($NAME ,$url, $user_pass, $client,$loglevel) = @_;

my $log=4;
if (defined($loglevel)) {$log=$loglevel};

Log $log, ("chkTplinkClient: $NAME: Parameter=@_");
       
my ($user, $pass) = split(/:/,$user_pass);
        # print $client,"\n";
        # replace mac separator : with -
        $client =~ s/:/-/g;

        #    my $user = 'admin';
        #    my $pass = 'admin';
        # my $url = 'http://192.168.27.241/userRpm/WlanStationRpm.htm';
        my $curl = WWW::Curl::Easy->new;
        $curl->setopt(CURLOPT_HEADER,1);
        $curl->setopt(CURLOPT_URL, $url);
        $curl->setopt(CURLOPT_HTTPAUTH,CURLAUTH_ANY);
        #$curl->setopt(CURLOPT_HTTPAUTH,CURLAUTH_DIGEST);
        #$curl->setopt(CURLOPT_USERPWD, 'admin:admin');
        $curl->setopt(CURLOPT_USERPWD, $user . ':' . $pass);
        # set connect timeout to 2 seconds
        $curl->setopt(CURLOPT_TIMEOUT,2);

        # A filehandle, reference to a scalar or reference to a typeglob can be used here.
        my $response_body;
        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);

        # Starts the actual request
        my $retcode = $curl->perform;

        # Looking at the results...
        if ($retcode == 0) {
                #print("Transfer went ok\n");
                my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
                # judge result and next action based on $response_code
                # print("Received response: $response_body\n");

                # put every found found mac address into the array (/g = all) array begin counting at 0
                my @macarray = $response_body =~ /[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}/g;

                # print ("$response_body");

                # print ("Max Array ID:$#macarray\n");
                my $i=0;
                while ($i<=$#macarray) {
                    # print uc($macarray[$i]). "=" . uc($client). "\n";
Log $log, ("$NAME: chkTplinkClient: Check: ". uc($macarray[$i]). "=" . uc($client));
Log $log, ("$NAME: chkTplinkClient: Mac $client FOUND in $url") if( uc($macarray[$i]) eq uc($client) );
                    return 1 if( uc($macarray[$i]) eq uc($client) );
                    $i++;
                    }
Log $log, ("$NAME: chkTplinkClient: Mac $client NOT found in $url");
                return 0;
                } else {
                # Error code, type of error, error message
                # print("An error happened: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf."\n");
Log $log, ("$NAME: chkTplinkClient: Error: An error happened: $retcode " . $curl->strerror($retcode) . " " . $curl->errbuf);
                return 0;
                }
return 0;
    } # end sub
##########





Eine Erkennung für mein iPhone habe ich zur Zeit so gelöst:

list PR_iPhonePipp
Internals:
   CFGFN
   DEF        function { (snmpCheck2("iPhone-Armin", "192.168.27.254",1,"public","F0:CB:A1:B4:8C:78",3 ) or snmpCheck2("iPhone-Armin","192.168.27.74",0,"public","F0:CB:A1:B4:8C:78",3) or chkTplinkClient("iPhone-ArminTP","http://192.168.27.241/userRpm/WlanStationRpm.htm", "admin:admin", "F0:CB:A1:B4:8C:78",3))   } 30 120
   MODE       function
   NAME       PR_iPhonePipp
   NOTIFYDEV  global
   NR         5536
   NTFY_ORDER 50-PR_iPhonePipp
   STATE      present
   TIMEOUT_NORMAL 30
   TIMEOUT_PRESENT 120
   TYPE       PRESENCE
   Readings:
     2016-09-01 00:46:01   presence        present
     2016-09-01 00:46:01   state           present
   Helper:
     call       { (snmpCheck2("iPhone-Armin", "192.168.27.254",1,"public","F0:CB:A1:B4:8C:78",3 ) or snmpCheck2("iPhone-Armin","192.168.27.74",0,"public","F0:CB:A1:B4:8C:78",3) or chkTplinkClient("iPhone-ArminTP","http://192.168.27.241/userRpm/WlanStationRpm.htm", "admin:admin", "F0:CB:A1:B4:8C:78",3))   }
Attributes:
   room       Favourites,Presence


Vmware-ESX-VM-Ubuntu 16.04 Docker Main-FHEM -> Raspberry Pi-B ser2net
HMLAN mit HomeMatic, Busware SCC433 stacked SCC868 (culfw), Jeelink, MAX Heizkörperthermostate, Enigma2 (Vudo2/DM800SE), Philips 55" Ambilight PHTV - WMBUS EnergyCam+Engelmann FAW, Intertechno-Komponenten, Ubiquiti mPower

pipp37

Hier noch der reine Quellcode für die Linux Commandline zum Testen.


File: get-tplink.pl

#!/usr/bin/env perl
use strict;
use warnings;
use WWW::Curl::Easy;



#########################################################################################################################
# get  mac addresses from wireless tplink status page  (Mac format in TPLINK Status Page: AA-BB-CC-DD-EE-FF)
#                                                      (MAC format in CALL:               AA:BB:CC:DD:EE:FF)
# (c) armin@pipp.at  8/2016
#
# Syntax: chkTplinkClient <URL> <user:pass> <AA:BB:CC:DD:EE::FF>
# Returns 1 if found
sub chkTplinkClient($$$)
    {
        my ($url, $user_pass, $client) = @_;

        my ($user, $pass) = split(/:/,$user_pass);
        print $client,"\n";
        # replace mac separator : with -
        $client =~ s/:/-/g;

        #    my $user = 'admin';
        #    my $pass = 'admin';
        #my $url = 'http://192.168.27.241/userRpm/WlanStationRpm.htm';
        my $curl = WWW::Curl::Easy->new;
        $curl->setopt(CURLOPT_HEADER,1);
        $curl->setopt(CURLOPT_URL, $url);
        $curl->setopt(CURLOPT_HTTPAUTH,CURLAUTH_ANY);
        #$curl->setopt(CURLOPT_HTTPAUTH,CURLAUTH_DIGEST);
        #$curl->setopt(CURLOPT_USERPWD, 'admin:admin');
        $curl->setopt(CURLOPT_USERPWD, $user . ':' . $pass);
        # set connect timeout to 2 seconds
        $curl->setopt(CURLOPT_TIMEOUT,2);

        # A filehandle, reference to a scalar or reference to a typeglob can be used here.
        my $response_body;
        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);

        # Starts the actual request
        my $retcode = $curl->perform;

        # Looking at the results...
        if ($retcode == 0) {
                #print("Transfer went ok\n");
                my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
                # judge result and next action based on $response_code
                #print("Received response: $response_body\n");

                # put every found found mac address into the array (/g = all) array begin counting at 0
                my @macarray = $response_body =~ /[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}/g;

                # print ("$response_body");

                #print ("Max Array ID:$#macarray\n");
                my $i=0;
                while ($i<=$#macarray) {
                    print uc($macarray[$i]). "=" . uc($client). "\n";
                    return 1 if( uc($macarray[$i]) eq uc($client) );
                    $i++;
                    }
                return 0;
                } else {
                # Error code, type of error, error message
                # print("An error happened: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf."\n");
                return 0;
                }
    return 0;
    } # end sub
##########

my $url1 = 'http://192.168.27.241/userRpm/WlanStationRpm.htm';
print (chkTplinkClient($url1,"admin:admin", "3C-07-71:B3-B6:70"),"\n");






check-snmp-phone.pl

#!/usr/bin/perl -w
#### OID #####
#
#   0   Mikrotik wireless mac table:    .1.3.6.1.4.1.14988.1.1.1.2.1.1
#   1   Mikrotik capsman mac table:     .1.3.6.1.4.1.14988.1.1.1.5.1.1
#   2   Apple Airport DHCP table:       .1.3.6.1.2.1.3.1.1.2
#


use Net::SNMP;

#########################################################################################################################
# hex mac address (AA:BB:CC:DD:EE:FF) to pointed  decimal values
sub HexMacToDec($)
    {
    my ($in) = @_;
    #print ("hexMac:" . $in);
    my @elements=split(/:/,$in);
    my $element="";
    my $ret="";
    #my $rethex="0x";

    for  $element  (@elements)
        {
        # print ".".hex($element);
        $ret.=hex($element) . "." ;
        #$rethex .= lc($element);
        }

    chop($ret);
    #{Log 3, ("hexMacToDec:Parameter=@_" . "<".$ret.">")};
    #print("$rethex\n");

    return $ret;
    }



#########################################################################################################################
# hex mac address (AA:BB:CC:DD:EE:FF) to hex value (0x...)
sub HexMacToHex($)
    {
    my ($in) = @_;
    my @elements=split(/:/,$in);
    my $element="";
    my $rethex="0x";

    for  $element  (@elements)
        {
        $rethex .= lc($element);
        }

    #print("$rethex\n");

    return $rethex;
    }


#########################################################################################################################
#
sub snmpCheck2($$$$)
    {
    my ($host,$oidindex,$community,$clientMac)=@_;
    my @oidarray = (".1.3.6.1.4.1.14988.1.1.1.2.1.1", ".1.3.6.1.4.1.14988.1.1.1.5.1.1", ".1.3.6.1.2.1.3.1.1.2");
    #my $community = "public";
    #my $host = $airport;
    #my $oid = ".1.3.6.1.2.1.3.1.1.2";
    #my $oid = ".1.3.6.1.2.1.3.1.1.2.25.1.10.0.1";

    #capsman                              last digit
                                             #1=mac
                                             #3=uptime
    #my $oid = ".1.3.6.1.4.1.14988.1.1.1.5.1.1";

    my $client = HexMacToHex($clientMac);
    my $oid = $oidarray[$oidindex];

    print("Host=$host / SNMP-com=$community\n");
    print("OID-Index=$oidindex / OID=$oid CheckMac=$client\n");
    print("DezimalMac=" . HexMacToDec($clientMac) . "\n");
    print("MacToHexac=" . HexMacToHex($clientMac) . "\n");

    my ( $session, $error ) = Net::SNMP->session(
        -hostname => $host,
        -community => $community,
        -port => 161,
        -version => 1
        );

    if( !defined($session) ) {
        return 0;
        return "Can't connect to host $host.";
        }

    my @snmpoids = ();

    my $response = $session->get_next_request($oid);
    my @nextid = keys %$response;
    while ( @nextid && $nextid[0] && $nextid[0] =~ m/^$oid/ ) {
        push( @snmpoids, $nextid[0] );
        #print ("$nextid[0]\n");
        $response = $session->get_next_request( $nextid[0] );
        @nextid = keys %$response;
        }

    if ( !defined($response = $session->get_request( @snmpoids ) ) ) {
        return 0;
        }

    foreach my $value (values %$response) {
        print (" $value:$client\n");
        return 1 if( $value eq $client )
        }

    return 0;
}



#lg handy
#print (HexMacToDec("A1:B1:C1:D1:E1:F1") ."\n");
#print("Mac registriert:" . snmpCheck("192.168.27.254",1,"public","0xc4438fa73ed6") ."\n");
print("MAC registerd:" . snmpCheck2("192.168.27.254",1,"public","c4:43:8F:a7:3e:d6") ."\n");





Vmware-ESX-VM-Ubuntu 16.04 Docker Main-FHEM -> Raspberry Pi-B ser2net
HMLAN mit HomeMatic, Busware SCC433 stacked SCC868 (culfw), Jeelink, MAX Heizkörperthermostate, Enigma2 (Vudo2/DM800SE), Philips 55" Ambilight PHTV - WMBUS EnergyCam+Engelmann FAW, Intertechno-Komponenten, Ubiquiti mPower

pd33

Hallo pipp37,

vielen Dank für das Modul. Ich nutze die CapsMan-Variante und bin absolut begeistert. Ich habe gesehen, dass bei manchen Presence-Varianten optional der Raum als Reading mit ausgegeben werden kann.

Wäre es denkbar, beim CapsMan das Interface als zusätzliches Reading mit auszugeben?


Vielen Dank und viele Grüße

pd33

Hallo zusammen,

ich habe mir den Spaß noch einmal genauer angeschaut und via SNMP keinen Weg gefunden, über den Access Point den dazugehörigen Raum zu definieren. Allerdings sind die MikroTiks sehr flexibel und so habe mit mit den Scripting etwas herumgespielt und einen Weg gefunden, den Raum zu setzen. Bei mir läuft das Script alle zwei Sekunden auf dem Router und setzt das Reading "room" im jeweiligen Device. Hier der Code mit ein wenig Erklärung:


# Script Name: CAPS-FHEM-presence per room
# inspired by http://wiki.mikrotik.com/wiki/Log_Parser_-_Event_Trigger_Script
# This script reads a specified log buffer.  At each log entry read, checked by values
# and set a Reading per registred Caps device. Then the buffer is cleared.
#
# You have to define a dedicated logging action and rule first:
# < /system logging action add memory-lines=100 memory-stop-on-full=no name=caps target=memory >
# < /system logging add action=caps disabled=no prefix="" topics=caps >
#
# define a scheduler to run the script each two seconds
# < /system scheduler
#    add interval=2s name=caps-presence-log-parser on-event=\
#    "/system script run caps-fhem-presence-final" policy=\
#    ftp,read,write,policy,test start-date=nov/09/2016 start-time=10:11:39 >
#
# script policy: policy=\
#    ftp,read,write,policy,test
#

# define the parameter to fit your environment
:local fhemserver "192.168.1.34"
:local fhemport "8083"
:local logBuffer "caps"
# end

# DO NOT EDIT BELOW THIS LINE

# define local variables
:local device
:local room
:local url
:local logMessage
:local ruleop

:local value
:local clearedbuf
:local lines
:local findindex
:local property
:local logParseVar

:local clearedbuf 0
:foreach rule in=[/log print as-value where buffer=($logBuffer)] do={
# Now all data is collected in memory..

# Clear log buffer right away so new entries come in
   :if ($clearedbuf = 0) do={
      /system logging action {
         :set lines [get ($logBuffer) memory-lines]
         set ($logBuffer) memory-lines 1
         set ($logBuffer) memory-lines $lines
      }
      :local clearedbuf 1
   }
# End clear log buffer

# Get each log entry's properties
   :foreach item in=[:toarray $rule] do={
      :local findindex [:find [:tostr $item] "="]
      :local property [:tostr [:pick [:tostr $item] 0 $findindex]]
      :local value [:tostr [:pick [:tostr $item] ($findindex + 1) [:len [:tostr $item]]]]
      :local  logParseVar $rule

:set logMessage $logParseVar

# clear varables
:set ruleop "ok"
:set device ""
:set room "na"
:set url ""

:if ([:len [:find [:tostr $logMessage] "disconnected"]] > 0) do={ :set ruleop "" }

:if ([:len $ruleop] = 2) do={

# DO NOT EDIT ABOVE THIS LINE

# define your caps clients, i.e.
#    :if ([:len [:find [:tostr $logMessage] "<mac address>"]] > 0) do={ :set device "<fhem device>" }
#    :if ([:len [:find [:tostr $logMessage] "00:11:22:33:44:55"]] > 0) do={ :set device "client1.mtik" }

   :if ([:len [:find [:tostr $logMessage] "00:11:22:33:44:55"]] > 0) do={ :set device "client1.mtik" }
   :if ([:len [:find [:tostr $logMessage] "00:11:22:33:44:56"]] > 0) do={ :set device "client2.mtik" }
   :if ([:len [:find [:tostr $logMessage] "00:11:22:33:44:57"]] > 0) do={ :set device "client3.mtik" }

# define your rooms based on defined interface name
#   :if ([:len [:find [:tostr $logMessage] "<CAPsMAN interface name>"]] > 0) do={ :set room "<room name>" }
#   :if ([:len [:find [:tostr $logMessage] "ap01"]] > 0) do={ :set room "kitchen" }

   :if ([:len [:find [:tostr $logMessage] "ap01"]] > 0) do={ :set room "dachgeschoss" }
   :if ([:len [:find [:tostr $logMessage] "ap02"]] > 0) do={ :set room "obergeschoss" }
   :if ([:len [:find [:tostr $logMessage] "ap03"]] > 0) do={ :set room "keller" }
   :if ([:len [:find [:tostr $logMessage] "ap04"]] > 0) do={ :set room "erdgeschoss" }

# DO NOT EDIT BELOW THIS LINE

   :if ([:len $device] > 0) do={
      # /tool fetch url="http://<fhemserver>:<fhemport>/fhemcmd=setreading%20<fhem device>%20room%20<room>"
      # /tool fetch url="http://192.168.1.34:8083/fhemcmd=setreading%20client1.mtik%20room%20keller"
         :set url ("http://" . $fhemserver . ":" .$fhemport ."/fhemcmd=setreading%20" . $device . "%20room%20" . $room )
         /tool fetch url=$url
      }
   }
}
}
# fin


Kurze Erklärung: Ich "kopiere" alle CAPsMAN relevanten Ereignisse in einem eigenen Log, im Speicher des Routers. Das Script fragt alle zwei Sekunden den Speicher ab und setzt bei jedem Client den Raum an Hand des genutzten Access Points (bzw. CAPsMAN Interface Name"). Danach wird der Logspeicher gelöscht, um nicht jedes mal hunderte von Einträgen durcharbeiten zu müssen.

Zusätzlich habe ich mir ein DOIF geschrieben, welches den Raum löscht, wenn der Client wieder aus dem WLAN verschwindet:


([client1.mtik] eq "absent")
(setreading client1.mtik room -)
DOELSEIF
([client1.mtik] eq "present")


Ich bin kein Script-Profi, aber so funktioniert es bei mir bisher ganz gut. Bei Fragen einfach melden bzw. hier antworten.


Viele Grüße!



QuesT

Hallo,

was mache ich falsch?

apt-get install snmpd hab ich gemacht.

2016.12.08 17:24:05 2: PRESENCE (PR_Alex_5x_SNMP) - error while processing check: unexpected function output (expected 0 or 1): Can't locate object method "session" via package "Net::SNMP" (perhaps you forgot to load "Net::SNMP"?) at ./FHEM/99_myUtils.pm line 294.


Danke

pipp37

Da fehlen die perl-libs für snmp.



apt-cache search snmp | grep perl

libfusioninventory-agent-task-snmpquery-perl - SNMP devices scan support for FusionInventory Agent
libnet-snmp-perl - Script SNMP connections
libsnmp-extension-passpersist-perl - Generic pass/pass_persist extension framework for Net-SNMP
libsnmp-info-perl - Object Oriented Perl5 Interface to Network devices and MIBs through SNMP
libsnmp-mib-compiler-perl - a MIB Compiler supporting SMIv1 and SMIv2
libsnmp-multi-perl - Perform SNMP operations on multiple hosts simultaneously
libsnmp-perl - SNMP (Simple Network Management Protocol) Perl5 support
libsnmp-session-perl - Perl support for accessing SNMP-aware devices

Dann diese  Pakete installieren.
apt-get install libnet-snmp-perl libsnmp-perl libsnmp-session-perl


Vmware-ESX-VM-Ubuntu 16.04 Docker Main-FHEM -> Raspberry Pi-B ser2net
HMLAN mit HomeMatic, Busware SCC433 stacked SCC868 (culfw), Jeelink, MAX Heizkörperthermostate, Enigma2 (Vudo2/DM800SE), Philips 55" Ambilight PHTV - WMBUS EnergyCam+Engelmann FAW, Intertechno-Komponenten, Ubiquiti mPower

QuesT


pipp37

Da fehlt wahrscheinlich noch

use Net::SNMP;


in der utils.
Ich habe den Code im 1. Post angepasst.
LG
Vmware-ESX-VM-Ubuntu 16.04 Docker Main-FHEM -> Raspberry Pi-B ser2net
HMLAN mit HomeMatic, Busware SCC433 stacked SCC868 (culfw), Jeelink, MAX Heizkörperthermostate, Enigma2 (Vudo2/DM800SE), Philips 55" Ambilight PHTV - WMBUS EnergyCam+Engelmann FAW, Intertechno-Komponenten, Ubiquiti mPower

QuesT

Danke geht jetzt.


JoeALLb

Ich nutze zwar kein CAPSMAN,
dafür aber den DHCP-Server, da dieser doch sehr gute Ergebnisse liefert.
Das Telefon scheint imer aufzuwachen, wenn das DHCP-Lease abgelaufen ist.
Daher setze ich:

1:  Die Leasezeit vom DHCP auf 10 Minuten
2: Ergänze unten genanntes SUB
3: Definiere PRESENCE mit

ersetze xx.xx.xx durch die IP des Handys
defmod HandyX PRESENCE function {presenceSNMP("xx.xx.xx")}

ersetze xxx.xxx.xxx.xxx durch die IP des Mikrotik
  sub presenceSNMP($) {
    my ($ip) = @_;
    my $tmp = qx(snmpget -v2c -cpublic xxx.xxx.xxx.xxx iso.3.6.1.2.1.9999.1.1.6.4.1.5.$ip) =~ m/.*:\s+(\d+)/m;
    return ( $1>4294967294 ) ? 0:1;
  }



klappt wunderbar!
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

pd33

Achtung bei der Nutzung von RouterOS 6.38.4 und höher! Dort ist die Liste der in CapsMan registrierten Clients via SNMP nicht abfragbar und daher funktioniert die Variante nicht mit den Releases. Laut MikroTik wird der Fehler mit 6.39 behoben. Im aktuellen 6.39rc soll es schon enthalten sein.


Viele Grüße!

gramels

Zitat von: pd33 am 06 Dezember 2016, 21:47:08
Hallo zusammen,

ich habe mir den Spaß noch einmal genauer angeschaut und via SNMP keinen Weg gefunden, über den Access Point den dazugehörigen Raum zu definieren. Allerdings sind die MikroTiks sehr flexibel und so habe mit mit den Scripting etwas herumgespielt und einen Weg gefunden, den Raum zu setzen. Bei mir läuft das Script alle zwei Sekunden auf dem Router und setzt das Reading "room" im jeweiligen Device. Hier der Code mit ein wenig Erklärung:


Hallo,

blöde Frage, braucht es bei diesem script den obige snmp Abfrage überhaupt?
Ich versuche es gerade stand alone, und bekomme es nicht zum laufen..

Grüsse
gramels

pd33

Zitat von: gramels am 10 April 2017, 23:33:42
Hallo,

blöde Frage, braucht es bei diesem script den obige snmp Abfrage überhaupt?
Ich versuche es gerade stand alone, und bekomme es nicht zum laufen..

Grüsse
gramels

Ja, da bei jedem Wechsel von einem AP zum nächsten AP immer erst ein "Connect" beim neuen AP vor dem "Disconnect" des alten AP kommt (zumindest bei der Controller-Variante). Somit ist es rein basierend auf den Logs nicht zu erkennen das ein Client noch eingebucht ist.

Ein weiteres Problem ist, dass selbst der reine Anmeldungsversuch am AP in der Reg.-Tabelle auftaucht. Da die Mac-Adresse immer im Klartext übertragen wird. Es kann also jemand die Anwesenheit leicht erzwingen, auch wenn er nicht den notwendigen WPA-Schlüssel kennt. Das sollte man bei der Variante natürlich berücksichtigen.

Sorry wegen der späten Antwort, es ging irgendwie unter. Läuft es mittlerweile?


Viele Grüße
Christian



borsti67

Hallo,

kann es sein, dass der TP-LINK-Code nur auf bestimmten Geräten oder älteren Firmwares läuft? Ich habe einen TL-WA850RE, aber der scheint diese RPM-Seiten nicht zu kennen, denn egal welches ergoogelte Ziel ich mittels curl/wget ziehen möchte, der liefert nur "Server Error 501: not implemented"... :(
cu/2
Borsti
---
FHEM 5.8 auf Synology DS211j (bis 11/17) | FHEM 6.0 auf Raspi Zero W (bis 11/20) | FHEM 6.2 als VM in Synology DS1815+ (ab 11/20)

pd33

Zitat von: borsti67 am 16 September 2017, 12:47:31
Hallo,

kann es sein, dass der TP-LINK-Code nur auf bestimmten Geräten oder älteren Firmwares läuft? Ich habe einen TL-WA850RE, aber der scheint diese RPM-Seiten nicht zu kennen, denn egal welches ergoogelte Ziel ich mittels curl/wget ziehen möchte, der liefert nur "Server Error 501: not implemented"... :(

Ich nutze leider keine TP-Links und kann daher nicht weiter helfen. Sorry.