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: 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

                                    1.1k
                                    Online

                                    32.3k
                                    Users

                                    81.0k
                                    Topics

                                    1.3m
                                    Posts

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