Shelly BLU devices

Begonnen von gvzdus, 20 Oktober 2024, 21:53:03

Vorheriges Thema - Nächstes Thema

gvzdus

Ich wundere mich, ob ich wirklich nur schlecht gesucht habe: Aber wie bindet man Shelly BLU devices ein?

Zum Hintergrund: Zu dem Zoo gehören die Shelly BLU Button, BLU Motion, BLU Door&Window u.s.w. Shelly hat wohl den Versuch aufgegeben, batteriegetriebene Geräte mit Wifi anzubinden und ist auf Bluetooth gewechselt. Nun muss ein Gen2 oder Gen3-Gerät das Bluetooth-Gateway bereitstellen.
Zum Ärger u.a. auch von Matthias Kleine gibt es keinen Standard, wie die Events von den Devices per MQTT propagiert werden (Shelly hat das wohl mal angekündigt, aber bis heute nicht implementiert). Stattdessen muss man ein eigenes Script aktivieren, und damit stellt sich die Frage der Vereinheitlichung.

Ich habe jetzt auf meinen Gateway-Shellys das "Library-Script" ble-shelly-dw.js geladen und modifiziert. In der Library wird es als "BLE in Scripting - Shelly BLU DoorWindow script actions" angepriesen.

Hier habe ich nun folgende Änderung eingetragen (1. Zeile als Suchpunkt):
console.log("Shelly BTH packet: ", JSON.stringify(BTHparsed));
  if (MQTT.isConnected()) {
    MQTT.publish("bthome/bth_" + res.addr, JSON.stringify(BTHparsed));
  }

Das führt nun dazu, dass BThome-Events unterhalb des Gateway-MQTT-Devices angelegt werden: Es entsteht ein erweitertes readingList:
  readingList shelly2pmg3_34cdb077312c:badoben2pm/online:.* online
shelly2pmg3_34cdb077312c:badoben2pm/events/rpc:.* { json2nameValue($EVENT, 'rpc_', $JSONMAP) }
shelly2pmg3_34cdb077312c:bthome/bth_3c_2e_f5_bc_2e_c7:.* { json2nameValue($EVENT, 'bth_3c_2e_f5_bc_2e_c7_', $JSONMAP) }

Das habe ich jetzt in meinem Fall dann so angepasst:
  readingList shelly2pmg3_34cdb077312c:badoben2pm/online:.* online
shelly2pmg3_34cdb077312c:badoben2pm/events/rpc:.* { json2nameValue($EVENT, 'rpc_', $JSONMAP) }
shelly2pmg3_34cdb077312c:bthome/bth_3c_2e_f5_73_2b_37:.* { json2nameValue($EVENT, 'bthome_badtuer_', $JSONMAP) }
shelly2pmg3_34cdb077312c:bthome/bth_3c_2e_f5_fb_3a_c6:.* { json2nameValue($EVENT, 'bthome_badfenster_', $JSONMAP) }
shelly2pmg3_34cdb077312c:bthome/bth_7c_c6_b6_91_c0_8d:.* { json2nameValue($EVENT, 'bthome_badswitch_', $JSONMAP) }

Nun kann ich also Events von den verschiedenen BLU-Devices sauber und mit sprechenden Namen weiterverarbeiten und bin damit am Ziel.

ABER:
Die Lösung hat den Nachteil, dass bei mehreren Gateway-Shellys unter jedem Gateway-Shelly die Readings angelegt werden.
Am schönsten wäre natürlich, wenn die BLU-Geräte als eigene FHEM-Devices angelegt würden. Das würde aber zum einen eine Konvention erfordern, mit welchem Script und Topic die BTHome-Events propagiert werden, und zum anderen wohl Änderungen am Autocreate von MQTT.

Bin ich wirklich der Erste, der sich die Gedanken macht?

rudolfkoenig

