Nach vielen Experimenten habe ich ein sehr kleines Skript erstellt, welches auf einem Shelly der Generation 3 (oder vermutlich höher) dazu genutzt werden kann, MQTT Nachrichten mit BTHome Sensordaten zu senden, also solche die von Shelly BLU Geräten kommen. Hierfür müssen alle zu beteiligenden Sensoren auf dem Shelly der Generation 3 ... eingerichtet werden - unter Components.
Dort sind anschließend die Sensor Identifier zu sehen - Struktur: "bthomesensor:<id>". Zu jedem per MQTT zu erfassenden Sensor bzw. physikalische Sensorgröße muss eine Action angelegt werden.
http://127.0.0.1/rpc/script.eval?id=<script id>&code="bths(<sensor id>)"
Beispiel:
http://127.0.0.1/rpc/script.eval?id=1&code="bths(202)"
bths() ist die einzige Funktion des kleinen Skripts. Sie holt unter Verwendung der Sensor Id die aktuellen Daten und den in deiner Konfiguration eingetragenen Namen mit optionaler Einheit, stellt diese für die MQTT Payload zusammen und sendet die MQTT Nachricht.
Die Component Namen brauchen mit dem von mir gewählten Separator (Konfigurationsvariable Sep im Skript) die folgende Struktur.
Beispiel:
Damit wird die Payload der MQTT Nachricht folgende Komponenten haben.
- Sensor Id
- Sensor Wert
- Timestamp der letzten Aktualisierung
- Sensorname
- Einheit
Selbstverständlich muss der Abonnent nicht alle diese Daten nutzen, sie stellen aber imho alle relevant nutzbaren Informationen bereit.
Das Skript
// created by eiche, 2025-05-08
// This script, running on a Shelly generation 3 or higher, sends MQTT messages with data from a BTHome sensor.
// To do this, you need to create an action for each sensor from which you want to retrieve data.
// In each of these actions, you must use the "script.eval" method with the following code: code="bths(<sensor id>)".
// The complete URL is http://127.0.0.1/rpc/script.eval?id=<script id>&code="bths(<sensor id>)",
// e.g. http://127.0.0.1/rpc/script.eval?id=1&code="bths(200)"
// The only function bths() requires a composition of sensor name and optional unit in the component name.
// Sensor name and unit must be separated by a separator containing the variable Sep, e.g. a colon.
// You may do something else with the sensor data, e.g. use the "HTTP.Get" method with an URL.
// But that method can be in an action and does not need a script.
// Have fun with it anyway!
// A small configuration
let
Topic = "experiment/bthome", // the MQTT topic
Sep = ':'; // the seperator symbol - it may be a string instead of one character
// end of configuration
// Get BTHome sensor data an send those via MQTT.
function bths(id) {
//print(id);
Shelly.call("bthomesensor.getstatus", {id:id}, function(res, errc, errm) {
if(errc) {console.log(errc, errm); return;}
//print(JSON.stringify(res));
let Sensor = {id:res.id, value:res.value, ts:res.last_updated_ts, name:"", unit:""};
Shelly.call("bthomesensor.getconfig", {id:id}, function(res, errc, errm, s) {
if(errc) {console.log(errc, errm); return;}
//print(JSON.stringify(res));
let n = res.name.split(Sep);
s.name = n[0];
if(n.length>1) s.unit = n[1];
let p = JSON.stringify(s);
print(p);
MQTT.publish(Topic, p); // or do something else with object p
}, Sensor);
});
}
Alles anzeigen
Dies alles ist mit etwas Konzentration leicht zu konfigurieren. Das Skript kann bei Bedarf so erweitert werden, dass Sensor spezifische Aktionen ausgeführt werden, bspw. MQTT Nachricht versenden oder HTTP Get URL nutzen oder bei Bedarf auch beides. Die flexibelste Variante einer solchen Erweiterung beinhaltet ein Datenfeld aus jeweils der Sensor Id und einer Referenz auf die zu nutzende Funktion zwecks senden der Daten bzw. auslösen einer Aktion.
function f200(p){
// do something
}
function f201(p){
// do something
}
let Action = [
{id:200, f:f200},
{id:201, f:f201},
// ...
];
Alles anzeigen
Die Funktionsnamen sind nur formal so gewählt und können selbstverständlich nach Belieben lauten. Alle diese Funktionen müssen ein Objekt als Parameter importieren, welches alle Sensordaten enthält.
Das Datenfeld Action ist nach der aktuell vorliegenden Sensor Id abzusuchen und, wenn gefunden, die zugeordnete Funktion (hier eine Referenz) mit dem aktuellen Sensordaten Objekt als Parameter aufzurufen. Die Funktionsreferenzen haben den Vorteil, dass eine Funktion auch im mehreren Action Einträgen genutzt werden kann.
Bei Fragen gebe ich gerne Auskunft, wenn der Frager wenigstens grundlegendste Kenntnisse hat. 