Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. script Portainer Api V3.3 - inkl. html Tabelle

    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

    script Portainer Api V3.3 - inkl. html Tabelle

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

      Edit: Header, Text, Scripte :). vielen Dank an alle die mir hier geholfen haben!

      Hallo,
      wie bekomme ich die Daten aus Portainer in den iobroker?

      Edit:
      Hier das, was chatgpt nach einigen Versuchen mir ausgegeben hat, das Javascript fragt die Portainer-Api in regelmaessigen Abstaenden ab, man kann Docker Container starten/stoppen, bekommt bei Aenderungen eine Msg per Discord, und es werden Cpu, Ram, Uptime, Image, IP, Port angezeigt:

      // 📦 Portainer Statusboard Version 3.3
      // by Ilovegym
      // 📜 Änderungsprotokoll
      // - Version 3.3: Mobile Ansicht – CPU/RAM ein-/ausblendbar
      // - Version 3.2: Mobile Ansicht mit Symbolstatus & 2-zeiligem Layout konfigurierbar
      // - Version 3.1: Mobiler Dashboard-Datenpunkt konfigurierbar
      // - Version 3.0: Mobiles Dashboard in Datenpunkt StatusMobile
      // - Version 2.7: Persistenter Theme-Switch
      // - Version 2.6: Persistente Filter und zusätzliche Filterfelder (CPU, RAM, Alter)
      // - Version 2.5: Filter für laufende Container eingebaut
      // - Version 2.4: "Erstellt" zeigt nun Alter in Tagen an
      // - Version 2.3: Alphabetische Standard-Sortierung
      // - Version 2.2: Warn-Icons, Farb-Balken für CPU/RAM, letzter Restart-Zeitpunkt
      // - Version 2.1: CPU und RAM korrekt aus Stats übernommen
      // - Version 2.0: Hinzugefügt: Restarted-Spalte, Tooltip mit IP, Theme-Switch, Sortierung
      // - Version 1.x: Basisfunktion: Containerdatenpunkte, Discord/Telegram Benachrichtigungen, Statusboard
      const exec = require('child_process').exec;
      
      // 🔧 KONFIGURATION
      const mobileLayoutColumns = 1; // 1 = eine Spalte, 2 = zwei Spalten in mobiler Ansicht
      
      const mobileColumnOrder = [
          'name', 'state', 'cpu', 'mem', 'uptime'
      ]; // Spaltenreihenfolge in der mobilen Ansicht
      
      const tableColumnOrder = [
          'name', 'cpu', 'mem', 'state', 'uptime', 'restartedRecently', 'restartAt', 'image', 'created', 'ports'
      ]; // Reihenfolge der Spalten im Statusboard
      
      const username = 'admin';
      const password = 'supergeheimespassword!';
      const portainerHost = 'http://10.10.2.10:9000';
      const endpointId = 2;  //default 1
      const datapointBase = '0_userdata.0.Portainer.Containers.';
      const statusBoardDP = '0_userdata.0.Portainer.Containers.Statusboard';
      const updateIntervalMinutes = 3;
      const mobileStatusDP = '0_userdata.0.Portainer.Containers.StatusMobile';
      const mobileUseSymbol = true;       // true = ✅/❌, false = 'running'
      const mobileShowCPU = true;         // true = CPU in mobiler Ansicht anzeigen
      const mobileShowRAM = true;         // true = RAM in mobiler Ansicht anzeigen
      const mobileTwoLineLayout = true;   // true = Name/Status oben, Details unten
      const discordDP = 'discord.0.xxxx.send'; //bitte anpassen
      
      const discordToggleDP = '0_userdata.0.Portainer.Notify.Discord';
      const telegramToggleDP = '0_userdata.0.Portainer.Notify.Telegram';
      const telegramInstance = 'telegram.0';
      
      // Initiale Schalter
      if (!existsState(discordToggleDP)) {
          createState(discordToggleDP, true, { type: 'boolean', name: 'Discord aktivieren', read: true, write: true });
      }
      if (!existsState(telegramToggleDP)) {
          createState(telegramToggleDP, false, { type: 'boolean', name: 'Telegram aktivieren', read: true, write: true });
      }
      
      function getTokenAndContainers() {
          const loginCmd = `curl -s -H "Content-Type: application/json" -X POST -d '{"Username":"${username}","Password":"${password}"}' ${portainerHost}/api/auth`;
          exec(loginCmd, (error, stdout) => {
              if (error) return log(`❌ Token-Fehler: ${error}`, 'error');
              try {
                  const token = JSON.parse(stdout).jwt;
                  if (!token) return log('❌ Kein Token erhalten', 'error');
                  getContainerList(token);
              } catch (e) {
                  log(`❌ Token-Parsing-Fehler: ${e.message}`, 'error');
              }
          });
      }
      
      function getContainerList(token) {
          const url = `${portainerHost}/api/endpoints/${endpointId}/docker/containers/json?all=1`;
          const cmd = `curl -s -H "Authorization: Bearer ${token}" "${url}"`;
          exec(cmd, (error, stdout) => {
              if (error) return log(`❌ Fehler beim Containerabruf: ${error}`, 'error');
      
              try {
                  const containers = JSON.parse(stdout);
                  const containerList = [];
      
                  containers.forEach(container => {
                      const id = container.Id;
                      const name = container.Names[0].replace(/^\//, '');
                      const dp = `${datapointBase}${name}`;
      
                      const image = container.Image;
                      const createdDate = new Date(container.Created * 1000);
                      const createdDaysAgo = Math.floor((Date.now() - createdDate.getTime()) / (1000 * 60 * 60 * 24));
                      const created = `${createdDate.toLocaleString('de-DE', { hour12: false })} (${createdDaysAgo} Tage alt)`;
                      const ports = (container.Ports || []).map(p => `${p.IP || '0.0.0.0'}:${p.PublicPort}->${p.PrivatePort}/${p.Type}`).join(', ');
                      const ip = container.NetworkSettings?.Networks?.bridge?.IPAddress || 'n/a';
      
                      createState(`${dp}.image`, image, true);
                      setState(`${dp}.image`, image, true);
                      createState(`${dp}.created`, created, true);
                      setState(`${dp}.created`, created, true);
                      createState(`${dp}.ports`, ports, true);
                      setState(`${dp}.ports`, ports, true);
                      createState(`${dp}.ip`, ip, true);
                      setState(`${dp}.ip`, ip, true);
                      createState(`${dp}.control`, false, { type: 'boolean', role: 'button', write: true, read: false });
      
                      const detailUrl = `${portainerHost}/api/endpoints/${endpointId}/docker/containers/${id}/json`;
                      const detailCmd = `curl -s -H "Authorization: Bearer ${token}" "${detailUrl}"`;
                      exec(detailCmd, (err, detailOut) => {
                          if (err) return log(`❌ Fehler bei Details für ${name}: ${err}`, 'warn');
                          try {
                              const detail = JSON.parse(detailOut);
                              const isRunning = detail?.State?.Running === true;
                              const state = isRunning ? 'running' : 'exited';
                              const startedAt = new Date(isRunning ? detail.State.StartedAt : 0);
                              const now = new Date();
                              const uptimeMs = isRunning ? now - startedAt : 0;
                              const uptimeText = formatUptime(uptimeMs);
      
                              const stateDP = `${dp}.state`;
                              getStateAsync(stateDP).then(oldState => {
                                  if (oldState && oldState.val !== state) {
                                      const msg = `🔔 Container \`${name}\` Status: \`${oldState.val}\` → \`${state}\``;
                                      sendDiscordMessage(msg);
                                      sendTelegramMessage(msg);
                                  }
                              });
      
                              createState(stateDP, state, true);
                              setState(stateDP, state, true);
                              createState(`${dp}.uptimeText`, uptimeText, true);
                              setState(`${dp}.uptimeText`, uptimeText, true);
      
                              const statsCmd = `curl -s -H "Authorization: Bearer ${token}" "${portainerHost}/api/endpoints/${endpointId}/docker/containers/${id}/stats?stream=false"`;
                              exec(statsCmd, (e, statsOut) => {
                                  if (e) return;
                                  try {
                                      const stats = JSON.parse(statsOut);
                                      const cpuDelta = stats.cpu_stats.cpu_usage.total_usage - stats.precpu_stats.cpu_usage.total_usage;
                                      const systemDelta = stats.cpu_stats.system_cpu_usage - stats.precpu_stats.system_cpu_usage;
                                      const cpuPercent = systemDelta > 0 ? (cpuDelta / systemDelta) * stats.cpu_stats.online_cpus * 100 : 0;
                                      const memMB = Math.round((stats.memory_stats.usage || 0) / 1024 / 1024);
      
                                      createState(`${dp}.cpu`, Math.round(cpuPercent * 10) / 10, true);
                                      setState(`${dp}.cpu`, Math.round(cpuPercent * 10) / 10, true);
                                      createState(`${dp}.mem`, memMB, true);
                                      setState(`${dp}.mem`, memMB, true);
      
                                      const cpuSafe = Math.round(cpuPercent * 10) / 10;
                                      const memSafe = memMB;
                                      const restartedRecently = isRunning && (uptimeMs < 2 * 60 * 1000);
                                      const restartAt = isRunning ? startedAt.toLocaleString('de-DE', { hour12: false }) : '-';
      containerList.push({ name, state, uptime: uptimeText, cpu: cpuSafe, mem: memSafe, image, ports, created, ip, restartedRecently, restartAt });
      
                                      setState(statusBoardDP, buildHTML(containerList), true);
                                      setState(mobileStatusDP, buildMobileHTML(containerList), true);
                                  } catch (e) {
                                      log(`⚠️ Stats-Parsing-Fehler ${name}: ${e.message}`, 'warn');
                                  }
                              });
      
                              
      
                          } catch (e) {
                              log(`❌ Detail-Parsing-Fehler ${name}: ${e.message}`, 'warn');
                          }
                      });
                  });
              } catch (err) {
                  log(`❌ Containerdaten-Fehler: ${err.message}`, 'error');
              }
          });
      }
      
      function formatUptime(ms) {
          const totalSeconds = Math.floor(ms / 1000);
          const days = Math.floor(totalSeconds / 86400);
          const hours = Math.floor((totalSeconds % 86400) / 3600);
          const minutes = Math.floor((totalSeconds % 3600) / 60);
          let str = '';
          if (days > 0) str += `${days}d `;
          if (days > 0 || hours > 0) str += `${hours}h `;
          str += `${minutes}min`;
          return str.trim();
      }
      
      on(new RegExp(`${datapointBase}(.*)\.control`), function (obj) {
          if (obj.state.val !== true) return;
          const name = obj.id.split('.')[4];
          const loginCmd = `curl -s -H "Content-Type: application/json" -X POST -d '{"Username":"${username}","Password":"${password}"}' ${portainerHost}/api/auth`;
          exec(loginCmd, (error, stdout) => {
              if (error) return log(`❌ Loginfehler: ${error}`, 'error');
              try {
                  const token = JSON.parse(stdout).jwt;
                  const listCmd = `curl -s -H "Authorization: Bearer ${token}" "${portainerHost}/api/endpoints/${endpointId}/docker/containers/json?all=1"`;
                  exec(listCmd, (err, out) => {
                      const list = JSON.parse(out);
                      const container = list.find(c => c.Names[0].replace(/^\//, '') === name);
                      if (!container) return log(`⚠️ Container ${name} nicht gefunden`, 'warn');
                      const action = container.State === 'running' ? 'stop' : 'start';
                      const actionUrl = `${portainerHost}/api/endpoints/${endpointId}/docker/containers/${container.Id}/${action}`;
                      const actionCmd = `curl -s -H "Authorization: Bearer ${token}" -X POST "${actionUrl}"`;
                      exec(actionCmd, () => {
                          log(`✅ Container ${name} ${action} ausgeführt`);
                          setTimeout(() => getTokenAndContainers(), 3000);
                          setTimeout(() => setState(obj.id, false, true), 500);
                      });
                  });
              } catch (e) {
                  log(`❌ Steuerungsfehler: ${e.message}`, 'error');
              }
          });
      });
      
      function sendDiscordMessage(message) {
          const discordEnabled = getState(discordToggleDP)?.val === true;
          if (discordEnabled && existsState(discordDP)) {
              setState(discordDP, message);
              log(`📤 Discord: ${message}`);
          } else {
              log(`ℹ️ Discord deaktiviert oder nicht verfügbar`, 'info');
          }
      }
      
      function sendTelegramMessage(message) {
          const telegramEnabled = getState(telegramToggleDP)?.val === true;
          if (telegramEnabled) {
              sendTo(telegramInstance, 'send', { text: message });
              log(`📤 Telegram: ${message}`);
          } else {
              log(`ℹ️ Telegram deaktiviert`, 'info');
          }
      }
      
      function buildHTML(list) {
          list.sort((a, b) => a.name.localeCompare(b.name));
          let html = `<b style="color:#ffffff;">🧾 Docker Statusboard</b><br>
          <label for="runningFilter" style="color:#ffffff;">🚦 Nur laufende anzeigen</label>
          <input type="checkbox" id="runningFilter" onchange="filterRunning()" style="margin-bottom:10px;">
          <label for="themeToggle" style="color:#ffffff;">🌗 Theme</label>
          <input type="checkbox" id="themeToggle" checked onchange="toggleTheme()" style="margin-bottom: 10px;"><br>
          <table id="dockerStatus" border="1" cellspacing="0" cellpadding="6"
              style="font-family:Arial; font-size:13px; border-collapse:collapse;
                     text-align:left; background:#1e1e1e; color:#ffffff; border-color:#444; width:100%;">
              <thead>
              <tr style="background:#333;">
                  <th onclick="sortTable(0)">Name</th>
                  <th onclick="sortTable(1)">CPU</th>
                  <th onclick="sortTable(2)">RAM</th>
                  <th onclick="sortTable(3)">Status</th>
                  <th onclick="sortTable(4)">Uptime</th>
                  <th onclick="sortTable(5)">Restarted</th>
                  <th onclick="sortTable(6)">Restart-Zeit</th>
                  <th onclick="sortTable(7)">Image</th>
                  <th onclick="sortTable(8)">Erstellt</th>
                  <th onclick="sortTable(9)">Ports</th>
              </tr>
              </thead><tbody>`;
      
          for (let c of list) {
              html += `<tr style="background:${c.state === 'running' ? '#2d572c' : '#571b1b'};" title="IP: ${c.ip}">
                  <td>${c.name}</td>
                  <td style="color:${c.cpu > 50 ? '#ff5555' : '#cccccc'}">${c.cpu}</td>
                  <td style="color:${c.mem > 500 ? '#ff8800' : '#cccccc'}">${c.mem}</td>
                  <td>${c.state === 'running' ? '✅' : '❌'} ${c.state}</td>
                  <td>${c.uptime}</td>
                  <td style="color: ${c.restartedRecently ? '#ffaa00' : '#cccccc'};">${c.restartedRecently ? 'ja' : 'nein'}</td>
                  <td>${c.restartAt}</td>
                  <td>${c.image}</td>
                  <td>${c.created}</td>
                  <td>${c.ports}</td>
              </tr>`;
          }
      
          html += `</tbody></table>
          <script>
              function filterRunning() {
                  var table = document.getElementById("dockerStatus");
                  var rows = table.getElementsByTagName("tr");
                  var onlyRunning = document.getElementById("runningFilter").checked;
                  for (var i = 1; i < rows.length; i++) {
                      var stateCell = rows[i].getElementsByTagName("td")[3];
                      if (!stateCell) continue;
                      var isRunning = stateCell.textContent.includes("running");
                      rows[i].style.display = (onlyRunning && !isRunning) ? "none" : "";
                  }
              }
              function sortTable(n) {
                  var table = document.getElementById("dockerStatus");
                  var switching = true;
                  var dir = "asc";
                  var switchcount = 0;
                  while (switching) {
                      switching = false;
                      var rows = table.rows;
                      for (var i = 1; i < rows.length - 1; i++) {
                          var shouldSwitch = false;
                          var x = rows[i].getElementsByTagName("TD")[n];
                          var y = rows[i + 1].getElementsByTagName("TD")[n];
                          var xContent = x.textContent || x.innerText;
                          var yContent = y.textContent || y.innerText;
                          var xNum = parseFloat(xContent);
                          var yNum = parseFloat(yContent);
                          var isNumber = !isNaN(xNum) && !isNaN(yNum);
                          if (isNumber) {
                              if ((dir === "asc" && xNum > yNum) || (dir === "desc" && xNum < yNum)) {
                                  shouldSwitch = true;
                                  break;
                              }
                          } else {
                              if ((dir === "asc" && xContent.toLowerCase() > yContent.toLowerCase()) ||
                                  (dir === "desc" && xContent.toLowerCase() < yContent.toLowerCase())) {
                                  shouldSwitch = true;
                                  break;
                              }
                          }
                      }
                      if (shouldSwitch) {
                          rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
                          switching = true;
                          switchcount++;
                      } else {
                          if (switchcount === 0 && dir === "asc") {
                              dir = "desc";
                              switching = true;
                          }
                      }
                  }
              }
          function toggleTheme() {
                  var table = document.getElementById("dockerStatus");
                  var isDark = document.getElementById("themeToggle").checked;
                  table.style.background = isDark ? "#1e1e1e" : "#ffffff";
                  table.style.color = isDark ? "#ffffff" : "#000000";
                  var th = table.getElementsByTagName("th");
                  for (var i = 0; i < th.length; i++) {
                      th[i].style.background = isDark ? "#333" : "#dddddd";
                  }
                  localStorage.setItem("themeDark", isDark);
              }
              window.addEventListener("load", () => {
                  document.getElementById("themeToggle").checked = localStorage.getItem("themeDark") === "true";
                  toggleTheme();
              });
              }
          </script>`;
          return html;
      }
      
      // Start und Zyklus
      getTokenAndContainers();
      schedule(`*/${updateIntervalMinutes} * * * *`, getTokenAndContainers);
      
      function buildMobileHTML(list) {
          list.sort((a, b) => a.name.localeCompare(b.name));
          let html = `<div style="font-family:Arial; font-size:14px;"><b>📱 Docker Übersicht</b><br><br>`;
      
          const columnWidth = mobileLayoutColumns === 2 ? '48%' : '100%';
          const wrapperStyle = mobileLayoutColumns === 2 ? 'display:flex; flex-wrap:wrap; justify-content:space-between;' : '';
      
          html += `<div style="${wrapperStyle}">`;
      
          for (let c of list) {
              const color = c.state === 'running' ? '#2d572c' : '#571b1b';
              const cpu = parseFloat(c.cpu);
              const mem = parseFloat(c.mem);
              const statusText = mobileUseSymbol ? (c.state === 'running' ? '✅' : '❌') : c.state;
              let metricsLine = '';
              if (mobileShowCPU) metricsLine += ` CPU: ${cpu}%`;
              if (mobileShowRAM) metricsLine += ` RAM: ${mem} MB`;
      
              let card = '';
              if (mobileTwoLineLayout) {
                  card = `<div style="margin-bottom:12px; padding:8px; border-radius:8px; background:${color}; width:${columnWidth}; box-sizing:border-box;">
                      <b>${c.name}</b><br>
                      <small>${statusText}${metricsLine}</small><br>
                      <small>Uptime: ${c.uptime}</small>
                  </div>`;
              } else {
                  card = `<div style="margin-bottom:12px; padding:8px; border-radius:8px; background:${color}; width:${columnWidth}; box-sizing:border-box;">
                      <b>${c.name}</b><br>
                      <small>Status: ${statusText}${metricsLine}, Uptime: ${c.uptime}</small>
                  </div>`;
              }
              html += card;
          }
      
          html += `</div></div>`;
          return html;
      }
      
      
      

      Edit2:
      Screenshot von den Objects:
      Screenshot 2025-08-01 at 14.38.20.png

      Edit3:
      Script um eine html Tabelle aus den States zu erzeugen, Datenpunkte und Container bitte anpassen:
      wurde alles in ein Script gepackt, ist einfacher.

      Screenshot: Tabelle
      Screenshot 2025-08-01 at 16.15.07.png

      Screenshot: Mobile Ansicht, 2 Spaltig (konfigurierbar)
      Screenshot 2025-08-04 at 20.53.06.png

      Codierknecht David G. 3 Replies Last reply Reply Quote 0
      • Codierknecht
        Codierknecht Developer Most Active @ilovegym last edited by Codierknecht

        @ilovegym sagte in script Dockermon Api:

        wie zerlege ich denn am besten das json

        Ich mache das erstmal immer mit dem "JSON Path Finder":

        7244da4a-b42f-4251-bfed-087876c54f96-image.png

        vom Dockermon-Container

        Geht das nicht auch direkt mit dem Portainer-API?

        a3848f38-9e4f-4d27-95e5-b2761f89e336-image.png

        vor allem, wenn ein Container weg oder dazu kommt.. ?

        In Zabbix geht das mit JSONPath, da kann man nach bestimmten Einträgen suchen.
        Geht sowas nicht auch mit JSONATA? Da ist vermutlich @mickym der Fachmann 😉

        1 Reply Last reply Reply Quote 1
        • David G.
          David G. @ilovegym last edited by

          @ilovegym

          Warum auch immer klappt blockly grad bei mir nicht und darf keine Variablen anlegen.....

          Du kannst aus der Blockly eine Liste erstellen und dann mit einer Schleife durcharbeiten.

          1 Reply Last reply Reply Quote 1
          • ilovegym
            ilovegym last edited by ilovegym

            @david-g @Codierknecht

            hab mal meinen "Sheldon" 🙂 gefragt (Chatgpt), und das kam zum schluss raus, habs noch n bisserl verfeinert, da die ersten Ansaetze nix waren..

            Das Script fragt direkt die Portainer-Api ab, einen Api-Key braucht man nicht und legt die Datenpunkte fuer Status, Ram, CPU und uptime im gewuenschten Ordner an.
            Man kann den/die Container starten/stoppen.

            Script in den ersten Beitrag verschoben, dieser wird immer aktualisiert.

            David G. 1 Reply Last reply Reply Quote 0
            • David G.
              David G. @ilovegym last edited by David G.

              @ilovegym

              Hat sich erledigt.
              Auch meine Nachricht.

              ilovegym 1 Reply Last reply Reply Quote 0
              • ilovegym
                ilovegym @David G. last edited by

                @david-g

                alles gut, bin gerade am erweitern / optimieren des Scripts..

                David G. 1 Reply Last reply Reply Quote 0
                • David G.
                  David G. @ilovegym last edited by

                  @ilovegym

                  Bei mir möchte es auch nicht ganz.

                  avascript.0	14:28:18.301	info	
                  Stopping script script.js.Eigene_Scripte.Portainer
                  javascript.0	14:28:18.359	info	
                  Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                  javascript.0	14:28:18.382	info	
                  registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                  javascript.0	14:28:18.470	error	
                  ❌ Fehler beim Parsen der Containerdaten: containers.forEach is not a function
                  
                  ilovegym 1 Reply Last reply Reply Quote 0
                  • ilovegym
                    ilovegym @David G. last edited by

                    @david-g

                    endpointid richtig? muss nicht 1 sein,bei ist es 2

                    David G. 1 Reply Last reply Reply Quote 0
                    • David G.
                      David G. @ilovegym last edited by

                      @ilovegym
                      Hab 2 getestet. Dann kommt keinen token erhalten. Dann wieder 1. Kommt jetzt auch keinen token erhalten.

                      ilovegym 1 Reply Last reply Reply Quote 0
                      • ilovegym
                        ilovegym @David G. last edited by

                        @david-g

                        hmm vielleicht Portainer wegen zuvielen falschen Zugriffen geblockt, war bei mir auch am Anfang, als das Script noch fehler hatte.. einfach Portainer neu starten...

                        David G. 1 Reply Last reply Reply Quote 0
                        • David G.
                          David G. @ilovegym last edited by David G.

                          @ilovegym

                          Die ganzen warns waren mit id 2, der Fehler beim Pharsen mit 1.

                          1.8.2025, 14:43:04.923	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 14:43:05.015	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 14:43:05.037	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 14:43:05.045	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 14:43:54.160	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 14:43:54.208	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 14:43:54.230	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 14:43:54.239	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 14:43:58.696	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 14:44:01.907	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 14:44:01.913	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 14:44:01.918	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 14:44:15.888	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 14:44:15.978	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 14:44:15.986	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 14:44:15.994	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 14:45:00.067	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 14:46:35.734	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 14:46:35.824	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 14:46:35.844	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 14:46:35.851	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 14:52:03.359	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 14:52:03.450	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 14:52:03.474	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 14:52:03.481	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 14:52:16.268	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 14:52:16.358	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 14:52:16.377	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 14:52:16.395	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 14:52:29.449	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 14:52:29.537	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 14:52:29.561	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 14:52:29.570	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Kein Token erhalten
                          1.8.2025, 15:01:54.921	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 15:01:55.010	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 15:01:55.023	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 15:01:55.205	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:55.205	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:55.206	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:55.206	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:55.206	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:55.208	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:55.208	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:55.208	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:55.208	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:55.209	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:55.209	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:55.209	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:56.195	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:56.196	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:57.205	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:57.206	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:57.211	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:57.213	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:57.218	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:57.224	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:57.231	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:57.233	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:57.235	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:57.236	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:57.236	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:57.237	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:57.240	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:57.240	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:01:57.241	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:96:25
                          1.8.2025, 15:01:57.241	[warn ]: javascript.0 (1615949)     at script.js.Eigene_Scripte.Portainer:99:25
                          1.8.2025, 15:02:14.020	[info ]: javascript.0 (1615949) Stopping script script.js.Eigene_Scripte.Portainer
                          1.8.2025, 15:02:14.111	[info ]: javascript.0 (1615949) Start JavaScript script.js.Eigene_Scripte.Portainer (Javascript/js)
                          1.8.2025, 15:02:14.130	[info ]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: registered 1 subscription, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                          1.8.2025, 15:02:14.221	[error]: javascript.0 (1615949) script.js.Eigene_Scripte.Portainer: ❌ Fehler beim Parsen der Containerdaten: containers.forEach is not a function
                          

                          Portainer 2.27.9

                          Edit
                          Evtl kann man den Endpoint automatisch ausfüllen, wenn man diesen leer lässt.

                          curl -H "Authorization: Bearer <JWT>" \
                               http://10.68.xx.zzz:9000/api/endpoints
                          

                          und dann den ersten falls es mehrere gibt.

                          1 Reply Last reply Reply Quote 0
                          • David G.
                            David G. @ilovegym last edited by David G.

                            @ilovegym

                            Die neue Version läuft.
                            Top.

                            Was ich mir wünschen würde:

                            • Discord deaktivieren zu können (hab es mir einfach unten rausgelöscht).
                            • Ggf Telegram hinzufügen (natürlich auch deaktivierbar)
                            • Created auch als TS (Da schaue ich, wann das letzte Update war um Container zu finden die nicht mehr gepflegt werden)

                            EDIT
                            Soll control die Container updaten?
                            Falls ja klappt es bei mir nicht.

                            EDIT 2
                            Wenn ich control in einem Container drücke, startet meine JS Instanz neu.

                            ilovegym 2 Replies Last reply Reply Quote 1
                            • ilovegym
                              ilovegym @David G. last edited by

                              @david-g

                              Control soll den Container starten / stoppen, das hat bei mir funktioniert..

                              Ich mach spätestens am Montag weiter.. 😃

                              Vielen Dank für das Testen!

                              1 Reply Last reply Reply Quote 0
                              • ilovegym
                                ilovegym @David G. last edited by ilovegym

                                @david-g

                                Hi David,
                                heute ist Montag und wie versprochen, eine neue Version, aktuell V3.3 - ist alles in ein Script gekommen und es gibt jede Menge neue Optionen, siehe Changelog 🙂

                                Viel Spass damit! (aktuelles Script im ersten Beitrag)

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

                                Support us

                                ioBroker
                                Community Adapters
                                Donate

                                406
                                Online

                                31.9k
                                Users

                                80.3k
                                Topics

                                1.3m
                                Posts

                                blockly javascript monitoring
                                3
                                14
                                201
                                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