Ich wuerde das mit dem bridgeRegexp loesen, das ist fuer Gateway Geraete vorgesehen:
https://fhem.de/commandref_modular.html#MQTT2_DEVICE-attr-bridgeRegexp
ZitatUsed to automatically redirect some types of topics to different MQTT2_DEVICE instances. The regexp is checked against the clientid:topic:message and topic:message. The newClientId is a perl expression!. Example:
attr zigbee2mqtt bridgeRegexp zigbee2mqtt/([A-Za-z0-9]*)[/]?.*:.* "zigbee_$1"
will create different MQTT2_DEVICE instances for different hex numbers in the topic. Note: the newClientId is enclosed in "", as it is a perl expression, should be unique, and the automatically created device will be created also with this name.
Notes:
multiple tuples of <regexp> newClientId are separated by newline
setting bridgeRegexp will remove the readingList attribute and all readings.
For a zigbee2mqtt device connected via MQTT2_SERVER the following is probably a better solution:
attr zigbee2mqtt bridgeRegexp zigbee2mqtt/0x........([^/]+):.* "zigbee_$1"

gvzdus

Das funktioniert schon sehr genial gut. Und schreit nach einer Wiki-Seite, damit "das Internet" es findet.
Magst Du bitte noch einmal über die Lösung schauen, ob es Verbesserungspotential gibt?

Ich habe folgende bridgeRegexp gesetzt (auf allen Shellys, die als Gateway mit dem Script arbeiten):
.*:bthome/bth_([0-9a-f_]*)/d:.* "bthome_$1"
Das Script auf den Shellys habe ich so geändert ("/d" hinten dran):
    MQTT.publish("bthome/bth_" + res.addr+"/d", JSON.stringify(BTHparsed));

Dann funktioniert es so: Neues BLU-Gerät auspacken, Taste drücken / schütteln, in FHEM wird ein neues Gerät angelegt:

Internals:
   CID        bthome_3c_2e_f5_69_bb_07
   DEF        bthome_3c_2e_f5_69_bb_07
   FUUID      6715f9dc-f33f-8d06-2353-b11f4ccc28470f22
   IODev      MQTT2_FHEM_Server
   LASTInputDev MQTT2_FHEM_Server
   MQTT2_FHEM_Server_CONN MQTT2_FHEM_Server_192.168.0.127_50411
   MQTT2_FHEM_Server_MSGCNT 3
   MQTT2_FHEM_Server_TIME 2024-10-21 09:08:55
   MSGCNT     3
   NAME       MQTT2_bthome_3c_2e_f5_69_bb_07
   NR         545
   STATE      ???
   TYPE       MQTT2_DEVICE
   eventCount 3
   READINGS:
     2024-10-21 09:04:05   IODev           MQTT2_FHEM_Server
     2024-10-21 08:51:08   associatedWith  solarshelly
     2024-10-21 09:08:55   d_BTHome_version 2
     2024-10-21 09:08:55   d_addr          3c:2e:f5:69:bb:07
     2024-10-21 09:08:55   d_battery       100
     2024-10-21 09:08:55   d_button        1
     2024-10-21 09:08:55   d_encryption    false
     2024-10-21 09:08:55   d_pid           30
     2024-10-21 09:08:55   d_rssi          -92
Attributes:
   readingList bthome/bth_3c_2e_f5_69_bb_07/d:.* { json2nameValue($EVENT, 'd_', $JSONMAP) }
   room       MQTT2_DEVICE

Frage: Kriegt man das "d_" als Prefix der Readings noch weg? Wenn ich das Topic wie ursprünglich mit "bthome/bth_<addr>" enden lasse, wandert die Adresse mit in die Readings beim Autocreate.

rudolfkoenig

ZitatUnd schreit nach einer Wiki-Seite, damit "das Internet" es findet.
Sowas gibts hier https://wiki.fhem.de/wiki/MQTT2-Module_-_Praxisbeispiele#bridgeRegexp
Vermutlich braucht es noch SEO :)
Ich habe bridgeRegexp zwar eingebaut, aber die Jungs von der attrTemplate Front (siehe /opt/fhem/FHEM/lib/AttrTemplate/mqtt2.template) haben mehr Erfahrung in der Anwendung.

ZitatKriegt man das "d_" als Prefix der Readings noch weg?
Ich glaube es liegt daran, dass du zu "complex" denkst :)
https://fhem.de/commandref_modular.html#MQTT2_SERVER-attr-autocreate

Beta-User

Zitat von: rudolfkoenig am 21 Oktober 2024, 11:05:48Ich glaube es liegt daran, dass du zu "complex" denkst :)
Vermutlich ist "complex" schon (vorsorglich!) ok, aber als mittleres Argument würde ich hier halt einfach "nichts" verwenden:
   readingList bthome/bth_3c_2e_f5_69_bb_07/d:.* { json2nameValue($EVENT, '', $JSONMAP) }
