Navigation

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

    NEWS

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    M
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 48
    • Best 9
    • Groups 1

    Machinima

    @Machinima

    19
    Reputation
    95
    Profile views
    48
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Machinima Follow
    Starter

    Best posts made by Machinima

    • Material Design Widets: Netzwerk Status

      In Anlehnung an die Views Skript Status und Adapter Status mit den Material Design Widgets habe ich mir eine View mit den Geräten aus dem TR064-Adapter erstellt, siehe nachfolgender Screenshot.

      Netzwerkgeräte VIS.png

      Github: Link

      Voraussetzung:

      • Material Design Widgets v0.2.66

      Funktionen:

      • Anzeige des Netzwerkstatus euer Geräte aus dem TR064-Adapter (online, offline)
      • Anzeige von Werten des Adapters (IP-Adresse, letzte An- und Abmeldung)
      • Einträge, die mit einem Link hinterlegt wurden, können per Klick auf das Symbol in einem neuen Browser-Tab geöffnet werden
      • Sortier und Filter Funktion
      • Einstellungen, siehe im Skript Sektion Einstellungen, Funktion der Einstellungen ist dort als Kommentar beschrieben.

      View zum Importieren (für Material Design Icons):

      {
        "settings": {
          "style": {
            "background_class": ""
          },
          "theme": "redmond",
          "sizex": "",
          "sizey": "",
          "gridSize": "",
          "useBackground": false,
          "snapType": null
        },
        "widgets": {
          "e00001": {
            "tpl": "tplHtml",
            "data": {
              "g_fixed": false,
              "g_visibility": false,
              "g_css_font_text": false,
              "g_css_background": true,
              "g_css_shadow_padding": false,
              "g_css_border": false,
              "g_gestures": false,
              "g_signals": false,
              "g_last_change": false,
              "visibility-cond": "==",
              "visibility-val": 1,
              "visibility-groups-action": "hide",
              "refreshInterval": "0",
              "signals-cond-0": "==",
              "signals-val-0": true,
              "signals-icon-0": "/vis/signals/lowbattery.png",
              "signals-icon-size-0": 0,
              "signals-blink-0": false,
              "signals-horz-0": 0,
              "signals-vert-0": 0,
              "signals-hide-edit-0": false,
              "signals-cond-1": "==",
              "signals-val-1": true,
              "signals-icon-1": "/vis/signals/lowbattery.png",
              "signals-icon-size-1": 0,
              "signals-blink-1": false,
              "signals-horz-1": 0,
              "signals-vert-1": 0,
              "signals-hide-edit-1": false,
              "signals-cond-2": "==",
              "signals-val-2": true,
              "signals-icon-2": "/vis/signals/lowbattery.png",
              "signals-icon-size-2": 0,
              "signals-blink-2": false,
              "signals-horz-2": 0,
              "signals-vert-2": 0,
              "signals-hide-edit-2": false,
              "lc-type": "last-change",
              "lc-is-interval": true,
              "lc-is-moment": false,
              "lc-format": "",
              "lc-position-vert": "top",
              "lc-position-horz": "right",
              "lc-offset-vert": 0,
              "lc-offset-horz": 0,
              "lc-font-size": "12px",
              "lc-font-family": "",
              "lc-font-style": "",
              "lc-bkg-color": "",
              "lc-color": "",
              "lc-border-width": "0",
              "lc-border-style": "",
              "lc-border-color": "",
              "lc-border-radius": 10,
              "lc-zindex": 0
            },
            "style": {
              "left": "0",
              "top": "0",
              "width": "100%",
              "background-color": "#44739e",
              "height": "50px",
              "z-index": "0"
            },
            "widgetSet": "basic"
          },
          "e00002": {
            "tpl": "tplVis-materialdesign-Select",
            "data": {
              "oid": "0_userdata.0.vis.NetzwerkStatus.sortMode",
              "g_fixed": false,
              "g_visibility": false,
              "g_css_font_text": false,
              "g_css_background": false,
              "g_css_shadow_padding": false,
              "g_css_border": false,
              "g_gestures": false,
              "g_signals": false,
              "g_last_change": false,
              "visibility-cond": "==",
              "visibility-val": 1,
              "visibility-groups-action": "hide",
              "inputType": "text",
              "inputLayout": "regular",
              "showInputMessageAlways": "true",
              "showInputCounter": false,
              "clearIconShow": false,
              "listDataMethod": "jsonStringObject",
              "countSelectItems": "1",
              "listPosition": "bottom",
              "showSelectedIcon": "prepend-inner",
              "showValue": false,
              "signals-cond-0": "==",
              "signals-val-0": true,
              "signals-icon-0": "/vis/signals/lowbattery.png",
              "signals-icon-size-0": 0,
              "signals-blink-0": false,
              "signals-horz-0": 0,
              "signals-vert-0": 0,
              "signals-hide-edit-0": false,
              "signals-cond-1": "==",
              "signals-val-1": true,
              "signals-icon-1": "/vis/signals/lowbattery.png",
              "signals-icon-size-1": 0,
              "signals-blink-1": false,
              "signals-horz-1": 0,
              "signals-vert-1": 0,
              "signals-hide-edit-1": false,
              "signals-cond-2": "==",
              "signals-val-2": true,
              "signals-icon-2": "/vis/signals/lowbattery.png",
              "signals-icon-size-2": 0,
              "signals-blink-2": false,
              "signals-horz-2": 0,
              "signals-vert-2": 0,
              "signals-hide-edit-2": false,
              "lc-type": "last-change",
              "lc-is-interval": true,
              "lc-is-moment": false,
              "lc-format": "",
              "lc-position-vert": "top",
              "lc-position-horz": "right",
              "lc-offset-vert": 0,
              "lc-offset-horz": 0,
              "lc-font-size": "12px",
              "lc-font-family": "",
              "lc-font-style": "",
              "lc-bkg-color": "",
              "lc-color": "",
              "lc-border-width": "0",
              "lc-border-style": "",
              "lc-border-color": "",
              "lc-border-radius": 10,
              "lc-zindex": 0,
              "inputLabelText": "Sortieren nach",
              "inputLabelColor": "#ffffff",
              "inputLabelFontFamily": "RobotoCondensed-LightItalic",
              "collapseIconColor": "#ffffff",
              "collapseIconSize": "",
              "jsonStringObject": "[\n\t{\n\t\t\"text\": \"Gerätename\",\n\t\t\"value\": \"name\",\n\t\t\"icon\": \"sort-alphabetical\"\n\t},\n\t{\n\t\t\"text\": \"IP Adresse\",\n\t\t\"value\": \"ipAddress\",\n\t\t\"icon\": \"ip\"\n\t}\n]",
              "listPositionOffset": true,
              "inputLayoutBackgroundColor": "transparent",
              "inputLabelColorSelected": "#ffffff",
              "inputTranslateX": "-15",
              "clearIcon": "",
              "inputLayoutBorderColorHover": "#ffffff",
              "inputLayoutBorderColorSelected": "#ffffff",
              "inputLayoutBorderColor": "#a1a1a1",
              "listItemFontColor": "",
              "inputTextColor": "#ffffff",
              "inputTextFontFamily": "RobotoCondensed-LightItalic",
              "prepandIcon": "",
              "prepandIconColor": "",
              "prepandIconSize": "",
              "prepandInnerIcon": "",
              "prepandInnerIconColor": "#ffffff",
              "prepandInnerIconSize": "18",
              "collapseIcon": "",
              "inputTranslateY": "-12",
              "listIconSelectedColor": "#44739e",
              "listIconColor": "",
              "appendOuterIcon": "",
              "appendOuterIconSize": "2",
              "listItemFont": "RobotoCondensed-Regular",
              "listItemRippleEffectColor": "",
              "inputLayoutBackgroundColorSelected": "",
              "inputLayoutBackgroundColorHover": ""
            },
            "style": {
              "left": "10px",
              "top": "0px",
              "z-index": "1",
              "width": "calc(50% - 20px)",
              "height": "40px"
            },
            "widgetSet": "materialdesign"
          },
          "e00003": {
            "tpl": "tplVis-materialdesign-Select",
            "data": {
              "oid": "0_userdata.0.vis.NetzwerkStatus.filterMode",
              "g_fixed": false,
              "g_visibility": false,
              "g_css_font_text": false,
              "g_css_background": false,
              "g_css_shadow_padding": false,
              "g_css_border": false,
              "g_gestures": false,
              "g_signals": false,
              "g_last_change": false,
              "visibility-cond": "==",
              "visibility-val": 1,
              "visibility-groups-action": "hide",
              "inputType": "text",
              "inputLayout": "regular",
              "showInputMessageAlways": "true",
              "showInputCounter": false,
              "clearIconShow": true,
              "listDataMethod": "jsonStringObject",
              "countSelectItems": "1",
              "listPosition": "bottom",
              "showSelectedIcon": "prepend-inner",
              "showValue": false,
              "signals-cond-0": "==",
              "signals-val-0": true,
              "signals-icon-0": "/vis/signals/lowbattery.png",
              "signals-icon-size-0": 0,
              "signals-blink-0": false,
              "signals-horz-0": 0,
              "signals-vert-0": 0,
              "signals-hide-edit-0": false,
              "signals-cond-1": "==",
              "signals-val-1": true,
              "signals-icon-1": "/vis/signals/lowbattery.png",
              "signals-icon-size-1": 0,
              "signals-blink-1": false,
              "signals-horz-1": 0,
              "signals-vert-1": 0,
              "signals-hide-edit-1": false,
              "signals-cond-2": "==",
              "signals-val-2": true,
              "signals-icon-2": "/vis/signals/lowbattery.png",
              "signals-icon-size-2": 0,
              "signals-blink-2": false,
              "signals-horz-2": 0,
              "signals-vert-2": 0,
              "signals-hide-edit-2": false,
              "lc-type": "last-change",
              "lc-is-interval": true,
              "lc-is-moment": false,
              "lc-format": "",
              "lc-position-vert": "top",
              "lc-position-horz": "right",
              "lc-offset-vert": 0,
              "lc-offset-horz": 0,
              "lc-font-size": "12px",
              "lc-font-family": "",
              "lc-font-style": "",
              "lc-bkg-color": "",
              "lc-color": "",
              "lc-border-width": "0",
              "lc-border-style": "",
              "lc-border-color": "",
              "lc-border-radius": 10,
              "lc-zindex": 0,
              "inputLabelText": "Filtern nach",
              "inputLabelColor": "#ffffff",
              "inputLabelFontFamily": "RobotoCondensed-LightItalic",
              "collapseIconColor": "#ffffff",
              "collapseIconSize": "",
              "jsonStringObject": "[\n\t{\n\t\t\"text\": \"online\",\n\t\t\"value\": \"online\",\n\t\t\"icon\": \"network\"\n\t},\n\t{\n\t\t\"text\": \"offline\",\n\t\t\"value\": \"offline\",\n\t\t\"icon\": \"network-off-outline\"\n\t}\n]",
              "listPositionOffset": true,
              "inputLayoutBackgroundColor": "transparent",
              "inputLabelColorSelected": "#ffffff",
              "inputTranslateX": "-15",
              "clearIcon": "",
              "inputLayoutBorderColorHover": "#ffffff",
              "inputLayoutBorderColorSelected": "#ffffff",
              "inputLayoutBorderColor": "#a1a1a1",
              "listItemFontColor": "",
              "inputTextColor": "#ffffff",
              "inputTextFontFamily": "RobotoCondensed-LightItalic",
              "prepandIcon": "",
              "prepandIconColor": "",
              "prepandIconSize": "",
              "prepandInnerIcon": "",
              "prepandInnerIconColor": "#ffffff",
              "prepandInnerIconSize": "18",
              "collapseIcon": "",
              "inputTranslateY": "-12",
              "listIconSelectedColor": "#44739e",
              "listIconColor": "",
              "appendOuterIcon": "",
              "appendOuterIconSize": "2",
              "listItemFont": "RobotoCondensed-Regular",
              "listItemRippleEffectColor": "",
              "inputLayoutBackgroundColorSelected": "",
              "inputLayoutBackgroundColorHover": "",
              "clearIconColor": "#ffffff"
            },
            "style": {
              "left": "calc(50% + 10px)",
              "top": "0px",
              "z-index": "1",
              "width": "calc(50% - 20px)",
              "height": "40px"
            },
            "widgetSet": "materialdesign"
          },
          "e00004": {
            "tpl": "tplVis-materialdesign-Icon-List",
            "data": {
              "g_fixed": false,
              "g_visibility": false,
              "g_css_font_text": false,
              "g_css_background": false,
              "g_css_shadow_padding": false,
              "g_css_border": false,
              "g_gestures": false,
              "g_signals": false,
              "g_last_change": false,
              "visibility-cond": "==",
              "visibility-val": 1,
              "visibility-groups-action": "hide",
              "wrapItems": true,
              "listItemDataMethod": "jsonStringObject",
              "countListItems": "1",
              "vibrateOnMobilDevices": "50",
              "listLayout": "card",
              "itemLayout": "horizontal",
              "listType0": "text",
              "showValueLabel0": "true",
              "listType1": "text",
              "showValueLabel1": "true",
              "signals-cond-0": "==",
              "signals-val-0": true,
              "signals-icon-0": "/vis/signals/lowbattery.png",
              "signals-icon-size-0": 0,
              "signals-blink-0": false,
              "signals-horz-0": 0,
              "signals-vert-0": 0,
              "signals-hide-edit-0": false,
              "signals-cond-1": "==",
              "signals-val-1": true,
              "signals-icon-1": "/vis/signals/lowbattery.png",
              "signals-icon-size-1": 0,
              "signals-blink-1": false,
              "signals-horz-1": 0,
              "signals-vert-1": 0,
              "signals-hide-edit-1": false,
              "signals-cond-2": "==",
              "signals-val-2": true,
              "signals-icon-2": "/vis/signals/lowbattery.png",
              "signals-icon-size-2": 0,
              "signals-blink-2": false,
              "signals-horz-2": 0,
              "signals-vert-2": 0,
              "signals-hide-edit-2": false,
              "lc-type": "last-change",
              "lc-is-interval": true,
              "lc-is-moment": false,
              "lc-format": "",
              "lc-position-vert": "top",
              "lc-position-horz": "right",
              "lc-offset-vert": 0,
              "lc-offset-horz": 0,
              "lc-font-size": "12px",
              "lc-font-family": "",
              "lc-font-style": "",
              "lc-bkg-color": "",
              "lc-color": "",
              "lc-border-width": "0",
              "lc-border-style": "",
              "lc-border-color": "",
              "lc-border-radius": 10,
              "lc-zindex": 0,
              "maxItemsperRow": "8",
              "json_string_oid": "0_userdata.0.vis.NetzwerkStatus.jsonList",
              "labelFontSize": "22",
              "subLabelFontSize": "14",
              "labelFontFamily": "RobotoCondensed-Regular",
              "horizontalIconContainerWidth": "70",
              "buttonHeight": "",
              "iconHeight": "35",
              "iconItemMinWidth": "300",
              "buttonLayout": "round",
              "autoLockAfter": "10",
              "lockIconTop": "5",
              "lockIconLeft": "5",
              "lockFilterGrayscale": "30",
              "lockApplyOnlyOnImage": "true",
              "subLabelFontFamily": "RobotoCondensed-BoldItalic",
              "subLabelFontColor": "black",
              "verticalIconContainerHeight": "70"
            },
            "style": {
              "left": "",
              "top": "50px",
              "width": "100%",
              "height": "calc(100% - 50px)",
              "overflow-y": "auto"
            },
            "widgetSet": "materialdesign"
          }
        },
        "name": "330_System_NetzwerkStatus",
        "filterList": []
      }
      

      Skript (mit Material Design Icons):

      /* Versionshistorie:
       * 
       * 1.0.2:
       * - neu: Anzeige der letzten An- und Abmeldung
       * - neu: Verwendung eigener Bilder möglich
       * 
       * 1.0.1:
       * - neu: In dem Mapping der IP-Adressen kann jetzt eine URL vergeben werden ('http' oder direkt eine spezifische URL)
       * - geändert: Styling der Details
       * - entfernt: MAC-Adresse
       * 
       * 1.0.0:
       * - Initial Release
       */
      
      const moment = require("moment");
       
      // Skript Einstellungen *************************************************************************************************************************************************
       
      let dpList = '0_userdata.0.vis.NetzwerkStatus.jsonList';          // Datenpunkt für IconList Widget (Typ: Zeichenkette (String))
       
      let dpSortMode = '0_userdata.0.vis.NetzwerkStatus.sortMode';      // Datenpunkt für Sortieren (Typ: Zeichenkette (String))
      let dpFilterMode = '0_userdata.0.vis.NetzwerkStatus.filterMode';  // Datenpunkt für Filter (Typ: Zeichenkette (String))
       
      const checkInterval = 30;                                         // Interval wie oft Status der Skripte aktualisiert werden soll (in Sekunden)
       
      let sprache = 'de';                                               // Sprache für formatierung letzte Änderung
      let formatierungLastChange = "ddd DD.MM - HH:mm";                 // Formatierung letzte Änderung -> siehe momentjs library
      
      let imagePath = '/vis.0/myImages/networkDevices/'                 // Pfad zu den verwendeten Bildern (bitte über den VIS Dateimanager hochladen)
                                                                        // nach Variable imagePath suchen und die entsprechenden Zeilen aus- bzw. einkommentieren
                                                                        // Das Bild (Dateiformat png) in der Mapping-Liste hinterlegen
      let defaultImage = 'ip-network-outline';                          // Standardbild, falls kein Bild angegeben wurde (Material Design Icons)
      //let defaultImage = `${imagePath}default.png`;                   // Standardbild, falls kein Bild angegeben wurde (eigenes Bild)
       
      let farbeGeraetOnline = 'green';                                  // Status Bar Farbe wenn Geräte online ist
      let farbeGeraetOffline = 'FireBrick';                             // Status Bar Farbe wenn Geräte offline ist
       
      let sortResetAfter = 120;                                         // Sortierung nach X Sekunden auf sortReset zurücksetzen (0=deaktiviert)
      let sortReset = 'name'                                            // Sortierung auf die zurückgesetzt werden soll
       
      let filterResetAfter = 120;                                       // Filter nach X Sekunden zurücksetzen (0=deaktiviert)
      
      const deviceNames = 
      [{ ip: "192.168.178.20", alias: "NAS",                           image: "nas",                   link: "http://diskstation:5000" },
       { ip: "192.168.178.37", alias: "Gosund Küchenlicht",            image: "toggle-switch-outline", link: "http" },
       { ip: "192.168.178.45", alias: "Homematic Raspi",               image: "server",                link: "http" },
       { ip: "192.168.178.32", alias: "OnePlus 3T",                    image: "cellphone" }
      ];
       
      // **********************************************************************************************************************************************************************
       
      // Fomate für moment Lib
      moment.locale(sprache);
      
      // auf Änderungen aktiver Skripts hören
      let activeSelector = `[id=tr-064.*.devices.*.active]`;
      let deviceActiveList = $(activeSelector);
      if (deviceActiveList.length === 0) {
          // Fehlermeldung ausgeben, wenn selector kein result liefert
          console.error(`no result for selector '${activeSelector}'`)
      } else {
          // listener nur für Änderung bei alive
          deviceActiveList.on(netzwerkStatus);
      } 
       
      // auf Änderungen der Sortieung hören
      on({ id: dpSortMode, change: 'any' }, netzwerkStatus);
      on({ id: dpSortMode, change: 'any' }, resetSort);
       
      // // auf Änderungen der Filter hören
      on({ id: dpFilterMode, change: 'any' }, netzwerkStatus);
      on({ id: dpFilterMode, change: 'any' }, resetFilter);
       
       
      // Funktion adapterStatus alle x Sekunden ausführen
      schedule('*/' + checkInterval + ' * * * * *', netzwerkStatus);
       
      function netzwerkStatus() {
          try {
              let deviceList = [];
       
              for (var i = 0; i <= deviceActiveList.length - 1; i++) {
                  let id = deviceActiveList[i].replace('.active', '');
                  let obj = getObject(id);
       
                  let pattern = /(?:\d{1,3}\.){3}\d{1,3}/i;
      
                  let ipAddress = obj.common.name.match(pattern)[0];
                  let image = defaultImage;
                  let deviceName = obj.common.name.replace(/ \((?:\d{1,3}\.){3}\d{1,3}\)/g, '');
                  let device = deviceNames.find(element => element.ip == ipAddress);
                  let listType = 'text';
                  let buttonLink = '';
      
                  if(device) {
                      deviceName = device.alias;
                      image = device.image;
                      //image = `${imagePath}${device.image}.png`;
      
                      if(device.link) {
                          listType = 'buttonLink';
      
                          if(device.link == 'http') {
                              buttonLink = `http://${ipAddress}`;
                          } else {
                              buttonLink = device.link;
                          }
                      }
                  }
      
                  let macAddress = obj.native.mac;
                  let imageColor = 'black';
                  let statusBarColor = farbeGeraetOffline;
                  let status = 2;
       
                  if (getState(deviceActiveList[i]).val) {
                      statusBarColor = farbeGeraetOnline;
                      status = 1;
                  }
      
                  if(listType === 'buttonLink') {
                      deviceName = `<span style="text-decoration: underline">${deviceName}</span>`                
                  }
      
                  let lastSignIn = 'noch nicht angemeldet';
                  let lastSignOff = 'noch nicht abgemeldet';
      
                  // Letzte Anmeldung auslesen
                  if(existsState(id + '.lastActive')) {
                      lastSignIn = 'angemeldet seit: ' + moment((getState(id + '.lastActive').val)).format("DD.MM.YY HH:mm:ss");
                  }        
      
                  // Letzte Abmeldung auslesen
                  if(existsState(id + '.lastInactive')) {
                      lastSignOff = 'abgemeldet seit: ' + moment((getState(id + '.lastInactive').val)).format("DD.MM.YY HH:mm:ss");
                  }
      
                  let subText = `<div style="color: black; font-family: RobotoCondensed-BoldItalic">${ipAddress}</div>
                                 <div style="color: grey; font-family: RobotoCondensed-Regular">${lastSignIn}</div>
                                 <div style="color: grey; font-family: RobotoCondensed-Regular">${lastSignOff}</div>`
       
                  deviceList.push({
                      text: deviceName,
                      subText: subText,
                      statusBarColor: statusBarColor,
                      image: image,
                      imageColor: imageColor,
                      listType: listType,
                      buttonLink: buttonLink,
                      showValueLabel: false,
                      name: deviceName,
                      ipAddress: ipAddress,
                      status: status
                  });
              }
       
              let sortMode = myHelper().getStateValueIfExist(dpSortMode, 'name');
       
              if (sortMode === 'name' || sortMode === 'ipAddress') {
                  deviceList.sort(function (a, b) {
                      return a[sortMode].toLowerCase() == b[sortMode].toLowerCase() ? 0 : +(a[sortMode].toLowerCase() > b[sortMode].toLowerCase()) || -1;
                  });
              } else if (sortMode === 'status') {
                  deviceList.sort(function (a, b) {
                      return a[sortMode] == b[sortMode] ? 0 : +(a[sortMode] < b[sortMode]) || -1;
                  });
              } else {
                  // default: nach name sortieren
                  sortMode = 'name'
                  deviceList.sort(function (a, b) {
                      return a[sortMode].toLowerCase() == b[sortMode].toLowerCase() ? 0 : +(a[sortMode].toLowerCase() > b[sortMode].toLowerCase()) || -1;
                  });
              }
       
       
              let filterMode = myHelper().getStateValueIfExist(dpFilterMode, null);
       
              if (filterMode && filterMode !== null && filterMode !== '') {
                  if (filterMode === 'offline') {
                      deviceList = deviceList.filter(function (item) {
                          return item.status === 2;
                      });
                  } else if (filterMode === 'online') {
                      deviceList = deviceList.filter(function (item) {
                          return item.status === 1;
                      });
                  }
              }
       
       
              let result = JSON.stringify(deviceList);
              if (getState(dpList) !== result) {
                  setState(dpList, result, true);
              }
       
          } catch (err) {
              console.error(`[netzwerkStatus] error: ${err.message}, stack: ${err.stack}`);
          }
      }
       
      function resetSort() {
          let sortMode = myHelper().getStateValueIfExist(dpSortMode, null);
       
          if (sortResetAfter > 0) {
              setTimeout(function () {
                  if (sortMode !== null && sortMode === myHelper().getStateValueIfExist(dpSortMode, null)) {
                      setState(dpSortMode, sortReset);
                  }
              }, sortResetAfter * 1000);
          }
      }
       
      function resetFilter() {
          let filterMode = myHelper().getStateValueIfExist(dpFilterMode, null);
       
          if (filterResetAfter > 0) {
              setTimeout(function () {
                  if (filterMode !== null && filterMode === myHelper().getStateValueIfExist(dpFilterMode, null)) {
                      setState(dpFilterMode, '');
                  }
              }, filterResetAfter * 1000);
          }
      }
       
      // Beim Staren des Skriptes Adapter Status abrufen
      netzwerkStatus();
       
      function myHelper() {
          return {
              getStateValueIfExist: function (id, nullValue = undefined, prepand = '', append = '') {
                  if (existsState(id)) {
                      return prepand + getState(id).val + append;
                  } else {
                      return nullValue;
                  }
              },
              getCommonPropertyIfExist: function (object, prop, nullValue = undefined, prepand = '', append = '') {
                  if (myHelper().checkCommonPropertyExist(object, prop)) {
                      return prepand + object.common[prop] + append;
                  } else {
                      return nullValue;
                  }
              },
              checkCommonPropertyExist: function (object, prop) {
                  if (object && object.common && object.common[prop]) {
                      return true;
                  } else {
                      return false;
                  }
              }
          }
      }
      

      Folgende NPM-Module müsst ihr in eurer Javascript-Instanz hinzufügen: moment, moment-timezone, moment-duration-format
      Außerdem bitte die Einstellung "Erlaube das Kommando setObject" in eurer Javascript-Instanz aktivieren

      posted in Praktische Anwendungen (Showcase)
      M
      Machinima
    • RE: Material Design Widets: Netzwerk Status

      @Negalein said in Material Design Widets: Netzwerk Status:

      @Machinima

      Ist es möglich, wie hier folgendes mit deinem Script umzusetzen?

      • eigene Bilder der Geräte verwendbar
      • bei Klick auf das Geräteicon soll sich die Gerätewebsite (als neuer Browsertab) öffnen

      Das ist kein Problem. Bau ich ein

      posted in Praktische Anwendungen (Showcase)
      M
      Machinima
    • RE: Material Design Widets: Netzwerk Status

      Ich habe die View und das Skript leicht angepasst, siehe 1. Post.
      Es ist jetzt möglich, Links zu vergeben.
      Ich arbeite auch bereits an einer Version, bei der man wahlweise zwischen eigenen Bildern oder den Material Design Icons switchen kann.

      posted in Praktische Anwendungen (Showcase)
      M
      Machinima
    • RE: Material Design Widets: Netzwerk Status

      @Knallochse
      Das müsste theoretisch über eine weitere Eigenschaft in der deviceNames-Auflistung realisierbar sein, z.B. über eine Zählervariable, die man selbst vergeben. Wenn die View initial geladen bzw. die aktuell verwendete Sortierung zurückgesetzt wird, käme deine für dich angepasste Sortierung zum Zug. Kann ich gerne noch mit einbauen.

      posted in Praktische Anwendungen (Showcase)
      M
      Machinima
    • RE: Windows Installer 2

      Ebenfalls alles ok. Getestet mit Windows 10 Pro 64-Bit (Build: 1909)

      posted in Tester
      M
      Machinima
    • RE: Skript um auf neue Tasmota Version zu prüfen

      In Anlehnung an das CCU-Firmwareupdate Skript habe ich mir das für die Sonoff-/Tasmota-Geräte angepasst. Auch hier müsst ihr einen Datenpunkt vom Typ Zeichenkette erstellen und ggf. in dem Skript ersetzen.

      const id_Version_Internet = '0_userdata.0.Servicemeldungen.Verfuegbare_Tasmota-Firmware'/*Verfuegbare Tasmota-Firmware*/;
      

      Benachrichtigung per Pushover, E-Mail oder oder Telegram funktioniert ebenfalls. Berücksichtigt werden nur Geräte, die unter dem Sonoff-Adapter laufen.

      const logging = true; 
      const debugging = false;
      
      //Prio für Pushover
      const prio_Firmware = 1;
      
      //Variablen für Pushover
      const sendpush = true;            //true = verschickt per Pushover Nachrchten // false = Pushover wird nicht benutzt
      const pushover_Instanz0 =  'pushover.0';     // Pushover instance für Pio = 0
      const pushover_Instanz1 =  'pushover.1';     // Pushover instance für Pio = 1
      const pushover_Instanz2 =  'pushover.2';     // Pushover instance für Pio = 2
      const pushover_Instanz3 =  'pushover.3';     // Pushover instance für Pio = -1 oder -2
      let _prio;
      let _titel;
      let _message;
      //const _device = 'TPhone';         //Welches Gerät soll die Nachricht bekommen
      const _device = 'All'; 
      
      //Variablen für Telegram
      const sendtelegram = false;            //true = verschickt per Telegram Nachrchten // false = Telegram wird nicht benutzt
      const user_telegram = '';             //User der die Nachricht bekommen soll
      
      //Variable zum verschicken der Servicemeldungen per eMail
      const sendmail = false;            //true = verschickt per email Nachrchten // false = email wird nicht benutzt
      
      let _message_tmp;
      
      const id_Version_Internet = '0_userdata.0.Servicemeldungen.Verfuegbare_Tasmota-Firmware'/*Verfuegbare Tasmota-Firmware*/;
      var cacheSelectorTasmotaVersions = $('channel[state.id=sonoff.0.*.Version]');
      
      const request = require('request');
      
      function func_Version() {
          var options = {
              url: 'https://api.github.com/repos/arendst/Tasmota/releases/latest',
              headers: {
                  'User-Agent': 'ioBroker Tasmota Firmware Check'
              }
          };
      
          request(options, function (error, response, body) {
              const availableFirmware = getState(id_Version_Internet).val;
      
              if(error) {
                  log('error: ' + error);
              } else {
                  var tasmotaJson = JSON.parse(body); 
                  var tasmotaTagName = tasmotaJson.tag_name;
                  var tasmotaVersion = tasmotaTagName.replace(/v/i, "").trim();
      
                  if(availableFirmware == ''){
                      if(logging){
                          log('ausgewähltes Objekt leer. Firmware wird erstmalig gesetzt. Firmware: '+ tasmotaVersion);// +' Zentrale: ' +Version[3]);
                      }
                      setState(id_Version_Internet, tasmotaVersion);
                  }
      
                  var devices = [];
      
                  cacheSelectorTasmotaVersions.each(function (id, i) {
                      var installedFirmware = getState(id).val.trim();
                      installedFirmware = installedFirmware.replace('(sonoff)', '').trim();
                      installedFirmware = installedFirmware.replace('(tasmota)', '').trim();
      
                      var obj = getObject(id);
                      var infoId = id.substring(0, id.lastIndexOf("."));
                      var hostName = getState(infoId + '.Hostname').val;
      
                      if(installedFirmware == tasmotaVersion){
                          if(logging){
                              log('Installierte Tasmota-Firmware für Gerät ' + hostName  + ' ist aktuell.');
                          }
                      } else {
                          if(logging){
                              log('Installierte Tasmota-Firmware für Gerät ' + hostName  + ' (' + installedFirmware + ') ist nicht aktuell. Aktuell verfügbare Version: ' + tasmotaVersion);
                          }
                          
                          if(availableFirmware == tasmotaVersion){
                              if(debugging){
                                  log('[DEBUG] ' + 'Version Internet hat sich nicht verändert');
                              }
                          } else {
                              if(debugging){
                                  log('[DEBUG] ' + 'Installierte Tasmota-Firmware ist nicht aktuell.');
                              }
                              
                              setState(id_Version_Internet, tasmotaVersion);
      
                              devices.push(hostName + ' (' + installedFirmware + ')');
                          }         
                      }
                  });
      
                  if(devices.length > 0) {
                      _message_tmp = 'Neue Tasmota-Firmware ' + tasmotaVersion + ' für folgende Geräte verfügbar:\n' + devices.join('\n');
              
                      //Push verschicken
                      if(sendpush){
                          _prio = prio_Firmware;
                          _titel = 'Tasmota-Firmware';
                          _message = _message_tmp;
                          send_pushover_V4(_device, _message, _titel, _prio);
                      }
                      if(sendtelegram){
                          _message = _message_tmp;
                          send_telegram(_message, user_telegram);
                      }
                      if(sendmail){
                          _message = _message_tmp;
                          send_mail(_message);
                      }
                  }
              }
          });
      }
              
      function send_pushover_V4 (_device, _message, _titel, _prio) {
              let pushover_Instanz;
              if (_prio === 0){pushover_Instanz =  pushover_Instanz0}
              else if (_prio == 1){pushover_Instanz =  pushover_Instanz1}
              else if (_prio == 2){pushover_Instanz =  pushover_Instanz2}
              else {pushover_Instanz =  pushover_Instanz3}
              sendTo(pushover_Instanz, { 
              device: _device,
              message: _message, 
              title: _titel, 
              priority: _prio,
              retry: 60,
              expire: 600,
              html: 1
          }); 
      }
      
      function send_telegram (_message, user_telegram) {
          sendTo('telegram.0', { 
              text: _message,
              user: user_telegram,
              parse_mode: 'HTML'
          }); 
      }
      
      function send_mail (_message) {
          sendTo("email", {
              //from:    "iobroker@mydomain.com",
              //to:      "aabbcc@gmail.com",
              subject: "Servicemeldung",
              text:    _message
          });
      }
      
      // um 10:00 Uhr prüfen
      schedule({hour: 10, minute: 0}, func_Version);
      
      //beim Starten
      func_Version();
      
      posted in Skripten / Logik
      M
      Machinima
    • RE: Material Design Widets: Netzwerk Status

      Neue Version des Skripts steht für euch bereit. An der View hat sich nichst geändert.
      Letzte An- und Abmeldung ist jetzt hinterlegt.
      Und ihr könnt jetzt eigene Bilder verwenden. Beachtet dazu die Hinweise im Skript!

      posted in Praktische Anwendungen (Showcase)
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Naja, wenn ich bspw. das StateListHorizontal- oder DisplayImage-Modul nehme, ist das immer links ausgerichtet. Ich würde das jedoch gerne zentriert ausrichten (ähnlich zu dem DateTime-Modul.), damit ich keine Unterbrechung im Design habe. Hier mal ein Beispiel:

      Baue ich gerne kurzfristig ein.

      Sehr cool, super Sache 👍

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Nein, das nicht. Ich stelle mir da eher so ein Modul vor, wie bspw. das Zeitplan-Element aus Blockly-Skripten (zu finden unter Triggers). Dann könnte man out of the box Cron Expressions im Dashboard bearbeiten und bräuchte nicht den Umweg über mehrere Datenpunkte gehen.

      Verstehe leider nicht, was du meinst. Ich kenne mich mit Blockly nicht aus. Sind "Cron Expressions" eine Funktion von Blockly? Du meinst du crontab -e unter Linux?

      Grundsätzlich ist jarvis eine Visualisierung und eine solche Logik gehört in einen Adapter, nicht in jarvis. Je nachdem, ob ich dich jetzt richtig verstanden habe.

      Achso, dann hole ich mal etwas weiter. Mir geht es weniger um die Verarbeitung einer Cron Expression (das macht bspw. der Script Engine Adapter), sondern um die Möglichkeit, eine Cron Expression (per Datenpunkt) visuell darzustellen bzw. dann auch bearbeiten zu können. Eine Cron Expression selbst ist nichts weiter als ein String bestehend aus 6 oder 7 Feldern, die jeweils ein bestimmtes Detail eines Zeitplans (Schedule) beschreiben. Hier ist eine gute Dokumentation (allerdings in Englisch).

      So viel zur Theorie, hier mal ein Beispiel von mir. Momentan verwende ich für einen Wecker folgende Hilfsstruktur
      Cron Helper.png

      In dem Blockly-Skript verwende ich unter anderem die Datenpunkte hoursCronPart, minutesCronPart und weekdayCronPart, um ein Schedule zu definieren.
      Blockly Schedule.png
      Diese Element erzeugt intern eine Cron Expression, wie in der oben genannten Dokumentation beschrieben.
      Beispiel (entspricht nicht dem oben genannten Abbild):

      0 0 12 * * ?
      

      Das Scheduling selbst übernimmt der Script Engine Adapter.
      Viel einfacher wäre es doch aber, direkt einen beliebigen Datenpunkt (der eine Cron Expression repräsentiert, z.B. unter 0_userData.0) in einem Jarvis-Modul einzubinden statt sich eine Hilfsstruktur überlegen zu müssen, um das irgendwie in Jarvis zu verwursten.

      Cron.png

      Wenn ich dann auf dieses Cron Expression-Widget in Jarvis klicken würde, würde eine Art Editor aufpoppen und ich könnte die Cron Expression schön visuell nach Material Design Pattern aufbereitet bearbeiten können. In einem der Schedule-Element von Blockly sieht das so, wenn man draufklickt:

      CronExpressions.png

      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Viel einfacher wäre es doch aber, direkt einen beliebigen Datenpunkt (der eine Cron Expression repräsentiert, z.B. unter 0_userData.0) in einem Jarvis-Modul einzubinden statt sich eine Hilfsstruktur überlegen zu müssen, um das irgendwie in Jarvis zu verwursten.

      Mit InputAction sollte das editierbar sein.

      Kann man machen, aber so eine Cron Expression ist nicht unbedingt leserlich. Ein entsprechender, visuell aufbereiteter Dialog würde das enorm vereinfachen. Ich weiß nicht, ob das überhaupt technisch umsetzbar ist und wie viel Aufwand das bedeutet.

      posted in Tester
      M
      Machinima

    Latest posts made by Machinima

    • RE: Adapter LightControl 0.4.x Stable

      @schmakus Evtl übersehe ich etwas, aber wo konfiguriere ich die einzelnen Lampen einer Gruppe?

      Screenshot 2022-12-23 135958.png

      posted in Tester
      M
      Machinima
    • RE: Adapter LightControl 0.4.x Stable

      @Schmakus Wäre es möglich, die Angabe des Lux-Sensors optional zu machen? Ich verwende das Pittini-Skript hauptsächlich nur dazu, um einzelne Lampen zu gruppieren (z.B. weil eine Stehlampe aus 2 Birnen besteht). Da ich keinen Lux-Sensor habe, kann ich deinen Adapter noch nicht so verwenden, wie ich das bräuchte

      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Timo-Winkler @Zefau
      Diesen Fehler habe ich seit ein paar Beta-Versionen ebenfalls

      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau said in jarvis - just another remarkable vis:

      Die Einheit im Datenpunkt bei der Geräte-Konfiguration hast du versucht anzupassen?

      Nein, ist alles beim alten. So sieht meine Konfiguration derzeit aus.

      LightTemperatureBody.png

      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau said in jarvis - just another remarkable vis:

      @WW1983 @Machinima sollte mit 1.1.0-beta.54 nun passen.

      Sieht jetzt gut, allerdings sind mir ein paar andere Fehler aufgefallen. Ich weiß nicht, ob die jetzt schon vorher bestanden oder erst mit der Beta 54 reingekommen sind.

      Beim Bearbeiten von Geräten mit dem Gewerk "Sonstiges" erhalte ich ebenfalls einen leeren Bildschirm, siehe Konsolenausgabe
      Fehler Gewerk Sonstiges.png

      Dann ist mir noch aufgefallen, dass die Zeitangaben vom Kalender in Englisch sind:

      • Mon, Tue, Wed... bei den Namen der Wochentage
      • October, December, January, etc. bei den Namen der Monate

      Die sollten sich doch eher an den Spracheinstellungen orientieren, oder? 😉
      Außerdem kann man nur Kalender bei dem Modul hinzufügen, nicht aber bestehende entfernen.

      Und der letzte Punkt:
      Wenn ich bei den Geräten vom Gewerk "Licht" das Body-Element LightTemperatureBody angebe, wird mir nicht die Kelvin-Skala angezeigt, sondern eine Prozentanzeige, so scheint es. Muss ich die Kelvin-Skala irgendwo angeben? Oder machst du das intern? Das Ergebnis sieht jedenfalls so aus:
      Fehler Anzeige LightTemperatureBody.png

      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau
      Bei mir wird ebenfalls, nach Hinzufügen des Kalendermoduls ein leerer Bildschirm angezeigt. Hier die Konsolenausgabe dazu (1.1.0beta.53 installiert):

      Fehler im Kalender Modul.png

      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Kann man machen, aber so eine Cron Expression ist nicht unbedingt leserlich. Ein entsprechender, visuell aufbereiteter Dialog würde das enorm vereinfachen. Ich weiß nicht, ob das überhaupt technisch umsetzbar ist und wie viel Aufwand das bedeutet.

      Grundsätzlich ist alles möglich, aber die Anforderung ist schon sehr speziell und in Anbetracht dessen, dass aktuell über 60 Feature Request offen sind wird das zeitlich eher eng.

      Verstehe. Ich habe auch nicht mit einer baldigen Umsetzung gerrechnet. Wenn das irgendwann mal kommt bzw. erstmal auf die Todo-Liste gesetzt wird, wäre ich auch schon froh. 😌 Insofern habe ich keine Bauchschmerzen damit, wenn andere Feature Requests erstmal Vorrang.

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Naja, wenn ich bspw. das StateListHorizontal- oder DisplayImage-Modul nehme, ist das immer links ausgerichtet. Ich würde das jedoch gerne zentriert ausrichten (ähnlich zu dem DateTime-Modul.), damit ich keine Unterbrechung im Design habe. Hier mal ein Beispiel:

      ist nun in 1.1.0-beta.38 verfügbar.

      Klappt grundsätzlich. Aber es gibt ein paar Probleme:
      Die Ausrichtung lässt sich nicht speichern. Davon abgesehen sind nun alle bisher erstellten Widgets mittig ausgerichtet. Default linksbündig wäre wohl meiner Meinung nach passender.

      Was mir auch auffällt: Der Adapter steht auf rot (siehe Log). Das Dashboard ist aber weiterhin aufrufbar, einzig das Wetter Modul kann nicht erfolgreich geladen werden.

      2020-10-18 16:54:27.946 - info: host.ioBroker-test instance system.adapter.jarvis.0 started with pid 28777
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: internal/modules/cjs/loader.js:960
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: throw err;
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: ^
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: Error: Cannot find module 'request-promise'
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: Require stack:
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: - /opt/iobroker/node_modules/iobroker.jarvis/jarvis.js
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Function.Module._resolveFilename (internal/modules/cjs/loader.js:957:15)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Function.Module._load (internal/modules/cjs/loader.js:840:27)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Module.require (internal/modules/cjs/loader.js:1019:19)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at require (internal/modules/cjs/helpers.js:77:18)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Object. (/opt/iobroker/node_modules/iobroker.jarvis/jarvis.js:4:18)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Module._compile (internal/modules/cjs/loader.js:1133:30)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Module.load (internal/modules/cjs/loader.js:977:32)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Function.Module._load (internal/modules/cjs/loader.js:877:14)
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) {
      2020-10-18 16:54:28.048 - error: host.ioBroker-test Caught by controller[0]: code: 'MODULE_NOT_FOUND',
      2020-10-18 16:54:28.049 - error: host.ioBroker-test Caught by controller[0]: requireStack: [ '/opt/iobroker/node_modules/iobroker.jarvis/jarvis.js' ]
      2020-10-18 16:54:28.049 - error: host.ioBroker-test Caught by controller[0]: }
      2020-10-18 16:54:28.049 - error: host.ioBroker-test instance system.adapter.jarvis.0 terminated with code 1 (JS_CONTROLLER_STOPPED)
      
      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Viel einfacher wäre es doch aber, direkt einen beliebigen Datenpunkt (der eine Cron Expression repräsentiert, z.B. unter 0_userData.0) in einem Jarvis-Modul einzubinden statt sich eine Hilfsstruktur überlegen zu müssen, um das irgendwie in Jarvis zu verwursten.

      Mit InputAction sollte das editierbar sein.

      Kann man machen, aber so eine Cron Expression ist nicht unbedingt leserlich. Ein entsprechender, visuell aufbereiteter Dialog würde das enorm vereinfachen. Ich weiß nicht, ob das überhaupt technisch umsetzbar ist und wie viel Aufwand das bedeutet.

      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Naja, wenn ich bspw. das StateListHorizontal- oder DisplayImage-Modul nehme, ist das immer links ausgerichtet. Ich würde das jedoch gerne zentriert ausrichten (ähnlich zu dem DateTime-Modul.), damit ich keine Unterbrechung im Design habe. Hier mal ein Beispiel:

      Baue ich gerne kurzfristig ein.

      Sehr cool, super Sache 👍

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Nein, das nicht. Ich stelle mir da eher so ein Modul vor, wie bspw. das Zeitplan-Element aus Blockly-Skripten (zu finden unter Triggers). Dann könnte man out of the box Cron Expressions im Dashboard bearbeiten und bräuchte nicht den Umweg über mehrere Datenpunkte gehen.

      Verstehe leider nicht, was du meinst. Ich kenne mich mit Blockly nicht aus. Sind "Cron Expressions" eine Funktion von Blockly? Du meinst du crontab -e unter Linux?

      Grundsätzlich ist jarvis eine Visualisierung und eine solche Logik gehört in einen Adapter, nicht in jarvis. Je nachdem, ob ich dich jetzt richtig verstanden habe.

      Achso, dann hole ich mal etwas weiter. Mir geht es weniger um die Verarbeitung einer Cron Expression (das macht bspw. der Script Engine Adapter), sondern um die Möglichkeit, eine Cron Expression (per Datenpunkt) visuell darzustellen bzw. dann auch bearbeiten zu können. Eine Cron Expression selbst ist nichts weiter als ein String bestehend aus 6 oder 7 Feldern, die jeweils ein bestimmtes Detail eines Zeitplans (Schedule) beschreiben. Hier ist eine gute Dokumentation (allerdings in Englisch).

      So viel zur Theorie, hier mal ein Beispiel von mir. Momentan verwende ich für einen Wecker folgende Hilfsstruktur
      Cron Helper.png

      In dem Blockly-Skript verwende ich unter anderem die Datenpunkte hoursCronPart, minutesCronPart und weekdayCronPart, um ein Schedule zu definieren.
      Blockly Schedule.png
      Diese Element erzeugt intern eine Cron Expression, wie in der oben genannten Dokumentation beschrieben.
      Beispiel (entspricht nicht dem oben genannten Abbild):

      0 0 12 * * ?
      

      Das Scheduling selbst übernimmt der Script Engine Adapter.
      Viel einfacher wäre es doch aber, direkt einen beliebigen Datenpunkt (der eine Cron Expression repräsentiert, z.B. unter 0_userData.0) in einem Jarvis-Modul einzubinden statt sich eine Hilfsstruktur überlegen zu müssen, um das irgendwie in Jarvis zu verwursten.

      Cron.png

      Wenn ich dann auf dieses Cron Expression-Widget in Jarvis klicken würde, würde eine Art Editor aufpoppen und ich könnte die Cron Expression schön visuell nach Material Design Pattern aufbereitet bearbeiten können. In einem der Schedule-Element von Blockly sieht das so, wenn man draufklickt:

      CronExpressions.png

      posted in Tester
      M
      Machinima
    • RE: jarvis v2.2.0 - just another remarkable vis

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Ich würde gern noch die Möglichkeit haben, die horizontale Ausrichtung von Widgets als auch deren Größe zu ändern (vor allem beim DisplayImage-Modul). Ich lasse mir u.a. den QR Code von meinen WLAN anzeigen. Allerdings sieht das auf meinem großen Desktop-Bildschirm gigantisch groß aus. Ändere ich die Höhe bzw. Breite des Moduls, ist die Anzeige da dann in Ordnung. Beim Smartphone ist es dann allerdings wieder zu klein.

      Was meinst du mit horizontaler Ausrichtung?

      Die Höhe von Widgets kannst du inzwischen anpassen (in Bezug zu DisplayImage).

      @Machinima sagte in jarvis - just another remarkable vis:

      Kann man irgendwie die Sichtbarkeit eines Widgets in Abhängigkeit von einem Switch oder Checkbox dynamisch setzen?

      Nein

      Naja, wenn ich bspw. das StateListHorizontal- oder DisplayImage-Modul nehme, ist das immer links ausgerichtet. Ich würde das jedoch gerne zentriert ausrichten (ähnlich zu dem DateTime-Modul.), damit ich keine Unterbrechung im Design habe. Hier mal ein Beispiel:
      Mittig zentrieren.png

      @Zefau said in jarvis - just another remarkable vis:

      @Machinima sagte in jarvis - just another remarkable vis:

      Außerdem würde ich mir gern auch ein Widget wünschen, mit dem man Cron Expression bearbeiten kann. Geht da was?

      Gibt es dafür einen Adapter für ioBroker?

      Nein, das nicht. Ich stelle mir da eher so ein Modul vor, wie bspw. das Zeitplan-Element aus Blockly-Skripten (zu finden unter Triggers). Dann könnte man out of the box Cron Expressions im Dashboard bearbeiten und bräuchte nicht den Umweg über mehrere Datenpunkte gehen.

      posted in Tester
      M
      Machinima
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo