Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Praktische Anwendungen (Showcase)
    4. CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor

    NEWS

    • Monatsrückblick - April 2025

    • Minor js-controller 7.0.7 Update in latest repo

    • Save The Date: ioBroker@Smart Living Forum Solingen, 14.06.

    CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor

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

      Der chaotische Versuchsaufbau 😉

      82a2a351-e341-489e-beff-6d88fe16dba4.jpg

      Werte kommen an!

      L1 NASS
      L2 TROCKEN

      e255c207-06a6-4d3b-9ffa-3effc55b4f02-image.png

      Jetzt geht es an die Feinheiten. Ich hoffe, man kann mit dem Converter in 10% umrechnen. Sonst mache ich das mit einem Alias.

      1 Reply Last reply Reply Quote 0
      • skvarel
        skvarel Developer last edited by

        Der DHT22 läuft nun, zwei Soil Sensoren auch.

        Bei den Reedkontakten habe ich noch ein Problem 😞

        Der zweite will einfach nicht.

        6d9f1f40-983c-48f7-adca-3e8bceca674e-image.png

        Identische Einstellungen, es bleibt aber bei N/A

        8d58d5d6-322b-4a32-a73c-bcf848decee2-image.png

        1 Reply Last reply Reply Quote 0
        • skvarel
          skvarel Developer last edited by

          Mit passendem Converter klappt es!

          caf8bf67-ab16-4b12-b4a5-da7d5ed269de-image.png

          1e3f9289-95ce-47fe-a1f2-8412539ad26b-image.png

          1 Reply Last reply Reply Quote 1
          • skvarel
            skvarel Developer last edited by skvarel

            UPDATE:

            311bd3a3-f98c-40e8-932c-7f33ce24727d-image.png

            l1: Bodentemperatur DS18B20 (liegt zur Zeit auf der Heizung)
            l2: Lufttemperatur & -feuchtigkeit DHT22
            l3: Bodenfeuchtigkeit Soil Sensor (wird hier noch falsch angezeigt)
            l4: Bodenfeuchtigkeit Soil Sensor
            l5: Reed für die Tür
            l6: Reed für das Fenster
            l7: Relais für Beleuchtung
            l8: Relais für Heizung/Frostschutz

            Bei den Details und in den Datenpunkten stimmen die Endpunkte L3 und L4. Im Dashboard bekomme ich es einfach nicht geändert 😞

            a009cc25-2c0f-4cfa-9dd2-85b2018d741e-image.png

            EDIT: Es handelt sich 'nur' um einen Übersetzungsfehler! In der englischen Ansicht passt es
            27c0996e-7677-4ffb-bb98-7ef8550f90e5-image.png

            1 Reply Last reply Reply Quote 0
            • skvarel
              skvarel Developer last edited by

              Die freie Version voll ausgereizt. Mehr geht nur mit der Premium!

              8885c4dd-e209-4fec-a83e-f5e0c30f92ae-image.png

              1 Reply Last reply Reply Quote 1
              • skvarel
                skvarel Developer last edited by

                Die Beschreibungen konnte ich auch direkt im Converter vergeben

                2b160b4e-af85-41cb-9dfb-eb9331c4b278-image.png

                1 Reply Last reply Reply Quote 1
                • skvarel
                  skvarel Developer last edited by

                  Ich habe leider ein Problem mit den Kontakt Datenpunkte.

                  Die Aktualisieren sich im Zigbee2mqtt Adapter nicht 😞

                  71f0bada-8d79-4feb-b25f-74c4e36e2987-image.png

                  53584d31-7ea3-4e12-b3da-d3364a9fcf56-image.png

                  Im mqtt Adapter kommt allerdings die Änderung an

                  79cf3c90-bf64-4867-a60b-13fae89ba8e3-image.png

                  Ich behelfe mich nun erstmal mit einem kleinen Blockly und zwei Hilfsdatenpunkten, bis ich eine Lösung gefunden habe
                  Ich lese das json jetzt aus dem mqtt Adpater aus
                  d40f0ed0-2cb4-4dec-8959-e1e54570f8a6-image.png

                  Wo die Daten herkommen ist beim Alias ja egal.
                  52c4ac7d-ca29-41c9-8161-357994d6b584-image.png

                  Da die Werte im Zigbee2mqtt ankommen und auch üer mqtt auswertbar sind, vermute ich das Problem irgendwo im Zigbee2mqtt Adapter.
                  Ich habe dazu ein Issue erstellt:

                  https://github.com/arteck/ioBroker.zigbee2mqtt/issues/436

                  skvarel created this issue in arteck/ioBroker.zigbee2mqtt

                  closed [Device problem]: DIY - Datenpunkte werden nicht aktualisiert #436

                  1 Reply Last reply Reply Quote 0
                  • skvarel
                    skvarel Developer last edited by

                    Das Widget dazu
                    (Die Werte stimmen natürlich noch nicht. Die Sensoren liegen alle noch hier im Büro und teilweise auf der Heizung)

                    b21bbfd9-6ada-4dcc-a94e-24c697a6899e-image.png

                    1 Reply Last reply Reply Quote 0
                    • skvarel
                      skvarel Developer last edited by

                      Fertig 🙂
                      Es fehlt nur noch die TPU-Dichtung unter dem Deckel.

                      d28fc773-44b3-4323-a6d3-fef52a130a08.jpg

                      1 Reply Last reply Reply Quote 3
                      • skvarel
                        skvarel Developer last edited by

                        Jetzt brauche ich erstmal eine neue Idee!

                        1 Reply Last reply Reply Quote 0
                        • skvarel
                          skvarel Developer last edited by

                          Ich hatte noch einen CC2531 und ein paar DHT22 übrig.

                          Natürlich wieder mit Icon und eigenem Konverter 🙂

                          Ein Sensor mit 2m Kabel für die neue Werkstatt und einmal 5m Kabel, durch die Wand für den Außenbereich.

                          2d92af21-3fc8-4666-8038-32f4e0044400-image.png

                          d14ed772-bd37-4f32-a7bb-f18414edf9c3-image.png

                          6485d35f-ce85-40e9-9be2-a65d0ee641c5-image.png

                          1 Reply Last reply Reply Quote 0
                          • skvarel
                            skvarel Developer last edited by

                            Hallo zusammen.

                            Ich habe mittlerweile ein paar eigene Zigbee Geräte in meinem Netzwerk. Klappt soweit sehr stabil.
                            Ich stehe nur vor einem 'Problem' bei einem externen Konverter. Kennst sich da jemand aus? Ich würde gern einen Wert direkt im Konverter umrechnen.

                            Alles unter 300mm soll als 'true' und alles darüber als 'false' angezeigt werden. Mit einem Alias ist das kein Problem! Ich hätte es aber gern direkt in der Zigbee-Kachel anders stehen.

                            Ich messe hier in der Mähroboter-Garage, ob Roberta drin steht oder unterwegs ist.

                            477111538_3070106873136313_7589983493516186053_n.jpg

                            So mache ich es zur Zeit (via Alias)

                            476391189_3070107329802934_5044627440779325810_n.jpg

                            Ausschnitt vom Konverter. Könnte man es nicht schon direkt hier umrechnen?

                            476403640_3070107776469556_1700162112400831784_n.jpg

                            Das wäre meine Wunschvorstellung (Photoshop)

                            476254301_3070109516469382_3767719117024236975_n.jpg

                            Asgothian 1 Reply Last reply Reply Quote 0
                            • Asgothian
                              Asgothian Developer @skvarel last edited by Asgothian

                              @skvarel sagte in CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor:

                              Hallo zusammen.

                              […]

                              Ausschnitt vom Konverter. Könnte man es nicht schon direkt hier umrechnen?

                              Kann man.

                              Dazu musst du 2 Dinge tun

                              • eine Funktion schreiben die die zigbee Nachricht abfängt um setzt
                              • das korrekte ‘expose’ dafür finden / definieren

                              Das hört sich jetzt sehr komplex an, ist es aber nicht.

                              • Du schaust dir die Funktion fz.ptvo_switch_analog_Input an. Wichtig sind die Parameter beim Aufruf sowie der rückgabewert
                              • du schreibst eine Funktion die mit den gleichen Parametern aufgerufen wird und rufst darin als erstes besagte fz… Funktion auf. Dann nimmst du den rückgabewert und baust den so um das deine Wunsch Bedingung erfüllt ist.
                              • Unter fromZigbee trägst du dann diese Funktion an Stelle der ptvo_switch_analog_Input ein.
                              • als letztes musst du schauen welcher Expose am besten dazu passt. Ich bin gerade unterwegs, kann da aber heute Nachmittag mal einen Vorschlag machen.

                              A.

                              skvarel 1 Reply Last reply Reply Quote 1
                              • skvarel
                                skvarel Developer @Asgothian last edited by

                                @asgothian .. puhh, das klingt doch schon kompliziert.

                                Asgothian 1 Reply Last reply Reply Quote 0
                                • skvarel
                                  skvarel Developer last edited by

                                  Hier nochmal der aktuelle Konverter:

                                  https://github.com/inventwo/custom-zigbee/blob/main/Converter/CC2531.US100.js

                                  1 Reply Last reply Reply Quote -1
                                  • Asgothian
                                    Asgothian Developer @skvarel last edited by Asgothian

                                    @skvarel sagte in CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor:

                                    @asgothian .. puhh, das klingt doch schon kompliziert.

                                    Es ist einfacher als du denkst. Ich hatte bei der Beschreibung aber auch einen Denkfehler. Versuch mal so:

                                    const fzlocal = {
                                    ptvo_switch_analog_to_boolean: {
                                            cluster: 'genAnalogInput',
                                            type: ['attributeReport', 'readResponse'],
                                            convert: (model, msg, publish, options, meta) => {
                                                const value =( msg.data['presentValue'] > 300 );
                                                const action = (value ? 'occupied':'free');
                                                return {action: postfixWithEndpointName(action, msg, model, meta)};
                                             },
                                    };
                                    
                                    const device = {
                                        zigbeeModel: ['CC2531.US100'],
                                        model: 'CC2531.US100',
                                        vendor: 'inventwo',
                                        description: '[CC2531 w. US-100 Sensor](https://github.com/inventwo/custom-zigbee)',
                                        fromZigbee: [fz.ignore_basic_report, fz.ptvo_switch_uart, fz.ptvo_switch_analog_input,fzlocal.ptvo_switch_analog_to_boolean],
                                        toZigbee: [tz.ptvo_switch_trigger, tz.ptvo_switch_uart,],
                                        exposes: [
                                          exposes.numeric('l1', ea.STATE).withDescription('Innenraummessung').withUnit('mm'),
                                          exposes.action(['occupied'].withDescription('Innenraum belegt'),
                                          exposes.action(['free'].withDescription('Innenraum frei'),
                                            ],
                                        meta: {
                                            multiEndpoint: true,
                                                    
                                        },
                                        endpoint: (device) => {
                                            return {
                                                l1: 1,
                                            };
                                        },
                                    
                                        configure: async (device, coordinatorEndpoint, logger) => {
                                          const endpoint = device.getEndpoint(1);
                                          await endpoint.read('genBasic', ['modelId', 'swBuildId', 'powerSource']);
                                        },
                                    
                                    };
                                    

                                    A.

                                    Nachtrag: ich hab das icon aus dem code genommen, und den Kopf nicht mit angegeben - das sollte aber kein problem für Dich sein

                                    Nachtrag2: ich hatte noch einen Denkfehler - ist jetzt korrigiert.

                                    skvarel 2 Replies Last reply Reply Quote 0
                                    • skvarel
                                      skvarel Developer @Asgothian last edited by skvarel

                                      @asgothian .. teste ich!

                                      1 Reply Last reply Reply Quote 0
                                      • skvarel
                                        skvarel Developer @Asgothian last edited by

                                        @asgothian .. das funktioniert leider überhaupt nicht

                                        94dc8da6-ed93-4fa0-aafd-40524a50b9d4-image.png

                                        Sobald ich deine Teile einsetze, kommt gar nichts mehr an. Bei dir waren noch ein paar Klammern offen. Die habe ich geschlossen.

                                        So hatte ich den Code verwendet:

                                        const fzlocal = {
                                          ptvo_switch_analog_to_boolean: {
                                                  cluster: 'genAnalogInput',
                                                  type: ['attributeReport', 'readResponse'],
                                                  convert: (model, msg, publish, options, meta) => {
                                                      const value =( msg.data['presentValue'] > 300 );
                                                      const action = (value ? 'occupied':'free');
                                                      return {action: postfixWithEndpointName(action, msg, model, meta)};
                                                   },
                                          }
                                        };
                                        
                                        const device = {
                                            zigbeeModel: ['CC2531.US100'],
                                            model: 'CC2531.US100',
                                            vendor: 'inventwo',
                                            description: '[CC2531 w. US-100 Sensor](https://github.com/inventwo/custom-zigbee)',
                                            fromZigbee: [fz.ignore_basic_report, fz.ptvo_switch_uart, fz.ptvo_switch_analog_input, fzlocal.ptvo_switch_analog_to_boolean],
                                            toZigbee: [tz.ptvo_switch_trigger, tz.ptvo_switch_uart,],
                                            exposes: [
                                              exposes.numeric('l1', ea.STATE).withDescription('Innenraummessung').withUnit('mm'),
                                              exposes.action(['occupied']).withDescription('Innenraum belegt'),
                                              exposes.action(['free']).withDescription('Innenraum frei'),
                                            ],
                                            meta: {
                                                multiEndpoint: true,
                                                        
                                            },
                                            endpoint: (device) => {
                                                return {
                                                    l1: 1,
                                                };
                                            },
                                            
                                            configure: async (device, coordinatorEndpoint, logger) => {
                                              const endpoint = device.getEndpoint(1);
                                              await endpoint.read('genBasic', ['modelId', 'swBuildId', 'powerSource']);
                                            },
                                        
                                        };
                                        
                                        Asgothian 2 Replies Last reply Reply Quote 0
                                        • Asgothian
                                          Asgothian Developer @skvarel last edited by

                                          @skvarel gibt es Meldungen im log ? Ich bin wieder unterwegs und schau mal wenn ich wieder zu Hause bin

                                          1 Reply Last reply Reply Quote 0
                                          • Asgothian
                                            Asgothian Developer @skvarel last edited by

                                            @skvarel ich hab nochmal was angepasst. Versuch bitte mal so:

                                            const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
                                            const zigbeeHerdsmanUtils = require('zigbee-herdsman-converters/lib/utils');
                                            
                                            
                                            const exposes = zigbeeHerdsmanConverters['exposes'] || require("zigbee-herdsman-converters/lib/exposes");
                                            const ea = exposes.access;
                                            const e = exposes.presets;
                                            const modernExposes = (e.hasOwnProperty('illuminance_lux'))? false: true;
                                            
                                            const fz = zigbeeHerdsmanConverters.fromZigbeeConverters || zigbeeHerdsmanConverters.fromZigbee;
                                            const tz = zigbeeHerdsmanConverters.toZigbeeConverters || zigbeeHerdsmanConverters.toZigbee;
                                            
                                            const ptvo_switch = (zigbeeHerdsmanConverters.findByModel)?zigbeeHerdsmanConverters.findByModel('ptvo.switch'):zigbeeHerdsmanConverters.findByDevice({modelID: 'ptvo.switch'});
                                            fz.legacy = ptvo_switch.meta.tuyaThermostatPreset;
                                            fz.ptvo_on_off = {
                                              cluster: 'genOnOff',
                                              type: ['attributeReport', 'readResponse'],
                                              convert: (model, msg, publish, options, meta) => {
                                                  if (msg.data.hasOwnProperty('onOff')) {
                                                      const channel = msg.endpoint.ID;
                                                      const endpointName = `l${channel}`;
                                                      const binaryEndpoint = model.meta && model.meta.binaryEndpoints && model.meta.binaryEndpoints[endpointName];
                                                      const prefix = (binaryEndpoint) ? model.meta.binaryEndpoints[endpointName] : 'state';
                                                      const property = `${prefix}_${endpointName}`;
                                            	  if (binaryEndpoint) {
                                                        return {[property]: msg.data['onOff'] === 1};
                                                      }
                                                      return {[property]: msg.data['onOff'] === 1 ? 'ON' : 'OFF'};
                                                  }
                                              },
                                            };
                                            const fzlocal = {
                                              local_analog_switch: {
                                                cluster: 'genAnalogInput',
                                                type: ['attributeReport', 'readResponse'],
                                                convert: (model, msg, publish, options, meta) => {
                                                    const payload = {};
                                                    const channel = msg.endpoint.ID;
                                                    const name = `l${channel}`;
                                                    const endpoint = msg.endpoint;
                                                    payload[name] = precisionRound(msg.data['presentValue'], 3);
                                                    payload[`contact_${channel}`] = (msg.data['presentValue']  < 300)
                                                    const cluster = 'genLevelCtrl';
                                                    if (endpoint && (endpoint.supportsInputCluster(cluster) || endpoint.supportsOutputCluster(cluster))) {
                                                        payload['brightness_' + name] = msg.data['presentValue'];
                                                    } else if (msg.data.description !== undefined) {
                                                        const data1 = msg.data['description'];
                                                        if (data1) {
                                                            const data2 = data1.split(',');
                                                            const devid = data2[1];
                                                            const unit = data2[0];
                                                            if (devid) {
                                                                payload['device_' + name] = devid;
                                                            }
                                            
                                                            const valRaw = msg.data['presentValue'];
                                                            if (unit) {
                                                                let val = precisionRound(valRaw, 1);
                                            
                                                                const nameLookup = {
                                                                    C: 'temperature',
                                                                    '%': 'humidity',
                                                                    m: 'altitude',
                                                                    Pa: 'pressure',
                                                                    ppm: 'quality',
                                                                    psize: 'particle_size',
                                                                    V: 'voltage',
                                                                    A: 'current',
                                                                    Wh: 'energy',
                                                                    W: 'power',
                                                                    Hz: 'frequency',
                                                                    pf: 'power_factor',
                                                                    lx: 'illuminance',
                                                                };
                                            
                                                                let nameAlt = '';
                                                                if (unit === 'A' || unit === 'pf') {
                                                                    if (valRaw < 1) {
                                                                        val = precisionRound(valRaw, 3);
                                                                    }
                                                                }
                                                                if (unit.startsWith('mcpm') || unit.startsWith('ncpm')) {
                                                                    const num = unit.substr(4, 1);
                                                                    nameAlt = num === 'A' ? unit.substr(0, 4) + '10' : unit;
                                                                    val = precisionRound(valRaw, 2);
                                                                } else {
                                                                    nameAlt = nameLookup[unit];
                                                                }
                                                                if (nameAlt === undefined) {
                                                                    const valueIndex = parseInt(unit, 10);
                                                                    if (!isNaN(valueIndex)) {
                                                                        nameAlt = 'val' + unit;
                                                                    }
                                                                }
                                            
                                                                if (nameAlt !== undefined) {
                                                                    payload[nameAlt + '_' + name] = val;
                                                                }
                                                            }
                                                        }
                                                    }
                                                    return payload;
                                                },
                                              },
                                            
                                              
                                            }
                                            
                                            const device = {
                                                zigbeeModel: ['CC2531.US100'],
                                                model: 'CC2531.US100',
                                                vendor: 'inventwo',
                                                description: '[CC2531 w. US-100 Sensor](https://github.com/inventwo/custom-zigbee)',
                                                fromZigbee: [fz.ignore_basic_report, fz.ptvo_switch_uart, fzlocal.local_analog_switch,],
                                                toZigbee: [tz.ptvo_switch_trigger, tz.ptvo_switch_uart,],
                                                exposes: [
                                                  exposes.numeric('l1', ea.STATE).withDescription('Innenraummessung').withUnit('mm'),
                                                  e.contact().withEndpoint('l1'),
                                                ],
                                                meta: {
                                                    multiEndpoint: true,
                                                            
                                                },
                                                endpoint: (device) => {
                                                    return {
                                                        l1: 1,
                                                    };
                                                },
                                                  configure: async (device, coordinatorEndpoint, logger) => {
                                                  const endpoint = device.getEndpoint(1);
                                                  await endpoint.read('genBasic', ['modelId', 'swBuildId', 'powerSource']);
                                                },
                                            
                                            };
                                            
                                            module.exports = device;
                                            

                                            (wieder ohne icon)

                                            skvarel 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            599
                                            Online

                                            31.6k
                                            Users

                                            79.4k
                                            Topics

                                            1.3m
                                            Posts

                                            10
                                            160
                                            10008
                                            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