[Modul] Shelly

Hallo Kai,
beim Plus 2 PM (Cover-Mode) wird eine Int-Variable mit dem Ident „State“ erzeugt. In dieser Variablen steht entweder Öffnen, Schließen oder Stop. Leider steht da nie Geöffnet oder Geschlossen. Woher wird diese Variable gefüllt ? Im MQTT-Explorer finde ich diesen Wert auch nicht.

Grüße Frank

Der Text sagt doch schon das es hier Aktionen sind welche du ausführen kannst.
Also ein Klick im Webfront auf Öffnen und schon wird geöffnet. Nix mit Status eines Zustandes.
Michael

hm - wenn ich den Shelly steuere (z.B. über Script oder WebUI) , dann ändert sich dieser State, je nachdem, ob ich gestartet oder gestoppt habe. Das klingt schon nach einem Status-Feld. Aber ja, über diese Variable kann man der Rollladen auch Hoch-/Runter/Stop-Steuern. In der Beschreibung steht allerdings, dass die ID „Roller“ heißt. Ist dann evtl. noch ein Fehler im Konfigurator ?

Moin Kai,
vielen Dank für das tolle Modul!
Ich nutze den Gen3 Shelly 2PM zum Ansteuern eines Shutters.
Hier komme ich in der Visualisierung/Bedienung nicht weiter.

Frage 1. Es gibt drei Visualisierungskacheln. Man kann immer nur eine gleichzeitig anzeigen?

Frage 2: Die wichtigsten Funktionen, die man täglich benötigt, sind quasi die, die auch shelly in Ihrer App präsentieren:

  1. Öffnen
  2. Schliessen
  3. Stop
  4. Slat Position
  5. Öffungs Position

Leider bekomme ich dies so mit der ip-symcon visu nicht hin. Die drei angebotenen Visus helfen mir hier nicht weiter. Es soll ja eine Kachel mit den Grundcontrols werden. Desweiteren sind die controls teilweise versteckt, benötigen 2 Klicks, (z.B. Lamellenpos.)

Kann ggf. eine Kachel ähnlich shelly mit den Grundfunktionen erstellt werden?

Moin @hub2000

dazu gibt es bereits eine passende Kachel von Symcon, schau mal hier:
Jalousie — IP-Symcon :: Automatisierungssoftware
Du musst nur gucken, dass die passenden Profile ausgewählt sind, dann bekommst du genau die drei Funktionen dargestellt.

Grüße,
Christian

Teste mal bitte folgendes Script:

/**
 * This script will use BLE observer to listen for advertising data from nearby Shelly BLU devices,
 * decodes the data using a BTHome data structure, and emits the decoded data for further processing.
 *
 * This script DOESN'T execute actions, only emit events. Can be used with `ble-events-handler.js` example.
 * You can configure the event name, by default its `shelly-blu`, the body of the event contains all the data
 * parsed from the BLE device
 *
 * Represents data provided by each device.
 * Every value illustrating a sensor reading (e.g., button) may be a singular sensor value or 
 * an array of values if the object has multiple instances. 
 * 
 * @typedef {Object} DeviceData
 * @property {number} pid - Packet ID.
 * @property {number} battery - The battery level of the device in percentage (%).
 * @property {number} rssi - The signal strength in decibels (dB).
 * @property {string} address - The MAC address of the Shelly BLU device.
 * @property {string} model - The model of the Shelly BLU device.
 * @property {number | number[]} [temperature] - The temperature value in degrees Celsius if the device has a temperature sensor. (Can be an array if has multiple instances)
 * @property {number | number[]} [humidity] - The humidity value in percentage (%) if the device has a humidity sensor. (Can be an array if has multiple instances)
 * @property {number | number[]} [illuminance] - The illuminance value in lux if the device has a light sensor. (Can be an array if has multiple instances)
 * @property {number | number[]} [motion] - Motion status: 0 for clear, 1 for motion (if the device has a motion sensor). (Can be an array if has multiple instances)
 * @property {number | number[]} [window] - Window status: 0 for closed, 1 for open (if the device has a reed switch). (Can be an array if has multiple instances)
 * @property {number | number[]} [button] - The number of presses if the device has a button. (Can be an array if has multiple instances)
 * @property {number | number[]} [rotation] - The angle of rotation in degrees if the device has a gyroscope. (Can be an array if has multiple instances)
 * 
 * @example
 * {"component":"script:*","name":"script","id":*,"now":*,"info":{"component":"script:*","id":*,"event":"shelly-blu","data":{"encryption":false,"BTHome_version":2,"pid":118,"battery":100,"button":1,"rssi":-76,"address":*},"ts":*}}
 */