Zitat von: gvzdus am 20 Oktober 2024, 21:53:03[...] gibt es keinen Standard, wie die Events von den Devices per MQTT propagiert werden (Shelly hat das wohl mal angekündigt, aber bis heute nicht implementiert). Stattdessen muss man ein eigenes Script aktivieren, und damit stellt sich die Frage der Vereinheitlichung.
Deswegen würde ich hier bei der langen Form von json2nameValue() bleiben, dann kann man das via attrTemplate vereinheitlichen.

Zitat von: gvzdus am 20 Oktober 2024, 21:53:03Bin ich wirklich der Erste, der sich die Gedanken macht?
Jein. Für Shelly gibt es sowas noch nicht, aber im Prinzip ist es kaum ein Unterschied, ob man ein OpenMQTTGateway (oder ein Tasmota-BLE-GW) verwendet. Jedenfalls zu ersterem gibt es einen (rudimentären) attrTemplate-Satz und einen oder mehrere Threads, die sich mit dem Vereinzeln usw. befassen.

Falls du einen attrTemplate-Satz bereitstellen willst: feel free, wir können uns den "Maintainer" gerne teilen (Otto123 mischt da auch mit).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

gvzdus

Hmmh, ja, mit nachträglichem Anpassen der Reading-List im angelegten BThome-Device geht es natürlich.
Aber ich suche ja nach einer Möglichkeit, dass eine Nachricht:

bthome/bth_" + res.addr+"/d" {"encryption":false,"BTHome_version":2,"pid":31,"battery":100,"button":1,"addr":"3c:2e:f5:69:bb:07","rssi":-
12:45:20
88}

direkt dazu führt, dass ein Device mit dem Namen der Adresse angelegt wird, dessen Readings aber "battery" u.s.w. ohne "d_" heißen.
Sende ich als Topic nur
"bthome/bth_" + res.addr+"",
und ändere die "bridgeRegex" auf:

.*:bthome/bth_([0-9a-f_]*):.* "bthome_$1"

so wird das BThome-Gerät richtig hässlich angelegt, nämlich so:
bthome/bth_e8_e0_7e_be_e3_ca:.* { json2nameValue($EVENT, 'bth_e8_e0_7e_be_e3_ca_', $JSONMAP) }
Sprich: Fällt Dir etwas ein, was ich an bridgeRegex und Topic "drehen" könnte, sodass das Reading nur "battery" heisst, also das automatisch angelegte readingList im Prefix leer ist?

Ein AttrTemplate könnte man bauen, aber im Kern wäre das nur ein schönes DevState-Icon :-). Es sind ja alles Sensoren.

Beta-User

Zitat von: gvzdus am 21 Oktober 2024, 12:56:09Fällt Dir etwas ein, was ich an bridgeRegex und Topic "drehen" könnte, sodass das Reading nur "battery" heisst, also das automatisch angelegte readingList im Prefix leer ist?

Ein AttrTemplate könnte man bauen, aber im Kern wäre das nur ein schönes DevState-Icon :-). Es sind ja alles Sensoren.
Na ja, "a)" könnte man lösen, indem man Rudi's Vorschlag umsetzt und den default für autocreate in MQTT2_SERVER verwendet...

Aber: Korrekterweise heißt dieses Reading eben nicht "battery", sondern "batteryPercent" (siehe Namenskonventionen zu Readings), und das könnte man via jsonMap gradeziehen. Daher der Vorschlag, das via attrTemplate zu lösen.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

gvzdus

Jetzt ist der Groschen auch bei mir gefallen - die URL hatte ich unter Rudis Reply nicht wahrgenommen.
Gibt es außer "batteryPercent" gar inzwischen noch andere Standards? :-)
Ich habe nur folgende Wiki-Seite ergoogled: https://wiki.fhem.de/wiki/DevelopmentGuidelinesReadings
Und: Welches AttrTemplate gefällt Dir denn herausragend gut für Sensoren? Ich habe aktuell zum Testen im Zoo:
  • Shelly BLU Wallswitch 4 (4 Buttons)
  • Shelly BLU Button
  • Shelly BLU Door/Window
  • Shelly BLU Motion
