[Modul] Shelly

Hallo Norden,

danke für deine Anleitung, hat funktioniert !
ist daran gelegen, das der Shelly nur bei aktiven AP im Symcon sichtbar war.
Die Kiste sendet alle ca. 6 Miunten einen neuen Wert.

Gruß Jürgen

Hänge mal hier rein…
ich möchte alle alten HM Fenstersensoren, die immer mehr spinnen gegen Shelly Door/windows Sensoren tauschen. Dazu habe ich für Tests nun ein Shelly BLU Gateway und einen Window Sensor besorgt.

Das BLU Gateway ist eingerichtet und MQTT aktiviert (nach FW update) - wird nun im MQTT Server von IPS angezeigt.
Dann habe ich den Fenstersensor aktiviert (in Shelly APP) - in der APP reagiert das Teil auf offen/geschlossen - als letzter „Reporter“ ist das BLU gateway angegeben.

Wie sind die nächsten Schritte um den Fensterzustand in IPS zu bekommen?
Hier stehe ich an.

Im Modul kann ich das GW auswählen - gebe den Namen im MQTT TOPIC wie in der App festgelegt an „shellyblugw-…“ - nach speichern wird das Gw in IPS offline angezeigt. in der APP wird MQTT als verbunden angezeigt.
Wie hängt dann der Fenstersensor zusammen mit dem Gateway in IPS. Im Modul kann ich den Sensor aussuchen soll aber einen „event“ und eine BLU Adresse angeben (ID, MAc … oder).

Bitte um Aufklärung bzw Hilfe - Danke schön. LG Alexander

Hallo, ich habe zum Test die neuen Thermostatventile Shelly BLU TRV mit Shelly BLU Gateway Gen 3 bestellt, bekomme die aber nicht eingebunden.
Das Gateway wird zwar im Konfigurator angezeigt, aber nicht erkannt. Muss ich da noch Anpassungen vornehmen oder mache ich etwas falsch ?
Andere Shelly klappen problemlos.
Vielen Dank !

Hi zusammen,

ich versuche gerade mehrere Shelly Blu H&T Sensoren einzubinden, doch leider bisher erfolglos. In der vergangenheit habe ich bereits Shelly Blue Window und Button1 ohne Probleme einbinden können. Läuft das bei den H&T Sensoren irgendwie anders ab?

Die Debug datei spuckt folgendes aus:
dump_H&T.txt (19,8 KB)

aber so richtig schlau werde ich nicht daraus. Das kommt immer, beim Tastendruck des H&T Sensors.

Generelle Frage: wie kann ich ein FW-update an den BLU-Geräten durchführen wenn diese nur über Symcon integriert sind?

Hallo Kai,

könntest du bei den Shelly 2PM Gen3 die Variablen für Temperatur und Netzfrequenz anpassen?
Derzeit werden sie nicht gefüllt, wohl aber geliefert:

JSON:Payload | {„id“:0, „source“:„limit_switch“, „state“:„open“,„apower“:0.0,„voltage“:236.8,„current“:0.000,„pf“:0.00,„freq“:50.0,„aenergy“:{„total“:45.977,„by_minute“:[0.000,0.000,0.000],„minute_ts“:1730370600},"temperature":{„tC“:28.5, „tF“:83.4},„pos_control“:true,„last_direction“:„open“,„current_pos“:100}

Danke dir!
Christian

Hallo Kai,

ich habe mich hier durch den Post mal durchgetankt. Allerdings komme ich mit meinem Problem nicht weiter.
Ich habe ein Shelly BLE-Gateway (USB-Stick) in Betrieb. An dem sind 2 Shelly BLU Button 1 angelernt. Die Buttons laufen im Beacon-Mode.

