Anwesenheit-Erkennung - Raspi + ESP32 (BLE + Eddystone + BTHome (Shelly) Protokoll)

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • Dütt
    LoxBus Spammer
    • 24.02.2019
    • 437

    #31
    Ja sind mehrere Geräte in der Cloud.

    fallst du noch ein Iphone zum Testen brauchst hab ich noch ein Glaube ich ein Iphone 13 zu Hause liegen.

    Kommentar


    • hismastersvoice
      hismastersvoice kommentierte
      Kommentar bearbeiten
      Was ich sagen kann...
      Selbst wenn ein Gerät in der Cloud angemeldet ist, so erhöht sich das "aktiv" sein um ca. 2 Min. danach ist aber auch Schluss
      Zwar ist das jetzt noch nicht die Lösung, aber ich glaube wirklich das es was damit zu tun haben könnte.

      Android ist so schön einfach... App installieren und aktiveren was sie senden soll. Das funktioniert perfekt.
      In 24h ca. 3-4% mehr Batterie drain mehr ist das nicht...

      Apple halt, da ist nie was einfach.
      Für mich ist nur interessant ob ich was gundlegend anders mache als andere Projekte.

      Dem ist aber nach durchschauen des Code zB von esppresence nicht so, die habe die gleichen Probleme wie ich.
  • hismastersvoice
    Supermoderator
    • 25.08.2015
    • 7596

    #32
    Habe das Enroll des IRK im Master und ESP32 eingebaut.


    Klicke auf die Grafik für eine vergrößerte Ansicht

Name: grafik.png
Ansichten: 214
Größe: 12,0 KB
ID: 479476
    Klicke auf die Grafik für eine vergrößerte Ansicht

Name: grafik.png
Ansichten: 167
Größe: 57,5 KB
ID: 479477


    Manko...
    Shelly wird keine IRK scannen können, das nötige Encryption-Paket fehlt leider.
    Aber die brauchen speicher für andere Dinge.
    ​Das Skripten ist schwere als gedacht am Shelly viele Limitierungen, aber da muss man halt sparsam mit Timer und anderen Dingen umgehen .

    Das Projekt wird umfangreicher als ich je gedacht habe... Aber man lernt ja immer was dabei


    Jetzt geht es mal wieder weiter mit testen.
    Kein Support per PN!

    Kommentar

    • hismastersvoice
      Supermoderator
      • 25.08.2015
      • 7596

      #33
      Als erstes mal Danke an Dütt für die Leihgabe eines iPhone.

      In der Tat ist es so das wenn min. zwei iPhones in der Cloud angemeldet sind, sind bleiben sie aktiv.
      Zuvor war men iPhone immer nur aktiv wenn ich das Display an hatte, und ca. 1min später tot bis ich es wieder an geschaltet habe.

      Jetzt funktioniert es sauber wie man unten sehen kann.
      Mein Tag....
      7:26 - 10:14 -> Arbeit
      10:14 - 10:18 -> kurz zu Hause
      10:18 - 12:26 -> Arbeit
      12:26 - 12:29 -> zu Hause
      12:29 - 12:34 -> zum Bäcker (hatte ich vergessen)
      12:34 - 15:30 -> zu Hause
      15:30 - 16:04 -> Friseur
      16:04 bis jetzt -> zu Hause

      Also wirklich exakt (incl. Offline-Timeouts)

      Klicke auf die Grafik für eine vergrößerte Ansicht

