Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. [erledigt]Skript zum Einsammeln von Batteriestatus von ...

    NEWS

    • Amazon Alexa - ioBroker Skill läuft aus ?

    • Monatsrückblick – September 2025

    • Neues Video "KI im Smart Home" - ioBroker plus n8n

    [erledigt]Skript zum Einsammeln von Batteriestatus von ...

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

      Hallo Zusammen,
      ich habe mehrere Zigbee Geräte am laufen, fast alle sind Batterie betrieben. Gibt es irgendwie eine Möglichkeit, eine Liste zu erzeugen, die mir z.b. für alle Zigbee eine json datei erzeugt und dort das Zigbee-Gerät und dann den Batterie Status hineinschreibt?

      Was meine ich? Die Zigbee Geräte sind alle mit einer Nummer aufgelistet - siehe Screenshot
      31b98a74-6c21-4dd8-86c5-5c9005507a6a-grafik.png

      Ich bekomme es nicht hin. Jemand eine Idee für einen Ansatz?

      danke
      Marcus

      paul53 1 Reply Last reply Reply Quote 0
      • paul53
        paul53 @mguenther last edited by

        @mguenther sagte: Geräte sind alle mit einer Nummer aufgelistet

        Die Geräte-ID ist wenig hilfreich. Gibt es sinnvolle Namen? Bitte zeigen!

        M 2 Replies Last reply Reply Quote 0
        • M
          mguenther @paul53 last edited by

          @paul53 gibts eben nicht, Paul - das ist ja mein Problem. Ich dachte irgendwie, dass man die Geräte ID irgendwie mit einem Platzhalter "*" ersetzen kann. Die Objekte unter der Objekt ID sind dann wieder identisch

          paul53 1 Reply Last reply Reply Quote 0
          • M
            mguenther @paul53 last edited by

            @paul53
            d9e3f3b5-59aa-4b94-8ddb-290fde857954-grafik.png

            mal als Screenshot

            paul53 1 Reply Last reply Reply Quote 0
            • paul53
              paul53 @mguenther last edited by

              @mguenther sagte: gibts eben nicht

              Auch nicht bei den Alias? Gibt es zu jedem Batterie-DP einen Alias?

              M 1 Reply Last reply Reply Quote 0
              • M
                mguenther @paul53 last edited by

                @paul53
                nicht zu allen.
                Zu denen ich bis jetzt etwas gemacht habe, ja - da gibts auch nen Alias. die Objekte unter den Objekt-IDs haben den Datenpunkt "battery"

                zigbee.0.00158d000237039e.battery
                
                paul53 1 Reply Last reply Reply Quote 0
                • paul53
                  paul53 @mguenther last edited by

                  @mguenther sagte: mal als Screenshot

                  Die Geräte haben keinen sinnvollen Namen? Wenn doch, könnte man den parentName des Batterie-DP verwenden.

                  M 1 Reply Last reply Reply Quote 0
                  • M
                    mguenther @paul53 last edited by

                    @paul53
                    nicht das ich wüsste - die Geräte werden in Zigbee gepaired und bekommen diese Object ID Zuweisung. Ich wollte es mir einfach machen und quasi nen Platzhalter verwenden. Klappt aber irgendwie nicht

                    1 Reply Last reply Reply Quote 0
                    • paul53
                      paul53 @mguenther last edited by

                      @mguenther sagte: Zu denen ich bis jetzt etwas gemacht habe, ja - da gibts auch nen Alias.

                      Dann verwende den Alias, wenn die ID-Struktur einheitlich ist.

                      M 1 Reply Last reply Reply Quote 0
                      • M
                        mguenther @paul53 last edited by

                        @paul53
                        ja, aber dann habe ich nicht alle zigbee geräte. ich wollte je eigentlich gerne alle zigbee geräte auswerten.

                        Homoran 1 Reply Last reply Reply Quote 0
                        • Homoran
                          Homoran Global Moderator Administrators @mguenther last edited by

                          @mguenther sagte in Skript zum Einsammeln von Batteriestatus von Zigbeegeräten?:

                          ich wollte je eigentlich gerne alle zigbee geräte auswerten.

                          und zu denen gibt es keine alias?

                          M 1 Reply Last reply Reply Quote 0
                          • M
                            mguenther @Homoran last edited by

                            @homoran
                            hi homoran,
                            nein, nicht zu allen. ich habe so etwas:

                            4173b22d-2136-40cf-8753-f1fffe12dff9-grafik.png

                            unter Sensordaten finde ich auch für einige Zigbeegeräte den "Batteriestatus"

                            paul53 1 Reply Last reply Reply Quote 0
                            • paul53
                              paul53 @mguenther last edited by

                              @mguenther sagte: nein, nicht zu allen.

                              Das ist schlecht.
                              Du zeigst uns nie die Namen. Ist die Bildschirmauflösung so niedrig?

                              Teste mal, was damit im Log erscheint:

                              const ids = $('zigbee.0.*.battery').toArray();
                              
                              function batterien() {
                                  for(let id of ids) {
                                      const val = getState(id).val;
                                      id = id.substring(0, id.lastIndexOf('.')); // Geräte-ID
                                      log(getObject(id).common.name + ': ' + val);        
                                  } 
                              }
                              
                              schedule('0 18 * * *', batterien); 
                              batterien();
                              
                              M 1 Reply Last reply Reply Quote 0
                              • M
                                mguenther @paul53 last edited by

                                @paul53
                                dann habe ich noch nicht verstanden, was du mit "Namen" meinst. Anbei der Log-Auszug:

                                javascript.0
                                	2025-09-30 14:33:24.904	info	script.js.System.TEST2Batterie: registered 0 subscriptions, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                                javascript.0
                                	2025-09-30 14:33:24.903	info	script.js.System.TEST2Batterie: Taster_Sonnenrollo: 16
                                javascript.0
                                	2025-09-30 14:33:24.903	info	script.js.System.TEST2Batterie: Zimmer1_Fernsehtaster_Paulina: 60
                                javascript.0
                                	2025-09-30 14:33:24.902	info	script.js.System.TEST2Batterie: Zimmer1_Fernsehtaster_Marcus: 60
                                javascript.0
                                	2025-09-30 14:33:24.902	info	script.js.System.TEST2Batterie: Garagenwand_Heizung: 83
                                javascript.0
                                	2025-09-30 14:33:24.901	info	script.js.System.TEST2Batterie: Garagenwand_Tor_Sued: 70
                                javascript.0
                                	2025-09-30 14:33:24.901	info	script.js.System.TEST2Batterie: Garagenwand_Raum_Sued: 100
                                javascript.0
                                	2025-09-30 14:33:24.900	info	script.js.System.TEST2Batterie: Garagenwand_Briefkasten: 0
                                javascript.0
                                	2025-09-30 14:33:24.899	info	script.js.System.TEST2Batterie: Tuerklingel: 0
                                javascript.0
                                	2025-09-30 14:33:24.897	info	script.js.System.TEST2Batterie: Technikraum: 0
                                javascript.0
                                	2025-09-30 14:33:24.897	info	script.js.System.TEST2Batterie: Garage: 100
                                javascript.0
                                	2025-09-30 14:33:24.896	info	script.js.System.TEST2Batterie: Server: 37
                                javascript.0
                                	2025-09-30 14:33:24.896	info	script.js.System.TEST2Batterie: Arbeitszimmer: 0
                                javascript.0
                                	2025-09-30 14:33:24.893	info	script.js.System.TEST2Batterie: Bad_klein: 97
                                javascript.0
                                	2025-09-30 14:33:24.893	info	script.js.System.TEST2Batterie: Bad_klein: 0
                                javascript.0
                                	2025-09-30 14:33:24.892	info	script.js.System.TEST2Batterie: WC: 83
                                javascript.0
                                	2025-09-30 14:33:24.891	info	script.js.System.TEST2Batterie: Garderobe: 57
                                javascript.0
                                	2025-09-30 14:33:24.891	info	script.js.System.TEST2Batterie: Bad_gross: 23
                                javascript.0
                                	2025-09-30 14:33:24.890	info	script.js.System.TEST2Batterie: Aussen: 43
                                javascript.0
                                	2025-09-30 14:33:24.890	info	script.js.System.TEST2Batterie: Zimmer3: 30
                                javascript.0
                                	2025-09-30 14:33:24.889	info	script.js.System.TEST2Batterie: EG: 17
                                javascript.0
                                	2025-09-30 14:33:24.889	info	script.js.System.TEST2Batterie: Zimmer2: 43
                                javascript.0
                                	2025-09-30 14:33:24.889	info	script.js.System.TEST2Batterie: Bad_gross: 3
                                javascript.0
                                	2025-09-30 14:33:24.888	info	script.js.System.TEST2Batterie: Zimmer1: 0
                                javascript.0
                                	2025-09-30 14:33:24.888	info	script.js.System.TEST2Batterie: Zimmer3: 100
                                javascript.0
                                	2025-09-30 14:33:24.888	info	script.js.System.TEST2Batterie: Zimmer2: 100
                                javascript.0
                                	2025-09-30 14:33:24.887	info	script.js.System.TEST2Batterie: Zimmer1_rechts: 90
                                javascript.0
                                	2025-09-30 14:33:24.887	info	script.js.System.TEST2Batterie: Zimmer1_links: 100
                                javascript.0
                                	2025-09-30 14:33:24.802	info	Start JavaScript script.js.System.TEST2Batterie (Javascript/js)
                                
                                paul53 1 Reply Last reply Reply Quote 0
                                • paul53
                                  paul53 @mguenther last edited by

                                  @mguenther sagte: Anbei der Log-Auszug:

                                  Der sieht gut aus. Also haben die Zigbee-Geräte sinnvolle Namen. Manche Namen sind allerdings doppelt vorhanden.
                                  Die Namen kann man auch im Tab "Objekte" zeigen:

                                  Namen_Tab_Objekte.JPG

                                  M 1 Reply Last reply Reply Quote 1
                                  • M
                                    mguenther @paul53 last edited by

                                    @paul53
                                    aber Paul, dein Ansatz mit const ids = $('zigbee.0.*.battery').toArray(); hat geholfen. ich bastle weiter und poste dann hier das Ergebnis.

                                    danke

                                    M 1 Reply Last reply Reply Quote 0
                                    • M
                                      mguenther @mguenther last edited by mguenther

                                      hier mein Skript - chatgpt hat mit draufgeschaut - ich schließe hier.

                                      // ===== Einstellungen =====
                                      const OUT = "0_userdata.0.vis.BatterieListeDebug"; // Datenpunkt für VIS
                                      const THRESH_LOW = 30;
                                      const THRESH_MED = 60;
                                      const MAX_HEIGHT = 660;
                                      const WIDTH = 405; // Gesamtbreite
                                      const STALE_HOURS = 168; // >7 Tage ohne Meldung = "nicht aktiv"
                                      
                                      // === Helfer ===
                                      function colorByVal(v) {
                                        if (!isFinite(v)) return "#9e9e9e";
                                        if (v < THRESH_LOW) return "#e53935";   // rot
                                        if (v < THRESH_MED) return "#fdd835";   // gelb
                                        return "#43a047";                       // grün
                                      }
                                      
                                      function devRoot(id) {
                                        const p = id.split(".");
                                        return [p[0], p[1], p[2]].join(".");
                                      }
                                      
                                      function niceNameFromRoot(rootId) {
                                        const obj = getObject(rootId);
                                        return obj?.common?.name || rootId;
                                      }
                                      
                                      function voltageToPercent(v) {
                                        if (!isFinite(v)) return null;
                                        const min = 2.0, max = 3.0;
                                        let pct = ((v - min) / (max - min)) * 100;
                                        return Math.max(0, Math.min(100, Math.round(pct)));
                                      }
                                      
                                      // Liefert den letzten Änderungszeitpunkt aller States eines Geräts
                                      function lastSeenDevice(root) {
                                        let last = 0;
                                        $('' + root + '.*').each(id => {
                                          const st = getState(id);
                                          if (st && st.lc && st.lc > last) last = st.lc;
                                        });
                                        return last;
                                      }
                                      
                                      // === Rendering ===
                                      function render() {
                                        const map = {};
                                      
                                        // Zigbee: echte %
                                        $('zigbee.0.*.battery').each(id => {
                                          const root = devRoot(id);
                                          const name = niceNameFromRoot(root);
                                          const raw = getState(id)?.val;
                                          const val = isFinite(raw) ? Math.max(0, Math.min(100, Math.round(Number(raw)))) : null;
                                          if (val !== null) map[root] = { type: "percent", name, val, sys: "Zigbee" };
                                        });
                                      
                                        // HmIP: Operating Voltage -> %
                                        $('hm-rpc.0.*.OPERATING_VOLTAGE').each(id => {
                                          const root = devRoot(id);
                                          const name = niceNameFromRoot(root);
                                          const val = voltageToPercent(getState(id)?.val);
                                          if (val !== null) map[root] = { type: "percent", name, val, sys: "HmIP" };
                                        });
                                      
                                        // Homematic: LOWBAT
                                        $('hm-rpc.0.*.LOWBAT').each(id => {
                                          const root = devRoot(id);
                                          const name = niceNameFromRoot(root);
                                          const lowbat = !!(getState(id)?.val);
                                          const unreach = !!(getState(root + ".0.UNREACH")?.val);
                                      
                                          const last = lastSeenDevice(root);
                                          const ageH = (Date.now() - last) / (1000 * 60 * 60);
                                      
                                          if (unreach) {
                                            map[root] = { type: "unreach", name, sys: "HM" };
                                          } else if (ageH > STALE_HOURS) {
                                            map[root] = { type: "stale", name, sys: "HM" };
                                          } else {
                                            map[root] = { type: "lowbat", name, lowbat, sys: "HM" };
                                          }
                                        });
                                      
                                        // Homematic: LOW_BAT
                                        $('hm-rpc.0.*.LOW_BAT').each(id => {
                                          const root = devRoot(id);
                                          const name = niceNameFromRoot(root);
                                          const lowbat = !!(getState(id)?.val);
                                          const unreach = !!(getState(root + ".0.UNREACH")?.val);
                                      
                                          const last = lastSeenDevice(root);
                                          const ageH = (Date.now() - last) / (1000 * 60 * 60);
                                      
                                          if (unreach) {
                                            map[root] = { type: "unreach", name, sys: "HmIP" };
                                          } else if (ageH > STALE_HOURS) {
                                            map[root] = { type: "stale", name, sys: "HmIP" };
                                          } else {
                                            map[root] = { type: "lowbat", name, lowbat, sys: "HmIP" };
                                          }
                                        });
                                      
                                        // Liste bauen
                                        let list = Object.values(map);
                                      
                                        // Sortierung (angepasst)
                                        list.sort((a, b) => {
                                          function weight(it) {
                                            if (it.type === "unreach") return 0;                                   // HM keine Meldung
                                            if (it.type === "percent" && it.sys === "Zigbee" && it.val === 0) return 1; // Zigbee 0%
                                            if (it.type === "stale") return 2;                                     // HM nicht aktiv
                                            if (it.type === "percent" && it.sys === "Zigbee" && it.val < THRESH_LOW) return 3; // Zigbee rot
                                            if (it.type === "lowbat" && it.lowbat === true) return 4;              // HM low
                                            if (it.type === "percent" && it.sys === "Zigbee" && it.val < THRESH_MED) return 5; // Zigbee gelb
                                            if (it.type === "percent" && it.sys === "Zigbee" && it.val >= THRESH_MED) return 6; // Zigbee grün
                                            if (it.type === "lowbat" && it.lowbat === false) return 7;             // HM grün
                                            return 99;
                                          }
                                      
                                          const wa = weight(a), wb = weight(b);
                                          if (wa !== wb) return wa - wb;
                                      
                                          // Falls gleiche Kategorie: nach Wert sortieren
                                          if (a.type === "percent" && b.type === "percent") {
                                            if (a.val == null) return 1;
                                            if (b.val == null) return -1;
                                            return a.val - b.val;
                                          }
                                          return 0;
                                        });
                                      
                                        // Zeilen bauen
                                        const rows = list.map(it => {
                                          if (it.type === "percent") {
                                            return `
                                              <tr style="border-bottom:1px solid #444;">
                                                <td style="width:55px; color:#f5f5f5;">${it.sys}</td>
                                                <td style="width:120px; color:#f5f5f5; font-size:12px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="${it.name}">${it.name}</td>
                                                <td style="width:55px; text-align:right; color:#f5f5f5;">${it.val == null ? "-" : it.val + " %"}</td>
                                                <td style="width:175px;">
                                                  <div style="width:100%; height:10px; border-radius:5px; background:#333; overflow:hidden;">
                                                    <div style="height:100%; width:${it.val ?? 0}%; background:${colorByVal(it.val)};"></div>
                                                  </div>
                                                </td>
                                              </tr>`;
                                          }
                                          if (it.type === "lowbat") {
                                            const ok = it.lowbat === false;
                                            const color = ok ? "#43a047" : "#e53935";
                                            const text  = ok ? "OK" : "LOW";
                                            return `
                                              <tr style="border-bottom:1px solid #444;">
                                                <td style="width:55px; color:#f5f5f5;">${it.sys}</td>
                                                <td style="width:120px; color:#f5f5f5; font-size:12px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="${it.name}">${it.name}</td>
                                                <td style="width:55px; text-align:right; color:#f5f5f5;">–</td>
                                                <td style="width:175px; color:${color}; font-weight:bold;">${text}</td>
                                              </tr>`;
                                          }
                                          if (it.type === "unreach") {
                                            return `
                                              <tr style="border-bottom:1px solid #444;">
                                                <td style="width:55px; color:#f5f5f5;">${it.sys}</td>
                                                <td style="width:120px; color:#f5f5f5; font-size:12px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="${it.name}">${it.name}</td>
                                                <td style="width:55px; text-align:right; color:#f5f5f5;">–</td>
                                                <td style="width:175px; color:#ff9800; font-weight:bold;">KEINE MELDUNG</td>
                                              </tr>`;
                                          }
                                          if (it.type === "stale") {
                                            return `
                                              <tr style="border-bottom:1px solid #444;">
                                                <td style="width:55px; color:#f5f5f5;">${it.sys}</td>
                                                <td style="width:120px; color:#f5f5f5; font-size:12px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="${it.name}">${it.name}</td>
                                                <td style="width:55px; text-align:right; color:#f5f5f5;">–</td>
                                                <td style="width:175px; color:#ff5722; font-weight:bold;">NICHT AKTIV</td>
                                              </tr>`;
                                          }
                                        }).join("");
                                      
                                        // HTML mit sticky Header
                                        const html = `
                                          <div style="font-family: system-ui, Segoe UI, Roboto, Arial; font-size:13px;
                                                      width:${WIDTH}px; max-height:${MAX_HEIGHT}px; overflow-y:auto;
                                                      padding:0; background:transparent;">
                                            <table style="width:${WIDTH}px; border-collapse:collapse; background:transparent;">
                                              <thead style="background:#212121;">
                                                <tr style="border-bottom:1px solid #666;">
                                                  <th style="width:55px; text-align:left; color:#f5f5f5; position:sticky; top:0; background:#212121;">Typ</th>
                                                  <th style="width:120px; text-align:left; color:#f5f5f5; position:sticky; top:0; background:#212121;">Gerät</th>
                                                  <th style="width:55px; text-align:right; color:#f5f5f5; position:sticky; top:0; background:#212121;">Batterie</th>
                                                  <th style="width:175px; text-align:left; color:#f5f5f5; position:sticky; top:0; background:#212121;">Status</th>
                                                </tr>
                                              </thead>
                                              <tbody>${rows}</tbody>
                                            </table>
                                          </div>`;
                                      
                                        setState(OUT, html, true);
                                      }
                                      
                                      // === Setup ===
                                      createState(OUT, "", { type: "string", role: "html", read: true, write: false }, () => {
                                        render();
                                      
                                        $('zigbee.0.*.battery').each(id => on({ id, change: "ne" }, render));
                                        $('hm-rpc.0.*.OPERATING_VOLTAGE').each(id => on({ id, change: "ne" }, render));
                                        $('hm-rpc.0.*.LOWBAT').each(id => on({ id, change: "ne" }, render));
                                        $('hm-rpc.0.*.LOW_BAT').each(id => on({ id, change: "ne" }, render));
                                        $('hm-rpc.0.*.UNREACH').each(id => on({ id, change: "ne" }, render));
                                      
                                        // Refresh alle 12 Stunden
                                        schedule("0 */12 * * *", render);
                                      });
                                      
                                      

                                      6b5592ae-b6ff-4685-8d3d-b1c59447e64e-grafik.png

                                      Tabelle ist html und lässt sich scrollen in meiner VIS

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

                                      Support us

                                      ioBroker
                                      Community Adapters
                                      Donate

                                      508
                                      Online

                                      32.3k
                                      Users

                                      81.0k
                                      Topics

                                      1.3m
                                      Posts

                                      3
                                      17
                                      413
                                      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