Ich habe dann alles im IPS so angelegt wie es in der Doku steht.
Beide Buttons sind im Objektbaum angelegt.
Die MAC-Adressen sind auch angegeben.
Ich sehe die Buttons im MQTT-Server-Debug. Aber die Einträge „Button, RSSI und Batterie“ werden im Objektbaum nicht aktualisiert.
Was mache ich falsch ?

Mein Script auf dem Shelly-Blue-Gateway sieht so aus.

/**
 * This script uses the BLE scan functionality in scripting
 * Selects Shelly BLU Motion from the aired advertisements, decodes
 * the service data payload and transfert it to an MQTT broker
 */

// Shelly BLU devices:
// SBBT - Shelly BLU Button
// SBDW - Shelly BLU DoorWindow

// sample Shelly DW service_data payload
// 0x40 0x00 0x4E 0x01 0x64 0x05 0x00 0x00 0x00 0x2D 0x01 0x3F 0x00 0x00

// First byte: BTHome device info, 0x40 - no encryption, BTHome v.2
// bit 0: “Encryption flag”
// bit 1-4: “Reserved for future use”
// bit 5-7: “BTHome Version”

// AD 0: PID, 0x00
// Value: 0x4E

// AD 1: Battery, 0x01
// Value, 100%

// AD 2: Illuminance, 0x05
// Value: 0

// AD 3: Window, 0x2D
// Value: true, open

// AD 4: Rotation, 0x3F
// Value: 0



// CHANGE THE CONFIG OBJECT TO MATCH YOUR NEEDS

let CONFIG = {
    shelly_blu_address: {
        "7c:c6:b6:72:15:36": "Button-Gabi",
        "7c:c6:b6:64:91:a8": "Button-Jürgen"
    },
};

// END OF CHANGE

// Convert all addresses to uppercase
for (let key in CONFIG.shelly_blu_address) {
    CONFIG.shelly_blu_address[key.toUpperCase()] = CONFIG.shelly_blu_address[key];
}

// MQTT publish function
function mqtt_publish(topic, payload) {
    let message = JSON.stringify(payload);
    MQTT.publish(topic, message, 0, false);
}

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

let ALLTERCO_MFD_ID = JSON.parse("0x" + ALLTERCO_MFD_ID_STR);
let BTHOME_SVC_ID = JSON.parse("0x" + BTHOME_SVC_ID_STR);

let SCAN_DURATION = BLE.Scanner.INFINITE_SCAN;

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

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;
}

let BTH = {};
BTH[0x00] = { n: "pid", t: uint8 };
BTH[0x01] = { n: "Battery", t: uint8, u: "%" };
BTH[0x15] = { n: "Battery-OK", t: uint8 };
BTH[0x16] = { n: "Battery-Charging", t: uint8 };
BTH[0x05] = { n: "Illuminance", t: uint24, f: 0.01 };
BTH[0x3f] = { n: "Rotation", t: int16, f: 0.1 };
BTH[0x02] = { n: "Temperature", t: int16, f: 0.01, u: "tC" };
BTH[0x45] = { n: "Temperature", t: int16, f: 0.1, u: "tF" };
BTH[0x04] = { n: "Pressure", t: uint24, f: 0.01};
BTH[0x03] = { n: "Humidity", t: uint16, f: 0.01, u: "%" };
BTH[0x2e] = { n: "Humidity", t: uint8, f: 1, u: "%" };
BTH[0x08] = { n: "Dewpoint", t: uint16, f: 0.01};
BTH[0x14] = { n: "Moisture", t: uint16, f: 0.01};
BTH[0x2f] = { n: "Moisture", t: uint8, f: 1};
BTH[0x20] = { n: "Moisture", t: uint8 };
BTH[0x20] = { n: "Moisture-Warn", t: uint8 };
BTH[0x12] = { n: "co2", t: uint16};
BTH[0x17] = { n: "co", t: uint8 };
BTH[0x0c] = { n: "Voltage", t: uint16, f: 0.001};
BTH[0x4a] = { n: "Voltage", t: uint16, f: 0.1};
BTH[0x18] = { n: "Cold", t: uint8 };
BTH[0x1c] = { n: "Gas", t: uint8 };
BTH[0x1d] = { n: "Heat", t: uint8 };
BTH[0x1e] = { n: "Light", t: uint8 };
BTH[0x1f] = { n: "Lock", t: uint8 };
BTH[0x1a] = { n: "Door", t: uint8 };
BTH[0x1b] = { n: "Garage-Door", t: uint8 };
BTH[0x21] = { n: "Motion", t: uint8 };
BTH[0x2d] = { n: "Window", t: uint8 };
BTH[0x3a] = { n: "Button", t: uint8 };

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);
        return res;
    },
    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;
            result[_bth.n] = _value;
            buffer = buffer.slice(getByteSize(_bth.t));
        }
        return result;
    },
};