Was ich nicht habe, ist der "H&T"-Sensor.
Wenn ich AttrTemplate richtig verstehe, könnte man über etwas wie filter:TYPE=MQTT2_DEVICE:FILTER=CID~bthome_.* automatisch selektieren.
Da ich ja das Skript auf dem Shelly "unter Kontrolle" habe, könnte ich "bthome_" auch per Erkennung der Merkmale des BThome-Pakets ausdifferenzieren, also z.B. "bth_(motion|switch|sens|ht)_".

gvzdus

P.S. Ich hänge mal die Beispiele dran, wie sie kommen:
Das "batteryPercent" kann ich natürlich direkt im Shelly-Script umsetzen.

Shelly BLU Button:
{"encryption":false,"BTHome_version":2,"pid":36,"battery":100,"button":1,"addr":"3c:2e:f5:69:bb:07","rssi":-85}
Shelly Door&Window:
{"encryption":false,"BTHome_version":2,"pid":136,"battery":100,"illuminance":36,"window":0,"rotation":0,"addr":"3c:2e:f5:bc:2e:c7","rssi":-46}
Shelly Motion:
{"encryption":false,"BTHome_version":2,"pid":156,"battery":100,"illuminance":250,"motion":1,"addr":"38:39:8f:9a:2b:c1","rssi":-82}
Shelly Wallswitch 4:
{"encryption":false,"BTHome_version":2,"pid":108,"battery":100,"button_0":0,"button_1":1,"button_2":0,"button_3":0,"addr":"7c:c6:b6:91:c0:8d","rssi":-59}

Beta-User

Zitat von: gvzdus am 21 Oktober 2024, 14:44:03Gibt es außer "batteryPercent" gar inzwischen noch andere Standards? :-)
Afaik nicht wirklich; hatte hier mal was angeschubst: https://forum.fhem.de/index.php?msg=1123606

Zitat von: gvzdus am 21 Oktober 2024, 14:54:56Das "batteryPercent" kann ich natürlich direkt im Shelly-Script umsetzen.
Stellt sich halt die Frage, was der (aus User-Sicht) einfachere Weg ist. Nach meinen bisherigen Erfahrungen ist es schwierig, wenn man als User an mehreren Enden anfassen muss und ggf. dann immer wieder ein script/eine config/... auf irgendeinem entfernten Gerät anfassen müßte, sobald man wieder ein neues Gadget in der Hand hat - und gerade die Shelly-Macher sind immer wieder für (unangenehme!) Überraschungen gut...

ZitatWenn ich AttrTemplate richtig verstehe, könnte man über etwas wie filter:TYPE=MQTT2_DEVICE:FILTER=CID~bthome_.* automatisch selektieren.
Jup. Die Idee hinter diesem Filter (bzw. auch hinter dem kompletten Deaktivieren einzelner Gruppen von templates) ist, dass der User zwar eine Idee bekommt, wie groß die Vielfalt ist, aber dann eben auch bestimmte Gruppen nur angezeigt bekommt, wenn er "passende" Devices hat.

Zitat von: gvzdus am 21 Oktober 2024, 14:44:03nd: Welches AttrTemplate gefällt Dir denn herausragend gut für Sensoren?
Die Frage kann man mAn. so nicht stellen. Bin grade wieder bei der Umstellung auf zigbee2mqtt, und da ist es oft so, dass man sich jedes Device (bzw. teils jeden schaltbaren Kanal) einzelner Devices genauer ansehen muss, damit man am Ende sowas wie "standardisierte und FHEM-konforme" Devices erhält. Beispiele:
{"encryption":false,"BTHome_version":2,"pid":136,"battery":100,"illuminance":36,"window":0,"rotation":0,"addr":"3c:2e:f5:bc:2e:c7","rssi":-46}Soll wäre für "window" (Vorschlag): "contact" (oder "state"?) mit "open" bzw. "closed"
{"encryption":false,"BTHome_version":2,"pid":156,"battery":100,"illuminance":250,"motion":1,"addr":"38:39:8f:9a:2b:c1","rssi":-82}"motion" ist auch so ein Kandidat. Auch da wäre ggf. motion/nomotion statt 1/0 wünschenswert, ob im Reading "motion" wäre die weitere Frage...

Beispiel, wie das ginge: zigbee2mqtt_ContactSensor
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Beta-User

Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Phlox

