Versionen im Vergleich

Schlüssel

  • Diese Zeile wurde hinzugefügt.
  • Diese Zeile wurde entfernt.
  • Formatierung wurde geändert.

...

  1. Zuerst muss der Bluetooth Dongle beschafft werden.
    Hat der Rechner bereits ein Bluetooth Modul sollte das genügen.
    Ich habe den LogiLink BT0015 verwendet. (Kostet unter 10 Euro)  
     
  2. Da ich bereits einen Linux Server hatte, kann ich ihn benutzen.
    Wer keinen hat, müsste sich einen aufsetzen - da gibt es diverse Anleitungen - das erspare ich uns hier. 
    Er sollte am Ende der Installation einen lauffähigen Webserver beinhalten.
     
  3. Auf dem Server muss dann das Paket bluez installiert sein.

    aptitude install bluez
     
  4. Mit den Kommandos hciconfig und hcitool kann man dann versuchen den Dongle zu aktivieren und die Tags zu scannen:
    Prompt> hciconfig hci0 up
    Prompt> /usr/bin/hcitool lescan
    LE Scan ...
    7C:2F:81:91:A1:B2 (unknown)
    7C:2F:81:91:A1:B2 Gigaset G-tag

    Wenn das nicht klappt, könnt ihr im Internet diverse Tutorials finden, wie das einzurichten ist
    oder wie die Fehlersuche anzugehen ist. Das würde hier den Rahmen sprengen. Ich setzte
    für die weitere Anleitung voraus, dass der Scan klappt. 
     
  5. Nun wird ein Shell Script erstellt, welches die Dongles scannt. Ich habe es scantag.sh genannt.

    Codeblock
    languagebash
    firstline1
    titlescantag.sh
    linenumberstrue
    collapsetrue
    hciconfig hci0 down
    hciconfig hci0 up
    (/bin/sleep 8;/usr/bin/killall --signal 2 /usr/bin/hcitool) |/usr/bin/hcitool lescan |grep -v "LE Scan" |cut -c1-17|sort -u

    Ich habe dem Script als Gruppe und Eigentümer root zugewiesen und die Rechte eingeschränkt:

    chmod 500 scantag.sh 
    chown root:root scantag.sh 
     
  6. Als nächstes müssen wir dem PHP-Script erlauben, das Scan-Script auszuführen.

    Dies erfolgt mit Hilfe des folgenden Kommandos und Hinzufügen des Eintrags für www-data:

    sudo visudo
    www-data ALL = NOPASSWD:/home/www/wo-auch-immer/scantag.sh 
     
  7. Nun das PHP-Script, welches vom Miniserver bei einer Leseanforderung aufgerufen wird:

    Codeblock
    languagephp
    firstline1
    titleindex.php
    linenumberstrue
    collapsetrue
    <?php
    // Bekannte G-Tags:
    $tags_known['1']   ="7C:2F:81:91:A1:B1"; // Tag rot
    $tags_known['2']   ="7C:2F:81:91:A1:B2"; // Tag grün
    $tags_known['4']   ="7C:2F:81:91:A1:B3"; // Tag schwarz
    $tags_known['8']   ="7C:2F:81:91:A1:B4"; // Tag orange
    $tags_known['16']  ="7C:2F:81:91:A1:B5"; // Tag weiß
    //31 = alle da
    //16 weiss
    //8 orange
    //4 schwarz
    //2 grün
    //1 rot  
    function output($output)
    {
    	echo $output." \n";
      $socket = fsockopen('udp://miniserver:11111');
      fputs($socket, "$output");
    	return;
    }
    // Ausführen des BLE-Scans
    exec('sudo /home/www/wo-auch-immer/scantag.sh',$tags_found);
    $tags_found = array_unique($tags_found,SORT_STRING);
    $bitmask=0;
    while(list($tag_user, $tag_mac) = each($tags_known))
      {
        unset($found_tags);
    		$found_tags = array_filter($tags_found, function($varu) use ($tag_mac) { return preg_match("/\b$tag_mac\b/i", $varu); });
    	if (count($found_tags) >= 1)
    		{
         $bitmask=$bitmask + $tag_user;
    		}
      }
      output($bitmask);

    Wenn man das Script im Browser aufruft, sollte eine Zahl welche in der Matrix den anwesenden Personen entspricht zurückgegeben werden.
    Parallel sendet das Script die Zahl auf den Port 11111 des Miniservers (virtueller Eingang).
     

  8. Zum Senden der Leseanforderung wird in der Loxone Config wird nun ein Virtueller Ausgang "G-Tag Leseanforderung" erstellt.

     

    Dahinter wird der Befehl erstellt:  (das ?read_G-Tags ist optional)

    Befehl bei EIN:  /bt/?read_G-Tags 
    HTTP Methode bei EIN:  GET 
     
  9. Zum Einlesen geht nun ein Merker auf Tr eines verzögerten Impuls Bausteins mit D: 0 und T; 90.
    Dieser verzögerte Impuls Baustein geht mit Q auf einen Impulsgeber mit TH: 0,5 und TL: 8,5.
    Dieser Impulsgeber geht mit Q direkt an den Virtuellen Ausgang.
    Wird der Merker nun getriggert, sendet der Miniserver für 90 Sekunden alle 9 Sekunden eine Leseanforderung.
    Der Merker wird durch diverse Ereignisse gesteuert - durch Bewegung vor und im Haus zum Beispiel.
     
  10. Nun der Empfangs-Teil. Dafür wird in der Loxone Config ein virtueller Eingang für die IP des Linux Rechners auf z.B. Port 11111 erstellt:

    Dahinter folgt wieder ein Befehl:

    Befehlserkennung: \v
    Als Digitaleingang verwenden nicht anhaken.

    Der Ausgang des Eingang-Befehls geht nun an AI1 eines Statusbausteins welcher auf der Favoriten-Seite visualisiert wird:
    Image RemovedImage Added
    Image Added 

  11. Da mir das zu heftig war, das alles in die Loxone Config zu klickern, habe ich mir eine Excel Tabelle erstellt und diese
    dann über einen Editor direkt als XML in die .loxone Projektdatei eingefügt.
    Bei mir sieht das dann so aus:

    Codeblock
    languagexml
    titleStatus-Text-Block
    collapsetrue
    					<StateTexts Num="32">
    						<StateText Valid="true" ValidV="true" Text="Ulli da                                    " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="1"/>
    						<StateText Valid="true" ValidV="true" Text="Chrissi da                                 " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="2"/>
    						<StateText Valid="true" ValidV="true" Text="Chrissi &amp; Ulli da                      " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="3"/>
    						<StateText Valid="true" ValidV="true" Text="Moritz da                                  " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="4"/>
    						<StateText Valid="true" ValidV="true" Text="Moritz &amp; Ulli da                       " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="5"/>
    						<StateText Valid="true" ValidV="true" Text="Moritz &amp; Chrissi da                    " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="6"/>
    						<StateText Valid="true" ValidV="true" Text="Moritz, Chrissi &amp; Ulli da              " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="7"/>
    						<StateText Valid="true" ValidV="true" Text="Oskar da                                   " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="8"/>
    						<StateText Valid="true" ValidV="true" Text="Oskar &amp; Ulli da                        " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="9"/>
    						<StateText Valid="true" ValidV="true" Text="Oskar &amp; Chrissi da                     " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="10"/>
    						<StateText Valid="true" ValidV="true" Text="Oskar, Chrissi &amp; Ulli da               " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="11"/>
    						<StateText Valid="true" ValidV="true" Text="Oskar &amp; Moritz da                      " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="12"/>
    						<StateText Valid="true" ValidV="true" Text="Oskar, Moritz &amp; Ulli da                " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="13"/>
    						<StateText Valid="true" ValidV="true" Text="Oskar, Moritz &amp; Chrissi da             " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="14"/>
    						<StateText Valid="true" ValidV="true" Text="Oskar, Moritz, Chrissi &amp; Ulli da       " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="15"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz da                                   " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="16"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz &amp; Ulli da                        " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="17"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz &amp; Chrissi da                     " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="18"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Chrissi &amp; Ulli da               " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="19"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz &amp; Moritz da                      " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="20"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Moritz &amp; Ulli da                " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="21"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Moritz &amp; Chrissi da             " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="22"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Moritz, Chrissi &amp; Ulli da       " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="23"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz &amp; Oskar da                       " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="24"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Oskar &amp; Ulli da                 " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="25"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Oskar &amp; Chrissi da              " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="26"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Oskar, Chrissi &amp; Ulli da        " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="27"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Oskar &amp; Moritz da               " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="28"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Oskar, Moritz &amp; Ulli da         " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="29"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Oskar, Moritz &amp; Chrissi da      " TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="30"/>
    						<StateText Valid="true" ValidV="true" Text="Heinz, Oskar, Moritz, Chrissi &amp; Ulli da" TextV="1" Icon="00000000-0000-0000-0000000000000000" Input0="1" CondV0="31" CondT0="31"/>
    						<StateText Valid="true" ValidV="true" Text="Niemand anwesend" TextV="0" Icon="00000000-0000-0000-0000000000000000"/>
    					</StateTexts>

    Der Ausgang TQ geht an einen visualisierten Logger-Baustein und der AQ über verzögerte Impuls-Bausteine an die Alarmanlage usw. 

  12. Viel Spaß bei der Umsetzung. 
     
Infowarning

Dieses Script ist sicher verbesserbar - über Anregungen freue ich mich immer. Verwendung auf eigene Gefahr!

Info

Ich habe ab und zu Aussetzer beim Einlesen welche dann im Logger-Baustein unschön als Niemand anwesend aufgelistet werden.
Das versuche ich noch irgendwie abzufangen. Da ich aber hauptsächlich den Statusbaustein auf der Favoriten-Seite nutze und die
Historie nur in einem Unterpunkt visualisiere stört es mich bisher nicht so sehr.

Verwandte Artikel

Nach Stichwort filtern (Inhalt nach Stichwort)
showLabelsfalse
max5
spacesLOX
showSpacefalse
sortmodified
reversetrue
typepage
cqllabel in ("anwesenheitserkennung","php","energy","linux","loxone","präsenz","low","bluetooth") and type = "page" and space = "LOX"
labelsBluetooth Low energy Präsenz anwesenheitserkennung PHP Linux Loxone

...