Ich hatte da auch schonmal was grob entworfen für IOS für andere Geräte müsste man sich lediglich die einzelnen Parameter raussuchen. Hab mich aber aktuell erst mal auf andere Projekte gestürzt aber evtl. kann das ganze behilflich sein auch in Verbindung mit eine Button blu z.b.
Evtl. kannst du das mal für irgendwas gebrauchen.
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