Shelly BLU - basics and gateway script| Shelly BLU devices are
battery-powered sensors and push-buttons using Bluetooth. Unlike the
other Shelly devices they have no WLAN and therefore cannot
send MQTT messages themselves. They broadcast their readings as
Bluetooth advertisements in the BTHome v2 format. For the
controller to receive these readings a gateway is required: a
mains-powered Shelly device with WLAN that receives the Bluetooth
broadcast and forwards it to the controller as an MQTT message.
The BTHome telegrams are decoded by the controller itself - the
script on the gateway only forwards the raw data. New device types
are therefore added with a software update of the controller,
without any change to the script. This page describes how the gateway is set up, how the messages are structured and which script runs on the gateway. The description of the individual function blocks can be found on the pages of the respective devices. |
|
| Update note: The script below requires controller version 2.3131 or later. When migrating, keep this order: update the controller first, then replace the script - otherwise no values will arrive. The previous large script with built-in decoding keeps working unchanged, replacing it is not mandatory. If several gateways are used, all of them should run the same script version. |
| Exception valve control: The Shelly BLU TRV does not require a script. It is paired with the Shelly BLU gateway and is controlled and read through the gateway's own messages. For the TRV the topic of the gateway and the Bluetooth ID of the valve are therefore entered in the function block. |
| The script publishes one message for
every BLU device received. The topic consists of the prefix
configured in the script and the Bluetooth address of the device: shelly-blu-aa:bb:cc:dd:ee:ff The content is a small JSON object containing the unmodified Bluetooth payload in hexadecimal notation: {"sv":1,"addr":"aa:bb:cc:dd:ee:ff","rssi":-62,"sd":"40004201642e2f45d600"} Here sv is the version of the message format, addr the Bluetooth address, rssi the signal strength and sd the BTHome telegram. The controller decodes the actual values from it, for example: {"encryption":false,"BTHome_version":2,"pid":66,"Battery":100,"humidity":47,"temperature":21.4,"addr":"aa:bb:cc:dd:ee:ff","rssi":-62} In the MQTT diagnostics both messages appear one below the other: first the raw message of the gateway, directly followed by the decoded version with the field names. Messages of the previous large script arrive already decoded and are evaluated unchanged. Important: The topic must not contain a slash. The controller only evaluates BLU messages if the topic consists of a single section. The default prefix shelly-blu- meets this condition. If it is changed, hyphens must still be used instead of slashes. The topic is entered completely in the function block, that is including prefix and address. The easiest way is to copy it from the MQTT diagnostics. |
Values in the JSON |
||
| Object ID | Field in the JSON | Usage |
| 0x01 | Battery | Battery in percent. All BLU blocks output the value at the "battery %" output and additionally set "battery alarm" as soon as the value is 10 % or less. |
| 0x3a | Button | Button press. See section "Special feature push-buttons". |
| 0x2d | Window | Window contact, output at the "window" output of the Door/Window block. |
| 0x3f | Rotation | Tilt of the Door/Window sensor in degrees. |
| 0x21 | motion | Motion, output at the "motion" output of the Motion block. Written in lower case. |
| 0x05 | Illuminance | Brightness in lux. Output directly by Door/Window and Motion. For the weather station, brightness in kLux, twilight and solar radiation are additionally calculated from it. |
| 0x45 | temperature | Temperature in °C for H&T and weather station. Written in lower case. |
| 0x2e | humidity | Relative humidity in percent for H&T and weather station. Written in lower case. |
| 0x04 | Pressure | Air pressure in hPa, weather station. |
| 0x08 | Dewpoint | Dew point in °C, weather station. |
| 0x44 | Wind / Gust | Wind speed in m/s. The weather station sends wind and gust under the same object ID. During decoding the two values are separated: the first one becomes "Wind", the second one "Gust". |
| 0x5e | WindDir | Wind direction in degrees, weather station. |
| 0x46 | UV | UV index, weather station. |
| 0x20 | Raining | Rain yes/no. This binary value reacts faster than the millimetre counter. Older script versions report it under the name "Moisture"; both spellings are read. |
| 0x5f | Rain | Rain counter in mm. From the continuous counter reading the controller calculates rain rate, event, hour, day, week, month, year and total amount. |
| 0x0c 0x4a |
Voltage | Voltage. For the weather station the voltage of the supercapacitor. |
| Upper and lower case: The field names are generated by the controller during decoding, so their spelling is fixed. Only with the previous large script, which decodes the values itself, the field names must match character by character: "Battery" is written with a capital letter, whereas "temperature", "humidity" and "motion" are written in lower case - otherwise the outputs keep their previous value. |
On the Shelly BLU Button 1 the
field "Button" contains a single number. It indicates how often or
how long the button was pressed:
"Button":[0,0,254,0] This list is created because object IDs that occur several times are collected during decoding instead of being overwritten. |
| CONFIG | Settings. The topic prefix is stored in topic_prefix (no slash allowed). With address the script can be restricted to a single device; as delivered, all received devices are forwarded. |
| toHex | Converts the Bluetooth payload to hexadecimal notation for the MQTT transmission. |
| last_pid | Suppresses repetitions. The packet number is stored per device address so that several BLU devices do not hide each other. Devices without a packet number, such as the weather station, and encrypted telegrams are not suppressed. |
| scanCB | Is called for every Bluetooth broadcast received, filters out BTHome telegrams (service ID fcd2) and publishes the raw data via MQTT. |
| The script forwards the raw data of all BTHome devices within reception range. Which device types are evaluated is determined by the controller - currently: Button 1, RC Button 4, Door/Window, Motion, H&T and the Ecowitt WS90 weather station. New device types are added with a software update of the controller, the script remains unchanged. |
// Shelly BLU Gateway - Minimalversion
// Leitet die BTHome-Rohdaten der Shelly BLU Geraete per MQTT an die Steuerung
// weiter. Die Dekodierung der Telegramme uebernimmt die Steuerung (ab Version
// 2.3131) - neue Geraetetypen erfordern daher kein Script-Update mehr.
let CONFIG = {
topic_prefix: "shelly-blu-", // kein "/" verwenden!
// address: "aa:bb:cc:dd:ee:ff", // optional: nur dieses Geraet weiterleiten
};
let HEX = "0123456789abcdef";
function toHex(s) {
let out = "";
for (let i = 0; i < s.length; i++) {
let hi = (s.at(i) >> 4) & 0x0f;
let lo = s.at(i) & 0x0f;
out = out + HEX.slice(hi, hi + 1) + HEX.slice(lo, lo + 1);
}
return out;
}
let last_pid = {};
function scanCB(ev, res) {
if (ev !== BLE.Scanner.SCAN_RESULT) return;
// nur BTHome-Telegramme (Service-Kennung fcd2) weiterleiten
if (typeof res.service_data === "undefined" || typeof res.service_data["fcd2"] === "undefined")
return;
if (typeof CONFIG.address !== "undefined" && CONFIG.address !== res.addr)
return;
let sd = res.service_data["fcd2"];
if (sd.length < 1) return;
// Wiederholungen unterdruecken: die Paketnummer (Kennung 0x00) steht laut
// BTHome-Spezifikation immer als erstes Objekt nach dem Info-Byte.
// Verschluesselte Telegramme und Geraete ohne Paketnummer (z.B. die
// Wetterstation WS90) werden nicht unterdrueckt.
if ((sd.at(0) & 1) === 0 && sd.length >= 3 && sd.at(1) === 0) {
if (last_pid[res.addr] === sd.at(2)) return;
last_pid[res.addr] = sd.at(2);
}
let msg = '{"sv":1,"addr":"' + res.addr + '","rssi":' + JSON.stringify(res.rssi) + ',"sd":"' + toHex(sd) + '"}';
if (MQTT.isConnected() === false) {
console.log("MQTT not connected");
return;
}
if (MQTT.publish(CONFIG.topic_prefix + res.addr, msg, 0, false) === false)
console.log("MQTT error publish");
}
console.log("BLE.Scanner.Start");
BLE.Scanner.Start({ duration_ms: BLE.Scanner.INFINITE_SCAN, active: false }, scanCB);
See also MQTT devices - general.
See also general parameters of all function
blocks.