So anbei noch das Script wie gesagt fehlt mir jetzt noch die Daten in HA zu bekommen werde aber auf MQTT gehen müssen. Aber Grundsätzlich wird das Device gefunden.
Ist halt erst mal nur grob hingeknallt 🤣
let CONFIG = {
room: "Büro",
prefix: "presence",
topic: "/presence",
rssiPresent: -40,
rssiNotPresent: -99,
mfdID: 0x004c,
handoff: 0x0c,
nearby: 0x10,
phone: 0x0e,
watch: 0x0f,
handoffActive: true,
debug: true
};
let DeviceParser = {
getData: function (res) {
if (res === null) return null;
let rssi = null;
let data = BLE.GAP.ParseManufacturerData(res.advData);
packedStruct.setBuffer(data);
let device = packedStruct.unpack('<HB>BB', ['mfdID', 'data0', 'data1', 'data2']);
if (device.mfdID !== CONFIG.mfdID) return null;
if (device.data0 === CONFIG.nearby) return null;
if (device.data0 === CONFIG.handoff && CONFIG.handoffActive === true){
rssi = Math.max(res.rssi, rssi);
if (CONFIG.debug === true) {
print ("Found Apple boradcast for handoff");
print ("mac=",res.addr,"; rssi=",res.rssi);
}
}
if (device.data2 === CONFIG.watch){
rssi = Math.max(res.rssi, rssi);
if (CONFIG.debug === true) {
print ("Found Apple Watch");
print ("mac=",res.addr,"; ac=",device.data2,"; rssi=",res.rssi);
}
}
if (device.data2 === CONFIG.phone){
rssi = Math.max(res.rssi, rssi);
if (CONFIG.debug === true) {
print ("Found iPhone");
print ("mac=",res.addr,"; ac=",device.data2,"; rssi=",res.rssi);
}
}
if (rssi === null) return null;
let rm = {
addr: res.addr,
rssi: res.rssi
};
return rm;
},
};
function scanCB(ev, res) {
if (ev !== BLE.Scanner.SCAN_RESULT) return;
let presence = DeviceParser.getData(res);
if (presence === null) return;
presence.presence = true;
presence.room = CONFIG.room;
print (JSON.stringify(presence));
if (presence.rssi > CONFIG.rssiPresent){
//presence.presence = true;
//Shelly.emitEvent("ble_presence", presence);
if (CONFIG.debug === true) {
print("present", JSON.stringify(presence));
}
} else if (presence.rssi < CONFIG.rssiNotPresent){
//presence.presence = false;
//Shelly.emitEvent("ble_presence", presence);
if (CONFIG.debug === true) {
print("not_present", JSON.stringify(presence));
}
}
}
BLE.Scanner.Start({
duration_ms: BLE.Scanner.INFINITE_SCAN,
active: true,
interval_ms: 1200,
window_ms: 50
}, scanCB);
let packedStruct = {
buffer: '',
setBuffer: function(buffer) {
this.buffer = buffer;
},
utoi: function(u16) {
return (u16 & 0x8000) ? u16 - 0x10000 : u16;
},
getUInt8: function() {
return this.buffer.at(0)
},
getInt8: function() {
let int = this.getUInt8();
if(int & 0x80) int = int - 0x100;
return int;
},
getUInt16LE: function() {
return 0xffff & (this.buffer.at(1) << 8 | this.buffer.at(0));
},
getInt16LE: function() {
return this.utoi(this.getUInt16LE());
},
getUInt16BE: function() {
return 0xffff & (this.buffer.at(0) << 8 | this.buffer.at(1));
},
getInt16BE: function() {
return this.utoi(this.getUInt16BE(this.buffer));
},
unpack: function(fmt, keyArr) {
let b = '<>!';
let le = fmt[0] === '<';
if(b.indexOf(fmt[0]) >= 0) {
fmt = fmt.slice(1);
}
let pos = 0;
let jmp;
let bufFn;
let res = {};
while(pos<fmt.length && pos<keyArr.length && this.buffer.length > 0) {
jmp = 0;
bufFn = null;
if(fmt[pos] === 'b' || fmt[pos] === 'B') jmp = 1;
if(fmt[pos] === 'h' || fmt[pos] === 'H') jmp = 2;
if(fmt[pos] === 'b') {
res[keyArr[pos]] = this.getInt8();
}
else if(fmt[pos] === 'B') {
res[keyArr[pos]] = this.getUInt8();
}
else if(fmt[pos] === 'h') {
res[keyArr[pos]] = le ? this.getInt16LE() : this.getInt16BE();
}
else if(fmt[pos] === 'H') {
res[keyArr[pos]] = le ? this.getUInt16LE() : this.getUInt16BE();
}
this.buffer = this.buffer.slice(jmp);
pos++;
}
return res;
}
};
Alles anzeigen