Shelly Blu Motion Helligkeitssensor

Hinweis zur Nutzung von Skripten (für Nutzer)

Die Verwendung von Skripten erfolgt ausdrücklich auf eigene Gefahr. Weder Shelly noch die jeweiligen Autoren oder Entwickler der Skripte übernehmen irgendeine Form der Haftung für mögliche Schäden, Fehlfunktionen, Datenverluste oder anderweitige Beeinträchtigungen, die durch die Nutzung dieser Skripte entstehen könnten. Bitte stellen Sie vor dem Einsatz sicher, dass Sie den Quellcode verstehen und sich der möglichen Auswirkungen bewusst sind. Die Skripte werden ohne Gewähr bereitgestellt und unterliegen keiner regelmäßigen Wartung oder offiziellen Unterstützung.


Hinweis für Entwickler

Wenn Sie eigene Skripte bereitstellen, achten Sie bitte darauf, eine klare Beschreibung, eventuelle Einschränkungen und Sicherheitsaspekte zu dokumentieren. Beachten Sie zudem, dass Nutzer Ihre Skripte grundsätzlich auf eigenes Risiko verwenden. Eine Haftung für Schäden ist ausgeschlossen, sofern diese nicht vorsätzlich oder grob fahrlässig verursacht wurden oder gesetzlich anderweitig geregelt ist.

VPN/Proxy erkannt

Es scheint, dass Sie einen VPN- oder Proxy-Dienst verwenden. Bitte beachten Sie, dass die Nutzung eines solchen Dienstes die Funktionalität dieser Webseite einschränken kann.

  • Ich breche mir die Finger...

    Ich bräuchte mal Eure Hilfe, evtl hat schon jemand ein Script

    Nach dem Motto: wenn Helligkeit <50 dann schalte Plug s aus bei >60 ein

    Vielen Dank im Voraus

    Einmal editiert, zuletzt von Gast141498 (28. März 2025 um 10:30)

  • Gast141498 28. März 2025 um 10:29

    Hat den Titel des Themas von „Shelly Blu Motion Helleigkeitssensor“ zu „Shelly Blu Motion Helligkeitssensor“ geändert.
  • finger nicht gebroche....hab´s hinbekommen.....

    unter targetMac die Mac Adresse des Motion Sensors eintgaen und weiter unten unter URL kann man eine Url eintargen. bei mir wird eina Lampa ein-und ausgeschaltet/******************* 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: true,

    // MAC address of the target Shelly BLU Motion device
    targetMac: "38:39:8f:ab:4e:f5",
    };
    /******************* 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 },
    0xF0: { n: "deviceID", t: uint16 },
    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);

    //Control the Shelly Plug S based on illuminance (now calls other URLs)
    if (data.illuminance !== undefined) {
    if (data.illuminance < 50) {
    Shelly.call("http.get", {
    url: "http://xxx.xxx.xxx.xxx/cs?c2=37&c1=RFCode%20%23001155",
    });
    } else {
    Shelly.call("http.get", {
    url: "http://xxx.xxx.xxx.xxx/cs?c2=39&c1=RFCode%20%23001150",
    });
    }
    }
    }

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

    //filter by mac address
    if (result.addr !== CONFIG.targetMac) {
    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;
    unpackedData.deviceID = unpackedData.deviceID;

    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();