Hallo,
funktioniert dieses script auch mit Shelly blu H&T?

Gibt es da eine Anleitung "Schritt für Schritt", wo man das script findet, was man ändern muss...
..und dann noch bridgeRegex ausführen?

Oder habe ich mit shelly blu HT über shelly plus1mini gen 3 sowieso keine Chance, das in fhem irgendwie abzufragen?

Vielen Dank für Eure Zeit und hoffentlich einer einigermaßen verständlichen Lösung, wenns die überhaupt für H&T gibt  :'(

Schöne erfolgreiche Zeit



gvzdus

Ich probier's mal:
Gegeben sei ein per MQTT an FHEM angebundener Shelly Gen2/3/4 als "BTHome"-Gateway.
Du gehst auf die Shelly-UI des Gerätes:
- In "Settings -> Bluetooth" schaltest Du alles ein (Enable BT, Enable RPC, Enable BT Gateway).
- In "Scripts" legst Du ein Script an, kopierst das Folgende hinein, startet es und denkst an "Run on startup" einschalten, damit es nach Reboot wieder anläuft:
/******************* START CHANGE HERE *******************/
// Script for BThome->MQTT->FHEM, based on "ble-shelly-motion.js" from library
// version 0.1, 20241021

let CONFIG = {
  // When set to true, debug messages will be logged to the console
  debug: true,

  // When set to true and the script ownes the scanner, the scan will be active.
  // Active scan means the scanner will ping back the Bluetooth device to receive all its data, but it will drain the battery faster
  active: false,

  // When `allowedMacAddresses` is set to null, events from every bluetooth device are accepted.
  allowedMacAddresses: null,
  //allowedMacAddresses: [
  //  "aa:bc:12:34:56:78", // events only from these mac addresses are allowed.
  //  "11:22:33:45:5a:bc",
  //],

  /**
   * Called when packet from filtered Shelly BLU Motion devices is received.
   * @param {Object} eventData Object, containing all parameters received from the Shelly BLU Motion device. Example: {"encryption":false,"BTHome_version":2,"pid":16,"battery":100,"illuminance":109,"motion":1,"button":1,"rssi":-53,"address":"aa:bc:12:34:56:78"}
   */
  onStatusUpdate: function (eventData) {
    // Do nothing at the moment.
  }
};
/******************* STOP CHANGE HERE *******************/

let ALLTERCO_MFD_ID_STR = "0ba9";
let BTHOME_SVC_ID_STR = "fcd2";

let uint8 = 0;
let int8 = 1;
let uint16 = 2;
let int16 = 3;
let uint24 = 4;
let int24 = 5;
let uint8OpenClose = 6;
let uint8Motion = 7;

//Logs the provided message with an optional prefix to the console.
function logger(message, prefix) {
  //exit if the debug isn't enabled
  if (!CONFIG.debug) {
    return;
  }

  let finalText = "";

  //if the message is list loop over it
  if (Array.isArray(message)) {
    for (let i = 0; i < message.length; i++) {
      finalText = finalText + " " + JSON.stringify(message[i]);
    }
  } else {
    finalText = JSON.stringify(message);
  }

  //the prefix must be string
  if (typeof prefix !== "string") {
    prefix = "";
  } else {
    prefix = prefix + ":";
  }

  //log the result
  console.log(prefix, finalText);
}

// The BTH object defines the structure of the BTHome data
let BTH = {};
BTH[0x00] = { n: "pid", t: uint8 };
BTH[0x01] = { n: "batteryPercent", t: uint8, u: "%" };
BTH[0x02] = { n: "temperature", t: int16, f: 0.01, u: "tC" };
BTH[0x03] = { n: "humidity", t: uint16, f: 0.01, u: "%" };
BTH[0x05] = { n: "illuminance", t: uint24, f: 0.01 };
BTH[0x21] = { n: "state", t: uint8Motion };
BTH[0x2d] = { n: "state", t: uint8OpenClose };
BTH[0x2e] = { n: "humidity", t: uint8, u: "%" };
BTH[0x3a] = { n: "button", t: uint8 };
BTH[0x3f] = { n: "rotation", t: int16, f: 0.1 };
BTH[0x45] = { n: "temperature", t: int16, f: 0.1 };

function getByteSize(type) {
  if (type === uint8 || type === int8 || type===uint8OpenClose || type===uint8Motion) return 1;
  if (type === uint16 || type === int16) return 2;
  if (type === uint24 || type === int24) return 3;
  //impossible as advertisements are much smaller;
  return 255;
}

// functions for decoding and unpacking the service data from Shelly BLU devices
let BTHomeDecoder = {
  utoi: function (num, bitsz) {
    let mask = 1 << (bitsz - 1);
    return num & mask ? num - (1 << bitsz) : num;
  },
  getUInt8: function (buffer) {
    return buffer.at(0);
  },
  getInt8: function (buffer) {
    return this.utoi(this.getUInt8(buffer), 8);
  },
  getUInt16LE: function (buffer) {
    return 0xffff & ((buffer.at(1) << 8) | buffer.at(0));
  },
  getInt16LE: function (buffer) {
    return this.utoi(this.getUInt16LE(buffer), 16);
  },
  getUInt24LE: function (buffer) {
    return (
      0x00ffffff & ((buffer.at(2) << 16) | (buffer.at(1) << 8) | buffer.at(0))
    );
  },
  getInt24LE: function (buffer) {
    return this.utoi(this.getUInt24LE(buffer), 24);
  },
  getBufValue: function (type, buffer) {
    if (buffer.length < getByteSize(type)) return null;
    let res = null;
    if (type === uint8) res = this.getUInt8(buffer);
    if (type === int8) res = this.getInt8(buffer);
    if (type === uint16) res = this.getUInt16LE(buffer);
    if (type === int16) res = this.getInt16LE(buffer);
    if (type === uint24) res = this.getUInt24LE(buffer);
    if (type === int24) res = this.getInt24LE(buffer);
    if (type === uint8OpenClose) res = this.getUInt8(buffer) ? "open" : "closed";
    if (type === uint8Motion) res = this.getUInt8(buffer) ? "motion" : "nomotion";
    return res;
  },

  // Unpacks the service data buffer from a Shelly BLU device
  unpack: function (buffer) {
    //beacons might not provide BTH service data
    if (typeof buffer !== "string" || buffer.length === 0) return null;
    let result = {};
    let _dib = buffer.at(0);
    result["encryption"] = _dib & 0x1 ? true : false;
    result["BTHome_version"] = _dib >> 5;
    if (result["BTHome_version"] !== 2) return null;
    //can not handle encrypted data
    if (result["encryption"]) return result;
    buffer = buffer.slice(1);

    let _bth;
    let _value;
    let _cntr = 0;
    while (buffer.length > 0) {
      _bth = BTH[buffer.at(0)];
      if (typeof _bth === "undefined") {
        logger("unknown type for " + buffer.at(0).toString(16), "BTH");
        break;
      }
      buffer = buffer.slice(1);
      _value = this.getBufValue(_bth.t, buffer);
      if (_value === null) break;
      if (typeof _bth.f !== "undefined") _value = _value * _bth.f;
      // Added: BLU Wallswitch4 has multiple buttons
      if (typeof result[_bth.n] !== "undefined") {
        result[_bth.n + "_" + _cntr++] = result[_bth.n];
        delete result[_bth.n];
      }
      result[_cntr>0 ? _bth.n + "_" + _cntr++ : _bth.n] = _value;
      buffer = buffer.slice(getByteSize(_bth.t));
    }
    return result;
  },
};

function onReceivedPacket (data) {
  if(CONFIG._processedMacAddresses !== null) {
    if(CONFIG._processedMacAddresses.indexOf(data.address) < 0) {
      logger(["Received event from", data.address, "outside of the allowed addresses"], "Info");
      return;
    }
  }

  logger(["Shelly BTH packet: ", data], "Info");
  if (MQTT.isConnected()) {
    MQTT.publish("bthome/bth_" + data.address, JSON.stringify(data));
  }
}

//saving the id of the last packet, this is used to filter the duplicated packets
let lastPacketId = 0x100;