let ShellyBLUParser = {
    getData: function (res) {
        let result = BTHomeDecoder.unpack(res.service_data[BTHOME_SVC_ID_STR]);
        result.addr = res.addr;
        result.rssi = res.rssi;
        return result;
    },
};

let last_packet_id = 0x100;
function scanCB(ev, res) {
    if (ev !== BLE.Scanner.SCAN_RESULT) return;
    // skip if there is no service_data member
    if (
        typeof res.service_data === "undefined" ||
        typeof res.service_data[BTHOME_SVC_ID_STR] === "undefined"
    )
        return;
    // skip if we are looking for name match but don't have active scan as we don't have name
    if (
        typeof CONFIG.shelly_blu_name_prefix !== "undefined" &&
        (typeof res.local_name === "undefined" ||
            res.local_name.indexOf(CONFIG.shelly_blu_name_prefix) !== 0)
    )
        return;
    // skip if we don't have address match
    if (
        typeof CONFIG.shelly_blu_address !== "undefined" &&
        !CONFIG.shelly_blu_address.hasOwnProperty(res.addr.toUpperCase())
    )
        return;
    let BTHparsed = ShellyBLUParser.getData(res);
    // // skip if parsing failed
    if (BTHparsed === null) {
        console.log("Failed to parse BTH data");
        return;
    }
    // skip, we are deduping results
    if (last_packet_id === BTHparsed.pid) return;
    last_packet_id = BTHparsed.pid;
    console.log("Shelly BTH packet: ", JSON.stringify(BTHparsed));
    // Get the topic for the current address
    let topic = CONFIG.shelly_blu_address[res.addr.toUpperCase()];
    console.log("Topic for the current address: ", topic);
    // Publish the data
    mqtt_publish(topic, BTHparsed);

}

print("Starting BLE scan");
BLE.Scanner.Start({ duration_ms: SCAN_DURATION, active: false }, scanCB);

Danke Dir
Jürgen

Vielleicht passt dein Script nicht zu dem Symcon Modul? RSSI sehe ich in dem Script gar nicht…
Das hier ausprobiert?

Michael

(Beitrag vom Verfasser gelöscht)

Ja habe ich auch ausprobiert. Muss ich an den Scripten was anpassen. Ich bin leider kein Programmierer und vermisse eigentlich auch die MAC-Adresse des Shelly BLU Button 1.
In den Scripten die man aus der Library (Konfiguration im Shelly BLE Gateway) holt ist alles klein geschrieben und in englisch bspw. rssi, button, battery. Zudem kann man dort keine MAC-Adresse hinterlegen. Im Modul von Kai sind die Variablen alle in Deutsch und teilweise mit Großbuchstaben am Anfang.

Ja, und? Namen sind Schall und Rauch. Im Code sind die schon richtig (kleingeschrieben).

Hast du in Symcon den Shelly BLU Configurator angelegt? Tauchen dort die Geräte auf?
Hast du sie einmal aufgeweckt nachdem du das Script auf dem Gateway und den Konfigurator angelegt hast?
Michael
Michael