Navigation

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

    NEWS

    • Monatsrückblick – September 2025

    • Neues Video "KI im Smart Home" - ioBroker plus n8n

    • Neues Video über Aliase, virtuelle Geräte und Kategorien

    • Profile
    • Following 0
    • Followers 0
    • Topics 68
    • Posts 314
    • Best 20
    • Groups 2

    BertDerKleine

    @BertDerKleine

    Starter

    21
    Reputation
    65
    Profile views
    314
    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
    • KI schreibt erfolgreich iobroker Blockly XML

      Ich möchte hier kurz darauf hinweisen, dass ich eben eine Skripting Fragestellung per KI (ChatGPT) gelöst habe, was wenig überraschend ist.

      Das besondere ist aber, dass die KI mir dann aktiv angeboten hat, das ganze in Blockly als XML zu übergeben und ich dieses XML dann tatsächlich erfolgreich im iobroker importieren konnte.
      Natürlich hatte ich dem Ding vorher erläutert, dass es um iobroker geht und ich eigentlich mit Blockly arbeite.

      Ich kannte bisher so Pseudocodebeschreibungen und Versuche, es als XML auszudrücken, die dann scheiterten beim Import.

      Also habe ich bisher immer selbst die Übersetzung in Blockly gemacht.

      Das war jetzt zwar nur ein triviales winziges Skript, aber immerhin. Das spart so schon Arbeit.

      posted in Skripten / Logik
      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

    Latest posts made by BertDerKleine

    • RE: Erfahrung: Hoymiles MS-A2 Akku via MQTT iobroker steuern

      @opöl sagte in Erfahrung: Hoymiles MS-A2 Akku via MQTT iobroker steuern:

      @bertderkleine ,

      vielen Dank für Deine Erklärungen. Eine Frage hätte ich noch. Du schriebst:

      „Die Wattwächter-Daten emulieren via Uni-Meter-Emulatorsoftware einen Shelly, den der Speicher dann erkennt und für Steuersignale nutzt.“

      Wo läuft die Uni-Meter Software und wird ein/mein Hichi WLAN IR Sensor genauso als Shelly erkannt wie Dein Wattwächter, also out of the box ohne zusätzliche HW/SW?

      Danke und Gruß

      Schau hier: https://github.com/sdeigm/uni-meter

      Bei mir läuft das auf demselben Raspi wie iobroker als Java.

      Die Portnutzung ist zu beachten und man braucht halt ein passendes Konfigurationsfile.

      Das Rumprobieren für genau Dein Setup wird eher unvermeidbar sein. Aber schau Dich im Netz um, da gibt es schon viele ausprobiere Kombis.

      posted in Einbindung von Geräten
      BertDerKleine
      BertDerKleine
    • RE: Erfahrung: Hoymiles MS-A2 Akku via MQTT iobroker steuern

      @opöl sagte in Erfahrung: Hoymiles MS-A2 Akku via MQTT iobroker steuern:

      @bertderkleine ,
      sehr interessanter Beitrag.
      Wenn ich Dich recht verstehe, betreibst Du den Speicher „stand alone“, also nur am Netz, ohne angeschlossene PV Anlage als „Powerbank“.

      Ohne kleines Balkopanel, ja. Den Strom erzeugen PV-Panels auf dem Dach ohne direkte Verkabelung zum Speicher.

      Zur Verbrauchsmessung nutzt Du einen IR Sensor (Hichi IR Sensor?) am Zähler.

      Ein Wattwächter, was quasi das gleiche ist, nur out-of-the Box benutzerfreundlich in Betrieb zu nehmen.

      Dann könnte ich den Verbrauch am Zähler über meinen Hichi erfassen und via iobroker und Java Script die Ladung und Entladung (nur über das Hausnetz) steuern.

      Korrekt.
      Wobei ich selbst aktuell in diesem Setup aktuell die aktive Steuerung (eher aus Bequemlichkeit) wieder der eingebauten Logik übertragen habe und MQTT nur zum Daten-Auslesen nutze.
      Die Wattwächter-Daten emulieren via Uni-Meter-Emulatorsoftware einen Shelly, den der Speicher dann erkennt und für Steuersignale nutzt.
      Für mein Setup reicht das aus.

      Das ließe dann (theoretisch) auch den Betrieb mehrerer Speicher sowie eine Nulleinspeisung zu.
      Ist das so grob richtig oder bin ich irgendwo komplett falsch abgebogen?
      Korrekt.

      Die "Nulleinspeisung" geht auf beide Wege.

      Der Betrieb komplexerer Logiken wie disjunkte Speicher oder das, was weiter oben diskutiert wurde hier im Thread, geht natürlich out of the box mit der eingebauten Steuerung nicht. Da spielt dann eine persönlich ausgestaltete Steuerung über iobroker ihre Stärken aus. Dafür ist das hier beschrieben: damit man es nach Gusto so formt, wie man es braucht.

      Zwei baugleiche 2kWh Speicher kann man natürlich auch mit der internen Steuerung einfach in Reihe schalten plug-and-play. Erst wenn man noch mehr will oder die unbedingt an unterschiedlichen Orten aufgestellt werden sollen, muss man zwingend selbst eine Steuerung schreiben in iobroker.

      posted in Einbindung von Geräten
      BertDerKleine
      BertDerKleine
    • RE: Regelmässiger Historienexport als Excel-Tabelle

      @klassisch sagte in Regelmässiger Historienexport als Excel-Tabelle:

      • Nachkommastellen pro Spalte konfigurierbar

      Warum? Bei meinen Python Scripts habe ich das einfach so in XLS geschrieben wie es ist und in xls dann die Nachbearbeitung gemacht.

      Klar geht das, aber jetzt wollte ich es direkt so haben, wie es am Ende aussehen soll. Wenn man mal dran ist ...

      • optionaler Multiplikator z.B. um von m3 auf Liter zu kommen

      Auch das ist in xls bequemer, denke ich.

      Bequemer absolut, aber wie gesagt, ich wollte es jetzt direkt rund haben,

      • optionales Auffüllen von Leerfeldern mit Nullen

      Das habe ich nicht verstanden. Welche Leerfelder?

      Bei manchen Datenpunkten, wie "Regen" gibt es halt an manchen Tagen gar keine Daten. Da kann es besser sein, eine Null statt einer Lücke zu haben. Ist aber eh optional.

      • Probleme mit vielen Daten für den Ganzjahresexport sind behoben

      Gibt es da Beschränkungen mit der Datenmenge oder Rechenleistung?

      Ich habe alte Datenreihen, die amfangs noch viel zu viele Datenänderungen aufgezeichnet hatten, was pro Tag sehr viele Einträge erzeugt. Und das Skript saugt sich ja für das vorgegebene Zeitfenster alles rein. Bei einem Jahr war der Puffer zu schnell voll und spätere Tage blieben leer. Jetzt ist der Puffer größer und es wird in Salamitaktik gearbeitet.

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: Regelmässiger Historienexport als Excel-Tabelle

      @klassisch
      Danke. Ich habe jetzt das Skript oben nochmal aktualisiert.
      Neuerungen:

      • Hinweise bzgl. des npm Moduls korrigiert. Jetzt wird empfohlen, exceljs lokal über den Eintrag in der Instanz zu hinterlegen, nicht mehr global per Kommandozeile
      • Nachkommastellen pro Spalte konfigurierbar
      • optionaler Multiplikator z.B. um von m3 auf Liter zu kommen
      • optionales Auffüllen von Leerfeldern mit Nullen
      • die Einheitennahmen aus den Datenpunkten werden jetzt in die Zellformatierung übernommen, so dass es netter zu lesen ist
      • Probleme mit vielen Daten für den Ganzjahresexport sind behoben
      • über den gesonderten DP "0_userdata.0.VollJahresDaten" kann man jetzt 1,2 oder 3 ganze Jahre gesamthaft auswerfen lassen. Solange der DP auf Null steht, läuft das normale monatliche Modell, sonst einfach 1,2 oder 3 eintragen.

      Ich denke, jetzt ist es schön rund. 🙂

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: Regelmässiger Historienexport als Excel-Tabelle

      @bahnuhr sagte in Regelmässiger Historienexport als Excel-Tabelle:

      Frage:
      Warum npm ?
      Müsste es nicht reichen "exceljs" bei javascript in der Instanz einzutragen.

      Ehrlicherweise muss ich sagen, ich habs einfach gemacht ohne Nachzudenken. Ich hatte mal ein Skript nachgebaut, wo ich was in die Instanz eintragen sollte und bei dem schien das doch völlig egal zu sein. Später war es bei einem anderen Fall so, dass esnur per Installation auf Kommandozeile klappt, nicht in der Instanz des Adapters.
      Ende vom Lied ist, dass ich es gar nicht mehr versucht habe.
      Vermutlich werde ich das nochmal umstellen später.

      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • Regelmässiger Historienexport als Excel-Tabelle

      Hallo,
      hier ein recht banaler Anwendungsfall. Ich möchte gerne für einige Datenpunkte auch außerhalb von iobroker bestimmte Kerndaten haben, um damit z.B. in Excel rumspielen zu können.

      Dabei will ich nicht jedes Datenfragment aus der History-DB pro Datenpunkt haben, sondern mir reicht hier ein Wert pro Tag, i.d.R. der Höchste Zählerstand eines Wertes.

      Das ganze will ich einfach automatisch einmal pro Monat zugesendet bekommen per Email.

      Als Zusatzfeature, das ich über einen extra Datenpunkt steuern kann, kann das Ding auch sofort ein ganzes Jahr in dieser Form exportieren.

      Vielleicht habt Ihr ja ähnliche Anforderungen, dann könnt Ihr hierdrauf aufsetzen.

      Ich hoffe, alles ist hinreichend sprechend und auskommentiert, dass es gut lesbar ist.
      Das Logging kann man ja leicht entfernen, wenn es nervt. 🙂

      /**
       * ================================================================
       * 📊 IOBROKER MONATLICHER HISTORIEN-BERICHT ALS EXCEL PER E-MAIL
       * ================================================================
       *
       * 🎯 ZWECK DES SKRIPTS:
       * Dieses Skript erstellt automatisch am Anfang jedes Monats eine Excel-Datei
       * mit allen Tageswerten des VORMONATS für konfigurierte Datenpunkte und sendet sie per E-Mail.
       * Alternativ kann es auch manuell gestartet werden, dann werden die Daten des AKTUELLEN Monats ausgegeben.
       * Bei Bedarf kann auch ein Jahresbericht (365 Tage) erstellt werden.
       *
       * ✅ WAS ES TUT:
       * 1. Liest Email-Absender und -Empfänger aus konfigurierbaren Datenpunkten.
       * 2. Ermittelt automatisch den richtigen Zeitraum (Vormonat, aktueller Monat oder 365 Tage).
       * 3. Holt für jeden konfigurierten Datenpunkt die Historie des Zeitraums.
       * 4. Aggregiert die Werte pro Tag (konfigurierbar pro Spalte).
       * 5. Wendet optional Multiplikator an (z. B. 1000 für Liter statt m³).
       * 6. Legt fest, wieviele Nachkommastellen verwendet werden.
       * 7. Kann leere Werte mit 0 auffüllen (optional).
       * 8. Erstellt eine ECHTE Excel-Datei (.xlsx) mit formatierter Tabelle.
       * 9. Sendet die Excel-Datei per E-Mail mit konfigurierbarem Betreff.
       *
       *  Gebastelt 2025 von BertDerKleine
       * 
       * 🧩 KONFIGURIERBAR:
       * - Liste der Datenpunkte mit:
       *   - id: Datenpunkt-Name
       *   - agg: 'max|min|avg|sum'
       *   - spaltenName: Anzeigename in Excel
       *   - nachkommastellen: Anzahl der Nachkommastellen (optional, default: 2)
       *   - multiplikator: Faktor für Multiplikation (optional, default: 1)
       *   - fuellenMitNull: Ob leere Werte mit 0 gefüllt werden sollen (optional, default: false)
       *
       * 📥 VORAUSSETZUNGEN:
       * - History-Adapter (history.0, sql.0, etc.) muss aktiv sein
       * - Email-Adapter (email.0) muss konfiguriert und verbunden sein
       * - Folgende Konfigurations-Datenpunkte müssen existieren:
       *   - 0_userdata.0.Email-Absender (string)
       *   - 0_userdata.0.Email-Empfaenger (string)
       *   - 0_userdata.0.Email-Betreff (string)
       *   - 0_userdata.0.VollJahresDaten (zahl: 0,1,2,3 Bei 0 läuft das Skript normal, bei 1/2/3 werden die Daten von 1-3 Jahren ausgegeben)
       *   - exceljs-Library muss installiert sein:
       *   → Im ioBroker JavaScript-Adapter in den Instanzeinstellungen unter
       *      "additional npm modules" eintragen: "exceljs"
       *
       * 📤 AUSGABE:
       * - Echte Excel-Datei (.xlsx) mit formatierter Tabelle
       * - Datum im Format TT.MM.JJJJ
       * - Zahlen als echte Excel-Zahlen (kein Text)
       * - Automatische Spaltenbreite
       * - Abwechselnde Zeilenfarben (Zebra-Stripes)
       * - Auto-Filter in der Kopfzeile
       * - Zwei Blätter: Daten + Zusammenfassung
       *
       * 🚀 AUTOMATISIERUNG:
       * Plane dieses Skript am 1. jedes Monats um 00:05 Uhr:
       *
       * ================================================================
       * 🔧 KONFIGURATION – HIER ANPASSEN!
       * ================================================================
       */
      
      // ✅ exceljs-Library laden (muss installiert sein: exceljs in "additional npm modules")
      try {
          const ExcelJS = require('exceljs');
          log('✅ ExcelJS erfolgreich geladen!', 'info');
      } catch (e) {
          log(`❌ Fehler beim Laden von ExcelJS: ${e.message}`, 'error');
          log('💡 Lösung: ExcelJS in den Instanzeinstellungen des JavaScript-Adapters unter "additional npm modules" hinzufügen', 'error');
          return;
      }
      
      const ExcelJS = require('exceljs');
      
      // Liste der zu verarbeitenden Datenpunkte
      // Jeder Eintrag: { id: '...', agg: 'max|min|avg|sum', spaltenName: '...', nachkommastellen?: number, multiplikator?: number, fuellenMitNull?: boolean }
      const Datenpunkte = [
          { id: 'alias.0.Aussentemperatur', agg: 'max', spaltenName: 'Höchste Aussentemperatur', nachkommastellen: 1, multiplikator: 1, fuellenMitNull: false },
          { id: 'alias.0.Aussentemperatur', agg: 'min', spaltenName: 'Niedrigste Aussentemperatur', nachkommastellen: 1, multiplikator: 1, fuellenMitNull: false },
          { id: 'alias.0.Regen', agg: 'max', spaltenName: 'Regenmenge', nachkommastellen: 1, multiplikator: 1, fuellenMitNull: true },
          { id: 'alias.0.GasH', agg: 'max', spaltenName: 'Gas für Heizung', nachkommastellen: 1, multiplikator: 1, fuellenMitNull: true },
          { id: 'alias.0.GasW', agg: 'max', spaltenName: 'Gas für Warmwasser', nachkommastellen: 1, multiplikator: 1, fuellenMitNull: true },
          { id: 'statistics.0.save.sumDelta.alias.0.Wasser.day', agg: 'max', spaltenName: 'Wasserverbrauch', nachkommastellen: 0, multiplikator: 1000, fuellenMitNull: true }, // in Liter
          { id: 'statistics.0.save.sumDelta.alias.0.PV_Erzeugung.day', agg: 'max', spaltenName: 'Strom-PV-Erzeugung', nachkommastellen: 0, multiplikator: 1, fuellenMitNull: false },
          { id: 'statistics.0.save.sumDelta.alias.0.Netzbezug.day', agg: 'max', spaltenName: 'Strom-Netzbezug', nachkommastellen: 2, multiplikator: 1, fuellenMitNull: false },
          { id: 'statistics.0.save.sumDelta.alias.0.Netzeinspeisung.day', agg: 'max', spaltenName: 'Strom-Netzeinspeisung', nachkommastellen: 2, multiplikator: 1, fuellenMitNull: false },
          { id: 'statistics.0.save.sumDelta.0_userdata.0.Verbrauch.day', agg: 'max', spaltenName: 'Strom-Verbrauch', nachkommastellen: 2, multiplikator: 1, fuellenMitNull: false }
      ];
      
      // Datenpunkte für Email-Konfiguration
      const EmailAbsenderDatenpunkt = '0_userdata.0.Email-Absender';
      const EmailEmpfaengerDatenpunkt = '0_userdata.0.Email-Empfaenger';
      const EmailBetreffDatenpunkt = '0_userdata.0.Email-Betreff';
      const VollJahresDatenDatenpunkt = '0_userdata.0.VollJahresDaten'; // "YES" oder "NO"
      
      // Adapter-Instanzen (anpassen, falls abweichend)
      const EmailAdapterInstanz = 'email.0';
      const HistoryAdapterInstanz = 'history.0'; // z. B. 'sql.0', 'influxdb.0'
      
      // Globale Variablen (lokal im Skript)
      let alleAggregiertenDaten = {};
      let sortierteTage = [];
      
      /**
       * ================================================================
       * HILFSFUNKTIONEN
       * ================================================================
       */
      
      function formatiereDatumFuerExcel(datum) {
          const jahr = datum.getFullYear();
          const monat = (datum.getMonth() + 1).toString().padStart(2, '0');
          const tag = datum.getDate().toString().padStart(2, '0');
          return `${tag}.${monat}.${jahr}`;
      }
      
      function bereinigeWerte(werte) {
          return werte.filter(wert => wert !== null && wert !== undefined && !isNaN(wert));
      }
      
      // Funktion: Historische Daten abrufen (optimiert für lange Zeiträume)
      async function holeHistorie(id, start, ende) {
          // ✅ Schätzung: wie viele Werte könnten es sein?
          const geschätzteTage = Math.ceil((ende.getTime() - start.getTime()) / (24 * 60 * 60 * 1000));
          const geschätzteWerteProTag = 150; // Anpassen je nach deinen Daten
          const geschätzteAnzahl = geschätzteTage * geschätzteWerteProTag;
          
          // ✅ Sicherstellen, dass genug Werte abgerufen werden
          const count = Math.min(200000, Math.max(50000, geschätzteAnzahl)); // Max 200.000, Min 50.000
      
          return new Promise((resolve, reject) => {
              sendTo(HistoryAdapterInstanz, 'getHistory', {
                  id: id,
                  options: { 
                      start: start.getTime(), 
                      end: ende.getTime(), 
                      aggregate: 'none', 
                      count: count 
                  }
              }, (ergebnis) => {
                  if (!ergebnis || !ergebnis.result || ergebnis.error) {
                      reject(new Error(ergebnis?.error || 'Unbekannter Fehler beim History-Abruf'));
                  } else {
                      resolve(ergebnis.result);
                  }
              });
          });
      }
      
      // Funktion: Einheit aus Datenpunkt auslesen
      function leseEinheitAusDatenpunkt(dpId) {
          try {
              const obj = getObject(dpId);
              if (obj && obj.common && obj.common.unit) {
                  return obj.common.unit;
              }
          } catch (e) {
              log(`⚠️ Fehler beim Lesen der Einheit von ${dpId}: ${e.message}`, 'warn');
          }
          return ''; // Falls keine Einheit vorhanden
      }
      
      /**
       * ================================================================
       * HAUPTPROGRAMM: EXCEL EXPORT
       * ================================================================
       */
      
      async function HauptprogrammExcelExport() {
          try {
              log('🚀 Starte Monatsbericht...', 'info');
              
              // ✅ Email-Konfiguration aus Datenpunkten lesen
              const absenderState = getState(EmailAbsenderDatenpunkt);
              const empfaengerState = getState(EmailEmpfaengerDatenpunkt);
              const betreffState = getState(EmailBetreffDatenpunkt);
              const vollJahresState = getState(VollJahresDatenDatenpunkt);
      
              if (!absenderState || !absenderState.val) {
                  log(`❌ Email-Absender-Datenpunkt "${EmailAbsenderDatenpunkt}" nicht gefunden oder leer!`, 'error');
                  return;
              }
              if (!empfaengerState || !empfaengerState.val) {
                  log(`❌ Email-Empfänger-Datenpunkt "${EmailEmpfaengerDatenpunkt}" nicht gefunden oder leer!`, 'error');
                  return;
              }
              if (!betreffState || !betreffState.val) {
                  log(`❌ Email-Betreff-Datenpunkt "${EmailBetreffDatenpunkt}" nicht gefunden oder leer!`, 'error');
                  return;
              }
      
              const emailAbsender = absenderState.val.toString();
              const emailEmpfaenger = empfaengerState.val.toString();
              const emailBetreff = betreffState.val.toString();
              const vollJahresDaten = vollJahresState?.val?.toString().toUpperCase();
      
              // ✅ Neue Jahresausgabe-Steuerung
              let jahreZurueck = 0; // Standard: normaler Modus
              if (vollJahresDaten === '1' || vollJahresDaten === '2' || vollJahresDaten === '3') {
                  jahreZurueck = parseInt(vollJahresDaten, 10);
              }
      
              log(`✅ Email von: ${emailAbsender} → an: ${emailEmpfaenger}`, 'info');
              log(`✅ Betreff: ${emailBetreff}`, 'info');
              log(`✅ Jahresausgabe-Modus: ${jahreZurueck > 0 ? jahreZurueck + ' Jahre' : 'Normal'}`, 'info');
      
              // ✅ Zeitraum berechnen
              const jetzt = new Date();
              let startDatum, endDatum;
      
              if (jahreZurueck > 0) {
                  // X Jahre zurück
                  startDatum = new Date(jetzt);
                  startDatum.setFullYear(startDatum.getFullYear() - jahreZurueck);
                  startDatum.setHours(0, 0, 0, 0);
                  endDatum = new Date(jetzt);
                  endDatum.setHours(23, 59, 59, 999);
                  log(`📅 Zeitraum: Letzte ${jahreZurueck} Jahr(e) (${startDatum.toLocaleDateString()} bis ${endDatum.toLocaleDateString()})`, 'info');
              } else {
                  // Prüfen, ob automatisch (1. des Monats) oder manuell
                  const istAutomatisch = jetzt.getDate() === 1 && jetzt.getHours() === 0 && jetzt.getMinutes() <= 10;
                  
                  if (istAutomatisch) {
                      // Vormonat
                      startDatum = new Date(jetzt.getFullYear(), jetzt.getMonth() - 1, 1);
                      endDatum = new Date(jetzt.getFullYear(), jetzt.getMonth(), 0);
                      endDatum.setHours(23, 59, 59, 999);
                      log(`📅 Zeitraum: Vormonat (${startDatum.toLocaleDateString()} bis ${endDatum.toLocaleDateString()})`, 'info');
                  } else {
                      // Aktueller Monat (manueller Start)
                      startDatum = new Date(jetzt.getFullYear(), jetzt.getMonth(), 1);
                      endDatum = new Date(jetzt);
                      endDatum.setHours(23, 59, 59, 999);
                      log(`📅 Zeitraum: Aktueller Monat (${startDatum.toLocaleDateString()} bis heute)`, 'info');
                  }
              }
      
              // ✅ Für jeden Datenpunkt Historie abrufen + aggregieren
              alleAggregiertenDaten = {}; // Lokale Variable
      
              for (const dp of Datenpunkte) {
                  log(`⏳ Verarbeite Datenpunkt: ${dp.id} → Spalte: "${dp.spaltenName}" (Aggregation: ${dp.agg})`, 'info');
      
                  let historieDaten;
                  try {
                      // ✅ Dynamische Anzahl von Werten basierend auf Zeitraum
                      const geschätzteTage = Math.ceil((endDatum.getTime() - startDatum.getTime()) / (1000 * 60 * 60 * 24));
                      const geschätzteAnzahl = geschätzteTage * 10; // Annahme: max. 10 Werte pro Tag
                      const count = Math.max(20000, geschätzteAnzahl);
      
                      historieDaten = await holeHistorie(dp.id, startDatum, endDatum); // Kein count mehr
                  } catch (fehler) {
                      log(`⚠️ Fehler beim Abruf von ${dp.id}: ${fehler.message}`, 'warn');
                      continue;
                  }
      
                  if (!historieDaten || historieDaten.length === 0) {
                      log(`⚠️ Keine Daten für ${dp.id} gefunden.`, 'warn');
                      continue;
                  }
      
                  // Gruppieren nach Tag
                  const gruppiertNachTag = {};
                  historieDaten.forEach(eintrag => {
                      if (eintrag && eintrag.val !== null && !isNaN(eintrag.val)) {
                          const eintragDatum = new Date(eintrag.ts);
                          const tagSchluessel = `${eintragDatum.getFullYear()}-${(eintragDatum.getMonth() + 1).toString().padStart(2, '0')}-${eintragDatum.getDate().toString().padStart(2, '0')}`;
                          if (!gruppiertNachTag[tagSchluessel]) gruppiertNachTag[tagSchluessel] = [];
                          gruppiertNachTag[tagSchluessel].push(eintrag.val);
                      }
                  });
      
                  // Pro Tag aggregieren
                  for (const [tagSchluessel, werte] of Object.entries(gruppiertNachTag)) {
                      const bereinigteWerte = bereinigeWerte(werte);
                      if (bereinigteWerte.length === 0) continue;
      
                      let aggregierterWert;
                      const aggTyp = (dp.agg || 'max').toLowerCase();
      
                      switch (aggTyp) {
                          case 'max':
                              aggregierterWert = Math.max(...bereinigteWerte);
                              break;
                          case 'min':
                              aggregierterWert = Math.min(...bereinigteWerte);
                              break;
                          case 'avg':
                              aggregierterWert = bereinigteWerte.reduce((summe, wert) => summe + wert, 0) / bereinigteWerte.length;
                              break;
                          case 'sum':
                              aggregierterWert = bereinigteWerte.reduce((summe, wert) => summe + wert, 0);
                              break;
                          default:
                              log(`⚠️ Unbekannter Aggregationstyp "${aggTyp}" für ${dp.id}. Nutze 'max'.`, 'warn');
                              aggregierterWert = Math.max(...bereinigteWerte);
                      }
      
                      // Multiplikator anwenden
                      aggregierterWert = aggregierterWert * (dp.multiplikator || 1);
      
                      // Eindeutigen Schlüssel erstellen
                      const eindeutigerSchluessel = `${dp.id}__${dp.agg}__${dp.spaltenName}`;
                      if (!alleAggregiertenDaten[tagSchluessel]) alleAggregiertenDaten[tagSchluessel] = {};
                      alleAggregiertenDaten[tagSchluessel][eindeutigerSchluessel] = aggregierterWert;
                  }
              }
      
              if (Object.keys(alleAggregiertenDaten).length === 0) {
                  log('❌ Keine Daten für irgendeinen Datenpunkt gefunden!', 'error');
                  return;
              }
      
              // ✅ Sortierte Tage
              sortierteTage = Object.keys(alleAggregiertenDaten).sort();
      
              log(`✅ Daten für ${sortierteTage.length} Tage aggregiert.`, 'info');
      
              // ✅ Excel-Datei erstellen
              const excelBase64 = await erstelleExcelDatei();
              log('✅ Excel-Datei mit formatierter Tabelle erfolgreich erstellt.', 'info');
      
              // ✅ Intelligenter Dateiname
              const zeitstempel = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
              let dateiname;
              if (jahreZurueck > 0) {
                  dateiname = `${jahreZurueck}-Jahresbericht_${zeitstempel}.xlsx`;
              } else {
                  // Prüfen, ob automatisch (1. des Monats) oder manuell
                  const jetzt = new Date();
                  const istAutomatisch = jetzt.getDate() === 1 && jetzt.getHours() === 0 && jetzt.getMinutes() <= 10;
                  if (istAutomatisch) {
                      dateiname = `Vormonatsbericht_${zeitstempel}.xlsx`;
                  } else {
                      dateiname = `Monatsbericht_${zeitstempel}.xlsx`;
                  }
              }
      
              // ✅ E-Mail senden
              sendeEmailMitAnhang(excelBase64, dateiname, emailAbsender, emailEmpfaenger, emailBetreff);
      
              // ✅ Timer bereinigen (ohne Skript zu beenden)
              setTimeout(() => {
                  log('✅ Aktuelle Ausführung beendet - Scheduler bleibt aktiv', 'info');
                  // Timer bereinigen
                  for (let i = 1; i < 1000; i++) {
                      clearTimeout(i);
                      clearInterval(i);
                  }
              }, 3000);
      
          } catch (fehler) {
              log(`❌ Fehler im Hauptskript: ${fehler.message}`, 'error');
          }
      }
      
      // Funktion: Echte Excel-Datei mit formatierter Tabelle erstellen
      async function erstelleExcelDatei() {
          try {
              log('⏳ Erstelle Excel-Datei...', 'info');
              
              // Erstelle ein neues Workbook
              const workbook = new ExcelJS.Workbook();
      
              // ✅ Dynamischen Tabellennamen erstellen
              let tabellenName = "Daten";
              if (sortierteTage.length > 0) {
                  const erstesDatum = sortierteTage[0];
                  const [jahr, monat] = erstesDatum.split('-');
                  tabellenName = `Daten ${jahr}-${monat.padStart(2, '0')}`;
              }
      
              // ✅ Arbeitsblatt erstellen
              const worksheet = workbook.addWorksheet(tabellenName);
      
              // Header-Zeile
              const ueberschriften = ['Datum', ...Datenpunkte.map(dp => dp.spaltenName)];
              worksheet.addRow(ueberschriften);
      
              // ✅ Daten sammeln für Tabelle
              const tabellenDaten = [];
      
              // Datenzeilen
              for (const tagSchluessel of sortierteTage) {
                  const teile = tagSchluessel.split('-').map(Number);
                  const datumObj = new Date(teile[0], teile[1] - 1, teile[2]);
                  const zeile = [formatiereDatumFuerExcel(datumObj)];
      
                  for (let dpIndex = 0; dpIndex < Datenpunkte.length; dpIndex++) {
                      const dp = Datenpunkte[dpIndex];
                      const eindeutigerSchluessel = `${dp.id}__${dp.agg}__${dp.spaltenName}`;
                      let wert = alleAggregiertenDaten[tagSchluessel]?.[eindeutigerSchluessel];
      
                      if (wert !== undefined) {
                          // ✅ ACHTUNG: Multiplikator wurde bereits in Hauptfunktion angewendet!
                          // Hier nur noch Nachkommastellen anwenden
                          const nachkommastellen = dp.nachkommastellen !== undefined ? dp.nachkommastellen : 2;
                          wert = parseFloat(wert.toFixed(nachkommastellen));
                          zeile.push(wert);
                      } else {
                          // Auffüllen mit Null, wenn konfiguriert
                          if (dp.fuellenMitNull) {
                              zeile.push(0);
                          } else {
                              zeile.push(null);
                          }
                      }
                  }
                  worksheet.addRow(zeile);
                  tabellenDaten.push(zeile);
              }
      
              log(`✅ ${sortierteTage.length} Datenzeilen vorbereitet`, 'info');
      
              // ✅ ECHTE EXCEL-TABELLE ERSTELLEN
              if (tabellenDaten.length > 0) {
                  worksheet.addTable({
                      name: 'DatenTabelle',
                      ref: 'A1',
                      headerRow: true,
                      totalsRow: false,
                      style: {
                          theme: 'TableStyleMedium2',
                          showRowStripes: true,
                          showColumnStripes: false
                      },
                      columns: ueberschriften.map(name => ({ name: name, filterButton: true })),
                      rows: tabellenDaten
                  });
              }
      
              // ✅ Spaltenbreiten und Zahlenformate
              worksheet.columns.forEach(column => {
                  column.width = 20;
              });
      
              // Zahlenformate für Daten-Spalten (ab Spalte B)
              for (let i = 1; i < ueberschriften.length; i++) {
                  const dp = Datenpunkte[i - 1]; // i-1 weil erste Spalte Datum ist
                  const nachkommastellen = dp.nachkommastellen !== undefined ? dp.nachkommastellen : 2;
                  const einheit = leseEinheitAusDatenpunkt(dp.id);
                  const column = worksheet.getColumn(i + 1); // +1 weil Excel-Spalten bei A=1 beginnen
                  column.numFmt = nachkommastellen === 0 
                      ? `0 " ${einheit}"` 
                      : `0.${'0'.repeat(nachkommastellen)} " ${einheit}"`;
              }
      
              // ✅ Zweites Blatt: Zusammenfassung
              const zusammenfassungBlatt = workbook.addWorksheet('Zusammenfassung');
      
              // Überschrift in Zelle A1
              const titelZelle = zusammenfassungBlatt.getCell('A1');
              titelZelle.value = 'Zusammenfassung';
              titelZelle.font = { bold: true, size: 14, color: { argb: 'FFFFFFFF' } };
              titelZelle.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF4472C4' } };
      
              // Leerzeile in A2
              zusammenfassungBlatt.getCell('A2').value = '';
      
              // Header-Zeile in Zeile 3
              const headerZellen = ['A3', 'B3', 'C3', 'D3', 'E3'];
              const headerWerte = ['Datenpunkt', 'Minimum', 'Maximum', 'Durchschnitt', 'Summe'];
              
              for (let i = 0; i < headerZellen.length; i++) {
                  const zelle = zusammenfassungBlatt.getCell(headerZellen[i]);
                  zelle.value = headerWerte[i];
                  zelle.font = { bold: true };
                  zelle.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFD9E1F2' } };
              }
      
              // Daten für Zusammenfassung sammeln und eintragen
              let aktuelleZeile = 4; // Start ab Zeile 4
              
              for (let i = 0; i < Datenpunkte.length; i++) {
                  const dp = Datenpunkte[i];
                  
                  // Werte sammeln und bereinigen
                  const werte = [];
                  for (const tag of sortierteTage) {
                      const eindeutigerSchluessel = `${dp.id}__${dp.agg}__${dp.spaltenName}`;
                      let val = alleAggregiertenDaten[tag]?.[eindeutigerSchluessel];
                      if (val !== undefined && val !== null && !isNaN(val)) {
                          // ✅ ACHTUNG: Multiplikator wurde bereits in Hauptfunktion angewendet!
                          // Hier nur noch Nachkommastellen anwenden
                          const nachkommastellen = dp.nachkommastellen !== undefined ? dp.nachkommastellen : 2;
                          val = parseFloat(val.toFixed(nachkommastellen));
                          werte.push(val);
                      }
                  }
      
                  if (werte.length === 0) {
                      log(`🔍   Keine gültigen Werte für ${dp.spaltenName}`, 'warn');
                      continue;
                  }
      
                  // Berechnungen
                  const min = Math.min(...werte);
                  const max = Math.max(...werte);
                  const avg = werte.reduce((sum, val) => sum + val, 0) / werte.length;
                  const summe = werte.reduce((sum, val) => sum + val, 0);
      
                  // Werte direkt in Zellen schreiben
                  zusammenfassungBlatt.getCell(`A${aktuelleZeile}`).value = dp.spaltenName;
                  zusammenfassungBlatt.getCell(`B${aktuelleZeile}`).value = min;
                  zusammenfassungBlatt.getCell(`C${aktuelleZeile}`).value = max;
                  zusammenfassungBlatt.getCell(`D${aktuelleZeile}`).value = avg;
                  zusammenfassungBlatt.getCell(`E${aktuelleZeile}`).value = summe;
      
                 // Zahlen formatieren
                  for (let col of ['B', 'C', 'D', 'E']) {
                      const zelle = zusammenfassungBlatt.getCell(`${col}${aktuelleZeile}`);
                      const nachkommastellen = dp.nachkommastellen !== undefined ? dp.nachkommastellen : 2;
                      const einheit = leseEinheitAusDatenpunkt(dp.id);
                      zelle.numFmt = nachkommastellen === 0 
                          ? `0 " ${einheit}"` 
                          : `0.${'0'.repeat(nachkommastellen)} " ${einheit}"`;
                  }
      
                  aktuelleZeile++;
              }
      
              // Falls keine Daten gefunden wurden
              if (aktuelleZeile === 4) {
                  zusammenfassungBlatt.getCell('A4').value = 'Keine Daten verfügbar';
                  zusammenfassungBlatt.getCell('A4').font = { italic: true, color: { argb: 'FF808080' } };
              }
      
              // Spaltenbreiten für Zusammenfassung
              for (let col of ['A', 'B', 'C', 'D', 'E']) {
                  zusammenfassungBlatt.getColumn(col).width = 20;
              }
      
              // ✅ IN BINÄREN BUFFER UMWANDELN
              const uint8Array = await workbook.xlsx.writeBuffer();
              const buffer = Buffer.from(uint8Array);
              const base64 = buffer.toString('base64');
              
              log('✅ Excel-Datei erfolgreich erstellt', 'info');
              return base64;
      
          } catch (fehler) {
              log(`❌ Fehler beim Erstellen der Excel-Datei: ${fehler.message}`, 'error');
              log(`❌ Stack: ${fehler.stack}`, 'error');
              throw fehler;
          }
      }
      
      // Funktion: E-Mail senden
      function sendeEmailMitAnhang(excelBase64, dateiname, absenderAdresse, empfaengerAdresse, betreff) {
          const text = `Hallo,\n\nIm Anhang findest du den monatlichen Aggregationsbericht als formatierte Excel-Tabelle.\n\nAutomatisch generiert von ioBroker.\nDatum: ${new Date().toLocaleString()}`;
      
          sendTo(EmailAdapterInstanz, {
              from: absenderAdresse,
              to: empfaengerAdresse,
              subject: betreff,
              text: text,
              attachments: [{
                  filename: dateiname,
                  content: excelBase64,
                  encoding: 'base64',
                  contentType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
              }]
          }, (fehler, ergebnis) => {
              if (fehler && typeof fehler === 'object' && fehler.result && fehler.result.includes('250')) {
                  log(`✅ E-Mail erfolgreich gesendet (Server: ${fehler.result})`, 'info');
              } else if (fehler) {
                  log(`❌ E-Mail-Fehler: ${JSON.stringify(fehler)}`, 'error');
              } else {
                  log(`✅ E-Mail mit Anhang "${dateiname}" gesendet.`, 'info');
              }
          });
      }
      
      /**
       * ================================================================
       * SCHEDULE + MANUELLEN START
       * ================================================================
       */
      
      // Zeitplanung: 1. Tag jedes Monats um 00:05 Uhr
      schedule('5 0 1 * *', HauptprogrammExcelExport);
      
      // Manueller Start: Nur wenn Skript neu geladen wird und Adapter schon läuft
      if (existsState('system.adapter.javascript.0.uptime') && 
          getState('system.adapter.javascript.0.uptime').val > 60) {
          log('🔁 Manueller Start des Skripts erkannt', 'info');
          setTimeout(HauptprogrammExcelExport, 2000); // Kleine Verzögerung für sicheres Starten
      }
      
      log('✅ Skript geladen - bereit für manuellen oder zeitgesteuerten Start', 'info');
      
      posted in Praktische Anwendungen (Showcase)
      BertDerKleine
      BertDerKleine
    • RE: [gelöst] Zeitsteuerung Javascript versus UI?

      @paul53 sagte in Zeitsteuerung Javascript versus UI?:

      @bertderkleine sagte: Javaskript, das ich (z.B. zum Testen aber auch sonst) gerne einfach manuell auslösen will ohne viel Brimborium. Ansonsten soll es aber i.d.R. automatisch zeitgesteueuert am Monatsersten ablaufen.

      Das macht man mit einer Funktion, die sowohl zu Monatsbeginn als auch bei Skriptstart aufgerufen wird.

      function actions() {
          // Aktionen 
      }
      
      schedule('5 0 1 * *', actions); // Ausführen zu Monatsbeginn
      
      actions(); // Ausführen bei Skriptstart
      

      Die Funktion wird allerdings auch bei Neustart der Javascript-Instanz ausgeführt, was man verhindern kann:

      function actions() {
          // Aktionen 
      }
      
      schedule('5 0 1 * *', actions); // Ausführen zu Monatsbeginn
      
      if(getState('system.adapter.javascript.0.uptime').val > 60) actions(); // Ausführen bei Skriptstart
      

      Super, danke! Das hat geholfen.

      posted in Skripten / Logik
      BertDerKleine
      BertDerKleine
    • [gelöst] Zeitsteuerung Javascript versus UI?

      Ich bräuchte mal Grundverständnis bzgl. einer Zeitsteuerung eines Javascripts.

      Hintergrund: Ich habe ein Javaskript, das ich (z.B. zum Testen aber auch sonst) gerne einfach manuell auslösen will ohne viel Brimborium. Ansonsten soll es aber i.d.R. automatisch zeitgesteueuert am Monatsersten ablaufen.

      Jetzt sehe ich im iob UI für Javascript a) rechts oben ein Uhr-Symbol, mit dem ich einen Wizard starte für einen CRON-Job.
      Der schreibt mir dann in die erste Zeile des Skriptes

      '{"time":{"exactTime":true,"start":"00:05"},"period":{"months":1,"dates":"[1]"}}'
      

      rein, sonst nix.

      Und ich habe links oben im UI den "play" Button, der das Skript laufen lässt.

      In meinem Fall läuft nach dem Play-Button das Skript einmal durch (während dieser Zeit ändert sich der "play" Button zu einem "Pause" Button) und endet dann (man sieht wieder den "Play"-Button).
      Ich kann nicht erkennen, ob die Zeitsteuerung irgendwie aktiv ist.

      Da ich ursprünglich schon - als die Zeitsteuerung noch nicht eingebaut sein sollte - feststellte, dass der manuelle Aufruf des Skripts, das Ding weiter sinnlos "laufen" lässt (erkennbar an dem "Pause"-Button), habe ich ein hartes Beenden des Skripts eingebaut, damit ich nicht selbst immer per Hand abbrechen muss.

      function beendeSkript() {
          log('✅ Beende Skript jetzt...', 'info');
          const maxHandles = 1000;
          for (let i = 1; i < maxHandles; i++) {
              clearTimeout(i);
              clearInterval(i);
          }
          if (typeof stopScript === 'function') stopScript();
          if (typeof process !== 'undefined' && process.exit) process.exit(0);
      }
      

      Ich mutmasse, das das jetzt verhindert, dass eine Zeitsteuerung aktiv ist.

      Fragen:

      1. Woran erkennt man, ob ein Skript aktuell auf eine Zeitsteuerung wartet?
      2. Ist die eine Zeile aus dem Wizard mit den einfachen Anführungszeichen ausreichend für eine Zeitsteuerung?
      3. Muss das Skript "laufen", also der UI-Button als "Pause"-Version sichtbar, damit eine Zeitsteuerung greift?
      4. Was wäre die beste Lösung, um die von mir oben beschriebene Kombination von optional manuellem Aufruf und Zeitsteuerung hinzubekommen?
      posted in Skripten / Logik
      BertDerKleine
      BertDerKleine
    • RE: Erfahrung: Hoymiles MS-A2 Akku via MQTT iobroker steuern

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

      Einzig bei Lastwechsel (E-Herd) ist noch nicht so zufriedenstellend 😉
      Irgendwie ist der Speicher zu langsam. Habe überschuss, speicher lädt, Last vom E-Herd geht rein, Speicher speist noch ein, obwohl Fremdbezug ist.

      Lastwechsel sind so ein Ding, denn die Steuerung soll ja tatsächlich gedämpft reagieren und nicht wild oszillieren.
      Da musst Du Dein Optimum durch ausprobieren finden.
      Du kannst das Samplingintervall etwas runtersetzen um mehr daten schneller zu bekommen und den Integralfaktor raufsetzen.
      Außerdem kannst Du mit der Schrittweite spielen (Zeile 254). Das ist aktuell auf 30% begrenzt.

      Ich habe hier auch mal die hardware-integrierte Logik über Unimeter-Emulation laufen gelassen und die ist zwar schneller in der Anpassung als das Skript oben mit den vorgeschlagenen Parametern, aber z.B. Wasserkocher sind dem auch eher zu schnell da und wieder weg.

      Am Ende bleibt daher nur Ausprobieren für das persönliche Verbrauchsprofil.

      Wenn Du bessere Parameter findest, kannst Du sie ja hier teilen.

      posted in Einbindung von Geräten
      BertDerKleine
      BertDerKleine
    • RE: KI schreibt erfolgreich iobroker Blockly XML

      @oliverio sagte in KI schreibt erfolgreich iobroker Blockly XML:

      @bertderkleine

      Die Programmier Fähigkeiten von ChatGPT 5
      Sind noch mal um einiges gegenüber 4 gestiegen.

      Bisher hatte ich tatsächlich eine negative Einschätzung von GPT-5, weil es wirklich noch viel falsch machte für einfache Programmieraufgaben.
      Aber an iobroker Blockly XMLs beissen sich die KIs sonst alle komplett die Zähle aus.

      posted in Skripten / Logik
      BertDerKleine
      BertDerKleine
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo