Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. BertDerKleine

    NEWS

    • Wir empfehlen: Node.js 22.x

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Profile
    • Following 0
    • Followers 0
    • Topics 65
    • Posts 301
    • Best 16
    • Groups 2

    BertDerKleine

    @BertDerKleine

    Starter

    16
    Reputation
    63
    Profile views
    301
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    BertDerKleine Follow
    Pro Starter

    Best posts made by BertDerKleine

    • E-Ink OpenEpaperLink - JSON-Steuerung per Javascript

      Nachdem die meisten OEPL Steuerungen anscheinend über den Weg der Screenshots mit Puppeteer gehen, hier mal mein Ansatz über JSONs.

      Mein Puppeteer Skript habe ich hierdurch ersetzt und bin sehr zufrieden damit.

      Mittels der Konfigurationsblöcke kann ich sehr simpel umsetzen, was ich mag und jeder Tag hat seine eigene Zeitsteuerung. Ich habe mal ein paar Varianten reinkopiert, die ich durchgespielt habe.

      Vielleicht hilfts ja jemandem. ☺

      /**
       * ############################################################################
       *  OpenEPaperLink – vollautomatische ePaper-Steuerung mit Zeitschaltung
       *  und Signalbildern für Fenster- / Tür-Status, realisiert über JSON-Templates
       * ############################################################################
       *
       *  Im August 2025 von BertDerKleine
       *
       *  Zweck
       *  =====
       *  Dieses Skript versorgt alle registrierten OpenEPaperLink-Tags (WLAN-ePaper-
       *  Displays) zyklisch mit aktuellen Daten aus ioBroker.  Durch konfigurierbare
       *  Zeitfenster und individuelle Update-Intervalle wird die Batterielaufzeit
       *  maximal geschont.  Neu hinzugekommen ist die Möglichkeit, einfache
       *  „Signalbilder“ einzublenden: anhand eines Boolean-Datenpunktes wird
       *  automatisch zwischen zwei Icon-Dateien (z. B. offen / geschlossen)
       *  gewechselt.
       *  Ziel war es, eine Lösung via JSON-Templates hinzubekommen, ohne den Umweg
       *  über Screenshots mit Puppeteer. U.a. umgeht dies das Problem, das Puppeteer
       *  immer nur eine Sache gleichzeitig tun kann, was zu Konflikten führen kann,
       *  wenn man viele Tags aktualisieren muss. 
       *
       *  Ablauf im Überblick
       *  -------------------
       *  1.  Konstanten am Kopf definieren Display-Größe und Access-Point.
       *  2.  In `tagConfig` pro Tag eintragen:
       *        – MAC-Adresse
       *        – Anzeige-Titel
       *        – Update-Intervall in Minuten
       *        – ZeitFenster (z. B. „07:00-23:00“)
       *        – body: Array aller anzuzeigenden Elemente
       *  3.  `starteTagUpdates()` startet für jeden Tag ein eigenes Intervall
       *      und führt sofort ein erstes Update aus.
       *  4.  `aktualisiereTag()` prüft das ZeitFenster, baut das JSON zusammen
       *      und sendet es per HTTP-POST an den Access-Point.
       *
       *  Element-Typen
       *  -------------
       *  •  Text:             { dp: 'pfad/zum/Datenpunkt', font: 'Nolo90', … }
       *  •  Fortschrittsbalken: { type: 'progressBar', dp: '…', fillColor: 2, … }
       *  •  Bild:             { image: { filename: '/Bild.jpg', x: 10, y: 20 } }
       *  •  Signalbild:       { type: 'signalImage',
       *                          dp: 'alias.0.Fenster_Kueche',
       *                          images: { true: '/offen.jpg', false: '/zu.jpg' },
       *                          x, y, imageWidth, imageHeight, label, … }
       *
       *  Voraussetzungen
       *  ---------------
       *  • ioBroker mit JavaScript-Adapter
       *  • Node-Modul „luxon“ (nur für zuverlässige Sommer-/Winterzeit)
       *      npm install luxon
       *  • Bild- und Icon-Dateien liegen im Root des Access-Points als 8bit sRGB JPGs
       *    rein schwarz, weiss und rot.
       *  ############################################################################
       */
      
      const http          = require('http');
      const querystring   = require('querystring');
      const { DateTime }  = require('luxon');
      
      /* --------------------------------------------------------------------------
       *  Globale Konstanten
       * -------------------------------------------------------------------------- */
      const AP_IP               = '192.168.178.233';   // IP des OpenEPaperLink-AP
      const BILDSCHIRM_BREITE   = 296;
      const BILDSCHIRM_HÖHE     = 152;
      const TITEL_BALKEN_HÖHE   = 20;
      const TITEL_SCHRIFT       = 'calibrib16';
      
      /* --------------------------------------------------------------------------
       *  Tag-Konfiguration
       *  Jeder Eintrag definiert exakt ein ePaper-Display.
       * -------------------------------------------------------------------------- */
      // Konfiguration der Tags mit MAC-Adresse, Titel, Update-Intervall, Zeitfenster und Inhalt
      const tagConfig = [
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für DG Außentemperatur 
          title: 'Aussentemperatur DG', // Titel, der auf dem Tag angezeigt wird
          updateIntervalMinutes: 30, // Update alle 30 Minuten
          ZeitFenster: '07:00-23:00', // Updates zwischen 07:00 und 23:00 (Europe/Berlin)
          body: [
            // Temperatur mit großer Schrift, linksbündig
            { dp: 'alias.0.Aussentemperatur_kombiniert', font: 'Nolo90', color: 1, suffix: '°C', x: 10, y: 40, decimalPlaces: 1 },
            // Regenmenge pro Tag, unten links
            { dp: 'alias.0.Regen_pro_Tag', font: 'bahnschrift30', color: 2, suffix: 'mm', x: 5, y: 127, decimalPlaces: 1 },
            // Luftfeuchtigkeit, rechtsbündig unten
            { dp: 'alias.0.Luftfeuchtigkeit_Gartenhaus', font: 'bahnschrift30', color: 1, prefix: 'LF ', suffix: '%', x: 296, y: 115, align: 2, decimalPlaces: 0 }
          ]
        },
        
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für Waage 
          title: 'Waage', 
          updateIntervalMinutes: 10, 
          ZeitFenster: '06:30-12:00', 
          body: [
            // Körpergewicht mit großer Schrift, linksbündig
            { dp: 'alias.0.Körpergewicht', font: 'Nolo70', color: 1, suffix: ' kg', x: 10, y: 40, decimalPlaces: 2 },
            // Widerstand, unten links
            { dp: 'alias.0.Körperwiderstand', font: 'bahnschrift30', color: 2, suffix: 'Ohm', x: 5, y: 127, decimalPlaces: 0 },
            // BMI, rechtsbündig unten
            { dp: 'alias.0.BMI', font: 'bahnschrift30', color: 1, prefix: 'BMI: ', suffix: '', x: 296, y: 115, align: 2, decimalPlaces: 1 }
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für die Kalendervorschau
          title: 'Kalender',
          updateIntervalMinutes: 120,
          ZeitFenster: '07:00-23:00',
          body: [
            // Kalendertext, oben links
            { dp: 'alias.0.Kalendervorschau', font: 'bahnschrift20', color: 1, x: 0, y: 25 }
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für Akku-Status
          title: 'Akku-Status',
          updateIntervalMinutes: 30,
          ZeitFenster: '07:00-23:00',
          body: [
            // Akku-Prozentsatz, rechtsbündig
            { dp: 'alias.0.Akku_Ladezustand', font: 'Nolo90', color: 1, suffix: '%', x: BILDSCHIRM_BREITE, y: 40, align: 2, decimalPlaces: 0 },
            // Fortschrittsbalken für Akku, unten
            { dp: 'alias.0.Akku_Ladezustand', type: 'progressBar', fillColor: 2, height: 32, y: BILDSCHIRM_HÖHE - 32 }
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für Stromwerte
          title: 'Stromwerte',
          updateIntervalMinutes: 60,
          ZeitFenster: '07:00-23:00',
          body: [
            { image: { filename: '/Sonne.jpg', x: 10, y: 25 } },
            // PV-Erzeugung, rechtsbündig
            { dp: 'sourceanalytix.0.alias__0__PV_Erzeugungszählerstand.currentYear.consumed.01_currentDay', font: 'bahnschrift30', color: 1, prefix: 'PV: ', suffix: ' kWh', x: BILDSCHIRM_BREITE, y: 28, align: 2, decimalPlaces: 1 },
            // Netzbezug, rechtsbündig
            { dp: 'sourceanalytix.0.alias__0__Netzbezugszählerstand.currentYear.consumed.01_currentDay', font: 'bahnschrift30', color: 2, prefix: 'Bezug: ', suffix: ' kWh', x: BILDSCHIRM_BREITE, y: 58, align: 2, decimalPlaces: 1 },
            // Netzeinspeisung, rechtsbündig
            { dp: 'sourceanalytix.0.alias__0__Netzeinspeisezählerstand.currentYear.delivered.01_currentDay', font: 'bahnschrift30', color: 1, prefix: 'Einsp.: ', suffix: ' kWh', x: BILDSCHIRM_BREITE, y: 88, align: 2, decimalPlaces: 1 },
            // Verbrauch, rechtsbündig
            { dp: 'sourceanalytix.0.alias__0__Verbrauchszaehlerstand.currentYear.consumed.01_currentDay', font: 'bahnschrift30', color: 1, prefix: 'Verbr.: ', suffix: ' kWh', x: BILDSCHIRM_BREITE, y: 118, align: 2, decimalPlaces: 1 }
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für Wasserverbrauch
          title: 'Wasserverbrauch',
          updateIntervalMinutes: 45,
          ZeitFenster: '07:00-23:00',
          body: [
            { image: { filename: '/Wasser.jpg', x: 10, y: 25, } },
            { dp: 'alias.0.Tages-Wasserverbrauch', font: 'Nolo90', color: 1, prefix: '', suffix: ' l', x: BILDSCHIRM_BREITE, y: 50, align: 2, decimalPlaces: 0 },
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für offene Fenster/Türen
          title: 'Fensterstatus',
          updateIntervalMinutes: 15,
          ZeitFenster: '07:00-23:00',
          body: [
            // Reihe 1 von links nach rechts; die verwendeten Signalbilder sind 48x48 Pixel gross
            { type: 'signalImage', dp: 'alias.0.Fenster_Küche', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 38, y: 22, imageWidth: 48, imageHeight: 48, label: 'Küche', labelColor: 1, labelSpacing: 2 },
            { type: 'signalImage', dp: 'alias.0.Fenster_Wohnzimmer', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 124, y: 22, imageWidth: 48, imageHeight: 48, label: 'Wohnzimmer', labelColor: 1, labelSpacing: 2 },
            { type: 'signalImage', dp: 'alias.0.Fenster_Keller', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 210, y: 22, imageWidth: 48, imageHeight: 48, label: 'Keller', labelColor: 1, labelSpacing: 2 },
      
            // Reihe 2 von links nach rechts
            { type: 'signalImage', dp: 'alias.0.Fenster_Gäste-WC', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 38, y: 82, imageWidth: 48, imageHeight: 48, label: 'Gäste-WC', labelColor: 1, labelSpacing: 2 },
            { type: 'signalImage', dp: 'alias.0.Tür_Terrasse', images: { true: '/door-open48.jpg', false: '/door-closed48.jpg' }, x: 124, y: 82, imageWidth: 48, imageHeight: 48, label: 'Terrassentür', labelColor: 1, labelSpacing: 2 },
            { type: 'signalImage', dp: 'alias.0.Fenster_Garage', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 210, y: 82, imageWidth: 48, imageHeight: 48, label: 'Garage', labelColor: 1, labelSpacing: 2 }
          ]
        }
      ];
      
      /* ############################################################################
       *  Hilfsfunktionen
       * ############################################################################ */
      
      /**
       * Prüft, ob die aktuelle Zeit im konfigurierten Zeitfenster liegt.
       * @param {string} ZeitFenster - Zeitfenster im Format "HH:mm-HH:mm" (z. B. "07:00-23:00").
       * @returns {boolean} - True, wenn die aktuelle Zeit im Zeitfenster liegt, sonst false.
       */
      function istImZeitFenster(ZeitFenster) {
        const jetzt = DateTime.now().setZone('Europe/Berlin');
        const [von, bis] = ZeitFenster.split('-').map(t => {
          const [h, m] = t.split(':').map(Number);
          return jetzt.set({ hour: h, minute: m, second: 0, millisecond: 0 });
        });
        return bis < von ? (jetzt >= von || jetzt <= bis) : (jetzt >= von && jetzt <= bis);
      }
      
      /**
       * Konvertiert eine Zeitangabe (HH:mm) in Minuten seit Mitternacht für Vergleiche.
       * @param {string} ZeitStr - Zeit im Format "HH:mm".
       * @returns {number} - Minuten seit Mitternacht.
       */
      function zeitZuMinuten(ZeitStr) {
        const [h, m] = ZeitStr.split(':').map(Number);
        return h * 60 + m;
      }
      
      /**
       * Erstellt die JSON-Elemente für die Titelleiste (Hintergrund + Text).
       * @param {string} titelText - Text, der in der Titelleiste erscheinen soll.
       * @returns {Array} - Array mit JSON-Elementen (box + text).
       */
      function titelElementeErzeugen(titelText) {
        const mitteX = Math.floor(BILDSCHIRM_BREITE / 2);
        return [
          { box: [0, 0, BILDSCHIRM_BREITE, TITEL_BALKEN_HÖHE, 1, 1, 1] },
          { text: [mitteX, 3, titelText, `fonts/${TITEL_SCHRIFT}`, 0, 1] }
        ];
      }
      
      /**
       * Verarbeitet ein einzelnes Anzeige-Element und liefert das dafür nötige JSON.
       * Erkannt werden:
       *  – Signalbilder (signalImage)
       *  – normale Bilder (image)
       *  – Texte (dp oder fester text)
       *  – Fortschrittsbalken (progressBar)
       *
       * @param {Object} item - Konfiguration des Elements
       * @returns {Object|Array} - JSON-Objekt oder Array von Objekten für die Darstellung
       */
      async function elementAuflösen(item) {
        /* ---------- Signalbild mit optionalem Label ---------- */
        if (item.type === 'signalImage') {
          const status = await getStateAsync(item.dp);
          const bild   = (status && status.val) ? item.images.true : item.images.false;
          const result = [{ image: [bild, item.x || 0, item.y || 0] }];
          if (item.label) {
            const labelX = (item.x || 0) + Math.floor((item.imageWidth || 48) / 2);
            const labelY = (item.y || 0) + (item.imageHeight || 48) + (item.labelSpacing || 2);
            result.push({ text: [labelX, labelY, item.label, 'tahoma11', item.labelColor || 1, 1] });
          }
          return result;
        }
      
        /* ---------- Normales Bild ---------- */
        if (item.image) {
          const { filename, x = 0, y = 0 } = item.image;
          return { image: [filename, x, y] };
        }
      
        /* ---------- Text & Balken ---------- */
        let wert = '';
        if (item.dp) {
          const state = await getStateAsync(item.dp);
          wert = (state && state.val != null) ? state.val : '';
          if (typeof wert === 'number' || !isNaN(parseFloat(wert))) {
            const stellen = typeof item.decimalPlaces === 'number' ? item.decimalPlaces : 2;
            wert = parseFloat(wert).toLocaleString('de-DE', { minimumFractionDigits: stellen, maximumFractionDigits: stellen });
          } else {
            wert = String(wert);
          }
        } else if (typeof item.text === 'string') {
          wert = item.text;
        }
      
        if (item.type === 'progressBar') {
          const prozent = parseFloat(wert) || 0;
          const breite  = Math.round(Math.max(0, Math.min(100, prozent)) / 100 * BILDSCHIRM_BREITE);
          const yPos    = typeof item.y === 'number' ? item.y : BILDSCHIRM_HÖHE - (item.height || 32);
          return { box: [0, yPos, breite, item.height || 32, item.fillColor || 2, item.fillColor || 2, item.fillColor || 2] };
        }
      
        if (item.prefix) wert = item.prefix + wert;
        if (item.suffix) wert = wert + item.suffix;
      
        const x      = typeof item.x === 'number' ? item.x : 0;
        const y      = typeof item.y === 'number' ? item.y : 0;
        const schrift = item.font || 'bahnschrift20';
        const farbe   = typeof item.color === 'number' ? item.color : 1;
        const textArr = [x, y, wert, schrift, farbe];
        if (typeof item.align === 'number') textArr.push(item.align);
        return { text: textArr };
      }
      
      /* ############################################################################
       *  HTTP-Sender
       * ############################################################################ */
      
      /**
       * Sendet das fertige JSON-Array an den OpenEPaperLink-Access-Point.
       * @param {string} mac        - MAC-Adresse des Tags
       * @param {Array}  jsonArray  - Vollständiges JSON-Array für das Display
       * @param {string} titel      - Nur für Logging/Console-Ausgabe
       * @returns {Promise}         - Resolves bei Erfolg, rejects bei Netzwerkfehler
       */
      function sendeAnTag(mac, jsonArray, titel) {
        const postData = querystring.stringify({ mac, json: JSON.stringify(jsonArray) });
        const options  = {
          hostname: AP_IP,
          port: 80,
          path: '/jsonupload',
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(postData)
          }
        };
      
        return new Promise((resolve, reject) => {
          const req = http.request(options, res => {
            let data = '';
            res.on('data', c => data += c);
            res.on('end', () => {
              console.log(`✅ "${titel}" (${mac}) → AP-Antwort: "${data.trim() || 'leer'}"`);
              resolve();
            });
          });
          req.on('error', e => {
            console.error(`❌ "${titel}" (${mac}) → HTTP-Fehler: ${e.message}`);
            reject(e);
          });
          req.write(postData);
          req.end();
        });
      }
      
      /* ############################################################################
       *  Update-Logik
       * ############################################################################ */
      
      /**
       * Aktualisiert ein einzelnes Tag, sofern die aktuelle Zeit im konfigurierten
       * Zeitfenster liegt.  Bei Erfolg wird das fertige JSON an den AP gesendet.
       * @param {Object} tag - Ein Eintrag aus tagConfig
       * @returns {Promise}  - Resolves bei Erfolg oder wenn außerhalb des Zeitfensters
       */
      async function aktualisiereTag(tag) {
        if (!istImZeitFenster(tag.ZeitFenster)) {
          console.log(`⏸️  "${tag.title}" (${tag.mac}) außerhalb des Zeitfensters ${tag.ZeitFenster}`);
          return;
        }
      
        const json = [{ clear: [1] }, ...titelElementeErzeugen(tag.title)];
        for (const item of tag.body) {
          const ergebnis = await elementAuflösen(item);
          Array.isArray(ergebnis) ? json.push(...ergebnis) : json.push(ergebnis);
        }
        await sendeAnTag(tag.mac, json, tag.title);
      }
      
      /**
       * Startet für jeden Tag ein eigenes setInterval und führt sofort ein erstes
       * Update aus.  So kann sich jeder Tag unabhängig aktualisieren.
       */
      function starteTagUpdates() {
        for (const tag of tagConfig) {
          const intervallMs = tag.updateIntervalMinutes * 60 * 1000;
          setInterval(() => aktualisiereTag(tag).catch(e =>
            console.error(`Fehler bei ${tag.title}: ${e.message}`)), intervallMs);
          aktualisiereTag(tag).catch(e =>
            console.error(`Erstes Update fehlgeschlagen bei ${tag.title}: ${e.message}`));
        }
      }
      
      /* ############################################################################
       *  Start
       * ############################################################################ */
      starteTagUpdates();
      
      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: [erledigt] Shelly v6.4.1 für 3 Pro EM - wie installieren?

      @mickym
      So, mit dem neuen Adapter läuft's jetzt. Danke.

      posted in ioBroker Allgemein
      BertDerKleine
      BertDerKleine
    • history Export nach CSV für einen DP komplett - wie?

      Hallo,
      ich habe einen Datenpunkt für eine Aussentemperatur, wo ich in den Einstellungen des History Adapters schön eingetragen habe Aufbewahrungsdauer= 1 Jahr.
      Nun gibt es ja im UI die Möglichkeit, sich die Verlaufsdaten anzuzeigen und dort auch einen Export nach CSV zu erzeugen.
      Technisch klappt das im Prinzip auch.
      Wie ich jetzt feststellen musste, scheint hier aber eine willkürliche Grenze von 2.000 Datensätzen vorhanden zu sein, was völlig losgelöst von der Aufbewahrungsdauer greift.

      Weiss jemand, wie ich für diesen Datenpunkt die komplette Historie exportiert bekomme?

      Prinzipiell möchte ich mir keinen Umstieg auf irgendwelche anderen DB antun, wenn das nicht zwingend nötig ist.

      Und ich verstehe nicht, wo der Sinn einer parametrisierbaren Aufbewahrungsdauer ist, wenn das Ding trotzdem tumbe einfach nach 2.000 Einträgen abschneidet.

      posted in Einsteigerfragen
      BertDerKleine
      BertDerKleine
    • RE: Mathematik in Blockly - was übersehe ich?

      @david-g

      Hier bitte:

      <xml xmlns="https://developers.google.com/blockly/xml">
        <variables>
          <variable id="o^g9yz%FO3Goz?PTyr+/">T</variable>
          <variable id="/q-tbHA$#DweiRyI85Hq">TK</variable>
          <variable id="g/*k5EP.^7F[)F^Fo1Sm">Rstern</variable>
          <variable id="5FvdDCV{-Un4tsilkDOO">mW</variable>
          <variable id="7-+N_9$/y/?4lB%@r6s!">r</variable>
          <variable id="qO}1VIq:VG#teK8H{Q4o">a</variable>
          <variable id="Yid+hQ){2[1t@fzM[EY#">b</variable>
          <variable id="v_}/{Xu~.;Z@PKJ)hhWo">SDD</variable>
          <variable id="t+LFI{ndYb2NM8ioU%NJ">DD</variable>
          <variable id="Xr*@=()f6?V%ZK:=E@Tr">v</variable>
          <variable id="1Zb0r2[j`H4MZ*o:{q%_">TD</variable>
          <variable id="L8Cs7E?B?X]eu~q}*h;c">AF</variable>
        </variables>
        <block type="comment" id="e/XG;L@R{l_MrKgz2wL$" x="-312" y="-412">
          <field name="COMMENT">Taupunkt alle 10 min berechnen</field>
          <next>
            <block type="schedule" id="TUQF2dy37MgW{wvm~}`5">
              <field name="SCHEDULE">*/10 * * * *</field>
              <statement name="STATEMENT">
                <block type="comment" id="-S_d,l^g66TccZ6Dluxy">
                  <field name="COMMENT">Temperatur in Celsius</field>
                  <next>
                    <block type="variables_set" id="cMw[E}*rvBK?67B.uka+">
                      <field name="VAR" id="o^g9yz%FO3Goz?PTyr+/">T</field>
                      <value name="VALUE">
                        <block type="get_value" id="^$OQa^0epGPjBS=UDTqO">
                          <field name="ATTR">val</field>
                          <field name="OID">alias.0.Aussentemperatur_Gartenhaus</field>
                        </block>
                      </value>
                      <next>
                        <block type="comment" id="?#6B,h,dlaaVn4!Ht]Xr">
                          <field name="COMMENT">Temperatur in Kelvin</field>
                          <next>
                            <block type="variables_set" id="=.KEIqXrg[J|=#[-CRSo">
                              <field name="VAR" id="/q-tbHA$#DweiRyI85Hq">TK</field>
                              <value name="VALUE">
                                <block type="math_arithmetic" id="%f2BAdP!||(YPmVS6R`B">
                                  <field name="OP">ADD</field>
                                  <value name="A">
                                    <shadow type="math_number" id="V%Oa/,@9=Eir:1y2fvfV">
                                      <field name="NUM">1</field>
                                    </shadow>
                                    <block type="variables_get" id="]tBY4[E@/n2~LgCQ=4Xa">
                                      <field name="VAR" id="o^g9yz%FO3Goz?PTyr+/">T</field>
                                    </block>
                                  </value>
                                  <value name="B">
                                    <shadow type="math_number" id="%i5(V)~ho0r^wg4LuT0(">
                                      <field name="NUM">273.15</field>
                                    </shadow>
                                  </value>
                                </block>
                              </value>
                              <next>
                                <block type="comment" id=";yf%7$SvHhMb:gnxMt]4">
                                  <field name="COMMENT">universelle Gaskonstante</field>
                                  <next>
                                    <block type="variables_set" id=";hoSsSn$O~DUmpP_^cW~">
                                      <field name="VAR" id="g/*k5EP.^7F[)F^Fo1Sm">Rstern</field>
                                      <value name="VALUE">
                                        <block type="math_number" id=",)dyI53B)#Z6{0Iz1$$h">
                                          <field name="NUM">8314.3</field>
                                        </block>
                                      </value>
                                      <next>
                                        <block type="comment" id="o4nL4JPOcDabtv$!8rqt">
                                          <field name="COMMENT">Molekulargewicht des Wasserdampfes</field>
                                          <next>
                                            <block type="variables_set" id="UKpN6SN{7^kCC+xdaRL^">
                                              <field name="VAR" id="5FvdDCV{-Un4tsilkDOO">mW</field>
                                              <value name="VALUE">
                                                <block type="math_number" id="oplrQ(+U81?Z,^X5nbZ;">
                                                  <field name="NUM">18.016</field>
                                                </block>
                                              </value>
                                              <next>
                                                <block type="comment" id="CFdIX4T6q6z3!0g[e-Lr">
                                                  <field name="COMMENT">relative Luftfeuchtigkeit</field>
                                                  <next>
                                                    <block type="variables_set" id="mi_e#JAmoPGAIS~w=Yi}">
                                                      <field name="VAR" id="7-+N_9$/y/?4lB%@r6s!">r</field>
                                                      <value name="VALUE">
                                                        <block type="get_value" id="`uaC7n[Sb*+Om~9nmxmb">
                                                          <field name="ATTR">val</field>
                                                          <field name="OID">alias.0.Luftfeuchtigkeit_Gartenhaus</field>
                                                        </block>
                                                      </value>
                                                      <next>
                                                        <block type="comment" id="C!^1|nSXSe@[X~_7q_^p">
                                                          <field name="COMMENT">Parameter</field>
                                                          <next>
                                                            <block type="variables_set" id="/7.+ip2BYsVMRRl;XA06">
                                                              <field name="VAR" id="qO}1VIq:VG#teK8H{Q4o">a</field>
                                                              <value name="VALUE">
                                                                <block type="logic_ternary" id="qKv~NI-*wL.5v_u*9W|P">
                                                                  <value name="IF">
                                                                    <block type="logic_compare" id="e}glge,w!C+fSS%p|S9i">
                                                                      <field name="OP">GTE</field>
                                                                      <value name="A">
                                                                        <block type="variables_get" id="qAAC7iqL[RiR6To5?uoT">
                                                                          <field name="VAR" id="o^g9yz%FO3Goz?PTyr+/">T</field>
                                                                        </block>
                                                                      </value>
                                                                      <value name="B">
                                                                        <block type="math_number" id="prP{Vn?kMYq0~W6pA=au">
                                                                          <field name="NUM">0</field>
                                                                        </block>
                                                                      </value>
                                                                    </block>
                                                                  </value>
                                                                  <value name="THEN">
                                                                    <block type="math_number" id="`@,@vz+~5Gl,lfeeUIbi">
                                                                      <field name="NUM">7.5</field>
                                                                    </block>
                                                                  </value>
                                                                  <value name="ELSE">
                                                                    <block type="math_number" id="m*CVnA~edQjHkQ~cMjtd">
                                                                      <field name="NUM">7.6</field>
                                                                    </block>
                                                                  </value>
                                                                </block>
                                                              </value>
                                                              <next>
                                                                <block type="variables_set" id=":FW]I8jfA/Cj)+)_}Kix">
                                                                  <field name="VAR" id="Yid+hQ){2[1t@fzM[EY#">b</field>
                                                                  <value name="VALUE">
                                                                    <block type="logic_ternary" id="mIV3AE6DL#4{wZNrfVsw">
                                                                      <value name="IF">
                                                                        <block type="logic_compare" id="gM?{6WJ8`#eO`5S{(~L-">
                                                                          <field name="OP">GTE</field>
                                                                          <value name="A">
                                                                            <block type="variables_get" id="aZ{s|I|[b@T}x5eSmQKQ">
                                                                              <field name="VAR" id="o^g9yz%FO3Goz?PTyr+/">T</field>
                                                                            </block>
                                                                          </value>
                                                                          <value name="B">
                                                                            <block type="math_number" id="npT|Gr-G?~T$i:DmX]PA">
                                                                              <field name="NUM">0</field>
                                                                            </block>
                                                                          </value>
                                                                        </block>
                                                                      </value>
                                                                      <value name="THEN">
                                                                        <block type="math_number" id="6o?ac_FukueC-kk@nq!o">
                                                                          <field name="NUM">237.3</field>
                                                                        </block>
                                                                      </value>
                                                                      <value name="ELSE">
                                                                        <block type="math_number" id="4;4K[{0)4(Vozm%75+_i">
                                                                          <field name="NUM">240.7</field>
                                                                        </block>
                                                                      </value>
                                                                    </block>
                                                                  </value>
                                                                  <next>
                                                                    <block type="comment" id="$B*=}.rL,X,qPq#qBoZo">
                                                                      <field name="COMMENT">Sättigungsdampfdruck in hPa</field>
                                                                      <next>
                                                                        <block type="variables_set" id="Q?E@]+o%?A5Vst;#UC%`">
                                                                          <field name="VAR" id="v_}/{Xu~.;Z@PKJ)hhWo">SDD</field>
                                                                          <value name="VALUE">
                                                                            <block type="math_arithmetic" id="(ZGnUJEP%3s.TfrDsFbS">
                                                                              <field name="OP">MULTIPLY</field>
                                                                              <value name="A">
                                                                                <shadow type="math_number" id="L@$PW9Ryp)lwi@}/4d@L">
                                                                                  <field name="NUM">6.1078</field>
                                                                                </shadow>
                                                                              </value>
                                                                              <value name="B">
                                                                                <shadow type="math_number" id="6!68UCqmG^mt}ntwAw$=">
                                                                                  <field name="NUM">1</field>
                                                                                </shadow>
                                                                                <block type="math_single" id="M:d2,qt=[n!JG^%L9;X.">
                                                                                  <field name="OP">POW10</field>
                                                                                  <value name="NUM">
                                                                                    <shadow type="math_number" id="F^/V0W(V%SRkgBJ[G~Lc">
                                                                                      <field name="NUM">9</field>
                                                                                    </shadow>
                                                                                    <block type="math_arithmetic" id="=Ik).QQ[s15+h0A?;;yb">
                                                                                      <field name="OP">DIVIDE</field>
                                                                                      <value name="A">
                                                                                        <shadow type="math_number" id="u#-uB_ADf8(QQ}AkR5zI">
                                                                                          <field name="NUM">1</field>
                                                                                        </shadow>
                                                                                        <block type="math_arithmetic" id="8ukI~R3.t!)Qsp:B54:*">
                                                                                          <field name="OP">MULTIPLY</field>
                                                                                          <value name="A">
                                                                                            <shadow type="math_number" id=":yHv-G%d7WkP)fIHpxXn">
                                                                                              <field name="NUM">1</field>
                                                                                            </shadow>
                                                                                            <block type="variables_get" id="^;M`T+e|OgmujVUBpBKf">
                                                                                              <field name="VAR" id="qO}1VIq:VG#teK8H{Q4o">a</field>
                                                                                            </block>
                                                                                          </value>
                                                                                          <value name="B">
                                                                                            <shadow type="math_number" id="#0eZmW-$afJh^VxL${6-">
                                                                                              <field name="NUM">1</field>
                                                                                            </shadow>
                                                                                            <block type="variables_get" id="Hn7+4.rg.?69*!?/CZB,">
                                                                                              <field name="VAR" id="o^g9yz%FO3Goz?PTyr+/">T</field>
                                                                                            </block>
                                                                                          </value>
                                                                                        </block>
                                                                                      </value>
                                                                                      <value name="B">
                                                                                        <shadow type="math_number" id="`N@cOBS1|I]jT+ex2qEf">
                                                                                          <field name="NUM">1</field>
                                                                                        </shadow>
                                                                                        <block type="math_arithmetic" id="6l%(Jm)9WT[?a@3kI=cK">
                                                                                          <field name="OP">ADD</field>
                                                                                          <value name="A">
                                                                                            <shadow type="math_number" id="Ws4MAaUO?jkUPN$*tIrT">
                                                                                              <field name="NUM">1</field>
                                                                                            </shadow>
                                                                                            <block type="variables_get" id="zY)d82gl|jfTj5;k%I8i">
                                                                                              <field name="VAR" id="Yid+hQ){2[1t@fzM[EY#">b</field>
                                                                                            </block>
                                                                                          </value>
                                                                                          <value name="B">
                                                                                            <shadow type="math_number" id="EaZjCk!yPqCGmFWT6Z|?">
                                                                                              <field name="NUM">1</field>
                                                                                            </shadow>
                                                                                            <block type="variables_get" id="T{h;k2FnMx*`:D,h6uUa">
                                                                                              <field name="VAR" id="o^g9yz%FO3Goz?PTyr+/">T</field>
                                                                                            </block>
                                                                                          </value>
                                                                                        </block>
                                                                                      </value>
                                                                                    </block>
                                                                                  </value>
                                                                                </block>
                                                                              </value>
                                                                            </block>
                                                                          </value>
                                                                          <next>
                                                                            <block type="comment" id="3Kh+_+mXR:2GO:O*m)vs">
                                                                              <field name="COMMENT">Dampfdruck in hPa</field>
                                                                              <next>
                                                                                <block type="variables_set" id="*ErK7$+[hH1[QvidG`i,">
                                                                                  <field name="VAR" id="t+LFI{ndYb2NM8ioU%NJ">DD</field>
                                                                                  <value name="VALUE">
                                                                                    <block type="math_arithmetic" id=".|hBJ(g|S-4zqJ)f*?C|">
                                                                                      <field name="OP">MULTIPLY</field>
                                                                                      <value name="A">
                                                                                        <shadow type="math_number" id="V%Oa/,@9=Eir:1y2fvfV">
                                                                                          <field name="NUM">1</field>
                                                                                        </shadow>
                                                                                        <block type="math_arithmetic" id=";T4GYS;.Q9f.KvVhNK(1">
                                                                                          <field name="OP">DIVIDE</field>
                                                                                          <value name="A">
                                                                                            <shadow type="math_number" id="V%Oa/,@9=Eir:1y2fvfV">
                                                                                              <field name="NUM">1</field>
                                                                                            </shadow>
                                                                                            <block type="variables_get" id="R?0v,jH7n,nd#LD[2GT0">
                                                                                              <field name="VAR" id="7-+N_9$/y/?4lB%@r6s!">r</field>
                                                                                            </block>
                                                                                          </value>
                                                                                          <value name="B">
                                                                                            <shadow type="math_number" id="8{M@RD3*mP}Oq0M?3^v$">
                                                                                              <field name="NUM">100</field>
                                                                                            </shadow>
                                                                                          </value>
                                                                                        </block>
                                                                                      </value>
                                                                                      <value name="B">
                                                                                        <shadow type="math_number" id="C(ggyO^$BRr(2B(zV-YH">
                                                                                          <field name="NUM">273.15</field>
                                                                                        </shadow>
                                                                                        <block type="variables_get" id="v_4VxNdh{u|Q%DJq_UVo">
                                                                                          <field name="VAR" id="v_}/{Xu~.;Z@PKJ)hhWo">SDD</field>
                                                                                        </block>
                                                                                      </value>
                                                                                    </block>
                                                                                  </value>
                                                                                  <next>
                                                                                    <block type="comment" id="]pfz|t_tdKSGb?BhvlTI">
                                                                                      <field name="COMMENT">Taupunkttemperatur in Celsius</field>
                                                                                      <next>
                                                                                        <block type="variables_set" id=")e/Z/L)M5Zkkn|fY9*~z">
                                                                                          <field name="VAR" id="Xr*@=()f6?V%ZK:=E@Tr">v</field>
                                                                                          <value name="VALUE">
                                                                                            <block type="math_single" id="]1b%g?0DLLaCIQ62Y#cX">
                                                                                              <field name="OP">LOG10</field>
                                                                                              <value name="NUM">
                                                                                                <shadow type="math_number" id="|~oa]5S~HC~,9hN8N{uO">
                                                                                                  <field name="NUM">9</field>
                                                                                                </shadow>
                                                                                                <block type="math_arithmetic" id="bFL4a$XZpyR.8(1pnljn">
                                                                                                  <field name="OP">DIVIDE</field>
                                                                                                  <value name="A">
                                                                                                    <shadow type="math_number" id="~?p.B[/Q*Me.QKW$;|CD">
                                                                                                      <field name="NUM">1</field>
                                                                                                    </shadow>
                                                                                                    <block type="variables_get" id="b`FE:4Mv_xu.zS/[{s=/">
                                                                                                      <field name="VAR" id="t+LFI{ndYb2NM8ioU%NJ">DD</field>
                                                                                                    </block>
                                                                                                  </value>
                                                                                                  <value name="B">
                                                                                                    <shadow type="math_number" id="yDGe4DBI6[!rju*,~6Gv">
                                                                                                      <field name="NUM">6.1078</field>
                                                                                                    </shadow>
                                                                                                  </value>
                                                                                                </block>
                                                                                              </value>
                                                                                            </block>
                                                                                          </value>
                                                                                          <next>
                                                                                            <block type="variables_set" id="K.PrWMw1NF?-!1Yv0NlE">
                                                                                              <field name="VAR" id="1Zb0r2[j`H4MZ*o:{q%_">TD</field>
                                                                                              <value name="VALUE">
                                                                                                <block type="math_arithmetic" id="FWOFiM+$xJIje~$92),]">
                                                                                                  <field name="OP">DIVIDE</field>
                                                                                                  <value name="A">
                                                                                                    <shadow type="math_number" id="V%Oa/,@9=Eir:1y2fvfV">
                                                                                                      <field name="NUM">1</field>
                                                                                                    </shadow>
                                                                                                    <block type="math_arithmetic" id="x-2PrSvt}r^~duF[:XB$">
                                                                                                      <field name="OP">MULTIPLY</field>
                                                                                                      <value name="A">
                                                                                                        <shadow type="math_number" id="~?p.B[/Q*Me.QKW$;|CD">
                                                                                                          <field name="NUM">1</field>
                                                                                                        </shadow>
                                                                                                        <block type="variables_get" id="lQWPuEueD1(5aXT%[]{L">
                                                                                                          <field name="VAR" id="Yid+hQ){2[1t@fzM[EY#">b</field>
                                                                                                        </block>
                                                                                                      </value>
                                                                                                      <value name="B">
                                                                                                        <shadow type="math_number" id=";/SQ.lAAZv7b+0gvFW@G">
                                                                                                          <field name="NUM">100</field>
                                                                                                        </shadow>
                                                                                                        <block type="variables_get" id="5)jLL?zx00kul:qSj({A">
                                                                                                          <field name="VAR" id="Xr*@=()f6?V%ZK:=E@Tr">v</field>
                                                                                                        </block>
                                                                                                      </value>
                                                                                                    </block>
                                                                                                  </value>
                                                                                                  <value name="B">
                                                                                                    <shadow type="math_number" id="nN_FxmGiO#EIrz9fdKU5">
                                                                                                      <field name="NUM">273.15</field>
                                                                                                    </shadow>
                                                                                                    <block type="math_arithmetic" id="}BfF:`jjZ$b+HY+pshlH">
                                                                                                      <field name="OP">MINUS</field>
                                                                                                      <value name="A">
                                                                                                        <shadow type="math_number" id="~?p.B[/Q*Me.QKW$;|CD">
                                                                                                          <field name="NUM">1</field>
                                                                                                        </shadow>
                                                                                                        <block type="variables_get" id="@*t^U#2,Bb%/sxFtswiH">
                                                                                                          <field name="VAR" id="qO}1VIq:VG#teK8H{Q4o">a</field>
                                                                                                        </block>
                                                                                                      </value>
                                                                                                      <value name="B">
                                                                                                        <shadow type="math_number" id="9Rr.;!sNpE@)3yM++X+G">
                                                                                                          <field name="NUM">100</field>
                                                                                                        </shadow>
                                                                                                        <block type="variables_get" id="Y1NKFr4@.ovjmsh|i86u">
                                                                                                          <field name="VAR" id="Xr*@=()f6?V%ZK:=E@Tr">v</field>
                                                                                                        </block>
                                                                                                      </value>
                                                                                                    </block>
                                                                                                  </value>
                                                                                                </block>
                                                                                              </value>
                                                                                              <next>
                                                                                                <block type="debug" id=".4P[N8va8y=j{Lj8@;we">
                                                                                                  <field name="Severity">info</field>
                                                                                                  <value name="TEXT">
                                                                                                    <shadow type="text" id="N1$OJw{0.kSSpr0VFdff">
                                                                                                      <field name="TEXT">test</field>
                                                                                                    </shadow>
                                                                                                    <block type="text_join" id="Z_Z84~P.^8$.DxHls01{">
                                                                                                      <mutation items="2"></mutation>
                                                                                                      <value name="ADD0">
                                                                                                        <block type="text" id=",!jdOQ|*w!hTFBqGy-W:">
                                                                                                          <field name="TEXT">TD: </field>
                                                                                                        </block>
                                                                                                      </value>
                                                                                                      <value name="ADD1">
                                                                                                        <block type="convert_tostring" id="J0~r{svo*_c2`@-(TOhU">
                                                                                                          <value name="VALUE">
                                                                                                            <block type="math_rndfixed" id="^O|nnaKw,4mVG_y-e.|*">
                                                                                                              <field name="n">2</field>
                                                                                                              <value name="x">
                                                                                                                <shadow type="math_number" id="5o~4bRrx(^NK-!jZ%2,R">
                                                                                                                  <field name="NUM">3.1234</field>
                                                                                                                </shadow>
                                                                                                                <block type="variables_get" id=",I*vaowB$Hmhp.(w@r,@">
                                                                                                                  <field name="VAR" id="1Zb0r2[j`H4MZ*o:{q%_">TD</field>
                                                                                                                </block>
                                                                                                              </value>
                                                                                                            </block>
                                                                                                          </value>
                                                                                                        </block>
                                                                                                      </value>
                                                                                                    </block>
                                                                                                  </value>
                                                                                                  <next>
                                                                                                    <block type="update" id="|vxUuOJ)`_y!E7M1:[G5">
                                                                                                      <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                                                                      <field name="OID">0_userdata.0.Taupunkttemperatur</field>
                                                                                                      <field name="WITH_DELAY">FALSE</field>
                                                                                                      <value name="VALUE">
                                                                                                        <block type="math_rndfixed" id="#vcLzyhM7I4?/a*/C|wZ">
                                                                                                          <field name="n">2</field>
                                                                                                          <value name="x">
                                                                                                            <shadow type="math_number" id="5o~4bRrx(^NK-!jZ%2,R">
                                                                                                              <field name="NUM">3.1234</field>
                                                                                                            </shadow>
                                                                                                            <block type="variables_get" id="0V,PrytRUU,U}-5BO_7i">
                                                                                                              <field name="VAR" id="1Zb0r2[j`H4MZ*o:{q%_">TD</field>
                                                                                                            </block>
                                                                                                          </value>
                                                                                                        </block>
                                                                                                      </value>
                                                                                                      <next>
                                                                                                        <block type="comment" id="9|.{=E@==ZQ;1EkqRkD!">
                                                                                                          <field name="COMMENT">Absolute Feuchte in g Wasserdampf / m³ Luft</field>
                                                                                                          <next>
                                                                                                            <block type="variables_set" id=")9u6oO!u}QJJUi_tDk+5">
                                                                                                              <field name="VAR" id="L8Cs7E?B?X]eu~q}*h;c">AF</field>
                                                                                                              <value name="VALUE">
                                                                                                                <block type="math_arithmetic" id="kaMi[~Jau7@BS)[E`d`}">
                                                                                                                  <field name="OP">MULTIPLY</field>
                                                                                                                  <value name="A">
                                                                                                                    <shadow type="math_number" id="O19FA=:II#Kcwv?X0rz[">
                                                                                                                      <field name="NUM">1</field>
                                                                                                                    </shadow>
                                                                                                                    <block type="math_arithmetic" id="f[@igd43wi@4fSwj8jY$">
                                                                                                                      <field name="OP">MULTIPLY</field>
                                                                                                                      <value name="A">
                                                                                                                        <shadow type="math_number" id=".s%?!UB#kYk;Q%|sdDl[">
                                                                                                                          <field name="NUM">1</field>
                                                                                                                        </shadow>
                                                                                                                        <block type="math_single" id="gdI6-ta$wYA]Br*bx9^`">
                                                                                                                          <field name="OP">POW10</field>
                                                                                                                          <value name="NUM">
                                                                                                                            <shadow type="math_number" id="W_TwJZ|B;BNQ*AzGhI5;">
                                                                                                                              <field name="NUM">5</field>
                                                                                                                            </shadow>
                                                                                                                          </value>
                                                                                                                        </block>
                                                                                                                      </value>
                                                                                                                      <value name="B">
                                                                                                                        <shadow type="math_number" id="cT]_U4(ip$:HMyH1#9a`">
                                                                                                                          <field name="NUM">1</field>
                                                                                                                        </shadow>
                                                                                                                        <block type="math_arithmetic" id="H-MnP?wN3}0a?bhsow(2">
                                                                                                                          <field name="OP">DIVIDE</field>
                                                                                                                          <value name="A">
                                                                                                                            <shadow type="math_number" id="rgL9sWwN2|NiXFoBA]gd">
                                                                                                                              <field name="NUM">1</field>
                                                                                                                            </shadow>
                                                                                                                            <block type="variables_get" id="TB0o1JRY?:EQk+*cFFNK">
                                                                                                                              <field name="VAR" id="5FvdDCV{-Un4tsilkDOO">mW</field>
                                                                                                                            </block>
                                                                                                                          </value>
                                                                                                                          <value name="B">
                                                                                                                            <shadow type="math_number" id="on1g-.T|%6K|mN1EptH(">
                                                                                                                              <field name="NUM">1</field>
                                                                                                                            </shadow>
                                                                                                                            <block type="variables_get" id=")C/K[O_aI+PLQJS1R+C(">
                                                                                                                              <field name="VAR" id="g/*k5EP.^7F[)F^Fo1Sm">Rstern</field>
                                                                                                                            </block>
                                                                                                                          </value>
                                                                                                                        </block>
                                                                                                                      </value>
                                                                                                                    </block>
                                                                                                                  </value>
                                                                                                                  <value name="B">
                                                                                                                    <shadow type="math_number" id="_L;Fa|jJ0iLxY7d%Q9dA">
                                                                                                                      <field name="NUM">1</field>
                                                                                                                    </shadow>
                                                                                                                    <block type="math_arithmetic" id="hGD$Sj+;$UCiqB1o]tjH">
                                                                                                                      <field name="OP">DIVIDE</field>
                                                                                                                      <value name="A">
                                                                                                                        <shadow type="math_number" id="{iLKlZfF,7VDbLu@9VpK">
                                                                                                                          <field name="NUM">1</field>
                                                                                                                        </shadow>
                                                                                                                        <block type="variables_get" id="eFMv@K+RsMr@Bywc|uC.">
                                                                                                                          <field name="VAR" id="t+LFI{ndYb2NM8ioU%NJ">DD</field>
                                                                                                                        </block>
                                                                                                                      </value>
                                                                                                                      <value name="B">
                                                                                                                        <shadow type="math_number" id="^8_oE4fa6e]WwWVE(SG6">
                                                                                                                          <field name="NUM">1</field>
                                                                                                                        </shadow>
                                                                                                                        <block type="variables_get" id="hGPiU3?F@*mckz9{Ka!e">
                                                                                                                          <field name="VAR" id="/q-tbHA$#DweiRyI85Hq">TK</field>
                                                                                                                        </block>
                                                                                                                      </value>
                                                                                                                    </block>
                                                                                                                  </value>
                                                                                                                </block>
                                                                                                              </value>
                                                                                                              <next>
                                                                                                                <block type="debug" id="*HpEuUA{7WQz9{rrr4D`">
                                                                                                                  <field name="Severity">info</field>
                                                                                                                  <value name="TEXT">
                                                                                                                    <shadow type="text" id="N1$OJw{0.kSSpr0VFdff">
                                                                                                                      <field name="TEXT">test</field>
                                                                                                                    </shadow>
                                                                                                                    <block type="text_join" id="jpOK{]/zjubFSYYjIc:]">
                                                                                                                      <mutation items="2"></mutation>
                                                                                                                      <value name="ADD0">
                                                                                                                        <block type="text" id="5{?Q$XBORl%wZ)b8bHtw">
                                                                                                                          <field name="TEXT">AF: </field>
                                                                                                                        </block>
                                                                                                                      </value>
                                                                                                                      <value name="ADD1">
                                                                                                                        <block type="convert_tostring" id="N(i~+Jz~W[8zJoW@m`Fo">
                                                                                                                          <value name="VALUE">
                                                                                                                            <block type="math_rndfixed" id="2L{?jY$.A?jFI+0WyPY,">
                                                                                                                              <field name="n">2</field>
                                                                                                                              <value name="x">
                                                                                                                                <shadow type="math_number" id="5o~4bRrx(^NK-!jZ%2,R">
                                                                                                                                  <field name="NUM">3.1234</field>
                                                                                                                                </shadow>
                                                                                                                                <block type="variables_get" id="hfIPp/E~X4b?V#l#UQCm">
                                                                                                                                  <field name="VAR" id="L8Cs7E?B?X]eu~q}*h;c">AF</field>
                                                                                                                                </block>
                                                                                                                              </value>
                                                                                                                            </block>
                                                                                                                          </value>
                                                                                                                        </block>
                                                                                                                      </value>
                                                                                                                    </block>
                                                                                                                  </value>
                                                                                                                  <next>
                                                                                                                    <block type="update" id="eX+we--@Ze)JpaA*3j?d">
                                                                                                                      <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                                                                                      <field name="OID">0_userdata.0.Absolute_Feuchte</field>
                                                                                                                      <field name="WITH_DELAY">FALSE</field>
                                                                                                                      <value name="VALUE">
                                                                                                                        <block type="math_rndfixed" id="xY9-+o53nTWYE`PV!(K:">
                                                                                                                          <field name="n">2</field>
                                                                                                                          <value name="x">
                                                                                                                            <shadow type="math_number" id="5o~4bRrx(^NK-!jZ%2,R">
                                                                                                                              <field name="NUM">3.1234</field>
                                                                                                                            </shadow>
                                                                                                                            <block type="variables_get" id="u7J)@W[vp4x`nKq!fJju">
                                                                                                                              <field name="VAR" id="L8Cs7E?B?X]eu~q}*h;c">AF</field>
                                                                                                                            </block>
                                                                                                                          </value>
                                                                                                                        </block>
                                                                                                                      </value>
                                                                                                                    </block>
                                                                                                                  </next>
                                                                                                                </block>
                                                                                                              </next>
                                                                                                            </block>
                                                                                                          </next>
                                                                                                        </block>
                                                                                                      </next>
                                                                                                    </block>
                                                                                                  </next>
                                                                                                </block>
                                                                                              </next>
                                                                                            </block>
                                                                                          </next>
                                                                                        </block>
                                                                                      </next>
                                                                                    </block>
                                                                                  </next>
                                                                                </block>
                                                                              </next>
                                                                            </block>
                                                                          </next>
                                                                        </block>
                                                                      </next>
                                                                    </block>
                                                                  </next>
                                                                </block>
                                                              </next>
                                                            </block>
                                                          </next>
                                                        </block>
                                                      </next>
                                                    </block>
                                                  </next>
                                                </block>
                                              </next>
                                            </block>
                                          </next>
                                        </block>
                                      </next>
                                    </block>
                                  </next>
                                </block>
                              </next>
                            </block>
                          </next>
                        </block>
                      </next>
                    </block>
                  </next>
                </block>
              </statement>
            </block>
          </next>
        </block>
      </xml>
      
      posted in Skripten / Logik
      BertDerKleine
      BertDerKleine
    • RE: E-INK Display OpenEPaperLink - Displayanzeige mit Batterie

      @beowolf
      Danke Dir. Problem ist mittlerweile auch gelöst.

      Ich hatte schon einen eigenen Thread aufgemacht: https://forum.iobroker.net/topic/81640/gelöst-puppeteer-adapter-läuft-auf-raspi-4-nicht

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: [gelöst] Werte für Grafik auf >0 begrenzen - wie?

      @glasfaser
      Aaaahhh... danke sehr. 👍
      Das hatte ich noch nicht gesehen. Jetzt habe ich die Formel da eingetragen.

      posted in ioBroker Allgemein
      BertDerKleine
      BertDerKleine
    • Lizenz-Login scheitert

      Wenn ich in der Admin-Oberfläche des iobroker in den Basiseinstellungen die Sektion "Lizenzen" besuche, wird dort ein Login für iobroker.net verlangt.
      Genau das gebe ich dort ein und bekomme den Fehler
      "Lizenzen können nicht aktualisiert werden: Authentifizierung erforderlich oder Login, Passwort ungültig".
      Mit ganz genau diesen Einstellungen kann ich mich aber stressfrei auf iobroker.net anmelden und meine Lizenzdaten anschauen (auch wenn da nicht mehr als die kostenlose iobroker.vis Lizenz erscheint).

      Jemand eine Idee, was ich hier falsch mache?

      posted in Einsteigerfragen
      BertDerKleine
      BertDerKleine
    • RE: E-Ink OpenEpaperLink - JSON-Steuerung per Javascript

      @rene55 sagte in E-Ink OpenEpaperLink - JSON-Steuerung per Javascript:

      @bertderkleine Danke für den guten Ansatz mit dem Script. Beschreibst du auch noch die Vorgehensweise mit den Schriften?

      Gerne.
      Zuerst lade und installiere zwei kostenlose Programme:
      FontForge: https://fontforge.org/en-US/downloads/
      und
      Processing: https://processing.org/download

      Schritt 1: Entscheide Dich für irgendeine .ttf Schriftartendatei auf Deinem Rechner, die Dir gefällt für die Ausgabe auf dem Display.

      Schritt 2: Lösche die überflüssigen Glyphen mit Fontforge.

      • Starte FontForge und öffne die TTF-Datei.
      • Wähle im Menü "Codierung / Compact", um leere Plätze auszublenden.
      • Markiere mit Maus Anklicken oder Maus drüberziehen überflüssige Glyphen. Mit "Shift" kann man getrennte Mehrfachauswahlen machen, was sonst unter Windows eher bei "Strg" geht.
      • Wähle Rechtsklick / "Löschen".
      • Wähle im Menü "Element / Schrift - Informationen", um die Schrift mit einem neuen eindeutigen Namen zu versehen, der sie von der Quelle unterscheidet.
      • Wähle im Menü "Datei / Schriften erstellen", um die reduzierte Datei als TrueType zu speichern.

      Schritt 3: Installiere die neue Schriftart zumindest temporär auf Deinem System für den Schritt 4. Danach kannst Du sie wieder löschen. Unter Windows geht das mit Rechtsklick / Installieren über der TTF-Datei.

      Schritt 4: Wandle die TTF in VLW um mit Processing

      • Starte Processing.
      • Wähle im Menü "Tools / Schrift erstellen"
      • Wähle die eben erstellte und installierte Schriftart, die Zielgröße und den Zieldateinamen.
        Drücke "OK"
      • Optional: Diesen Export mit verschiedenen Zielgrößen wiederholen.

      Fertig!

      Nun nur noch ins "fonts" Verzeichnis des AP mit dem Filebrowser des WebUI des AP hochladen.

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: [gelöst] modbus Verbindung zu SMA Wechselrichter läuft nicht

      @thomas-braun
      Danke, ich habe die IP Adresse hier im Log gekürzt gehabt, das ist also keine Problemursache.

      Ich bin jetzt tatsächlich weiter gekommen.
      Für die Nachwelt, falls das hier mal jemand liest, die Infos kommen von:
      https://openwb.de/forum/viewtopic.php?t=829

      Offensichtlich ist es üblich, dass der Modbus Server erstmal nicht läuft.
      Und leider scheint die einzige Möglichkeit, den entsprechenden Parameter zu ändern, die Software Sunny Explorer zu sein
      https://www.sma.de/produkte/monitoring-control/sunny-explorer
      Die gibts nur für Windows und wurde zuletzt 2020 aktualisiert.

      In der Software gibt man sein Anlagenpasswort ein und kann über Ethernet dann Einstellungen vornehmen.

      Nebenbei habe ich dann so tatsächlich auch die richtige Gerätenummer rausgefunden, die nicht "1" war.

      posted in ioBroker Allgemein
      BertDerKleine
      BertDerKleine
    • RE: Lizenz-Login scheitert

      @djmarc75
      Das log sagt nur "error: Cannot read licenses: Authentication required."

      posted in Einsteigerfragen
      BertDerKleine
      BertDerKleine

    Latest posts made by BertDerKleine

    • RE: E-Ink OpenEpaperLink - JSON-Steuerung per Javascript

      Ich teile hier noch mal eine mögliche Ergänzung, die ich bei mir selbst verwende.
      Meist gibt man ja eher Zahlen aus, das ist fein soweit. Wenn man aber längere Textfelder ausgeben will, gibt es das Problem, das der Text zu lang ist und eigentlich umgebrochen werden muss.
      Beispiel: Texte aus dem Kalender.

      Mein erster Lösungsansatz sieht im Code so aus:

      Neu hinzugekommen sind für Textfelder drei Parameter:

      • maxZeilenbreite: Zeichen, die maximal pro Zeile hinpassen auf das Display
      • maxZeilen: maximal auszugebende Zeilen auf dem Display für dieses Textfeld
      • zeilenAbstand: Pixelhöhe pro Zeile inkl. optischem Abstand

      Ersetze im Text-Block (ganz unten in "elementAuflösen" ) die Zeilen

      const textArr = [x, y, wert, schrift, farbe];
      if (typeof item.align === 'number') textArr.push(item.align);
      return { text: textArr };
      

      durch die gepimpte Version:

      // --- automatischer Zeilenumbruch ---
      if (item.maxZeilenbreite && item.maxZeilen) {
        const breite   = item.maxZeilenbreite;
        const zeilen   = item.maxZeilen;
        const abstand  = item.zeilenAbstand || 20;
        const zeilenArr = wert.split('\n');              // erlaubt manuelle \n
      
        const result = [];
        let posY = y;
        let zähler = 0;
      
        for (const rawLine of zeilenArr) {
          const words = rawLine.split(' ');
          let line = '';
          for (const w of words) {
            const probe = line + (line ? ' ' : '') + w;
            if (probe.length > breite && line.length) {
              // neue Zeile
              result.push({ text: [x, posY, line.trim(), schrift, farbe] });
              posY += abstand;
              zähler++;
              if (zähler >= zeilen) return result;
              line = w;
            } else {
              line = probe;
            }
          }
          if (line) {
            result.push({ text: [x, posY, line.trim(), schrift, farbe] });
            posY += abstand;
            zähler++;
            if (zähler >= zeilen) return result;
          }
        }
        return result;
      }
      
      // --- klassischer Einzeiler (wie bisher) ---
      const textArr = [x, y, wert, schrift, farbe];
      if (typeof item.align === 'number') textArr.push(item.align);
      return { text: textArr };
      

      Die relevante Konfigurationszeile in der Konfig sieht dann z.B. so aus:

      { dp: 'alias.0.Kalendervorschau', font: 'calibrib16', color: 1, x: 0, y: 25, maxZeilenbreite: 38, maxZeilen: 7, zeilenAbstand: 17 }
      

      Das setzt zwar etwas Fingerspitzengefühl beim Benutzer voraus, aber gegen eine Vollautomatisierung spricht die Herausforderung, dass jede Schriftart in Pixeln unterschiedlich breit und hoch ist. Dazu mache ich lieber mit drei Parametern per Hand Anpassungen, als zu versuchen, das mit Formlen in den Griff zu bekommen.

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: Test Adapter e3oncan - Viessmann E3 Serie einbinden

      @jrbwh sagte in Test Adapter e3oncan - Viessmann E3 Serie einbinden:

      /opt/iobroker/node_modules/iobroker.e3oncan/

      Danke Dir für die super fixe Reaktion! 👍 👍 👍

      Ich habe die Befehle ausgeführt und jetzt läuft der Adapter wieder! 😀
      Klasse, danke!

      Hier das Feedback des Systems:

      Bert@iobroker:/opt/iobroker/node_modules/iobroker.e3oncan $ npm rb
      rebuilt dependencies successfully
      Bert@iobroker:/opt/iobroker/node_modules/iobroker.e3oncan $ npm i
      
      added 402 packages, and audited 404 packages in 2m
      
      77 packages are looking for funding
        run `npm fund` for details
      
      found 0 vulnerabilities
      

      Haben dem Ding wirklich 402 Pakete gefehlt? Die Eieeruhr beim Ausführen von "npm i" hat eine Weile gedreht.

      Ich verstehe von sowas ja nichts...

      posted in Tester
      BertDerKleine
      BertDerKleine
    • RE: Test Adapter e3oncan - Viessmann E3 Serie einbinden

      @jrbwh
      Hallo, ich habe eben meinen iobroker auf NodeJS v22.18 geupdated. Leider scheint dies dem e3onCAN nicht gut getan zu haben, denn jetzt funktioniert er nicht mehr.

      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	instance system.adapter.e3oncan.0 terminated with code 1 (JS_CONTROLLER_STOPPED)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: Node.js v22.18.0
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: }
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: code: 'ERR_DLOPEN_FAILED'
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: at Object..js (node:internal/modules/cjs/loader:1820:10) {
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: at Module._compile (node:internal/modules/cjs/loader:1688:14)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: at Object.<anonymous> (/opt/iobroker/node_modules/socketcan/dist/socketcan.js:51:26)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: at require (node:internal/modules/helpers:135:16)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: at Module.require (node:internal/modules/cjs/loader:1445:12)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.026	error	Caught by controller[0]: at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.025	error	Caught by controller[0]: at TracingChannel.traceSync (node:diagnostics_channel:322:14)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.025	error	Caught by controller[0]: at Function._load (node:internal/modules/cjs/loader:1246:12)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.025	error	Caught by controller[0]: at Module.load (node:internal/modules/cjs/loader:1423:32)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.025	error	Caught by controller[0]: at Object..node (node:internal/modules/cjs/loader:1846:18)
      host.iobrokerpi4b
      	2025-08-17 17:28:23.025	error	Caught by controller[0]: Error: Module did not self-register: '/opt/iobroker/node_modules/socketcan/build/Release/can.node'.
      host.iobrokerpi4b
      	2025-08-17 17:28:23.025	error	Caught by controller[0]: ^
      host.iobrokerpi4b
      	2025-08-17 17:28:23.025	error	Caught by controller[0]: return process.dlopen(module, path.toNamespacedPath(filename));
      host.iobrokerpi4b
      	2025-08-17 17:28:23.025	error	Caught by controller[0]: node:internal/modules/cjs/loader:1846
      host.iobrokerpi4b
      	2025-08-17 17:28:21.579	info	instance system.adapter.e3oncan.0 in version "0.10.9" started with pid 662310
      host.iobrokerpi4b
      	2025-08-17 17:28:19.832	info	"system.adapter.e3oncan.0" enabled
      

      Hast Du Tips, was man da tun kann?

      posted in Tester
      BertDerKleine
      BertDerKleine
    • RE: E-Ink OpenEpaperLink - JSON-Steuerung per Javascript

      @rene55 sagte in E-Ink OpenEpaperLink - JSON-Steuerung per Javascript:

      @bertderkleine Danke für den guten Ansatz mit dem Script. Beschreibst du auch noch die Vorgehensweise mit den Schriften?

      Gerne.
      Zuerst lade und installiere zwei kostenlose Programme:
      FontForge: https://fontforge.org/en-US/downloads/
      und
      Processing: https://processing.org/download

      Schritt 1: Entscheide Dich für irgendeine .ttf Schriftartendatei auf Deinem Rechner, die Dir gefällt für die Ausgabe auf dem Display.

      Schritt 2: Lösche die überflüssigen Glyphen mit Fontforge.

      • Starte FontForge und öffne die TTF-Datei.
      • Wähle im Menü "Codierung / Compact", um leere Plätze auszublenden.
      • Markiere mit Maus Anklicken oder Maus drüberziehen überflüssige Glyphen. Mit "Shift" kann man getrennte Mehrfachauswahlen machen, was sonst unter Windows eher bei "Strg" geht.
      • Wähle Rechtsklick / "Löschen".
      • Wähle im Menü "Element / Schrift - Informationen", um die Schrift mit einem neuen eindeutigen Namen zu versehen, der sie von der Quelle unterscheidet.
      • Wähle im Menü "Datei / Schriften erstellen", um die reduzierte Datei als TrueType zu speichern.

      Schritt 3: Installiere die neue Schriftart zumindest temporär auf Deinem System für den Schritt 4. Danach kannst Du sie wieder löschen. Unter Windows geht das mit Rechtsklick / Installieren über der TTF-Datei.

      Schritt 4: Wandle die TTF in VLW um mit Processing

      • Starte Processing.
      • Wähle im Menü "Tools / Schrift erstellen"
      • Wähle die eben erstellte und installierte Schriftart, die Zielgröße und den Zieldateinamen.
        Drücke "OK"
      • Optional: Diesen Export mit verschiedenen Zielgrößen wiederholen.

      Fertig!

      Nun nur noch ins "fonts" Verzeichnis des AP mit dem Filebrowser des WebUI des AP hochladen.

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: E-Ink OpenEpaperLink - JSON-Steuerung per Javascript

      P.S.: Ich habe öfter eine Schriftart "Nolo", wie "Nolo90" verwendet in dem Beispielskript. Das ist einfach eine gut lesbare Schriftart, die ich selbst reduziert auf die nötigen Zeichen und dann in das VLW Format konvertiert habe; und anschliessend natürlich auf den AP ins "fonts" Verzeichnis hochgeladen.
      Bei sehr großen Schriften wie "90" ist es wichtig, nicht zu viele Glyphen zu haben, da sonst im Pixelformat die VLW-Datei riesig wird.
      Geht aber alles in 5 min umzusetzen, da die Software dafür ja simpel zu bedienen ist.
      Ich habe mir einfach Nolo20, ... , Nolo80, Nolo90 gebaut und hochgeladen und gut ist. Zusammen knapp 1.050 kB. Im Filesystem sind dann immer noch 4MB frei.

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • E-Ink OpenEpaperLink - JSON-Steuerung per Javascript

      Nachdem die meisten OEPL Steuerungen anscheinend über den Weg der Screenshots mit Puppeteer gehen, hier mal mein Ansatz über JSONs.

      Mein Puppeteer Skript habe ich hierdurch ersetzt und bin sehr zufrieden damit.

      Mittels der Konfigurationsblöcke kann ich sehr simpel umsetzen, was ich mag und jeder Tag hat seine eigene Zeitsteuerung. Ich habe mal ein paar Varianten reinkopiert, die ich durchgespielt habe.

      Vielleicht hilfts ja jemandem. ☺

      /**
       * ############################################################################
       *  OpenEPaperLink – vollautomatische ePaper-Steuerung mit Zeitschaltung
       *  und Signalbildern für Fenster- / Tür-Status, realisiert über JSON-Templates
       * ############################################################################
       *
       *  Im August 2025 von BertDerKleine
       *
       *  Zweck
       *  =====
       *  Dieses Skript versorgt alle registrierten OpenEPaperLink-Tags (WLAN-ePaper-
       *  Displays) zyklisch mit aktuellen Daten aus ioBroker.  Durch konfigurierbare
       *  Zeitfenster und individuelle Update-Intervalle wird die Batterielaufzeit
       *  maximal geschont.  Neu hinzugekommen ist die Möglichkeit, einfache
       *  „Signalbilder“ einzublenden: anhand eines Boolean-Datenpunktes wird
       *  automatisch zwischen zwei Icon-Dateien (z. B. offen / geschlossen)
       *  gewechselt.
       *  Ziel war es, eine Lösung via JSON-Templates hinzubekommen, ohne den Umweg
       *  über Screenshots mit Puppeteer. U.a. umgeht dies das Problem, das Puppeteer
       *  immer nur eine Sache gleichzeitig tun kann, was zu Konflikten führen kann,
       *  wenn man viele Tags aktualisieren muss. 
       *
       *  Ablauf im Überblick
       *  -------------------
       *  1.  Konstanten am Kopf definieren Display-Größe und Access-Point.
       *  2.  In `tagConfig` pro Tag eintragen:
       *        – MAC-Adresse
       *        – Anzeige-Titel
       *        – Update-Intervall in Minuten
       *        – ZeitFenster (z. B. „07:00-23:00“)
       *        – body: Array aller anzuzeigenden Elemente
       *  3.  `starteTagUpdates()` startet für jeden Tag ein eigenes Intervall
       *      und führt sofort ein erstes Update aus.
       *  4.  `aktualisiereTag()` prüft das ZeitFenster, baut das JSON zusammen
       *      und sendet es per HTTP-POST an den Access-Point.
       *
       *  Element-Typen
       *  -------------
       *  •  Text:             { dp: 'pfad/zum/Datenpunkt', font: 'Nolo90', … }
       *  •  Fortschrittsbalken: { type: 'progressBar', dp: '…', fillColor: 2, … }
       *  •  Bild:             { image: { filename: '/Bild.jpg', x: 10, y: 20 } }
       *  •  Signalbild:       { type: 'signalImage',
       *                          dp: 'alias.0.Fenster_Kueche',
       *                          images: { true: '/offen.jpg', false: '/zu.jpg' },
       *                          x, y, imageWidth, imageHeight, label, … }
       *
       *  Voraussetzungen
       *  ---------------
       *  • ioBroker mit JavaScript-Adapter
       *  • Node-Modul „luxon“ (nur für zuverlässige Sommer-/Winterzeit)
       *      npm install luxon
       *  • Bild- und Icon-Dateien liegen im Root des Access-Points als 8bit sRGB JPGs
       *    rein schwarz, weiss und rot.
       *  ############################################################################
       */
      
      const http          = require('http');
      const querystring   = require('querystring');
      const { DateTime }  = require('luxon');
      
      /* --------------------------------------------------------------------------
       *  Globale Konstanten
       * -------------------------------------------------------------------------- */
      const AP_IP               = '192.168.178.233';   // IP des OpenEPaperLink-AP
      const BILDSCHIRM_BREITE   = 296;
      const BILDSCHIRM_HÖHE     = 152;
      const TITEL_BALKEN_HÖHE   = 20;
      const TITEL_SCHRIFT       = 'calibrib16';
      
      /* --------------------------------------------------------------------------
       *  Tag-Konfiguration
       *  Jeder Eintrag definiert exakt ein ePaper-Display.
       * -------------------------------------------------------------------------- */
      // Konfiguration der Tags mit MAC-Adresse, Titel, Update-Intervall, Zeitfenster und Inhalt
      const tagConfig = [
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für DG Außentemperatur 
          title: 'Aussentemperatur DG', // Titel, der auf dem Tag angezeigt wird
          updateIntervalMinutes: 30, // Update alle 30 Minuten
          ZeitFenster: '07:00-23:00', // Updates zwischen 07:00 und 23:00 (Europe/Berlin)
          body: [
            // Temperatur mit großer Schrift, linksbündig
            { dp: 'alias.0.Aussentemperatur_kombiniert', font: 'Nolo90', color: 1, suffix: '°C', x: 10, y: 40, decimalPlaces: 1 },
            // Regenmenge pro Tag, unten links
            { dp: 'alias.0.Regen_pro_Tag', font: 'bahnschrift30', color: 2, suffix: 'mm', x: 5, y: 127, decimalPlaces: 1 },
            // Luftfeuchtigkeit, rechtsbündig unten
            { dp: 'alias.0.Luftfeuchtigkeit_Gartenhaus', font: 'bahnschrift30', color: 1, prefix: 'LF ', suffix: '%', x: 296, y: 115, align: 2, decimalPlaces: 0 }
          ]
        },
        
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für Waage 
          title: 'Waage', 
          updateIntervalMinutes: 10, 
          ZeitFenster: '06:30-12:00', 
          body: [
            // Körpergewicht mit großer Schrift, linksbündig
            { dp: 'alias.0.Körpergewicht', font: 'Nolo70', color: 1, suffix: ' kg', x: 10, y: 40, decimalPlaces: 2 },
            // Widerstand, unten links
            { dp: 'alias.0.Körperwiderstand', font: 'bahnschrift30', color: 2, suffix: 'Ohm', x: 5, y: 127, decimalPlaces: 0 },
            // BMI, rechtsbündig unten
            { dp: 'alias.0.BMI', font: 'bahnschrift30', color: 1, prefix: 'BMI: ', suffix: '', x: 296, y: 115, align: 2, decimalPlaces: 1 }
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für die Kalendervorschau
          title: 'Kalender',
          updateIntervalMinutes: 120,
          ZeitFenster: '07:00-23:00',
          body: [
            // Kalendertext, oben links
            { dp: 'alias.0.Kalendervorschau', font: 'bahnschrift20', color: 1, x: 0, y: 25 }
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für Akku-Status
          title: 'Akku-Status',
          updateIntervalMinutes: 30,
          ZeitFenster: '07:00-23:00',
          body: [
            // Akku-Prozentsatz, rechtsbündig
            { dp: 'alias.0.Akku_Ladezustand', font: 'Nolo90', color: 1, suffix: '%', x: BILDSCHIRM_BREITE, y: 40, align: 2, decimalPlaces: 0 },
            // Fortschrittsbalken für Akku, unten
            { dp: 'alias.0.Akku_Ladezustand', type: 'progressBar', fillColor: 2, height: 32, y: BILDSCHIRM_HÖHE - 32 }
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für Stromwerte
          title: 'Stromwerte',
          updateIntervalMinutes: 60,
          ZeitFenster: '07:00-23:00',
          body: [
            { image: { filename: '/Sonne.jpg', x: 10, y: 25 } },
            // PV-Erzeugung, rechtsbündig
            { dp: 'sourceanalytix.0.alias__0__PV_Erzeugungszählerstand.currentYear.consumed.01_currentDay', font: 'bahnschrift30', color: 1, prefix: 'PV: ', suffix: ' kWh', x: BILDSCHIRM_BREITE, y: 28, align: 2, decimalPlaces: 1 },
            // Netzbezug, rechtsbündig
            { dp: 'sourceanalytix.0.alias__0__Netzbezugszählerstand.currentYear.consumed.01_currentDay', font: 'bahnschrift30', color: 2, prefix: 'Bezug: ', suffix: ' kWh', x: BILDSCHIRM_BREITE, y: 58, align: 2, decimalPlaces: 1 },
            // Netzeinspeisung, rechtsbündig
            { dp: 'sourceanalytix.0.alias__0__Netzeinspeisezählerstand.currentYear.delivered.01_currentDay', font: 'bahnschrift30', color: 1, prefix: 'Einsp.: ', suffix: ' kWh', x: BILDSCHIRM_BREITE, y: 88, align: 2, decimalPlaces: 1 },
            // Verbrauch, rechtsbündig
            { dp: 'sourceanalytix.0.alias__0__Verbrauchszaehlerstand.currentYear.consumed.01_currentDay', font: 'bahnschrift30', color: 1, prefix: 'Verbr.: ', suffix: ' kWh', x: BILDSCHIRM_BREITE, y: 118, align: 2, decimalPlaces: 1 }
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für Wasserverbrauch
          title: 'Wasserverbrauch',
          updateIntervalMinutes: 45,
          ZeitFenster: '07:00-23:00',
          body: [
            { image: { filename: '/Wasser.jpg', x: 10, y: 25, } },
            { dp: 'alias.0.Tages-Wasserverbrauch', font: 'Nolo90', color: 1, prefix: '', suffix: ' l', x: BILDSCHIRM_BREITE, y: 50, align: 2, decimalPlaces: 0 },
          ]
        },
        {
          mac: '0000AABBCCDDEEFF', // MAC-Adresse des Tags für offene Fenster/Türen
          title: 'Fensterstatus',
          updateIntervalMinutes: 15,
          ZeitFenster: '07:00-23:00',
          body: [
            // Reihe 1 von links nach rechts; die verwendeten Signalbilder sind 48x48 Pixel gross
            { type: 'signalImage', dp: 'alias.0.Fenster_Küche', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 38, y: 22, imageWidth: 48, imageHeight: 48, label: 'Küche', labelColor: 1, labelSpacing: 2 },
            { type: 'signalImage', dp: 'alias.0.Fenster_Wohnzimmer', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 124, y: 22, imageWidth: 48, imageHeight: 48, label: 'Wohnzimmer', labelColor: 1, labelSpacing: 2 },
            { type: 'signalImage', dp: 'alias.0.Fenster_Keller', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 210, y: 22, imageWidth: 48, imageHeight: 48, label: 'Keller', labelColor: 1, labelSpacing: 2 },
      
            // Reihe 2 von links nach rechts
            { type: 'signalImage', dp: 'alias.0.Fenster_Gäste-WC', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 38, y: 82, imageWidth: 48, imageHeight: 48, label: 'Gäste-WC', labelColor: 1, labelSpacing: 2 },
            { type: 'signalImage', dp: 'alias.0.Tür_Terrasse', images: { true: '/door-open48.jpg', false: '/door-closed48.jpg' }, x: 124, y: 82, imageWidth: 48, imageHeight: 48, label: 'Terrassentür', labelColor: 1, labelSpacing: 2 },
            { type: 'signalImage', dp: 'alias.0.Fenster_Garage', images: { true: '/window_open48.jpg', false: '/window_closed48.jpg' }, x: 210, y: 82, imageWidth: 48, imageHeight: 48, label: 'Garage', labelColor: 1, labelSpacing: 2 }
          ]
        }
      ];
      
      /* ############################################################################
       *  Hilfsfunktionen
       * ############################################################################ */
      
      /**
       * Prüft, ob die aktuelle Zeit im konfigurierten Zeitfenster liegt.
       * @param {string} ZeitFenster - Zeitfenster im Format "HH:mm-HH:mm" (z. B. "07:00-23:00").
       * @returns {boolean} - True, wenn die aktuelle Zeit im Zeitfenster liegt, sonst false.
       */
      function istImZeitFenster(ZeitFenster) {
        const jetzt = DateTime.now().setZone('Europe/Berlin');
        const [von, bis] = ZeitFenster.split('-').map(t => {
          const [h, m] = t.split(':').map(Number);
          return jetzt.set({ hour: h, minute: m, second: 0, millisecond: 0 });
        });
        return bis < von ? (jetzt >= von || jetzt <= bis) : (jetzt >= von && jetzt <= bis);
      }
      
      /**
       * Konvertiert eine Zeitangabe (HH:mm) in Minuten seit Mitternacht für Vergleiche.
       * @param {string} ZeitStr - Zeit im Format "HH:mm".
       * @returns {number} - Minuten seit Mitternacht.
       */
      function zeitZuMinuten(ZeitStr) {
        const [h, m] = ZeitStr.split(':').map(Number);
        return h * 60 + m;
      }
      
      /**
       * Erstellt die JSON-Elemente für die Titelleiste (Hintergrund + Text).
       * @param {string} titelText - Text, der in der Titelleiste erscheinen soll.
       * @returns {Array} - Array mit JSON-Elementen (box + text).
       */
      function titelElementeErzeugen(titelText) {
        const mitteX = Math.floor(BILDSCHIRM_BREITE / 2);
        return [
          { box: [0, 0, BILDSCHIRM_BREITE, TITEL_BALKEN_HÖHE, 1, 1, 1] },
          { text: [mitteX, 3, titelText, `fonts/${TITEL_SCHRIFT}`, 0, 1] }
        ];
      }
      
      /**
       * Verarbeitet ein einzelnes Anzeige-Element und liefert das dafür nötige JSON.
       * Erkannt werden:
       *  – Signalbilder (signalImage)
       *  – normale Bilder (image)
       *  – Texte (dp oder fester text)
       *  – Fortschrittsbalken (progressBar)
       *
       * @param {Object} item - Konfiguration des Elements
       * @returns {Object|Array} - JSON-Objekt oder Array von Objekten für die Darstellung
       */
      async function elementAuflösen(item) {
        /* ---------- Signalbild mit optionalem Label ---------- */
        if (item.type === 'signalImage') {
          const status = await getStateAsync(item.dp);
          const bild   = (status && status.val) ? item.images.true : item.images.false;
          const result = [{ image: [bild, item.x || 0, item.y || 0] }];
          if (item.label) {
            const labelX = (item.x || 0) + Math.floor((item.imageWidth || 48) / 2);
            const labelY = (item.y || 0) + (item.imageHeight || 48) + (item.labelSpacing || 2);
            result.push({ text: [labelX, labelY, item.label, 'tahoma11', item.labelColor || 1, 1] });
          }
          return result;
        }
      
        /* ---------- Normales Bild ---------- */
        if (item.image) {
          const { filename, x = 0, y = 0 } = item.image;
          return { image: [filename, x, y] };
        }
      
        /* ---------- Text & Balken ---------- */
        let wert = '';
        if (item.dp) {
          const state = await getStateAsync(item.dp);
          wert = (state && state.val != null) ? state.val : '';
          if (typeof wert === 'number' || !isNaN(parseFloat(wert))) {
            const stellen = typeof item.decimalPlaces === 'number' ? item.decimalPlaces : 2;
            wert = parseFloat(wert).toLocaleString('de-DE', { minimumFractionDigits: stellen, maximumFractionDigits: stellen });
          } else {
            wert = String(wert);
          }
        } else if (typeof item.text === 'string') {
          wert = item.text;
        }
      
        if (item.type === 'progressBar') {
          const prozent = parseFloat(wert) || 0;
          const breite  = Math.round(Math.max(0, Math.min(100, prozent)) / 100 * BILDSCHIRM_BREITE);
          const yPos    = typeof item.y === 'number' ? item.y : BILDSCHIRM_HÖHE - (item.height || 32);
          return { box: [0, yPos, breite, item.height || 32, item.fillColor || 2, item.fillColor || 2, item.fillColor || 2] };
        }
      
        if (item.prefix) wert = item.prefix + wert;
        if (item.suffix) wert = wert + item.suffix;
      
        const x      = typeof item.x === 'number' ? item.x : 0;
        const y      = typeof item.y === 'number' ? item.y : 0;
        const schrift = item.font || 'bahnschrift20';
        const farbe   = typeof item.color === 'number' ? item.color : 1;
        const textArr = [x, y, wert, schrift, farbe];
        if (typeof item.align === 'number') textArr.push(item.align);
        return { text: textArr };
      }
      
      /* ############################################################################
       *  HTTP-Sender
       * ############################################################################ */
      
      /**
       * Sendet das fertige JSON-Array an den OpenEPaperLink-Access-Point.
       * @param {string} mac        - MAC-Adresse des Tags
       * @param {Array}  jsonArray  - Vollständiges JSON-Array für das Display
       * @param {string} titel      - Nur für Logging/Console-Ausgabe
       * @returns {Promise}         - Resolves bei Erfolg, rejects bei Netzwerkfehler
       */
      function sendeAnTag(mac, jsonArray, titel) {
        const postData = querystring.stringify({ mac, json: JSON.stringify(jsonArray) });
        const options  = {
          hostname: AP_IP,
          port: 80,
          path: '/jsonupload',
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(postData)
          }
        };
      
        return new Promise((resolve, reject) => {
          const req = http.request(options, res => {
            let data = '';
            res.on('data', c => data += c);
            res.on('end', () => {
              console.log(`✅ "${titel}" (${mac}) → AP-Antwort: "${data.trim() || 'leer'}"`);
              resolve();
            });
          });
          req.on('error', e => {
            console.error(`❌ "${titel}" (${mac}) → HTTP-Fehler: ${e.message}`);
            reject(e);
          });
          req.write(postData);
          req.end();
        });
      }
      
      /* ############################################################################
       *  Update-Logik
       * ############################################################################ */
      
      /**
       * Aktualisiert ein einzelnes Tag, sofern die aktuelle Zeit im konfigurierten
       * Zeitfenster liegt.  Bei Erfolg wird das fertige JSON an den AP gesendet.
       * @param {Object} tag - Ein Eintrag aus tagConfig
       * @returns {Promise}  - Resolves bei Erfolg oder wenn außerhalb des Zeitfensters
       */
      async function aktualisiereTag(tag) {
        if (!istImZeitFenster(tag.ZeitFenster)) {
          console.log(`⏸️  "${tag.title}" (${tag.mac}) außerhalb des Zeitfensters ${tag.ZeitFenster}`);
          return;
        }
      
        const json = [{ clear: [1] }, ...titelElementeErzeugen(tag.title)];
        for (const item of tag.body) {
          const ergebnis = await elementAuflösen(item);
          Array.isArray(ergebnis) ? json.push(...ergebnis) : json.push(ergebnis);
        }
        await sendeAnTag(tag.mac, json, tag.title);
      }
      
      /**
       * Startet für jeden Tag ein eigenes setInterval und führt sofort ein erstes
       * Update aus.  So kann sich jeder Tag unabhängig aktualisieren.
       */
      function starteTagUpdates() {
        for (const tag of tagConfig) {
          const intervallMs = tag.updateIntervalMinutes * 60 * 1000;
          setInterval(() => aktualisiereTag(tag).catch(e =>
            console.error(`Fehler bei ${tag.title}: ${e.message}`)), intervallMs);
          aktualisiereTag(tag).catch(e =>
            console.error(`Erstes Update fehlgeschlagen bei ${tag.title}: ${e.message}`));
        }
      }
      
      /* ############################################################################
       *  Start
       * ############################################################################ */
      starteTagUpdates();
      
      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: E-INK Display OpenEPaperLink - Displayanzeige mit Batterie

      So, jetzt habe ich einen Spaghetti AP zusammengebastelt und eine handvoll Displays und konnte aus den theoretischen mal praktische Übungen machen.

      Dabei stiess ich auf einen bösen Stolperstein bei der Hardware:
      Es gibt nämlich beim ESP32-S3 Teile, die auf den ersten Block genau passend ausschauen von den Specs, es aber dann doch nicht sind, Beispiel: https://de.aliexpress.com/item/1005009621440783.html
      Wenn man es weiss, erkennt man die nicht passende Hardware daran, dass es keinen GPIO Pin #20 gibt (und die Pins alle anders sortiert sind).

      Frage jetzt zur Ansteuerung des Displays:
      Die Firmware bietet ja eine "copy" Funktion. Irgendwie bekomme ich die aber nicht zum Fliegen.
      a) gibts dazu irgendwelche Doku Links?
      b) konkret gefragt: in welchem Format gibt man hier die MAC-Adresse ein? Also eher "00112233..." oder "00:11:22:33..."?

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: E-INK Display OpenEPaperLink - Displayanzeige mit Batterie

      Hallo,
      eben mal das Blockly aus Beitrag #274 (https://forum.iobroker.net/topic/66380/e-ink-display-openepaperlink-displayanzeige-mit-batterie/274) versucht laufen zu lassen.
      Das führt aber nur zu Fehler:

      javascript.0	19:04:21.885	warn	request package is deprecated - please use httpGet (or a stable lib like axios) instead!
      
      javascript.0	19:04:21.918	error	    at Object.<anonymous> (script.js.08_E-Ink_Displays.Bild_an_OpenEpaperLink_Tags_senden:41:13)
      

      Hat jemand ein Blockly, das heute noch läuft?

      Mit JS habe ich mir auch was hingefrickelt, aber ein Blockly, das Stand heute noch läuft wäre super.

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: Erfahrung: Hoymiles MS-A2 Akku via MQTT iobroker steuern

      @assz sagte in Erfahrung: Hoymiles MS-A2 Akku via MQTT iobroker steuern:

      @bertderkleine
      Wollte nur andere User mit solch einem Vorhaben über das gegenseitige Speichergeschaukel im Vorfeld informieren.
      system runs bug-free 😉

      Wenn's gut läuft, magst Du das Skript hier als Anregung für andere posten?

      posted in Einbindung von Geräten
      BertDerKleine
      BertDerKleine
    • RE: Shelly Pro 3EM saldierender Stromzähler in Blockly

      @paul53 Hallo, cih bin gerade über diesen Thread hier gestolpert, weil ich auch eine Herausforderung mit meinem Shelly Pro 3 EM habe. Diese ist verwandt, aber anders als das bisher hier diskutierte:

      Mein Shelly sitzt nämlich nicht dort, wo der offizielle Zählerwerkelt, sondern er ist bewusst so eingebaut, dass er nur die hausinternen Verbraucher zählt, d.h. er ignoriert und kennt nicht die Leistung, die vom Dach kommt, sondern die längste Zeit hat er rein den Verbrauch im Haus gemessen.

      Nebenbei: Es gibt einen IR-Lesekopf-Zähler auf dem Zähler des Netzbetreibers, wo ich Einspeise- und Bezugszählerstände ablese und der auch die aktuelle Leistung in Summe (unter Berücksichtigung PV) kennt.

      Bisher klappte das wunderbar.

      Seitdem ich haber am Hausnetz einen Hyomiles Speicher habe, "spinnt" der Shelly Verbrauchszählerstand (zu hoch), den ich per mQTT aus dem DP "TotalActiveEnergy" ziehe.

      Das ganze hat also Null mit den PV-Sachen zu tun und würde genauso doof laufen ganz ohne PV. Es tritt auf, weil der Speicher (den ich ja einfach aus dem Netz aufladen kann) irgendwann beim Entladen "negative" Leistungen auf einer Phase erzeugt. Der Shelly hantiert seltsam mit TotalActiveEnergy und TotalActiveReturnEnergy.

      Auch wenn ich es nicht ganz blicke, scheint die Problemursache hier skizziert zu sein: https://community.simon42.com/t/shellypro3em-balkonkraftwerk-ins-energiedashboard/33080/4

      Hat jemand sowas schon mal gelöst für iobroker oder eine Idee, wie man es lösen könnte?

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo