Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. ioBroker Allgemein
    4. Mit Blockly mehrere DP in ein influxDB Measurement schreiben

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Mit Blockly mehrere DP in ein influxDB Measurement schreiben

    This topic has been deleted. Only users with topic management privileges can see it.
    • P
      prorun last edited by

      Hi, ich möchte mit Blockly zwei Datenpunkte in ein influxDB Measurement schreiben.

      mit folgender Vorlage arbeite ich.

      @legro said in Daten nur einmal täglich in Influxdb schreiben:

      Hier ein Beispiel, wie ich das mit meinem Gasverbrauch geregelt habe ..

      201e54f1-f21c-4faf-9556-0efebf7e0644-image.png

      sendTo('influxdb.0', 'storeState', {
          id: ziel,
          state: {ts: zeit, val: wert, ack: false, from: ziel}
      }, result => console.log('added'));
      

      Ergebnis:
      195f6229-d2f8-454a-9d48-1eddd0e4f04c-image.png

      Nun möchte ich aber zwei Datenpunkte in das gleiche Measurement schreiben sodass es wie folgt aussieht:
      45b9629e-fb6e-4fac-bc56-a89a1cbea0b0-image.png

      Folgendes hatte ich ausprobiert. Leider ohne Erfolg:
      73bc24f6-10d7-4532-98bb-61f9e044accb-image.png

      sendTo('influxdb.0', 'storeState', {
          id: ziel,
          state: {ts: zeit, latitude: latitude, longitude: longitude, ack: false, from: ziel}
      }, result => console.log('added'));
      

      Weiß jemand wie der Quelltext des Java-Blockly-Blocks abgeändert werde muss sodass ich zwei Datenpunkte in das gleiche Measurement schreiben kann?

      T Marc Berg 2 Replies Last reply Reply Quote 0
      • T
        TT-Tom @prorun last edited by

        @prorun

        vielleicht hilft das hier weiter

        P 1 Reply Last reply Reply Quote 0
        • P
          prorun @TT-Tom last edited by

          @tt-tom
          Vielen Dank für den Hinweis jedoch wird in all diesen Beispielen immer nur ein Wert pro Measurement übergeben (val: 123). Ich benötige jedoch zwei Fields in diesem einen Measurement.

          Folgendes

          sendTo('influxdb.0', 'storeState', {
              id: ziel,
              state: {ts: zeit, fields: {lati: latitude, longi: longitude}, ack: false, from: ziel}
          }, result => console.log('added'));
          

          funktioniert leider auch nicht.

          T 1 Reply Last reply Reply Quote 0
          • T
            TT-Tom @prorun last edited by

            @prorun

            dann kann ich dir das noch empfehlen, ist zwar nicht Blockly aber sehr gut erklärt.
            Link Text

            P 1 Reply Last reply Reply Quote 1
            • P
              prorun @TT-Tom last edited by

              Ja, per JavaScript klappt es grundsätzlich jedoch bekomme ich in Java die nötigen Bedingen die ich zusätzlich brauche nicht hin.

              Aber vlt kann davon jemand ableiten wie es in Blockly aussehen müsste?

              // v0.1
              const axios = require('axios').default;
               
              const influxDbInstance = 'influxdb.0';
              const token = 'TOKEN';
              const measurement = 'Measurement';
               
              const loggingTemplate = {
                  '0_userdata.0.test-number2': 'latitude',
                  '0_userdata.0.test-number3': 'longitude',
              };
               
              const loggingObj = {};
               
              async function start() {
                  const influxDbInstanceConfig = await getObjectAsync(`system.adapter.${influxDbInstance}`);
               
                  const protocol = influxDbInstanceConfig.native.protocol;
                  const host = influxDbInstanceConfig.native.host;
                  const port = influxDbInstanceConfig.native.port;
                  const org = influxDbInstanceConfig.native.organization;
                  const bucket = influxDbInstanceConfig.native.dbname;
               
                  console.log(`Starting "${measurement}" logging to ${protocol}://${host}:${port} into bucket "${bucket}" by org ${org}`);
               
                  // Init loggingObj with current values
                  for (let [objId, key] of Object.entries(loggingTemplate)) {
                      const state = await getStateAsync(objId);
                      if (state && !isNaN(state.val)) {
                          loggingObj[key] = state.val;
                      } else {
                          loggingObj[key] = 0;
                      }
                  }
               
                  on({ id: Object.keys(loggingTemplate), change: 'ne' }, async (obj) => {
                      // Update value in loggingObj
                      const key = loggingTemplate[obj.id];
                      loggingObj[key] = obj.state.val;
               
                      // Save Data
                      const data = `${measurement} ${Object.keys(loggingObj)
                          .filter(key => !isNaN(loggingObj[key]))
                          .map((key) => `${key}=${loggingObj[key]}`)
                          .join(',')}`;
               
                      if (data) {
                          // console.log(`Saving "${data}" to InfluxDB @ ${protocol}://${host}:${port}/`);
               
                          axios.post(`${protocol}://${host}:${port}/api/v2/write?bucket=${bucket}&org=${org}`, data, {
                              headers: {
                                  'Content-Type': 'text/plain',
                                  'Authorization': `Token ${token}`
                              }
                          }).catch(err => {
                              console.error(err);
                          });
                      }
                  });
              }
              start();
              

              Wenn mir bzgl. des JavaScripts jemand aufzeigen könnte wie ich dafür sorgen kann dass die Abfrage der Datenpunkte (latitude und longitude) verzögert zum trigger erfolgt wäre mein Problem auch gelöst.

              Hintergrund: die Werte latitude und longitude kommen etwas zeitversetzt rein, manchmal nur mit einem Versatz von 2ms, aber das ist ausreichend dass zuerst eine falsche Kombination in die influx geschrieben wird - neue latitude mit altem longitude und 2ms später die richtige Kombination. Ich brauche quasi eine Verzögerungszeit zwischen triggern des Skripts und auslesen der Werte aus den beiden Datenpunkten.

              In Blockly eine Warteschleife mit der entsprechenden Verzögerung zu bauen die unterbrochen wird wenn 2ms später der zweite Wert das skript triggert und dann erst das Auslesen der Datenpunkte erfolgt bekomme ich hin. Das in Java umzusetzen übersteigt jedoch meine java-Kenntnisse.

              1 Reply Last reply Reply Quote 0
              • Marc Berg
                Marc Berg Most Active @prorun last edited by

                @prorun sagte in Mit Blockly mehrere DP in ein influxDB Measurement schreiben:

                Weiß jemand wie der Quelltext des Java-Blockly-Blocks abgeändert werde muss sodass ich zwei Datenpunkte in das gleiche Measurement schreiben kann?

                Du kannst mit dem InfluxDB Adapter nicht mehrere Fields und/oder Tags schreiben, und Blockly setzt meines Wissens nur auf dem Adapter auf.

                @Kamikaze hatte aber ein ähnliches Problem per Skript gelöst:

                https://forum.iobroker.net/post/1092536

                P 1 Reply Last reply Reply Quote 0
                • P
                  prorun @Marc Berg last edited by prorun

                  @marc-berg Schade dass es mit Blockly nicht funktioniert. Dann wäre ich damit besser klargekommen.

                  Habe es jetzt aber per JavaScript gelöst bekommen.

                  Mit folgendem Skript erhält man ein einziges Measurement was latitude und longitude mit exakt gleichen Zeitstempel enthält. Zusätzlich können latitude und longitude zeitversetzt eintrudeln - welcher Wert zuerst kommt ist dabei egal. In diesem Beispiel hier bis zu 10 Sekunden Versatz. Es wird also obwohl latitude und longitude in unterschiedlichen Datenpunkten liegen und bei Änderung beider Werte das Skript 2x triggert (bei Änderung von latitude und noch mal bei Änderung von longitude) immer nur einmal und nur die neuste Kombination der Werte in die influxDB geschrieben.

                  Funktioniert jetzt einwandfrei. Hiermit ist es möglich Koordinaten sauber in der influxDB abzulegen um mit Grafana beispielsweise Routen daraus zu basteln.

                  // v0.2
                  const axios = require('axios').default;
                   
                  const influxDbInstance = 'influxdb.0';
                  const token = 'TOKEN';
                  const measurement = 'GPS-Test';
                   
                  const loggingTemplate = {
                      '0_userdata.0.test-number2': 'lati',
                      '0_userdata.0.test-number3': 'longi',
                  };
                  
                  const loggingObj = {};
                  
                  async function start() {
                      const influxDbInstanceConfig = await getObjectAsync(`system.adapter.${influxDbInstance}`);
                  
                      const protocol = influxDbInstanceConfig.native.protocol;
                      const host = influxDbInstanceConfig.native.host;
                      const port = influxDbInstanceConfig.native.port;
                      const org = influxDbInstanceConfig.native.organization;
                      const bucket = influxDbInstanceConfig.native.dbname;
                  
                      console.log(`Starting "${measurement}" logging to ${protocol}://${host}:${port} into bucket "${bucket}" by org ${org}`);
                  
                      // Init loggingObj with current values
                      for (let [objId, key] of Object.entries(loggingTemplate)) {
                          const state = await getStateAsync(objId);
                          if (state && !isNaN(state.val)) {
                              loggingObj[key] = state.val;
                          } else {
                              loggingObj[key] = 0;
                          }
                      }
                  // Variable für Timeout sodass bei Wiederholung der vorherige Timeout abgebrochen werden kann
                  let timeoutHandler;
                  
                  // Trigger-Bedingung (bei Änderung eines der DP (loggingTemplate))
                  on({ id: Object.keys(loggingTemplate), change: 'ne' }, async (obj) => {
                      // Update value in loggingObj
                      const key = loggingTemplate[obj.id];
                      loggingObj[key] = obj.state.val;
                  
                      // Lösche vorherigen Timeout, falls vorhanden
                      if (timeoutHandler) {
                          clearTimeout(timeoutHandler);
                      }
                  
                      // Setze neuen Timeout
                      timeoutHandler = setTimeout(async () => {
                          // Save Data
                          const data = `${measurement} ${Object.keys(loggingObj)
                              .filter(key => !isNaN(loggingObj[key]))
                              .map((key) => `${key}=${loggingObj[key]}`)
                              .join(',')}`;
                  
                          if (data) {
                              // console.log(`Saving "${data}" to InfluxDB @ ${protocol}://${host}:${port}/`);
                  
                              axios.post(`${protocol}://${host}:${port}/api/v2/write?bucket=${bucket}&org=${org}`, data, {
                                  headers: {
                                      'Content-Type': 'text/plain',
                                      'Authorization': `Token ${token}`
                                  }
                              }).catch(err => {
                                  console.error(err);
                              });
                          }
                      }, 10000); // 10.000 Millisekunden = 10 Sekunden
                  });
                  }
                  start();
                  

                  Uns so hier sieht das ganze dann in Grafana mit dem Widget Geomap aus:
                  2023-12-19 14_21_41-Window.png

                  from(bucket: "iobroker")
                    |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
                    |> filter(fn: (r)   => 
                    r._measurement == "GPS-Test" and 
                    r._field == "lati" or
                    r._field == "longi" )
                    |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
                    |> drop(columns: ["_start", "_stop", "_measurement"])
                  
                  Marc Berg 1 Reply Last reply Reply Quote 0
                  • Marc Berg
                    Marc Berg Most Active @prorun last edited by

                    @prorun
                    Über welchen Mechanismus bekommst du die GPS-Daten rein?

                    P 1 Reply Last reply Reply Quote 0
                    • P
                      prorun @Marc Berg last edited by

                      @marc-berg

                      Unterschiedlich.

                      Fahrzeuge kommen über BMW-Adapter

                      iPhone kommt über zwei iot-services (lati, longi) die über zahlreiche Kurzbefehle (für jede halbe stunde einen), die den aktuellen Standort abfragen, befüttert werden. Leider nicht mehr über den apple-find-me-Adapter 😭
                      Wenn fürs iPhone jemand eine Alternative kennt, immer her damit.

                      Und Android-Geräte habe ich endlich allesamt abgeschafft. Also fast. Meine Frau darf sich Heiligabend freuen - ob sie will oder nicht 😎 😉 😈

                      1 Reply Last reply Reply Quote 1
                      • First post
                        Last post

                      Support us

                      ioBroker
                      Community Adapters
                      Donate
                      FAQ Cloud / IOT
                      HowTo: Node.js-Update
                      HowTo: Backup/Restore
                      Downloads
                      BLOG

                      690
                      Online

                      31.9k
                      Users

                      80.1k
                      Topics

                      1.3m
                      Posts

                      3
                      9
                      696
                      Loading More Posts
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes
                      Reply
                      • Reply as topic
                      Log in to reply
                      Community
                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                      The ioBroker Community 2014-2023
                      logo