diff --git a/CHANGELOG.md b/CHANGELOG.md index cd3669d..f4e6d76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog All notable changes to this project will be documented in this file. +## [11.4.0] - 2024-10-04 +### support for shelly RC button 4 - [#181](https://github.com/windkh/node-red-contrib-shelly/issues/181) + ## [11.3.0] - 2024-09-27 ### removed all promises diff --git a/README.md b/README.md index 8bb19f8..5f826be 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ Generation 3 devices: - Shelly 1 Mini, 1PM Mini, PM Mini - Shelly Plus H&T +BLU Devices +- Shelly RC Button 4 Others may work but are not really tested so far. @@ -786,6 +788,8 @@ pane telling you that installation of the webhook failed. ## BLU Gateway (Shelly BLU Gateway) The node is able to control a shelly BLU gateway. This node should be only used with callback mode and event output. It uploads two scripts: one for the callback like in all other gen 2 devices and one that scans for bluetooth signals. +This script was taken from https://github.com/ALLTERCO/shelly-script-examples/blob/main/ble-shelly-blu.js and is licensed +under the apache 2.0 license! The output of the node is an event object. Bluetooth event objects have the event name "shelly-blu". @@ -808,6 +812,51 @@ msg.payload.info.data.address +## Some notes about BLU Support +Almost all gen2+ device support bluetooth and can be used as blu gateway by using callback mode and activating +the gateway support in the config node. Messages from the BLU devices are in BTHomeV2 format: https://bthome.io/format/ + + + +## BLU RC Button 4 +The node is able to control a shelly RC button 4. This device communicates via bluetooth. You must use at least one shelly as bluetooth +gateway to be able to receive message in node-red from that device. +This gateway node should be only used with callback mode and event output. +It uploads two scripts: one for the callback like in all other gen 2 devices and one that scans for bluetooth signals. +This script was taken from https://github.com/ALLTERCO/shelly-script-examples/blob/main/ble-shelly-blu.js and is licensed +under the apache 2.0 license! + +The output of the node is an event object. Bluetooth event objects have the event name "shelly-blu". + +BLU devices contain a detailed description about the types that are used: E.g. the documenation for the shelly RC button 4 +can be found here: https://shelly-api-docs.shelly.cloud/docs-ble/Devices/wall_us/ +Type 0x3A is tranmitted if a button is pressed. The value can be on of the following: +0x00 - none (button not pressed) +0x01 - press +0x02 - double press +0x03 - triple press +0x04 - long press +0xFE - hold +The buttons are transmitted as an array with the values mentioned above. + +``` +msg.payload.info.event === "shelly-blu" +``` + + +You can take the mac-address to find out what BLU device sent the messages: + + +``` +msg.payload.info.data.address +``` + + +### Examples: +[**shelly BLU RC button 4 flow**](examples/blubutton4.json) + + + # Shelly REST API For a complete documentation see also https://shelly-api-docs.shelly.cloud/#common-http-api diff --git a/examples/blubutton4.json b/examples/blubutton4.json new file mode 100644 index 0000000..8de4770 --- /dev/null +++ b/examples/blubutton4.json @@ -0,0 +1 @@ +[{"id":"5ae5ea9d59cabfd2","type":"shelly-gen2","z":"62a53d6e4cbdfb9a","hostname":"192.168.178.76","description":"ShellyBluGateway","mode":"callback","verbose":false,"server":"7f2759a4fe573634","outputmode":"event","uploadretryinterval":5000,"pollinginterval":5000,"pollstatus":false,"getstatusoncommand":false,"devicetype":"SNGW-BT01","devicetypemustmatchexactly":false,"captureblutooth":true,"outputs":1,"x":330,"y":100,"wires":[["cca090e1ec3df949","1036e2e1278be0a8"]]},{"id":"cc48394b6f62d257","type":"debug","z":"62a53d6e4cbdfb9a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":100,"wires":[]},{"id":"47a53d4373d2f908","type":"inject","z":"62a53d6e4cbdfb9a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":100,"wires":[["5ae5ea9d59cabfd2"]]},{"id":"cca090e1ec3df949","type":"function","z":"62a53d6e4cbdfb9a","name":"filter for BLU events","func":"if(msg.payload.info){\n let isBluMessage = msg.payload.info.event === \"shelly-blu\";\n if (isBluMessage){\n node.send([msg, null]);\n }\n}\nelse{\n node.send([null, msg]);\n}\n","outputs":2,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":100,"wires":[["274ab400bebe2077"],["659e6672bcb7be07"]]},{"id":"93977f546b1ba812","type":"debug","z":"62a53d6e4cbdfb9a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":60,"wires":[]},{"id":"274ab400bebe2077","type":"function","z":"62a53d6e4cbdfb9a","name":"switch RC button 4","func":"// see also https://shelly-api-docs.shelly.cloud/docs-ble/Devices/wall_us/\n\n// TODO: adapt your mac addresses here\nlet rcbutton4 = \"7c:c6:b6:75:1b:1d\";\n\nif (msg.payload.info.data.address == rcbutton4){\n let buttons = msg.payload.info.data.button;\n\n let messages = [];\n\n for(let i=0; i 0) { _bth = BTH[buffer.at(0)]; if (typeof _bth === "undefined") { - logger("unknown type", "BTH"); + console.log("BTH: Unknown type"); break; } buffer = buffer.slice(1); _value = this.getBufValue(_bth.t, buffer); if (_value === null) break; if (typeof _bth.f !== "undefined") _value = _value * _bth.f; - result[_bth.n] = _value; + + if (typeof result[_bth.n] === "undefined") { + result[_bth.n] = _value; + } + else { + if (Array.isArray(result[_bth.n])) { + result[_bth.n].push(_value); + } + else { + result[_bth.n] = [ + result[_bth.n], + _value + ]; + } + } + buffer = buffer.slice(getByteSize(_bth.t)); } return result; }, }; -// Еmitting the decoded BLE data to a specified event. It allows other scripts to receive and process the emitted data +/** + * Еmitting the decoded BLE data to a specified event. It allows other scripts to receive and process the emitted data + * @param {DeviceData} data + */ function emitData(data) { if (typeof data !== "object") { return; @@ -158,7 +187,6 @@ function BLEScanCallback(event, result) { typeof result.service_data === "undefined" || typeof result.service_data[BTHOME_SVC_ID_STR] === "undefined" ) { - logger("Missing service_data member", "Error"); return; } @@ -172,7 +200,7 @@ function BLEScanCallback(event, result) { typeof unpackedData === "undefined" || unpackedData["encryption"] ) { - logger("Encrypted devices are not supported", "Error"); + console.log("Error: Encrypted devices are not supported"); return; } @@ -185,6 +213,7 @@ function BLEScanCallback(event, result) { unpackedData.rssi = result.rssi; unpackedData.address = result.addr; + unpackedData.model = result.local_name; emitData(unpackedData); } @@ -198,7 +227,7 @@ function init() { } //get the config of ble component - let BLEConfig = Shelly.getComponentConfig("ble"); + const BLEConfig = Shelly.getComponentConfig("ble"); //exit if the BLE isn't enabled if (!BLEConfig.enable) { @@ -214,7 +243,7 @@ function init() { } else { //start the scanner - let bleScanner = BLE.Scanner.Start({ + const bleScanner = BLE.Scanner.Start({ duration_ms: BLE.Scanner.INFINITE_SCAN, active: CONFIG.active }); @@ -226,6 +255,11 @@ function init() { //subscribe a callback to BLE scanner BLE.Scanner.Subscribe(BLEScanCallback); + + // disable console.log when logs are disabled + if (!CONFIG.debug) { + console.log = function() {}; + } } -init(); \ No newline at end of file +init(); diff --git a/shelly/scripts/callback.script b/shelly/scripts/callback.js similarity index 100% rename from shelly/scripts/callback.script rename to shelly/scripts/callback.js