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