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.
    • 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

                          1.1k
                          Online

                          32.3k
                          Users

                          81.0k
                          Topics

                          1.3m
                          Posts

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