Name: grafik.png
Ansichten: 166
Größe: 62,1 KB
ID: 479882



      Das heißt es geht wirklich nur wenn zwei iPhone oder iPhone mit iWatch im Spiel sind.
      Also geht es bei beim meinem Projekt so gut oder schlecht wie bei ESPresence. Beruhigt mich
      Kein Support per PN!

      Kommentar

      • hismastersvoice
        Supermoderator
        • 25.08.2015
        • 7596

        #34
        Ich hadere immer noch mit dem Thema Verschlüsselung

        Erste Hürde habe ich nach 14 Stunden Arbeit überwunden....
        Die Loxone Interkommunikation mit Verschlüsselung.

        Ich wollte unbedingt die ICI Schnittstelle von Loxone nutzen, ich finde sie praktisch mit Lernfenster etc.
        Loxone selber beschreibt überhaupt nicht, weder verschlüsselt noch unverschlüsselt.
        Im Loxwiki findet man die Beschreibung der unverschlüsselten.


        Klicke auf die Grafik für eine vergrößerte Ansicht  Name: grafik.png Ansichten: 45 Größe: 15,9 KB ID: 480159Klicke auf die Grafik für eine vergrößerte Ansicht  Name: grafik.png Ansichten: 36 Größe: 26,2 KB ID: 480160


        Alle Daten werden jetzt vom Aggregator zum MiniServer verschlüsselt übermittelt.
        Der Master und ESP32 ist als nächstes dran.

        Einen Web-Flasher habe ich auch schon gebaut um alles einfach auf die ESPs zu bekommen.


        Als Dankeschön für Dütt für die Hilfe mit dem iPhone habe ich auch ein paar LAN-ESP32 mit eingebaut,er nutzt die Olimex POE.
        Mehr ESPs mit LAN hatte ich nicht zu Hause, man kann aber noch weitere einfügen wenn man die Pin-Belegung kennt.
        Klicke auf die Grafik für eine vergrößerte Ansicht  Name: grafik.png Ansichten: 37 Größe: 35,1 KB ID: 480161

        Zuletzt geändert von hismastersvoice; 08.03.2026, 17:26.
        Kein Support per PN!

        Kommentar


        • Govlar
          Govlar kommentierte
          Kommentar bearbeiten
          Ich habe gerade heute auch die Verschlüsselung dokumentiert, zumindest bisher nur in meinem Github Repository https://github.com/Multivit4min/loxo...in/PROTOCOL.md was mir aber aufgefallen ist wenn Pakete verschlüsselt gesendet werden wird kein Datentyp mehr gesendet, geht somit die automatische erkennung der Pakete nicht mehr?
          Hab leider keinen 2. Miniserver zum testen zur Hand.

          Das Limit von 35 Paketen bezieht sich pro Sekunde auf eine Dauer von 2 Minuten, sind also immer noch 2100 Nachrichten pro Minute die du übertragen kannst, das Limit ist da dann relativ großzügig

          SmartActuatorRGBW funktioniert in meiner Doku auch noch nicht, weiß nicht genau was die da für Magie betreiben wenn die Umschaltung zwischen RGB und Farbtemperaturen passiert und bei dem T5 Taster ist auch noch nicht ganz logisch was da hin und her geht
          Zuletzt geändert von Govlar; 05.03.2026, 21:01.

        • hismastersvoice
          hismastersvoice kommentierte
          Kommentar bearbeiten
          Ich habe bis jetzt

          Der Miniserver erkennt den Typ an der Kombination aus Flag-Byte und IV-Type-Byte:

          | Datentyp | Flag | IV-Type | CT-Blöcke | Paket-Bytes |
          |----------|------|---------|-----------|-------------|
          | Digital | 0x02 | 0x2B | 1 (16B) | 59B |
          | Text | 0x03 | 0x29 | 2 (32B) | 75B |
          | Analog | 0x03 | 0x2A | 2 (32B) | 75B |

          T5 etc habe ich noch nicht gemacht, waren für mich nötig.

          Wenn man einfach nur ein das Flag schickt kommt immer digital, und Passwort Fehler.

        • Prof.Mobilux
          Prof.Mobilux kommentierte
          Kommentar bearbeiten
          Bzgl. maximaler Messages über die Interkommunikation müsst ihr in euren Projekten nur aufpassen, falls Leute die Schnittstelle auch mit 2 Miniservern nutzen - also so, wie sie eigentlich mal gedacht war. Das und zusätzlich eure Messages können das Limit eventuell schnell erreichen.
      • hismastersvoice
        Supermoderator
        • 25.08.2015
        • 7596

        #35
        Version 1.0.0 ist online...

        https://ble-presence.de/handbuch.php

        Habe viel getestet und versucht Fehler zu finden.
        Ich hoffe das beim testen auch "alles" funktioniert.

        Testet und meldet gerne jeden Fehler der euch auffällt.


        Das Handbuch ist noch nicht fertig und muss an vielen Stellen noch angepasst werden.
        Aber Installation und Grundeinrichtung sollte schon mal passen
        Kein Support per PN!

        Kommentar


        • Prof.Mobilux
          Prof.Mobilux kommentierte
          Kommentar bearbeiten
          Da steckt viel Arbeit drin. Geiles Projekt!

        • Pat201290
          Pat201290 kommentierte
          Kommentar bearbeiten
          Danke für die Mühe. Hab eine kleine Spende da gelassen ^^
      • AlexAn
        Lebende Foren Legende
        • 25.08.2015
        • 4555

        #36
        Das ist echt ein coole Sache was du das geschaffen hast
        Bin noch nicht fertigt aber das wird schon.

        Hab schon fast ein schlechtes Gewissen weil ich noch nicht zum Einrichten gekommen bin....
        Klicke auf die Grafik für eine vergrößerte Ansicht

