Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Obi Bluetooth Lichterkette in IOBroker integrieren

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Obi Bluetooth Lichterkette in IOBroker integrieren

    This topic has been deleted. Only users with topic management privileges can see it.
    • F
      Fabian1 last edited by Fabian1

      Hallo Zusammen,
      ich bin echt am verzweifeln, habe keine Lust mehr und brauche dringend ein frisches paar Augen!
      Alles hat damit angefangen, dass meine Frau davon abgeraten hat, die 5. Twinkly Lichterkette für den Garten zu bestellen! 😄
      Also bin ich zum Obi und habe mich nach Alternativen umgeguckt und bin dabei auf diese Lichterkette gestoßen! WhatsApp Image 2024-11-26 at 16.56.25.jpeg
      Die perfekte Länge und Bluetooth Steuerung per App, da dachte ich mir, perfekt, die kriege ich bestimmt irgendwie in den IOBroker integriert und kann sie dann zusammen mit den anderen Lichterketten über den Außenlichtsensor dimmen bzw. ein und ausschalten. (Außerdem liebe ich die Herausforderung 🙂 )

      Zu diesem Zeitpunkt dachte ich noch, der schwierigste Teil wird, die funktionsweise der App reverse zu engineeren und herauszufinden, was ich senden muss um die verschiedenen Funktionen zu triggern. Das war allerdings dank eines alten Android Handys meiner Frau und Wireshark ziemlich easy. Also kannte ich jetzt die Daten die ich senden muss und die richtigen Addressen. Am Handy hat es sofort funktioniert und ich dachte, ok das war einfach, jetzt lade ich mir einfach einen IOB Adapter runter der Bluetooth Befehle senden kann (sowie die 1000 IPhone und Android Apps die es da gibt) und das war's. Leider hab ich dann gemerkt den gibt es nicht! 😲

      Also bin ich selbst zur tat geschritten und habe folgendes Skript programmiert und es funktioniert fast alles!
      Die Lichterkette wird verbunden, ich kann die Services auslesen aber ich KRIEG EINFACH KEINE BEFEHLE GESENDET, immer Fehler beim Schreiben des Wertes in die Characteristic!! 💩

      Ich bin echt mit meinem Latein am Ende! Hier das Skript:

      // Laden des dbus-next Moduls
      const dbus = require('dbus-next');
      
      // Pfad zum Datenpunkt
      const datapointPath = 'javascript.0.MeineVariablen.Lichterkette_OnOff';
      
      // Zustand 'Lichterkette_OnOff' erstellen, falls nicht vorhanden
      createState(datapointPath, false, {
         name: 'Lichterkette On/Off',
         type: 'boolean',
         role: 'switch',
         read: true,
         write: true,
         def: false
      }, () => {
         // Event Listener für Zustandsänderungen registrieren
         on({ id: datapointPath, change: 'ne' }, (obj) => {
             const action = obj.state.val ? 'on' : 'off';
             controlLight(action)
                 .then(() => {
                     console.log(`Lichterkette wurde ${action === 'on' ? 'eingeschaltet' : 'ausgeschaltet'}`);
                 })
                 .catch((err) => {
                     console.error('Fehler bei der Steuerung der Lichterkette:', err.message || err);
                 });
         });
      });
      
      // Hauptfunktion zur Steuerung der Lichterkette
      function controlLight(action) {
         return new Promise(async (resolve, reject) => {
             const bus = dbus.systemBus();
      
             const bluezServiceName = 'org.bluez';
             const adapterPath = '/org/bluez/hci0'; // Bluetooth-Adapter (hci0)
             const deviceAddress = '24:35:02:27:DE:6E'; // MAC-Adresse Lichterkette
             const devicePath = adapterPath + '/dev_' + deviceAddress.replace(/:/g, '_');
      
             try {
                 // Verbindung zum BlueZ-Service herstellen
                 const bluez = await bus.getProxyObject(bluezServiceName, '/');
                 const manager = bluez.getInterface('org.freedesktop.DBus.ObjectManager');
      
                 // Alle verwalteten Objekte abrufen
                 const objects = await manager.GetManagedObjects();
      
                 // Prüfen, ob das Gerät bereits bekannt ist
                 let deviceFound = false;
      
                 for (const [path, interfaces] of Object.entries(objects)) {
                     if (path === devicePath) {
                         deviceFound = true;
                         break;
                     }
                 }
      
                 // Wenn das Gerät nicht gefunden wurde, Discovery starten
                 if (!deviceFound) {
                     console.log('Gerät nicht gefunden, starte Discovery...');
      
                     const adapter = await bus.getProxyObject(bluezServiceName, adapterPath);
                     const adapterInterface = adapter.getInterface('org.bluez.Adapter1');
      
                     await adapterInterface.StartDiscovery();
      
                     // Warten, bis das Gerät gefunden wird oder Timeout nach 15 Sekunden
                     await new Promise((resolveDiscovery, rejectDiscovery) => {
                         const timeout = setTimeout(() => {
                             rejectDiscovery(new Error('Gerät wurde während der Discovery nicht gefunden'));
                         }, 15000); // Timeout nach 15 Sekunden
      
                         manager.on('InterfacesAdded', (path, interfaces) => {
                             if (path === devicePath) {
                                 clearTimeout(timeout);
                                 resolveDiscovery();
                             }
                         });
                     });
      
                     await adapterInterface.StopDiscovery();
                 }
      
                 // Verbindung zum Gerät herstellen
                 const device = await bus.getProxyObject(bluezServiceName, devicePath);
                 const deviceInterface = device.getInterface('org.bluez.Device1');
      
                 try {
                     await deviceInterface.Connect();
                     console.log('Verbunden mit der Lichterkette');
      
                     // Verzögerung erhöhen
                     await new Promise((resolveDelay) => setTimeout(resolveDelay, 5000)); // 5 Sekunden warten
      
                     // Services und Characteristics auflisten
                     await listServicesAndCharacteristics(devicePath, bus);
                 } catch (error) {
                     console.error('Fehler beim Verbinden mit dem Gerät:', error.message || error);
                     return reject(error);
                 }
      
                 // **Characteristic für Initialisierung und Ein/Aus finden**
                 const characteristicUUID = '0000fff1-0000-1000-8000-00805f9b34fb'; // Verwenden von 0000fff1-... für beide Befehle
                 const characteristicPath = await findCharacteristicPath(devicePath, characteristicUUID, bus);
                 if (!characteristicPath) {
                     console.error('Characteristic für Ein/Aus nicht gefunden');
                     await deviceInterface.Disconnect();
                     return reject(new Error('Characteristic für Ein/Aus nicht gefunden'));
                 }
      
                 // Interface der Characteristic abrufen
                 const characteristic = await bus.getProxyObject(bluezServiceName, characteristicPath);
                 const characteristicInterface = characteristic.getInterface('org.bluez.GattCharacteristic1');
      
                 // **Ein-/Ausschaltbefehl senden**
                 // Befehl basierend auf der Aktion definieren
                 const value = action === 'on' ? [0x01, 0x01, 0x01, 0x01] : [0x01, 0x01, 0x01, 0x00];
      
                 try {
                     await characteristicInterface.WriteValue(Buffer.from(value), { type: dbus.Variant('s', 'command') });
                     console.log(`Lichterkette wurde ${action === 'on' ? 'eingeschaltet' : 'ausgeschaltet'}`);
                 } catch (error) {
                     console.error('Fehler beim Schreiben des Wertes in die Characteristic:', error.message || error);
                 }
      
                 // Verbindung zum Gerät trennen
                 try {
                     await deviceInterface.Disconnect();
                     console.log('Verbindung zur Lichterkette getrennt');
                 } catch (error) {
                     console.error('Fehler beim Trennen der Verbindung zum Gerät:', error.message || error);
                 }
      
                 resolve();
             } catch (err) {
                 console.error('Fehler in controlLight:', err.message || err);
                 reject(err);
             }
         });
      }
      
      // Hilfsfunktion, um den Pfad der Characteristic zu finden
      function findCharacteristicPath(devicePath, characteristicUUID, bus) {
         return new Promise(async (resolve) => {
             const bluezServiceName = 'org.bluez';
             const manager = await bus.getProxyObject(bluezServiceName, '/').then((obj) => obj.getInterface('org.freedesktop.DBus.ObjectManager'));
             const objects = await manager.GetManagedObjects();
      
             for (const [path, interfaces] of Object.entries(objects)) {
                 if (path.startsWith(devicePath) && 'org.bluez.GattCharacteristic1' in interfaces) {
                     const uuid = interfaces['org.bluez.GattCharacteristic1'].UUID.value.toLowerCase();
                     if (uuid === characteristicUUID.toLowerCase()) {
                         return resolve(path);
                     }
                 }
             }
             resolve(null);
         });
      }
      
      // Funktion zum Auflisten der verfügbaren Services und Characteristics
      function listServicesAndCharacteristics(devicePath, bus) {
         return new Promise(async (resolve) => {
             const manager = await bus.getProxyObject('org.bluez', '/').then((obj) => obj.getInterface('org.freedesktop.DBus.ObjectManager'));
             const objects = await manager.GetManagedObjects();
      
             console.log(`Anzahl der Objekte: ${Object.keys(objects).length}`);
      
             console.log('Verfügbare Services und Characteristics:');
             let found = false;
             for (const [path, interfaces] of Object.entries(objects)) {
                 if (path.startsWith(devicePath)) {
                     found = true;
                     console.log(`Gefundenes Objekt: ${path}`);
                     if ('org.bluez.GattService1' in interfaces) {
                         const uuid = interfaces['org.bluez.GattService1'].UUID.value;
                         console.log(`Service: ${path}, UUID: ${uuid}`);
                     }
                     if ('org.bluez.GattCharacteristic1' in interfaces) {
                         const uuid = interfaces['org.bluez.GattCharacteristic1'].UUID.value;
                         const flags = interfaces['org.bluez.GattCharacteristic1'].Flags.value;
                         console.log(`Characteristic: ${path}, UUID: ${uuid}, Flags: ${flags}`);
                     }
                 }
             }
             if (!found) {
                 console.log('Keine Services oder Characteristics gefunden.');
             }
             resolve();
         });
      }
      
      
      

      In der Konsole funktioniert es übrigens:
      mit

      bluetoothctl
      power on
      scan on
      connect 24:35:02:27:DE:6E
      gatt.select-attribute 0000fff1-0000-1000-8000-00805f9b34fb
      
      Aus:
      gatt.write "0x01 0x01 0x01 0x00"
      
      Ein:
      gatt.write "0x01 0x01 0x01 0x01"
      

      Kann ich die Lichterkette aus der Konsole ein- und ausschalten, aber ich finde einfach keinen Weg, das ganze in ein Skript zu packen.

      Vielen Dank für eure Hilfe,
      Fabian

      F 1 Reply Last reply Reply Quote 0
      • F
        Fabian1 @Fabian1 last edited by

        ok ich habe es hinbekommen, zwar mit exec, aber besser als garnichts!
        Ich habe jetzt also eine Obi Bluetooth Lichterkette die per Alexa steuerbar ist.
        Es funktioniert bis jetzt An und Aus und Helligkeit in %. Falls noch jemand vor einer ähnlichen Problem steht, hier die Lösung:

        const { exec } = require('child_process');
        
        // MAC-Adresse des Geräts und UUID der GATT-Characteristic
        const deviceAddress = '24:35:02:27:DE:6E';
        const characteristicUUID = '0000fff1-0000-1000-8000-00805f9b34fb';
        
        // Pfade zu den Datenpunkten
        const datapointOnOff = 'javascript.0.MeineVariablen.Lichterkette_OnOff';
        const datapointBrightness = 'javascript.0.MeineVariablen.Lichterkette_Helligkeit';
        
        // Warteschlange und Status
        const actionQueue = [];
        let isProcessing = false;
        
        // Funktion: Shell-Befehl ausführen mit Debugging und Timeout
        function executeBluetoothCommand(command, timeout = 10000) {
            console.log(`Führe aus: ${command}`);
            return new Promise((resolve, reject) => {
                const process = exec(command, (error, stdout, stderr) => {
                    if (error) {
                        console.error(`Fehler: ${stderr || error.message}`);
                        return reject(stderr || error.message);
                    }
                    console.log(`Erfolg: ${stdout}`);
                    resolve(stdout.trim());
                });
        
                // Timeout hinzufügen
                setTimeout(() => {
                    process.kill('SIGTERM');
                    reject('Befehl abgebrochen (Timeout)');
                }, timeout);
            });
        }
        
        // Funktion: Gerät ist verbunden prüfen
        async function isDeviceConnected() {
            try {
                const output = await executeBluetoothCommand(`bluetoothctl info ${deviceAddress}`);
                return output.includes('Connected: yes');
            } catch (error) {
                console.warn('Verbindungsprüfung fehlgeschlagen:', error);
                return false;
            }
        }
        
        // Funktion: Wiederholungsversuch für einen Befehl
        async function retryCommand(command, retries = 10) {
            for (let i = 0; i < retries; i++) {
                try {
                    return await executeBluetoothCommand(command);
                } catch (error) {
                    console.warn(`Fehler beim Befehl: ${command}, Versuch ${i + 1} von ${retries}`);
                }
            }
            throw new Error(`Befehl fehlgeschlagen nach ${retries} Versuchen: ${command}`);
        }
        
        // Funktion: Gerät verbinden
        async function connectToDevice() {
            try {
                console.log('Versuche Verbindung zum Gerät herzustellen...');
                if (!(await isDeviceConnected())) {
                    await retryCommand(`bluetoothctl connect ${deviceAddress}`);
                }
                console.log('Verbindung erfolgreich hergestellt.');
            } catch (error) {
                console.error('Verbindung fehlgeschlagen, versuche Fehler zu beheben...');
                await retryCommand(`bluetoothctl power on`);
                await retryCommand(`bluetoothctl connect ${deviceAddress}`);
                console.log('Verbindung nach Fehlerbehebung erfolgreich.');
            }
        }
        
        // Funktion: Gerät trennen
        async function disconnectDevice() {
            try {
                console.log('Trenne Verbindung zum Gerät...');
                if (await isDeviceConnected()) {
                    await retryCommand(`bluetoothctl disconnect ${deviceAddress}`);
                }
                console.log('Verbindung erfolgreich getrennt.');
            } catch (error) {
                console.error('Fehler beim Trennen der Verbindung:', error);
            }
        }
        
        // Funktion: GATT-Wert schreiben
        async function writeGattValue(value) {
            try {
                console.log(`Schreibe Wert: ${value} an die GATT-Characteristic...`);
                const script = `
        bluetoothctl << EOF
        menu gatt
        select-attribute ${characteristicUUID}
        write ${value}
        exit
        EOF
                `;
                await executeBluetoothCommand(script);
            } catch (error) {
                console.error('Fehler beim Schreiben auf die GATT-Characteristic:', error);
                throw new Error('GATT-Wert konnte nicht geschrieben werden.');
            }
        }
        
        // Funktion: Helligkeit berechnen
        function calculateBrightnessHex(brightnessPercent) {
            const brightnessHex = Math.round((brightnessPercent / 100) * 0x64).toString(16).padStart(2, '0');
            return `"0x03 0x01 0x01 0x${brightnessHex}"`;
        }
        
        // Funktion: Lichterkette steuern
        async function controlLight(action, brightness = null) {
            try {
                await connectToDevice();
                if (action) {
                    if (brightness !== null) {
                        const brightnessValue = calculateBrightnessHex(brightness);
                        await writeGattValue(brightnessValue);
                    } else {
                        const value = action === 'on' ? '"0x01 0x01 0x01 0x01"' : '"0x01 0x01 0x01 0x00"';
                        await writeGattValue(value);
                    }
                }
                await disconnectDevice();
            } catch (error) {
                console.error('Fehler bei der Steuerung der Lichterkette:', error);
            }
        }
        
        // Funktion: Warteschlange abarbeiten
        async function processQueue() {
            if (isProcessing) return; // Verhindert gleichzeitige Verarbeitung
        
            isProcessing = true;
            while (actionQueue.length > 0) {
                const { action, brightness } = actionQueue.shift(); // Nächsten Befehl aus der Warteschlange holen
                console.log(`Verarbeite Aktion: ${action}, Helligkeit: ${brightness}`);
                await controlLight(action, brightness);
            }
            isProcessing = false;
        }
        
        // Datenpunkte erstellen, falls nicht vorhanden
        createState(datapointOnOff, false, {
            name: 'Lichterkette On/Off',
            type: 'boolean',
            role: 'switch',
            read: true,
            write: true,
            def: false
        }, () => {
            // Event Listener für Zustandsänderungen registrieren
            on({ id: datapointOnOff, change: 'ne' }, async (obj) => {
                const action = obj.state.val ? 'on' : 'off';
                actionQueue.push({ action, brightness: null });
                processQueue();
            });
        });
        
        createState(datapointBrightness, 100, {
            name: 'Lichterkette Helligkeit',
            type: 'number',
            role: 'level.dimmer',
            read: true,
            write: true,
            def: 100,
            min: 0,
            max: 100
        }, () => {
            // Event Listener für Helligkeitsänderungen registrieren
            on({ id: datapointBrightness, change: 'ne' }, async (obj) => {
                const brightness = obj.state.val;
        
                if (brightness < 3) {
                    // Wenn Helligkeit unter 3%, Lichterkette ausschalten
                    console.log('Helligkeit unter 3% - Lichterkette wird ausgeschaltet.');
                    setState(datapointOnOff, false); // Setzt On/Off-Datenpunkt auf false
                } else {
                    // Ansonsten Helligkeit setzen
                    actionQueue.push({ action: 'on', brightness });
                    processQueue();
                }
            });
        });
        
        // Debugging: Manuelle Steuerung
        (async () => {
            try {
                console.log('Teste Steuerung: Einschalten mit 50% Helligkeit...');
                actionQueue.push({ action: 'on', brightness: 50 });
                processQueue();
        
                console.log('Teste Steuerung: Ausschalten...');
                actionQueue.push({ action: 'off', brightness: null });
                processQueue();
            } catch (error) {
                console.error('Fehler bei manueller Steuerung:', error);
            }
        })();
        
        
        OliverIO 1 Reply Last reply Reply Quote 0
        • OliverIO
          OliverIO @Fabian1 last edited by

          @fabian1 sagte in Obi Bluetooth Lichterkette in IOBroker integrieren:

          bluetoothctl

          das hier ist die javascript bibliothek die direkten zugriff auf den bluetooth stack bereitstellt.. ob das da so einfach ist wie mit bluetoothctl, weiß ich nicht.
          https://www.npmjs.com/package/node-ble

          ich hab mir mal was mit dbus events gebaut, die auf bluetooth events horchen.
          das war ein krampf. das war allerdings auch nicht in javascript sondern mit python.

          F 1 Reply Last reply Reply Quote 1
          • F
            Fabian1 @OliverIO last edited by

            @oliverio node-ble und noble habe ich zuerst versucht, das hat überhaupt nicht funktioniert, darum bin ich dann auf dbus gewechselt und das hätte auch super funktioniert, wenn ich rausgefunden hätte, wie ich die Befehle im richtigen Format sende. 🙂 Die Lichterkette erwartet nämlich strings und das habe ich einfach nicht hinbekommen und meine online suche hat gezeigt, ich bin da nicht der Einzige. 😄 Irgendwie ist alles was mit bluetooth zu tun hat immer ein absoluter krampf!

            Ich habe jetzt eine neue Version die 100% zuverlässig ist, falls das jemand gebrauchen kann: (diese benutzt das gatttool)

            const { exec } = require('child_process');
            
            // MAC-Adresse des Geräts und Handle der GATT-Characteristic
            const deviceAddress = '24:35:02:27:DE:6E';
            const characteristicHandle = '0x0025';
            
            // Pfade zu den Datenpunkten
            const datapointOnOff = 'javascript.0.MeineVariablen.Lichterkette_OnOff';
            const datapointBrightness = 'javascript.0.MeineVariablen.Lichterkette_Helligkeit';
            
            // Warteschlange und Status
            const actionQueue = [];
            let isProcessing = false;
            
            // Funktion: Shell-Befehl ausführen mit Debugging und Timeout
            function executeCommand(command, timeout = 10000) {
                console.log(`Führe aus: ${command}`);
                return new Promise((resolve, reject) => {
                    const process = exec(command, (error, stdout, stderr) => {
                        if (error) {
                            console.error(`Fehler: ${stderr || error.message}`);
                            return reject(stderr || error.message);
                        }
                        console.log(`Erfolg: ${stdout}`);
                        resolve(stdout.trim());
                    });
            
                    setTimeout(() => {
                        process.kill('SIGTERM');
                        reject('Befehl abgebrochen (Timeout)');
                    }, timeout);
                });
            }
            
            // Funktion: GATT-Wert schreiben mit Wiederholungslogik
            async function writeGattValueWithRetries(value, maxRetries = 10, initialDelay = 500) {
                let attempts = 0;
                let delay = initialDelay;
            
                while (attempts < maxRetries) {
                    try {
                        console.log(`Versuch ${attempts + 1}/${maxRetries}: Sende GATT-Befehl`);
                        await writeGattValue(value);
                        console.log('Befehl erfolgreich gesendet.');
                        return; // Erfolgreich, keine weiteren Versuche notwendig
                    } catch (error) {
                        attempts++;
                        console.error(`Fehler beim Senden (Versuch ${attempts}):`, error);
                        if (attempts >= maxRetries) {
                            console.error('Maximale Anzahl an Versuchen erreicht. Abbruch.');
                            throw new Error('GATT-Befehl konnte nach mehreren Versuchen nicht gesendet werden.');
                        }
                        console.log(`Warte ${delay} ms vor erneutem Versuch...`);
                        await new Promise((resolve) => setTimeout(resolve, delay));
                        delay *= 2; // Verzögerung verdoppeln
                    }
                }
            }
            
            // Funktion: GATT-Wert schreiben
            async function writeGattValue(value) {
                const command = `gatttool -b ${deviceAddress} --char-write-req --handle=${characteristicHandle} --value="${value}"`;
                console.log(`Sende GATT-Befehl: ${command}`);
                try {
                    const output = await executeCommand(command);
                    console.log(`GATT-Befehl erfolgreich: ${output}`);
                } catch (error) {
                    console.error('Fehler beim Schreiben auf die GATT-Characteristic:', error);
                    throw new Error('GATT-Wert konnte nicht geschrieben werden.');
                }
            }
            
            // Funktion: Helligkeit berechnen
            function calculateBrightnessHex(brightnessPercent) {
                const brightnessHex = Math.round((brightnessPercent / 100) * 0x64).toString(16).padStart(2, '0');
                return `030101${brightnessHex}`;
            }
            
            // Funktion: Lichterkette steuern
            async function controlLight(action, brightness = null) {
                try {
                    if (action) {
                        if (brightness !== null) {
                            const brightnessValue = calculateBrightnessHex(brightness);
                            await writeGattValueWithRetries(brightnessValue);
                        } else {
                            const value = action === 'on' ? '01010101' : '01010100';
                            await writeGattValueWithRetries(value);
                        }
                    }
                } catch (error) {
                    console.error('Fehler bei der Steuerung der Lichterkette:', error);
                }
            }
            
            // Funktion: Warteschlange abarbeiten
            async function processQueue() {
                if (isProcessing) return; // Verhindert gleichzeitige Verarbeitung
            
                isProcessing = true;
                while (actionQueue.length > 0) {
                    const { action, brightness } = actionQueue.shift(); // Nächsten Befehl aus der Warteschlange holen
                    console.log(`Verarbeite Aktion: ${action}, Helligkeit: ${brightness}`);
                    await controlLight(action, brightness);
                }
                isProcessing = false;
            }
            
            // Datenpunkte erstellen, falls nicht vorhanden
            createState(datapointOnOff, false, {
                name: 'Lichterkette On/Off',
                type: 'boolean',
                role: 'switch',
                read: true,
                write: true,
                def: false
            }, () => {
                // Event Listener für Zustandsänderungen registrieren
                on({ id: datapointOnOff, change: 'ne' }, async (obj) => {
                    const action = obj.state.val ? 'on' : 'off';
                    actionQueue.push({ action, brightness: null });
                    processQueue();
                });
            });
            
            createState(datapointBrightness, 100, {
                name: 'Lichterkette Helligkeit',
                type: 'number',
                role: 'level.dimmer',
                read: true,
                write: true,
                def: 100,
                min: 0,
                max: 100
            }, () => {
                // Event Listener für Helligkeitsänderungen registrieren
                on({ id: datapointBrightness, change: 'ne' }, async (obj) => {
                    const brightness = obj.state.val;
            
                    if (brightness < 3) {
                        // Wenn Helligkeit unter 3%, Lichterkette ausschalten
                        console.log('Helligkeit unter 3% - Lichterkette wird ausgeschaltet.');
                        setState(datapointOnOff, false); // Setzt On/Off-Datenpunkt auf false
                    } else {
                        // Ansonsten Helligkeit setzen
                        actionQueue.push({ action: 'on', brightness });
                        processQueue();
                    }
                });
            });
            
            // Debugging: Manuelle Steuerung
            /*(async () => {
                try {
                    console.log('Teste Steuerung: Einschalten mit 50% Helligkeit...');
                    actionQueue.push({ action: 'on', brightness: 50 });
                    processQueue();
            
                    console.log('Teste Steuerung: Ausschalten...');
                    actionQueue.push({ action: 'off', brightness: null });
                    processQueue();
                } catch (error) {
                    console.error('Fehler bei manueller Steuerung:', error);
                }
            })();
            */
            
            1 Reply Last reply Reply Quote 0
            • First post
              Last post

            Support us

            ioBroker
            Community Adapters
            Donate

            592
            Online

            31.8k
            Users

            80.0k
            Topics

            1.3m
            Posts

            2
            4
            269
            Loading More Posts
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes
            Reply
            • Reply as topic
            Log in to reply
            Community
            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
            The ioBroker Community 2014-2023
            logo