// Callback for the BLE scanner object
function BLEScanCallback(event, result) {
  //exit if not a result of a scan
  if (event !== BLE.Scanner.SCAN_RESULT) {
    return;
  }

  //exit if service_data member is missing
  if (
    typeof result.service_data === "undefined" ||
    typeof result.service_data[BTHOME_SVC_ID_STR] === "undefined"
  ) {
    return;
  }

  let unpackedData = BTHomeDecoder.unpack(
    result.service_data[BTHOME_SVC_ID_STR]
  );

  //exit if unpacked data is null or the device is encrypted
  if (
    unpackedData === null ||
    typeof unpackedData === "undefined" ||
    unpackedData["encryption"]
  ) {
    logger("Encrypted devices are not supported", "Error");
    return;
  }

  //exit if the event is duplicated
  if (lastPacketId === unpackedData.pid) {
    return;
  }

  lastPacketId = unpackedData.pid;

  unpackedData.rssi = result.rssi;
  unpackedData.address = result.addr;

  onReceivedPacket(unpackedData);
}

// Initializes the script and performs the necessary checks and configurations
function init() {
  //exit if can't find the config
  if (typeof CONFIG === "undefined") {
    console.log("Error: Undefined config");
    return;
  }

  //get the config of ble component
  let BLEConfig = Shelly.getComponentConfig("ble");

  //exit if the BLE isn't enabled
  if (!BLEConfig.enable) {
    console.log(
      "Error: The Bluetooth is not enabled, please enable it from settings"
    );
    return;
  }

  //check if the scanner is already running
  if (BLE.Scanner.isRunning()) {
    console.log("Info: The BLE gateway is running, the BLE scan configuration is managed by the device");
  }
  else {
    //start the scanner
    let bleScanner = BLE.Scanner.Start({
        duration_ms: BLE.Scanner.INFINITE_SCAN,
        active: CONFIG.active
    });

    if(!bleScanner) {
      console.log("Error: Can not start new scanner");
    }
  }

  if (
    typeof CONFIG.allowedMacAddresses !== "undefined"
  ) {
    if(CONFIG.allowedMacAddresses !== null) {
      // Process configured mac addresses all to lower case and remove duplicates.
      CONFIG._processedMacAddresses =
        CONFIG
          .allowedMacAddresses
          .map(function (mac) { return mac.toLowerCase(); })
          .filter(function (value, index, array) { return array.indexOf(value) === index; })
    }
    else {
      CONFIG._processedMacAddresses = null;
    }
  }

  //subscribe a callback to BLE scanner
  BLE.Scanner.Subscribe(BLEScanCallback);
}

init();

Mit ein bisschen Geduld oder durch Aktionen eines Gerätes solltest Du jetzt im Debug-Log des Shellys folgende Zeilen sehen:

Info: "Shelly BTH packet: " {"encryption":false,"BTHome_version":2,"pid":26,"batteryPercent":100,"humidity":58,"temperature":24
09:11:57
.6,"rssi":-89,"address":"7c:c6:b6:65:14:0c"}

Bitte bis hier hin erst einmal nachvollziehen! Falls nichts kommt, könntest Du z.B. Encryption bei den BThome-Devices eingeschaltet haben.

Jetzt füge bitte auf Deinem MQTT-Shelly in FHEM folgendes Attribut hinzu:

attr <ShellyDevice> bridgeRegexp .*:bthome/bth_([a-z_0-9_]+):.* "bth_$1"
Wenn's glatt läuft, sollten jetzt "bth_"-Geräte für jedes BThome-Gerät in FHEM erzeugt werden.

Phlox

@gvzdus

vielen Dank für die schnelle und perfekte Antwort.

So wie ich das durchgelesen habe, ist das das gleiche Procedere wie für die anderen bekannten 4 blu Geräte...und da hatte bei mir für den blu motion und blu windows/door das Ganze schon funktioniert. ;D

Ich war mir nur unsicher, ob ich das gleiche script und  bridgeRegexp für den blu ht verwenden kann.

Heut abend probier´s ich und schreib gleich obs funktioniert hat.

Vielen lieben Dank und Respekt vor eurem know how.

Ciao

gvzdus

Etwas nervig finde ich, dass Shelly m.W. keinen "Standard" für das Bridging "BT-Home -> MQTT" vorgeschlagen hat, bzw. ein Skript wie meines nicht direkt integriert hat.
Für etwas "autoritärere" Plattformen wie HA gibt es dann natürlich den Hausstandard des einen Entwicklers, aber in unser freien, chaotischen FHEM-Welt haben wir natürlich gleich Wildwuchs.