/******************* START CHANGE HERE *******************/
const CONFIG = {
  // Specify the destination event where the decoded BLE data will be emitted. It allows for easy identification by other applications/scripts
  eventName: "shelly-blu",

  // If the script owns the scanner and this value is set to true, the scan will be active.
  // If the script does not own the scanner, it may remain passive even when set to true. 
  // 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 set to true, debug messages will be logged to the console
  debug: false,
};
/******************* STOP CHANGE HERE *******************/

const BTHOME_SVC_ID_STR = "fcd2";

const uint8 = 0;
const int8 = 1;
const uint16 = 2;
const int16 = 3;
const uint24 = 4;
const int24 = 5;

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

function getByteSize(type) {
  if (type === uint8 || type === int8) 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
const BTHomeDecoder = {
  utoi: function (num, bitsz) {
    const 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);
    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;
    while (buffer.length > 0) {
      _bth = BTH[buffer.at(0)];
      if (typeof _bth === "undefined") {
        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;

      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
 * @param {DeviceData} data 
 */
function emitData(data) {
  if (typeof data !== "object") {
    return;
  }

  Shelly.emitEvent(CONFIG.eventName, 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"]
  ) {
    console.log("Error: Encrypted devices are not supported");
    return;
  }

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

  lastPacketId = unpackedData.pid;

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

  emitData(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
  const 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
    const bleScanner = BLE.Scanner.Start({
        duration_ms: BLE.Scanner.INFINITE_SCAN,
        active: CONFIG.active
    });

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

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

  // disable console.log when logs are disabled
  if (!CONFIG.debug) {
    console.log = function() {};
  }
}

init();

Das ist bei mir auf dem Gateway und damit funktioniert es.

Grüße,
Kai

1 „Gefällt mir“

Wie bekomme ich den Shelly kalibriert, wenn der Antrieb keine Abschaltung intern hat? Hat das schon mal jemand versucht?

Mit der aktuellen Beta Version vom Modul solte der erkannt werden.

Das Problem ist mit der nächsten Version gefixt.

Ich habe den Bezug im Thread verloren, um was ging es nochmal?

Ja schon, aber gerade bei den Bluetooth Geräte ist das echt schwer ohne es zu testen.

Fix kommt gleich mit der nächsten Beta Version.

Das wird ein Bug in der Firmware sein.

Das wird ein Bug in der Firmware sein.

Das ist richtig.

Die Bezeichnung ist in der Shelly Doku nicht vorhanden.
Ich habe den Konfigurator nun angepasst, der zeigt das Gerät nun als „Shelly Pro 2 PM (SPSW-202XE12UL - nicht in der Shelly Doku)“ an.

Mit der nächste Beta Version gibt es die Variable, um die Minuten einzustellen. :slight_smile:

Aktuell noch nicht, mir fehlt das Gerät zum testen.

Hast du RPC aktiviert?
Aber mit der neuen Beta Version sollte es nun auch funktionieren.

Die Variable ist nur zum bedienen gedacht, es gibt eine weitere Variable „Running State“ (Laufender Status), die Variable bennene ich mal in aktueller Status um.
Running State wird per MQTT gefüllt, State nutzt du nur um das Geerät zu bedienen.

Hast du die aktuelle Beta Version installiert?

Ich habe die Doku angepasst.

Grüße,
Kai

1 „Gefällt mir“

Schau mal auf der Shelly Webseite, die Doku ist eigentlich ganz gut.

Grüße,
Kai

Es gibt eine neue Beta Version.

Neu: SPSW-202XE12UL hinzugefügt
Neu:Shelly TRV: Boost Minuten eingebaut
Fix: Shelly Smoke Fix für Generic status update over MQTT

Grüße,
Kai

1 „Gefällt mir“

Moin @KaiS,

noch habe ich ein Gerät da (BT Gateway und TRV), wenn ich dir da helfen kann!?
Muss es bis zum 31.01.25 zurücksenden.

Möchte das TRV nicht behalten wegen der Bauform.
Mann muss die M30 Verschraubung abnehmen und die Batterien zu tauschen!

Danke und Gruß
Carsten

Moin,
nach längerem Probieren weiß ich leider nicht, wie ich die Instanz überhaupt einegbaut bekomme. Es werden mir nur „Jalousie“ Instanzen anderer Hersteller angezeigt, aber nicht die IPS Jalousie Instanz

Ersetzt diese alternative Instanz quasi die oben gezeigte Instanz von Kai?

Es geht nicht um Instanzen.
Sondern um die Profile der Variablen.
Die Anzeige in der Kachel Visu kommt auch nicht vom Modul, sondern wird durch die Visu auf Basis der Variablen und deren Profile vorgeschlagen und umgesetzt.
Das sind aber alles Themen der Kachel Visu und nicht vom Shelly Modul.
Michael

1 „Gefällt mir“

Es gibt noch eine neue Beta Version:

  • Neu: Shelly BLU RC Button 4

Grüße,
Kai

Alles klar, habe nun in der Variable „Lamellenposition“ das Std-Profil durch ein eigenes ersetzt (Lamella).

Wie bekäme ich jetzt noch die drei Buttons (Auf/Zu/Stop) in die Visu? ich weiß wie man einzelne separate buttons hinzufügt. Aber wie bekommt man eine all-in-one Kachel?
Das wäre die die Programmierung einer „Shelly 3PM Shutter Kachel“ oder?

Und was ich nicht verstehe: Wie bekommt die Lamellensteuerung nun die Info, wie lange die Lamelle drehen sol (Z.B. 1,9 sec, was eine Konfig im Shelly ist), oder werden die Konfigs im Shelly automatisch berücksichtigt?

Hallo Kai,

vielen Dank für Dein Engagement! :slight_smile:

Habe das Update installiert RPC ist eingeschaltet, Daten kommen, Statusvariablen werden aber bis auf „Ereichbarkeit“ leider immer noch nicht aktualisiert… :frowning:

Joachim
dump rm.txt (19,9 KB)

Gar nicht.
Hier ist die Kachel beschrieben:

Michael

Fix ist online.

Grüße,
Kai

Guten Morgen Kai,
ich kann irgendwie nichts finden, bezüglich des Shelly 3EM (nicht pro)

Hatte den schon vor einiger Zeit eingebunden. Da aber festgestellt, dass er ja keine Gesamtleistung ausgibt.

Ich habe dann mal hier im Forum danach gesucht und hier Deine Antwort gefunden.

Nun endlich meine Frage:

Hast Du die Berechnung der Gesamtleistung in das Modul eingebunden?

Oder sollte ich lieber den Shelly 3EM pro kaufen?

Schönen Samstag.

Beste Grüße Christian

Moin,
oh, das iust natürlich schade, da die useability so nicht ganz für uns passt.
Ich kann halt auch nict bei den ganzen jalousien extra Buttons hinzufügen, dann wird das super unübersichtlich.
Was muss man machen, um sich doch noch so eine Customized Kachel zu erstellen?

  • Gibt es Gruppierugen von Elementen/Instanzen zu einer Kachel?
  • Muß ein SDK bemüht werden?
  • geht es über ein PHP Script?

Das ist mein erste Projekt, daher die Fagen…