Hallo zusammen
Ich versuche nun schon ein Weilchen die States meines BLU Motion in mein iobroker zu bekommen.
Ich habe den USB BLU Gateway (mit mqtt zum iobroker verbunden, wird dort als true angezeigt) und den BLU Motion mit dem USB BLU Gateway verbunden. In der Shelly App werden mir beide angezeigt, auch die States des BLU Motion.
Ich habe nun das Skript hier genommen, um die States des BLU Motion auch im iobroker zu haben - da ja das wohl sonst nicht geht...
Ich habe das Skript im BLU Gateway eingefügt und es läuft (debug aktiviert).
Im iobroker werden jedoch keine Datenpunkte für den BLU Motion angelegt; auch im Debug vom Adapter im iobroker wird nichts angezeigt....
Was mache ich falsch?
Hier das kopierte und angepasste Skript:
/* ============================= Config CHANGE HERE =============================== */
let mqttID = "shellyBLU"; //MQTT Topic ID, (behind topicPrefix)
let mqttIDwithDType = true; //Adds a device type to the MQTT topic ID, can be disabled for backward compatibility, true/false
let sendMQTT = true; //Send Blu Data also per MQTT, true/false
let topicPrefix = "blumotionoben"; //Here you can set your own mqtt Topic Prefix
let vSwitch = false; //Create MQTT virtual Switch states, true/false
let uFixer = false; //Try to Fix Shelly MQTT Connections Bugs, true/false
let debug = true; //Show debug msg in log, true/false, warning setting this to 'true' will delay reaktion speed a lot
/* ============================== STOP CHANGING HERE =============================== */
//========= Skript Setup =========
let mqttQOS = 0; //MQTT QOS Setting, Can be 0 - at most once, 1 - at least once or 2 exactly once. Default is 0
let activeScan = true; //Active or Passiv Bluetooth Scan, true/false
let _cid = "0ba9"; //Allterco, Company ID(MFD)
let uuid = "fcd2"; //BTHome, Service ID
let devID1 = "SBBT"; //Blu Button1, deviceID, --> SBBT-002C, evt. 002C = Device Charge???
let devID2 = "SBDW"; //Blu Door/Window, deviceID --> SBDW-002C
let devID3 = 'SBMO'; //Blu Motion, deviceID, --> SBMO-003Z
let BTHomeObj = {}, vSwitchCache = {}, last_packet_id = 0x100, last_addr = 0, scanDuration = BLE.Scanner.INFINITE_SCAN, tHandel = null;
let bthObjectIDs = []; //Used BTHome Service.Payload ObjectID List for BluButton1 and BluDoorWindow,(here you can find a full Device List --> " https://bthome.io/format ")
bthObjectIDs[0x00] = { key: 'pid', dataType: 'uint8' };
bthObjectIDs[0x01] = { key: 'battery', dataType: 'uint8', unit: '%' };
bthObjectIDs[0x3a] = { key: 'inputID', dataType: 'uint8' };
bthObjectIDs[0x05] = { key: 'illuminance', dataType: 'uint24', factor: 0.01 };
bthObjectIDs[0x1a] = { key: 'doorStateID', dataType: 'uint8' };
bthObjectIDs[0x2d] = { key: 'windowStateID', dataType: 'uint8' };
bthObjectIDs[0x3f] = { key: 'rotationLvl', dataType: 'int16', factor: 0.1 };
bthObjectIDs[0x21] = { key: 'motionID', dataType: 'uint8' };
//Change settings into string and boolean map and cheack befor using, mit ner schleife
//=========== End Setup ===========
function Str(data){
if(data === null || data === undefined) return null;
if(typeof data === 'string') return data;
return JSON.stringify(data);
}
function FixMQTT() {
//Restart Shelly if MQTT connection is false, over 10 min.
print('Debug: MQTT connection Status is _[', MQTT.isConnected(), ']_');
if (!MQTT.isConnected()) print('Debug: Trying to Fix MQTT Connection with Reboot');
if (!MQTT.isConnected()) Shelly.call('Shelly.Reboot');
if (tHandel) Timer.clear(tHandel);
}
function SendMQTTmsg(mac, event) {
if (MQTT.isConnected()) {
let mainTopic = mqttID + '-', Get = event.info.data, dID = 'Error_no_ID', topicCount = 0, edID = Str(Get.doorStateID)||Str(Get.windowStateID)||Str(Get.motionID);
if(edID !== null) dID = 'd'+ edID;
if(Str(Get.inputID)) dID = Str(Get.inputID);
//Clear uFixer Timer
if (tHandel) Timer.clear(tHandel);
tHandel = null;
//Virtual Switch logic
if (vSwitch && dID && dID !== '0' && dID !== '254') {
if (vSwitchCache['s' + dID] === undefined || vSwitchCache['s' + dID] === 'false') {
vSwitchCache['s' + dID] = 'true';
} else {
vSwitchCache['s' + dID] = 'false';
}
}
//Prefix and MQTTid logic
if (mqttIDwithDType && typeof Get.assumedDevice === 'string') mainTopic += Get.assumedDevice + '-';
mainTopic += mac + '/';
if (topicPrefix.length !== 0) mainTopic = topicPrefix + '/' + mainTopic;
let mqttTopicMap = [ //A map of all MQTT Topics that can be send
{ key: 'events/rpc', value: event },
{ key: 'status/input:' + dID, value: event.info.ts },
{ key: 'status/switch:' + dID, value: vSwitchCache['s' + dID] },
{ key: 'info/battery', value: Get.battery},
{ key: 'info/rssi', value: Get.rssi },
{ key: 'info/lastTimeStamp', value: event.info.ts },
{ key: 'info/lastAktion', value: event.info.event },
{ key: 'info/lastAktionID', value: dID },
{ key: 'info/mac', value: Get.mac },
{ key: 'info/device', value: Get.device },
{ key: 'info/assumedDevice', value: Get.assumedDevice },
{ key: 'info/gateway', value: Get.gateway },
{ key: 'info/deviceMode', value: Get.deviceMode },
{ key: 'status/deviceState', value: Get.deviceState },
{ key: 'status/illuminance', value: Get.illuminance },
{ key: 'status/rotationLvl', value: Get.rotationLvl }];
//Send MQTT Msg/topics, publish all msgs
if (debug) print('Debug: MQTT Publishing_Topic: ', mainTopic, 'events/rpc _Payload: ', Str(event));
for (i in mqttTopicMap) {
if (mqttTopicMap[i].key && mqttTopicMap[i].value !== undefined) {
MQTT.publish(mainTopic + mqttTopicMap[i].key, Str(mqttTopicMap[i].value), mqttQOS);
topicCount += 1;
}
}
if (debug) print('Debug: ', topicCount, ' out of ', mqttTopicMap.length, ' possible MQTT messages have been sent.');
} else {
print('Error: MQTT is still not ready, cant send msg');
if (!tHandel && uFixer) {
print('Debug: Trying to Fix MQTT Connection Bug, this will take about 15min.');
tHandel = Timer.set(10 * 60 * 1000, false, FixMQTT);
}
}
}
function FilterEvents(obj) {
if (obj.info === undefined || obj.info.data === undefined) return;
if (obj.info.data.generation === 'BLU') SendMQTTmsg(obj.info.data.mac, obj);
}
function TranslateButtonEvents(buttonID) {
if (typeof buttonID !== 'number') return;
let buttonEventMap = ['wake_up', 'single_push', 'double_push', 'triple_push', 'long_push', 'pairing_push', 'default_reset_push'], bInput = buttonID;
if (bInput > 6 && bInput !== 254) bInput = 'unknown_push';
if (bInput < 7) bInput = buttonEventMap[bInput];
if (bInput === 254) bInput = 'hold_push';
return bInput;
}
let BTHomeDecoder = {
UInt_To_Int: function (uint, bitsz) {
let mask = 1 << (bitsz - 1); //create mask to filter last bit
if (uint & mask) {
return uint - (1 << bitsz); //convert uint to negative int
} else {
return uint; //uint is positive, no change needed.
}
},
GetMaxBytes: function (dataType) {
if (dataType === 'uint8' || dataType === 'int8') return 1;
if (dataType === 'uint16' || dataType === 'int16') return 2;
if (dataType === 'uint24' || dataType === 'int24') return 3;
return 255;
},
GetValue: function (dataType, buffer) {
let maxBytes = this.GetMaxBytes(dataType);
if (buffer.length < maxBytes) {
print('Error: ValueBuffer has, ', buffer.length, ' Bytes with DataType, ', dataType);
return null;
}
let data = null;
let _1stByte = buffer.at(0); //get 1.Byte of Buffer
let _2ndByte = null;
if (maxBytes > 1) _2ndByte = buffer.at(1); //get 2.Byte of Buffer
let _3rdByte = null;
if (maxBytes > 2) _3rdByte = buffer.at(2); //get 3.Byte of Buffer
if (dataType === 'uint8') data = _1stByte;
if (dataType === 'int8') data = this.UInt_To_Int(_1stByte, 8);
if (dataType === 'uint16') data = 0xffff & ((_2ndByte << 8) | _1stByte);
if (dataType === 'int16') data = this.UInt_To_Int(0xffff & ((_2ndByte << 8) | _1stByte), 16);
if (dataType === 'uint24') data = 0x00ffffff & ((_3rdByte << 16) | (_2ndByte << 8) | _1stByte);
if (dataType === 'int24') data = this.UInt_To_Int(0x00ffffff & ((_3rdByte << 16) | (_2ndByte << 8) | _1stByte), 24);
return data;
},
Unpack: function (payload) {
if (typeof payload !== "string" || payload.length === 0) return null;
let btHomeObj = {}, byte = payload.at(0), value, objectID; //byte = payload.at(0) --> get 1.Byte of Payload
if (byte & 0x1) {
btHomeObj['encryption'] = true; //analyze 1. Bit and set btHomeObj encryption boolean
} else {
btHomeObj['encryption'] = false;
}
btHomeObj['version'] = byte >> 5; //cut,move to 6.Bit, save the rest as version
if (btHomeObj['version'] !== 2) return null; //analyse the rest Bits 6,7,8 inside version, exit if BTHome Version is not 2
if (btHomeObj['encryption']) return btHomeObj; //exit if payload is encrypted
payload = payload.slice(1); //remove used 1.Byte from payload
while (payload.length > 0) {
byte = payload.at(0); //get 1.Byte of Payload
objectID = bthObjectIDs[byte]; //compare 1.Byte with known BTHome objectIds list, add parameter if known object
if (objectID === undefined) {
print('Error: Unknown BThome Object, decimal_ID: ', byte, ' convert to hex and compare hex_ID "0x.." with full objID list --> https://bthome.io/format');
break; //exit loop, if objectID is unknown
}
payload = payload.slice(1); //remove used 1.Byte from payload
value = this.GetValue(objectID.dataType, payload);
if (value === null || value === undefined) break; //exit loop
if (objectID.factor !== undefined) value = (value * objectID.factor); //add factor
btHomeObj[objectID.key] = value;
if (objectID.unit !== undefined) value = (Str(value) + objectID.unit); //add unit
if (objectID.unit !== undefined) btHomeObj[(objectID.key + "String")] = value;
payload = payload.slice(this.GetMaxBytes(objectID.dataType)); //remove used value Bytes from payload
}
return btHomeObj;
},
};
function SendEvent() {
if (typeof BTHomeObj.inputID === 'number' && BTHomeObj.illuminance === undefined) BTHomeObj.assumedDevice = 'Button'; //somehow filter for blu Button
if (typeof BTHomeObj.illuminance === 'number' && BTHomeObj.motion === undefined) BTHomeObj.assumedDevice = 'Door-Window'; //somehow filter for blu Door-Window
if (typeof BTHomeObj.motionID === 'number') BTHomeObj.assumedDevice = 'Motion'; //somehow fiter for blu Motion
if (typeof BTHomeObj.doorStateID === 'number') BTHomeObj.deviceMode = 'Door';
if (typeof BTHomeObj.windowStateID === 'number') BTHomeObj.deviceMode = 'Window';
if (BTHomeObj.deviceMode) BTHomeObj.deviceState = Str(BTHomeObj.doorStateID) || Str(BTHomeObj.windowStateID);
if (BTHomeObj.deviceState === '1') BTHomeObj.deviceState = 'Open';
if (BTHomeObj.deviceState === '0') BTHomeObj.deviceState = 'Closed';
if (BTHomeObj.assumedDevice) BTHomeObj.generation = 'BLU';
if (typeof BTHomeObj.motionID === 'number') BTHomeObj.deviceState = BTHomeObj.motionID;
if (BTHomeObj.motionID === 1) BTHomeObj.deviceState = 'Motion-Detected';
if (BTHomeObj.motionID === 0) BTHomeObj.deviceState = 'No-Motion';
Shelly.emitEvent(BTHomeObj.buttonInput || 'Status_' + BTHomeObj.deviceState, BTHomeObj);
}
function ScanCB(status, response) {
if (status !== BLE.Scanner.SCAN_RESULT) return; //exit if Scan status is stopped or unknown
if (response.service_data === undefined || response.service_data[uuid] === undefined) return; //Filter only BThome Responses
BTHomeObj = BTHomeDecoder.Unpack(response.service_data[uuid]); //decode Sevice Data
if (BTHomeObj === null) { print('Error: Failed to Unpack service_data of, ', response.addr); return; }
if (last_packet_id === BTHomeObj.pid && last_addr === response.addr) return; //exit if packet is already known.
if (debug) print('Debug: Received packet, raw Data:', response);
if (response.local_name !== undefined) BTHomeObj.device = 'Unknown-Device--> ' + response.local_name;
if (response.local_name !== undefined && response.local_name.indexOf(devID1) >= 0) BTHomeObj.device = 'Blu-Button1'; //search for Blu Button1
if (response.local_name !== undefined && response.local_name.indexOf(devID2) >= 0) BTHomeObj.device = 'Blu-Door-Window'; //search for Blu Door/Window
if (response.local_name !== undefined && response.local_name.indexOf(devID3) >= 0) BTHomeObj.device = 'Blu-Motion'; //search for Blu Motion
if (response.local_name === undefined) BTHomeObj.device = 'Hidden-Device';
last_packet_id = BTHomeObj.pid, last_addr = response.addr, BTHomeObj.mac = response.addr, BTHomeObj.rssi = response.rssi, BTHomeObj.gateway = Shelly.getDeviceInfo().id;
if (debug) print('Debug: Received BTHome packet: ', BTHomeObj);
BTHomeObj.buttonInput = TranslateButtonEvents(BTHomeObj.inputID);
SendEvent();
}
function Start_BLE_Scan() {
let bleScanStarted = BLE.Scanner.Start({ duration_ms: scanDuration, active: activeScan }, ScanCB);
if (bleScanStarted === false) {
print('Error: BTHome Scanner could not be started, will try again in 5sek.');
Timer.set(5000, false, Start_BLE_Scan);
} else {
let scanType = 'Passiv';
if (activeScan) scanType = 'Active';
print('Status: BTHome ', scanType, ' Scanner running in Background');
}
}
//__Main__
Start_BLE_Scan();
if (sendMQTT) Shelly.addEventHandler(FilterEvents);
Alles anzeigen
Im Debug vom Gateway-Skript steht folgendes:
Debug: Received packet, raw Data: {
19:25:13
"addr": "60:ef:ab:16:34:5d",
19:25:13
"addr_type": 1, "rssi": -77,
19:25:13
"advData": "\2\1\6\x0E\x16��D\0\5\1d\5�5\0!\0",
19:25:13
"scanRsp": "\n\bSBMO-003Z\x10��\v\1\1\0\v\5\0\n]4\x16��`",
19:25:13
"flags": 6,
19:25:13
"local_name": "SBMO-003Z",
19:25:13
"manufacturer_data": {
19:25:13
"0ba9": "\1\1\0\v\5\0\n]4\x16��`"
19:25:13
},
19:25:13
"service_data": {
19:25:13
"fcd2": "D\0\5\1d\5�5\0!\0"
19:25:13
}
19:25:13
}
19:25:13
Debug: Received BTHome packet: { "encryption": false, "version": 2, "pid": 5, "battery": 100,
19:25:13
"batteryString": "100%",
19:25:13
"illuminance": 138, "motionID": 0,
19:25:13
"device": "Blu-Motion",
19:25:13
"mac": "60:ef:ab:16:34:5d",
19:25:13
"rssi": -77,
19:25:13
"gateway": "shellyblugw-3ce90e7dd764"
19:25:14
}
19:25:14
Debug: MQTT Publishing_Topic: blumotionoben/shellyBLU-Motion-60:ef:ab:16:34:5d/ events/rpc _Payload: {"component":"script:1","name":"script","id":1,"now":1695835514.01855683326,"info":{"component":"script:1","id":1,"event":"Status_No-Motion","data":{"en
19:25:14
ryption":false,"version":2,"pid":5,"battery":100,"batteryString":"100%","illuminance":138,"motionID":0,"device":"Blu-Motion","mac":"60:ef:ab:16:34:5d","rssi":-77,"gateway":"shellyblugw-3ce90e7dd764","assumedDevice":"Motion","generation":"BLU","deviceState
19:25:14
:"No-Motion"},"ts":1695835514.01999998092}}
19:25:14
Debug: 13 out of 16 possible MQTT messages have been sent.
19:25:14
Debug: Received packet, raw Data: {
19:26:41
"addr": "60:ef:ab:16:34:5d",
19:26:41
"addr_type": 1, "rssi": -76,
19:26:41
"advData": "\2\1\6\x0E\x16��D\0\6\1d\5\0\0\0!\1",
19:26:41
"scanRsp": "\n\bSBMO-003Z\x10��\v\1\1\0\v\5\0\n]4\x16��`",
19:26:41
"flags": 6,
19:26:41
"local_name": "SBMO-003Z",
19:26:41
"manufacturer_data": {
19:26:41
"0ba9": "\1\1\0\v\5\0\n]4\x16��`"
19:26:41
},
19:26:41
"service_data": {
19:26:41
"fcd2": "D\0\6\1d\5\0\0\0!\1"
19:26:41
}
19:26:41
}
19:26:41
Debug: Received BTHome packet: { "encryption": false, "version": 2, "pid": 6, "battery": 100,
19:26:41
"batteryString": "100%",
19:26:41
"illuminance": 0, "motionID": 1,
19:26:41
"device": "Blu-Motion",
19:26:41
"mac": "60:ef:ab:16:34:5d",
19:26:41
"rssi": -76,
19:26:41
"gateway": "shellyblugw-3ce90e7dd764"
19:26:41
}
19:26:41
Debug: MQTT Publishing_Topic: blumotionoben/shellyBLU-Motion-60:ef:ab:16:34:5d/ events/rpc _Payload: {"component":"script:1","name":"script","id":1,"now":1695835601.29745817184,"info":{"component":"script:1","id":1,"event":"Status_Motion-Detected","data
19:26:41
:{"encryption":false,"version":2,"pid":6,"battery":100,"batteryString":"100%","illuminance":0,"motionID":1,"device":"Blu-Motion","mac":"60:ef:ab:16:34:5d","rssi":-76,"gateway":"shellyblugw-3ce90e7dd764","assumedDevice":"Motion","generation":"BLU","deviceS
19:26:41
ate":"Motion-Detected"},"ts":1695835601.29999995231}}
19:26:41
Debug: 13 out of 16 possible MQTT messages have been sent.
19:26:41
Debug: Received packet, raw Data: {
19:28:22
"addr": "60:ef:ab:16:34:5d",
19:28:22
"addr_type": 1, "rssi": -77,
19:28:22
"advData": "\2\1\6\x0E\x16��D\0\7\1d\5@8\0!\0",
19:28:22
"scanRsp": "\n\bSBMO-003Z\x10��\v\1\1\0\v\5\0\n]4\x16��`",
19:28:22
"flags": 6,
19:28:22
"local_name": "SBMO-003Z",
19:28:22
"manufacturer_data": {
19:28:22
"0ba9": "\1\1\0\v\5\0\n]4\x16��`"
19:28:22
},
19:28:22
"service_data": {
19:28:22
"fcd2": "D\0\7\1d\5@8\0!\0"
19:28:22
}
19:28:22
}
19:28:22
Debug: Received BTHome packet: { "encryption": false, "version": 2, "pid": 7, "battery": 100,
19:28:22
"batteryString": "100%",
19:28:22
"illuminance": 144, "motionID": 0,
19:28:22
"device": "Blu-Motion",
19:28:22
"mac": "60:ef:ab:16:34:5d",
19:28:22
"rssi": -77,
19:28:22
"gateway": "shellyblugw-3ce90e7dd764"
19:28:22
}
19:28:22
Debug: MQTT Publishing_Topic: blumotionoben/shellyBLU-Motion-60:ef:ab:16:34:5d/ events/rpc _Payload: {"component":"script:1","name":"script","id":1,"now":1695835702.72083306312,"info":{"component":"script:1","id":1,"event":"Status_No-Motion","data":{"en
19:28:22
ryption":false,"version":2,"pid":7,"battery":100,"batteryString":"100%","illuminance":144,"motionID":0,"device":"Blu-Motion","mac":"60:ef:ab:16:34:5d","rssi":-77,"gateway":"shellyblugw-3ce90e7dd764","assumedDevice":"Motion","generation":"BLU","deviceState
19:28:22
:"No-Motion"},"ts":1695835702.72000002861}}
19:28:22
Debug: 13 out of 16 possible MQTT messages have been sent.
19:28:22
›_
Alles anzeigen
Grüsse Euch
Matt