Name: image.png
Ansichten: 74
Größe: 75,7 KB
ID: 480483
        Zuletzt geändert von AlexAn; 11.03.2026, 19:04.
        Grüße Alex

        Kommentar


        • hismastersvoice
          hismastersvoice kommentierte
          Kommentar bearbeiten
          Kein Stress... Freu mich über Rückmeldung...
          Es ist sehr mächtig geworden, und ich habe viel getestet, aber da sind noch bestimmt viele Dinge zum nachbessern.
      • hismastersvoice
        Supermoderator
        • 25.08.2015
        • 7596

        #37
        ...und mir gehen die Ideen noch nicht aus.

        Ich arbeite gerade an einer Headmap die ich mit den Werten fixen Werten oder wenn aktiv noch besser aus der Auto-Kalibration erstelle.
        Muss ich noch verfeinern, aber die Gundidee geht schon mal.

        Klicke auf die Grafik für eine vergrößerte Ansicht

Name: grafik.png
Ansichten: 81
Größe: 200,4 KB
ID: 480496
        Kein Support per PN!

        Kommentar

        • hme0354
          Lox Guru
          • 06.07.2019
          • 1015

          #38
          hismastersvoice wie viele Scanner hast du dann in deinem Haus?
          Smarthome: 1x Miniserver Gen. 2, 3x Relay Extensions, 1x Tree Extension, 1x DI-Extension, 1x Air Base Extension, 8x RGBW Tree Dimmer, 9x Touch-Tree, 1x Nano DI Tree, 10x Tree BWM
          Technik: IDM Aero SLM 3-11 mit HGL, MS4H mit 9 Zonen, 2x Loxberry, 2x RPI für Anzeige, Doorbird, Froggit WH2600, POE+ System für Peripherie, Gedad Luftgütesensoren, Deconz (Bridge + 2x BWM + 2x RGBW + 5 Smartplug)

          Kommentar


          • hismastersvoice
            hismastersvoice kommentierte
            Kommentar bearbeiten
            9 aktuell...
            Nur Anwesenheit würden aber zwei reichen. Für Position braucht es etwas mehr.
        • AlexAn
          Lebende Foren Legende
          • 25.08.2015
          • 4555

          #39
          Shelly Gen3 mit 8 BTHome Geräten und Script hat Probleme mit dem Speicher.
          Teste mal ein nacktes Gen4 Gerät.
          Zuletzt geändert von AlexAn; In den letzten 4 Wochen.
          Grüße Alex

          Kommentar


          • hismastersvoice
            hismastersvoice kommentierte
            Kommentar bearbeiten
            Kannst du mir die Konsolen Ausgabe zeigen...
            Ggf debug einschalten.
        • AlexAn
          Lebende Foren Legende
          • 25.08.2015
          • 4555

          #40
          Klicke auf die Grafik für eine vergrößerte Ansicht  Name: image.png Ansichten: 0 Größe: 15,8 KB ID: 480566
          Klicke auf die Grafik für eine vergrößerte Ansicht  Name: image.png Ansichten: 0 Größe: 91,1 KB ID: 480568Konsole sag nichts bzw. das Script hört ohne Fehlermeldung auf.
          War mir aber schon klar da in der Vergangenheit immer wieder Hinweise diesbezüglich zu lesen waren.

          Das Script läuft aus meiner Sicht ohne Probleme.
          Bevor du da Energie rein steckst teste ich das mit einer anderen Hardware.
          Zuletzt geändert von AlexAn; In den letzten 4 Wochen.
          Grüße Alex

          Kommentar


          • AlexAn
            AlexAn kommentierte
            Kommentar bearbeiten
            Bei 2 Geräten mit Speicherproblemen war MQTT ein
            UDP bei allen Scanner ein
            AP aus
            Matter war ein

            Test ohne MQTT und Matter läuft

          • hismastersvoice
            hismastersvoice kommentierte
            Kommentar bearbeiten
            Ah.. dann verbraucht er dort wohl mehr Speicher.

            Schau ich mir mal an.

          • AlexAn
            AlexAn kommentierte
            Kommentar bearbeiten
            Plus und Gen3 laufen jetzt ohne MQTT/Matter
            Aktuell 9 Shelly Scanner in Betrieb
            Zuletzt geändert von AlexAn; In den letzten 4 Wochen.
        • hismastersvoice
          Supermoderator
          • 25.08.2015
          • 7596

          #41
          AlexAn
          Versuch das Skript mal, habe noch ein paar Optimierungen für den RAM eingebaut.
          Wusste nicht das Shelly alles in dem RAM lädt, sogar Kommentare.
          Er zeigt dir in der Konsole auch den Freeheap an...

          Code:
           [BLE] dachboden -> 192.168.136.120 [API] 20:30:43
           [MEM] boot free=82748 20:30:43
           [REG] Registering... 20:30:46
           [REG] OK 20:30:47
           [MEM] post-reg free=81396
          Code:
          let C={
                  name:"test",
                  host:"192.168.xxx.xxx",
                  api_key:"xxxxxxx",
                  scan_interval:5,
                  hb_interval:10,
                  offline_after:30,
                  debug:false
          };
          let VERSION="1.0.0";
          let BTHOME="fcd2";
          let EDDYSTONE="feaa";
          let CALIB_UUID_PREFIX="B1E0CA11";
          let _P="/shelly/";
          let _H="0123456789abcdef";
          let _s3="\x04\x05\x0A\x42\x4B\x4C";
          let _s4="\x3E\x4D\x4E\x4F\x50";
          let _s2="\x02\x03\x06\x07\x08\x0B\x0C\x0E\x12\x13\x14\x3D\x40\x41\x43\x45\x46\x47\x48\x49\x4A\x51\x52";
           
          function objSize(id){
            let c=String.fromCharCode(id);
            if(_s3.indexOf(c)>=0)return 3;
            if(_s4.indexOf(c)>=0)return 4;
            if(_s2.indexOf(c)>=0)return 2;
            if(id<=0x53)return 1;
            return -1;
          }
           
          let known={};
          let knownUuid={};
          let discMode=false;
          let discDevs={};
          let discTimer=null;
          let devs={};
          let pending=[];
          let ready=false;
          let scanning=false;
          let bootTs=0;
          let lastPid={};
          let calibBuf={};
          let batchTimer=null;
          let hbTimer=null;
          let pollTimer=null;
          let retryTimer=null;
          let offlineInitTimer=null;
           
          function ts(){return Math.floor(Date.now()/1000);}
           
          function mem(tag){
            Shelly.call("Sys.GetStatus",{},function(r){
              if(r)print("[MEM] "+tag+" free="+r.ram_free);
            });
          }
           
          function macKey(a){return a.split(":").join("").toLowerCase();}
           
          function toHex(b){return _H[(b>>4)&0xF]+_H[b&0xF];}
           
          function url(p){return "http://"+C.host+":8099"+p;}
           
          function post(p,body,cb){
            if(C.api_key)body.api_key=C.api_key;
            Shelly.call("HTTP.Request",{
              method:"POST",url:url(p),body:JSON.stringify(body),
              content_type:"application/json",timeout:5
            },function(r,ec){
              if(ec!==0||!r||!r.body){if(cb)cb(null);return;}
              try{if(cb)cb(JSON.parse(r.body));}catch(e){if(cb)cb(null);}
            });
          }
           
          function get(p,cb){
            let u=url(p);
            if(C.api_key)u+=(u.indexOf("?")>=0?"&":"?")+"api_key="+C.api_key;
            Shelly.call("HTTP.Request",{
              method:"GET",url:u,timeout:5
            },function(r,ec){
              if(ec!==0||!r||!r.body){if(cb)cb(null);return;}
              try{if(cb)cb(JSON.parse(r.body));}catch(e){if(cb)cb(null);}
            });
          }
           
          function parseBTHome(raw){
            if(!raw||raw.length<2)return null;
            let result={pid:-1,battery:-1,button:-1};
            if(raw.charCodeAt(0)&0x01)return null;
            let i=1;
            while(i<raw.length){
              let id=raw.charCodeAt(i);
              i++;
              if(id===0x53){
                if(i>=raw.length)break;
                i+=1+raw.charCodeAt(i);
                continue;
              }
              let size=objSize(id);
              if(size<0||i+size>raw.length)break;
              if(id===0x00||id===0x01||id===0x3A){
                let val=0;
                for(let b=0;b<size;b++){
                  val=val+(raw.charCodeAt(i+b)<<(b*8));
                }
                if(id===0x00)result.pid=val;
                else if(id===0x01)result.battery=val;
                else if(id===0x3A)result.button=val;
              }
              i+=size;
            }
            return result;
          }
           
          function parseEddystoneBatt(raw){
            if(!raw||raw.length<4)return -1;
            if(raw.charCodeAt(0)!==0x20)return -1;
            let mV=(raw.charCodeAt(2)<<8)|raw.charCodeAt(3);
            if(mV===0)return -1;
            let pct=Math.round((mV-2000)/10);
            if(pct<0)return 0;
            if(pct>100)return 100;
            return pct;
          }
           
          function parseIBeacon(advData){
            if(!advData)return null;
            let raw=BLE.GAP.ParseManufacturerData(advData);
            if(!raw||raw.length<25)return null;
            if(raw.charCodeAt(0)!==0x4C||raw.charCodeAt(1)!==0x00)return null;
            if(raw.charCodeAt(2)!==0x02||raw.charCodeAt(3)!==0x15)return null;
            let u="";
            for(let i=4;i<20;i++){
              u+=toHex(raw.charCodeAt(i));
              if(i===7||i===9||i===11||i===13)u+="-";
            }
            let txp=raw.charCodeAt(24);
            if(txp>127)txp-=256;
            return {uuid:u,major:(raw.charCodeAt(20)<<8)|raw.charCodeAt(21),minor:(raw.charCodeAt(22)<<8)|raw.charCodeAt(23),txpower:txp};
          }
           
          function isCalibBeacon(ib){
            if(!ib||!ib.uuid)return false;
            return ib.uuid.substring(0,8).toUpperCase()===CALIB_UUID_PREFIX;
          }
           
          function handleCalibBeacon(ib,rssi){
            let key=ib.major+":"+ib.minor;
            let e=calibBuf[key];
            if(!e){e={s:0,c:0,t:ib.txpower};calibBuf[key]=e;}
            e.s+=rssi;
            e.c++;
          }
           
          function sendCalibration(){
            let readings=[];
            for(let key in calibBuf){
              let e=calibBuf[key];
              if(e.c===0)continue;
              let parts=key.split(":");
              let avg=Math.round(e.s/e.c);
              readings.push({major:parseInt(parts[0]),minor:parseInt(parts[1]),rssi:avg,distance:Math.round(Math.pow(10,(e.t-avg)/25)*100)/100});
            }
            calibBuf={};
            if(readings.length===0)return;
            if(C.debug)print("[CAL] "+readings.length);
            post(_P+"calibration",{scanner:C.name,readings:readings},null);
          }
           
          function sendButtonEvent(mac,event,rssi,pid){
            let names=["none","press","double_press","triple_press","long_press"];
            let name=(event>=1&&event<=4)?names[event]:"unknown";
            if(C.debug)print("[BTN] "+mac+" -> "+name+" pid="+JSON.stringify(pid));
            post(_P+"event",{scanner:C.name,mac:mac,event:name,rssi:rssi,pid:pid,timestamp:ts()},null);
          }
           
          function loadKnown(macs){
            known={};
            knownUuid={};
            if(!macs)return;
            for(let i=0;i<macs.length;i++){
              let m=macs[i];
              if(m.length===12)known[m]=true;
              else if(m.length===36&&m.indexOf("-")>0)knownUuid[m]=true;
            }
          }
           
          function register(){
            print("[REG] Registering...");
            let info=Shelly.getDeviceInfo();
            let wifi=Shelly.getComponentStatus("wifi");
            post(_P+"register",{
              scanner:C.name,
              ip:(wifi&&wifi.sta_ip)?wifi.sta_ip:"0.0.0.0",
              model:info?(info.model||"Shelly"):"Shelly",
              firmware:info?(info.fw_id||"?"):"?",
              scan_interval:C.scan_interval
            },function(d){
              if(!d||!d.success){
                print("[REG] Failed, retry 10s");
                if(retryTimer)Timer.clear(retryTimer);
                retryTimer=Timer.set(10000,false,register);
                return;
              }
              loadKnown(d.known_macs);
              if(C.debug){
                let cM=0,cU=0;
                for(let k in known)cM++;
                for(let k in knownUuid)cU++;
                print("[REG] OK: "+cM+"M "+cU+"U");
              }else{
                print("[REG] OK");
              }
              mem("post-reg");
              if(d.scan_interval)C.scan_interval=d.scan_interval;
              ready=true;
              startScan();
              startTimers();
            });
          }
           
          function startScan(){
            if(scanning)return;
            BLE.Scanner.Subscribe(onScan);
            BLE.Scanner.Start({duration_ms:-1,active:true});
            scanning=true;
          }
           
          function onScan(ev,res){
            if(ev!==BLE.Scanner.SCAN_RESULT||!res||!res.addr)return;
           
            if(discMode){
              let mac=res.addr.toUpperCase();
              let ib=parseIBeacon(res.advData);
              let dk=ib?ib.uuid:macKey(mac);
              if(!discDevs[dk]||res.rssi>discDevs[dk].r){
                let entry={m:mac,n:res.local_name||"",r:res.rssi,tp:"mac"};
                if(ib){
                  entry.tp="ibeacon";
                  entry.iu=ib.uuid.toUpperCase();
                  entry.ima=ib.major;
                  entry.imi=ib.minor;
                }else if(res.service_data&&res.service_data[BTHOME]){
                  entry.tp="bthome";
                }
                discDevs[dk]=entry;
              }
              return;
            }
           
            let ib=parseIBeacon(res.advData);
            if(ib&&isCalibBeacon(ib)){
              handleCalibBeacon(ib,res.rssi);
              return;
            }
           
            let mac=res.addr.toUpperCase();
            let mk=macKey(mac);
            let isMac=known[mk]===true;
            let isUuid=false;
            let dk=mk;
           
            if(!isMac){
              if(ib&&knownUuid[ib.uuid]){
                isUuid=true;
                dk=ib.uuid;
              }else{
                return;
              }
            }
           
            let t=ts();
            let d=devs[dk];
            if(!d){
              d={o:false,s:0,r:-100,m:mac,t:0,b:-1,u:isUuid,ui:""};
              devs[dk]=d;
            }
           
            d.s=t;
            d.r=res.rssi;
            d.m=mac;
            if(isUuid&&ib)d.ui=ib.uuid;
           
            let bth=null;
            if(res.service_data&&res.service_data[BTHOME]){
              bth=parseBTHome(res.service_data[BTHOME]);
            }
           
            if(bth&&bth.pid>=0){
              if(lastPid[dk]===bth.pid)return;
              lastPid[dk]=bth.pid;
            }
           
            if(bth&&bth.battery>=0&&bth.battery<=100)d.b=bth.battery;
           
            if(d.b<0&&res.service_data&&res.service_data[EDDYSTONE]){
              let eB=parseEddystoneBatt(res.service_data[EDDYSTONE]);
              if(eB>=0)d.b=eB;
            }
           
            if(bth&&bth.button>=1){
              sendButtonEvent(mac,bth.button,res.rssi,bth.pid);
            }
           
            let wasOff=!d.o;
            d.o=true;
           
            let scan={address:mac,rssi:res.rssi,is_online:1,local_name:""};
            if(d.b>=0)scan.battery=d.b;
           
            if(isUuid&&ib){
              scan.ibeacon_uuid=ib.uuid;
              scan.ibeacon_major=ib.major;
              scan.ibeacon_minor=ib.minor;
              scan.ibeacon_txpower=ib.txpower;
            }
           
            if(wasOff){
              if(C.debug){
                let l=isUuid?dk.substring(0,8)+"...":mac;
                print("[ON] "+l+" R:"+res.rssi);
              }
              if(pending.length<20)pending.push(scan);
              d.t=t;
              sendBatch();
            }else if(t-d.t>=C.scan_interval){
              if(pending.length<20)pending.push(scan);
              d.t=t;
            }
          }
           
          function checkOffline(){
            let t=ts();
            let ct=C.offline_after*3;
            for(let mk in devs){
              let d=devs[mk];
              let age=t-d.s;
              if(d.o&&age>=C.offline_after){
                d.o=false;
                d.t=t;
                if(C.debug){
                  let l=d.u?d.ui.substring(0,8)+"...":d.m;
                  print("[OFF] "+l);
                }
                let os={address:d.m,rssi:-100,is_online:0,local_name:""};
                if(d.u&&d.ui)os.ibeacon_uuid=d.ui;
                if(pending.length<20)pending.push(os);
              }
              if(!d.o&&age>=ct){
                delete devs[mk];
                delete lastPid[mk];
              }
            }
          }
           
          function sendBatch(){
            if(!ready)return;
            checkOffline();
            if(pending.length===0)return;
            let scans=pending;
            pending=[];
            if(C.debug)print("[TX] "+scans.length);
            post(_P+"scan",{scanner:C.name,scans:scans,discovery:false},function(d){
              if(!d)print("[ERR] Batch failed");
            });
          }
           
          function heartbeat(){
            if(!ready)return;
            sendCalibration();
            Shelly.call("Sys.GetStatus",{},function(sr){
              let hb={scanner:C.name,uptime:ts()-bootTs};
              if(sr&&sr.ram_free){
                hb.free_mem=sr.ram_free;
                if(C.debug)print("[MEM] hb free="+sr.ram_free);
              }
              post(_P+"heartbeat",hb,function(d){
                if(!d||!d.success){
                  print("[ERR] HB failed");
                  ready=false;
                  if(retryTimer)Timer.clear(retryTimer);
                  retryTimer=Timer.set(5000,false,register);
                }
              });
            });
          }
           
          function offlineInit(){
            offlineInitTimer=null;
            let cnt=0;
            for(let mk in known){
              if(!devs[mk]){
                if(pending.length<20){
                  pending.push({address:mk,rssi:-100,is_online:0,local_name:""});
                  cnt++;
                }
              }
            }
            for(let uu in knownUuid){
              if(!devs[uu]){
                let c="";
                for(let j=0;j<uu.length;j++){
                  if(uu.charAt(j)!=="-")c+=uu.charAt(j);
                }
                if(pending.length<20){
                  pending.push({address:c,rssi:-100,is_online:0,local_name:"",ibeacon_uuid:uu});
                  cnt++;
                }
              }
            }
            if(cnt>0)sendBatch();
          }
           
          function startTimers(){
            if(batchTimer)Timer.clear(batchTimer);
            batchTimer=Timer.set(C.scan_interval*1000,true,sendBatch);
            if(hbTimer)Timer.clear(hbTimer);
            hbTimer=Timer.set(C.hb_interval*1000,true,heartbeat);
            if(offlineInitTimer)Timer.clear(offlineInitTimer);
            offlineInitTimer=Timer.set(C.offline_after*1000,false,offlineInit);
            if(pollTimer)Timer.clear(pollTimer);
            pollTimer=Timer.set(300000,true,pollDevices);
          }
           
          function startDiscovery(duration){
            if(discMode)return "already running";
            if(!duration||duration<5)duration=15;
            discMode=true;
            discDevs={};
            if(discTimer)Timer.clear(discTimer);
            discTimer=Timer.set(duration*1000,false,discEnd);
            return "started";
          }
           
          function discEnd(){
            discMode=false;
            discTimer=null;
            sendDiscoveryResults();
          }
           
          function sendDiscoveryResults(){
            let devices=[];
            for(let k in discDevs){
              let dd=discDevs[k];
              let entry={mac:dd.m,name:dd.n,rssi:dd.r,type:dd.tp};
              if(dd.iu){
                entry.ibeacon_uuid=dd.iu;
                entry.ibeacon_major=dd.ima;
                entry.ibeacon_minor=dd.imi;
              }
              devices.push(entry);
            }
            discDevs={};
            let dUrl="http://"+C.host+"/ble/api.php?action=report_discovery";
            if(C.api_key)dUrl+="&api_key="+C.api_key;
            Shelly.call("HTTP.Request",{
              method:"POST",url:dUrl,
              body:JSON.stringify({client_id:C.name,timestamp:ts(),devices:devices}),
              content_type:"application/json",timeout:15
            },function(r,ec){
              if(ec!==0||!r||r.code!==200)print("[DISC] Send failed");
            });
          }
           
          function pollDevices(){
            get(_P+"devices?scanner="+C.name,function(d){
              if(!d||!d.success||!d.known_macs)return;
              loadKnown(d.known_macs);
            });
          }
           
          function status(){
            let kon=0,koff=0,kn=0,ku=0;
            for(let mk in devs){if(devs[mk].o)kon++;else koff++;}
            for(let k in known)kn++;
            for(let k in knownUuid)ku++;
            return JSON.stringify({ready:ready,known_mac:kn,known_uuid:ku,online:kon,offline:koff,uptime:ts()-bootTs,pending:pending.length,discovery:discMode});
          }
           
          bootTs=ts();
          print("=== BLE Presence Shelly v"+VERSION+" ===");
          print("[BLE] "+C.name+" -> "+C.host+(C.api_key?" [API]":" [NO KEY]"));
          mem("boot");
          retryTimer=Timer.set(3000,false,register);
          Ich habe doch einen Shelly 1PM Mini da gehabt....
          Was ich gerade lernen musste, ist das im Zigbee-Mode das Bluetooth Modul sehr eingeschränkt ist, und er dann nicht alls Scanner laufen kann.
          Zuletzt geändert von hismastersvoice; In den letzten 4 Wochen.
          Kein Support per PN!

          Kommentar

          • AlexAn
            Lebende Foren Legende
            • 25.08.2015
            • 4555

            #42
            MQTT, UDP, und BTHome kein Problem (64.xxx)
            Sobald Matter und vermutlich auch ZigBee aktiviert wird hat er das Speicherproblem.


            Klicke auf die Grafik für eine vergrößerte Ansicht  Name: image.png Ansichten: 0 Größe: 5,1 KB ID: 480602

            Auch die alten Plus Geräte laufen mit dem neuen Script sehr stabil.
            Für mein Setting komme ich ohne Matter aus.



            Gen4 dürfte mit dem Script ein Problem haben:
            Klicke auf die Grafik für eine vergrößerte Ansicht  Name: image.png Ansichten: 0 Größe: 67,5 KB ID: 480604
            altes und neues Script probiert.
            im Master ist der 10. Scanner online - Zugangsdaten also OK
            Zuletzt geändert von AlexAn; In den letzten 4 Wochen.
            Grüße Alex

            Kommentar


            • hismastersvoice
              hismastersvoice kommentierte
              Kommentar bearbeiten
              Gen4 hat zwei Firmware Typen.
              Zigbee oder Matter.

              Bei der Zigbee Firmware sind viele BLE Funktionen abgeschaltet. Geht nur mit der Matter FW.
          • AlexAn
            Lebende Foren Legende
            • 25.08.2015
            • 4555

            #43
            MQTT und Matter ist auf EIN

            Klicke auf die Grafik für eine vergrößerte Ansicht

