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: 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.0k
                              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