Name: image.png
Ansichten: 63
Größe: 51,8 KB
ID: 480641
            Grüße Alex

            Kommentar

            • AlexAn
              Lebende Foren Legende
              • 25.08.2015
              • 4555

              #44
              Wie kann ich Scanner löschen die ich umbenannt habe?
              Bei den registrierten Shellies ist er weg aber beim Dashboard ist er nach wie vor offline vorhanden.
              Zuletzt geändert von AlexAn; In den letzten 4 Wochen.
              Grüße Alex

              Kommentar


              • hismastersvoice
                hismastersvoice kommentierte
                Kommentar bearbeiten
                Dashboard - Cleanup
            • AlexAn
              Lebende Foren Legende
              • 25.08.2015
              • 4555

              #45
              Manchmal wäre es so einfach...

              Zwischenzeitlich hat sich ein Script an einem Shelly aufgehängt weil er zu viele Zugriffe hatte. Hab mal die Sensoren die ich nicht brauche gelöscht und arbeite vorerst nur mit 5Taster und einem iPhone.
              Grüße Alex

              Kommentar


              • hismastersvoice
                hismastersvoice kommentierte
                Kommentar bearbeiten
                Was heißt zu viele Zugriffe?
                Was für Devices hast du genutzt, bzw. wie viele?

                Ich habe das Skript RAM-technisch eigentlich auf 30 Devices ausgelegt.

              • AlexAn
                AlexAn kommentierte
                Kommentar bearbeiten
                5x H&T und ein Ultraschall
                4 oder 5 waren auf einem Scanner

                Über die Nacht kein Ausfall
            Lädt...