Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Visualisierung
    4. [Vorlage] MDCSS v2: ical Kalendar anzeigen

    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

    [Vorlage] MDCSS v2: ical Kalendar anzeigen

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

      Hallo,

      bekomme beim starten des Scripts folgende Meldung:

      14:54:45.933 warn javascript.0 (22584) at MduiShowIcal.getState (script.js.Allgemein.Kalenderansicht:187:16)
      14:54:45.934 warn javascript.0 (22584) at MduiShowIcal.onBuildHTML (script.js.Allgemein.Kalenderansicht:608:73)
      14:54:45.934 warn javascript.0 (22584) at MduiShowIcal.doStart (script.js.Allgemein.Kalenderansicht:366:14)
      14:54:45.935 warn javascript.0 (22584) at MduiShowIcal.start (script.js.Allgemein.Kalenderansicht:112:26)
      14:54:45.936 warn javascript.0 (22584) at script.js.Allgemein.Kalenderansicht:724:18
      14:54:46.027 info javascript.0 (22584) script.js.Allgemein.Kalenderansicht: [mduiShowIcal] script started
      14:54:46.027 info javascript.0 (22584) script.js.Allgemein.Kalenderansicht: registered 3 subscriptions and 0 schedules

      und im log:

      javascript.0 2020-07-19 15:00:08.698 warn (22584) at process.topLevelDomainCallback (domain.js:126:23)
      javascript.0 2020-07-19 15:00:08.697 warn (22584) at processImmediate (timers.js:658:5)
      javascript.0 2020-07-19 15:00:08.696 warn (22584) at tryOnImmediate (timers.js:676:5)
      javascript.0 2020-07-19 15:00:08.696 warn (22584) at runCallback (timers.js:705:18)
      javascript.0 2020-07-19 15:00:08.695 warn (22584) at Immediate.setImmediate (/opt/iobroker/node_modules/iobroker.js-controller/lib/adapter.js:5384:37)
      javascript.0 2020-07-19 15:00:08.695 warn (22584) at Object.stateChange (/opt/iobroker/node_modules/iobroker.javascript/main.js:451:25)
      javascript.0 2020-07-19 15:00:08.694 warn (22584) at Object.callback (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1052:38)
      javascript.0 2020-07-19 15:00:08.694 warn (22584) at Object.subscribe.obj (script.js.Allgemein.Kalenderansicht:364:60)
      javascript.0 2020-07-19 15:00:08.694 warn (22584) at MduiShowIcal.onIcalTable (script.js.Allgemein.Kalenderansicht:391:12)
      javascript.0 2020-07-19 15:00:08.693 warn (22584) at MduiShowIcal.onBuildHTML (script.js.Allgemein.Kalenderansicht:608:73)
      javascript.0 2020-07-19 15:00:08.693 warn (22584) at MduiShowIcal.getState (script.js.Allgemein.Kalenderansicht:187:16)
      javascript.0 2020-07-19 15:00:08.690 warn (22584) getState "0_userdata.0.mdui.showIcal.log0.filter" not found (3)

      Habe ich noch was vergessen einzustellen?

      Nach stundenlanger Wartezeit geht es auf einmal.

      Gruß Holger

      E 1 Reply Last reply Reply Quote 0
      • E
        Ente @Holger Etzel last edited by

        @sigi234

        Hallo siggi234,

        danke für den Install-Screenshot. 😉

        sigi234 1 Reply Last reply Reply Quote 0
        • sigi234
          sigi234 Forum Testing Most Active @Ente last edited by sigi234

          @Ente sagte in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

          @sigi234

          Hallo siggi234,

          danke für den Install-Screenshot. 😉

          Screenshot (674)_LI.jpg

          /*
          *** MduiShowIcal
          Dieses Script überwacht den ical-Adapter und erzeugt bei Änderungen an dessen States HTML-List States für die Anzeige als 
          Kalender in Listform mit
          * Tagesauflösung von "von/bis"-Terminen, inkl. Berücksichtigung der Uhrzeiten
          * Tagesdatum, Kalendarfarben aus ical oder optional aus dem Script
          * Termintext und -ort
          * optionalem Icon je Kalendar
          * optionalem "ignore", wenn ein Kalendar unberücksichtigt bleiben soll
          
          Es werden States für n-Logs erzeugt, jedem, Log kann ein Standardfilter mitgegeben werden. In jedem Log-Ordner 
          befindet sich ein list-HTML State, welcher direkt in der vis angezeigt werden kann (jeweils im basic-string (unescaped) Widget). 
          Über optionale Filter als string (Bsp:':Abfall:') oder als RegExp (Bsp:'/Feiertag|Geburtstag/') kann festgelegt werden, 
          welche Einträge beim Aufbau der list-HTML States berücksichtigt werden. 
          Bsp.: 
          log0 Filter: "abfall" oder ":Abfall:" (=Kalendarname) -> Zeigt nur Abfalltermine
          log0 Filter: "ferien" oder ":Ferien:" (=Kalendarname) -> Zeigt nur Ferientermine
          
          
          **** Installation
          Einfach als serverseitiges Script installieren und starten-5 Sek warten-stoppen-starten. Beim 1.Start werden 
          die notwendigen States unter STATE_PATH = '0_userdata.0.mdui.showIcal.' erzeugt. Erst beim 2.Start
          instanziiert das Script die Event-Handler und läuft dann.
          
          **** Konfiguration
          Eigentlich ist keine notwendig.
          Optional in der Funktion MduiShowIcal|doInit() eine Anpassung der KONFIGURATION vornehmen
          Optional Anpassung der tmpList.
            
          **** Dokumentation
          https://github.com/Uhula/ioBroker-Material-Design-Style/wiki/3.5-MduiShowIcal
          
          ###### Um ein Feedback zu erhalten wäre es schön, wenn jeder, der diese Vorlagen nutzt, den  1.Beitrag des Themas positiv bewertet (Pfeil nach oben oder unten ;-) ). Ich kann dann auch abschätzen, ob sich die weitere Pflege lohnt. Thx!
          
          ***** States
          Unter dem STATE_PATH werden die folgenden States erzeugt:
          version : Script-Version, wird verwendet um Script-Updates zu erkennen
          updatePressed : auf true setzen, wenn ein table/list update außerhalb des Intervals erfolgen soll
          
          Weiterhin werden MAX_LOG_FOLDER Unterordner im STATE_PATH erzeugt (N=0-9):
          
          * LogN.table        : enthält die table-HTML für ein basic-string (unescaped) Widget
          * LogN.list         : enthält die list-HTML für ein basic-string (unescaped) Widget
          * LogN.count        : Anzahl der Log-Zeilen (wenn das Log mit '/:error:|:warn:/' gefiltert ist, dann ist es die Anzahl der Fehler/Warnungen)
          * LogN.filter       : Filter, der auch die logCache angewendet wurde im .table/.list zu erzeugen (siehe Filter)
          * LogN.lastUpdate   : Timestamp des letzten Updates
          
          
          ***** Filter
          In den filter-States können sowohl strings (Bsp:'error') als auch RegExp-Strings (Bsp:'/warn|error/') 
          hinterlegt werden. RegExp-Strings werden an den einschließenden  '/' erkannt. Über den ':' kann der Anfang
          eines Feldes mit in den Filter einbezogen werden. 
          Beispiele: 
          '/Feiertag|Geburtstag/' (RegExp) zeigt alle Zeilen an, in denen 'Feiertag' oder 'Geburtstag' in irgendeinem Feld vorkommen
          ':Abfall:' (string) zeigt alle Zeilen an, welche derKalendar 'Abfall' lautet
          'Arzt' (string) zeigt alle Zeilen an, in denen 'Arzt' in irgendeinem Feld vorkommt
          
          **** Lizenz
          (c) 2020 by UH, MIT License, no warranty, use on your own risc
          
          *** Changelog
          2020.05.01 UH 
          * Anpassung an neues MduiBase (intern)
          * Anpassung an MDCSS 2.5
          * Serientermine vor dem aktuellem Datum werden nicht mehr angezeigt
          
          */
          
          // ------------------------------------------------------------------------------------- 
          // MduiBase
          // ------------------------------------------------------------------------------------- 
          
          class MduiBase {
          
              constructor() {
                this.init();
              }
              
              //
              init() {
                  // const
                  this.DEBUG      = false;
                  this.VERSION    = '1.0/2020-01-01';
                  this.NAME       = 'mduiBase';
                  this.STATE_PATH = '0_userdata.0.mdui.base.';
                  this.STATE_UNKNOWN    =  0;
                  this.STATE_INSTALLING = 10;
                  this.STATE_INSTALLED  = 11;
                  this.STATE_STARTING   = 20;
                  this.STATE_STARTED    = 21;
                  this.STATE_STOPPING   = 30;
                  this.STATE_STOPPED    = 31;
              
                  // var
                  this.state = this.STATE_UNKNOWN;
                  this.states = [];
                  this.subscribers = [];
                  this.schedulers = [];
              
                  this.doInit();
              
                  // init der states
                  this.states.push( { id:'version',     common:{name:'installed script-version', write:false, def:this.VERSION} } );
              }
              
              //
              // start the script/class
              //
              start() {
                  // beim 1.Start nur die States erzeugen
                  if ( !this.existState("version") || (this.getState('version').val!=this.VERSION) ) {
                      for (let s=0; s<this.states.length; s++) { this.createState( this.states[s].id ); }
                      this.logWarn('first script start, creating states for version '+this.VERSION+', automatic restarting script again in 10 sec ...');
                      setStateDelayed(this.STATE_PATH + 'version', this.VERSION, 3000);
                      setTimeout( this.start.bind(this), 10000 );
                      this.state = this.STATE_INSTALLED; 
                      return;
                  }
                  switch (this.state) {
                      case this.STATE_UNKNOWN : ;
                      case this.STATE_INSTALLING : ;
                      case this.STATE_INSTALLED : ;
                      case this.STATE_STOPPED : {
                          this.state = this.STATE_STARTING; 
                          if (this.doStart()) {
                              this.log('script started');
                              this.state = this.STATE_STARTED;
                          }
                          break;    
                      }
                      case this.STATE_STARTING : ;
                      case this.STATE_STARTED : {
                          this.logWarn('script already starting/started');
                          break;    
                      }
                      case this.STATE_STOPPING : {
                          this.logWarn('script is stopping, pls start later again');
                          break;    
                      }
                
                  } 
              }
              
              //
              // stop the script/class
              //
              stop() {
                  switch (this.state) {
                      case this.STATE_STARTED : {
                          this.state = this.STATE_STOPPING; 
                          if (this.doStop()) {
                              for (let i=0; i<this.subscribers.length; i++) if (this.subscribers[i] !== undefined) unsubscribe( this.subscribers[i] );
                              this.subscribers = [];
                              for (let i=0; i<this.schedulers.length; i++) if (this.schedulers[i] !== undefined) clearSchedule( this.schedulers[i] );
                              this.schedulers = [];
                              this.state = this.STATE_STOPPED; 
                              this.log('script stopped');
                          }
                          break;    
                      }
                      default : {
                          this.log('cant stopp script, because not startet');
                      }
                  } 
              }
              
              //
              // virtual functions, overwrite it 
              //
              doInit() { return true; }
              doStart() { return true; }
              doStop() { return true; }
              
              // einen on-Handler registrieren
              subscribe( handler ) {
                  this.subscribers.push( handler );
              }
              
              // einen timer registrieren
              schedule( handler ) {
                  this.schedulers.push( handler );
              }
              
              //
              // tool functions 
              //
              logDebug(msg) { if (this.DEBUG) console.log('['+this.NAME+'] '+msg); }
              log(msg) { console.log('['+this.NAME+'] '+msg); }
              logWarn(msg) { console.warn('['+this.NAME+'] '+msg); }
              logError(msg) { console.error('['+this.NAME+'] '+msg); }
              
              // über den $-Operator nachsehen, ob der state bereits vorhanden ist
              // getState().notExists geht auch, erzeugt aber Warnmeldungen!
              existState(id) {
                  return ( $(this.STATE_PATH+id).length==0?false:true);
              }
              
              // wrapper, adds statepath to state-ID
              getState(id) {
                  return getState(this.STATE_PATH + id);
              }
              
              // like setState(), but adds statepath to state_ID and checks if state exists, when not, creates it
              setState(id,value) {
                  if ( !this.existState(id) ) this.createState(id,value,undefined);
                  else setState( this.STATE_PATH + id, value);
              }
              
              // like cresteState(), but adds statepath to state_ID and checks if state exists, when not, creates it
              createState(id,value,common) {
                  if ( !this.existState(id) ) {
                      if (common===undefined) {
                          // id im states-Array suchen
                          for (var i=0; i<this.states.length; i++) { 
                              if (this.states[i].id==id) {
                                  if (this.states[i].hasOwnProperty('common'))
                                      common = this.states[i].common;
                                 break;
                              }   
                          }
                      }
                      if ( (typeof value === 'undefined') && (common.hasOwnProperty('def'))) value = common.def;
                      // unter "0_userdata.0"
                      let obj = {};
                      obj.type = 'state';
                      obj.native = {};
                      obj.common = common;
                      setObject(this.STATE_PATH + id, obj, (err) => {
                              if (err) {
                                  this.log('cant write object for state "' + this.STATE_PATH + id + '": ' + err);
                              } else { 
                                  this.log('state "' + this.STATE_PATH + id + '" created');
                              }
                      });
              
                      setTimeout( setState, 3000, this.STATE_PATH + id, value );
                  }
              }
              
              // true, if str contains filter string or regexp 
              fitsFilter(str, filter) {
                  if ( (filter===undefined) || !filter || (filter=='') )
                      return true;
                  if ( filter instanceof RegExp )  {
                      if (str.match( filter ) != null) return true;
                  } else if (typeof filter == 'string') {
                      if(str.includes(filter)) return true;
                  }
                  return false;        
              }
              
              //
              escapeRegExp(str) {
                  return str.replace(/[.*+?^${}()|[]\]/g, '\\$&'); 
              }
              
              // wandelt eine Farbe im hex-Format (#000000) in ein RGB-Array[2] um
              hexToRGB(hex) {
                  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
                  return result 
                      ? [parseInt(result[1],16),parseInt(result[2],16),parseInt(result[3],16)]
                      : [0,0,0];
              };
              
              // Helligkeit berechnen
              getLuminance(r, g, b) {
                  var a = [r, g, b].map(function (v) {
                      v /= 255;
                      return v <= 0.03928
                          ? v / 12.92
                          : Math.pow( (v + 0.055) / 1.055, 2.4 );
                  });
                  return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
              }
              
              // Kontrats berechnen
              getContrast(rgb1, rgb2) {
                  var l1 = this.getLuminance(rgb1[0], rgb1[1], rgb1[2]) + 0.05;
                  var l2 = this.getLuminance(rgb2[0], rgb2[1], rgb2[2]) + 0.05;
                  if ( l1 > l2 ) return l1 / l2 
                  else return l2 / l1;
              }
              
              // liefert die fontColor auf Basis der backgroundColor durch Berechnung
              // des Kontrasts
              getFontColor(backgroundColor) {
                  if ( this.getContrast(this.hexToRGB(backgroundColor),this.hexToRGB("#000000")) < 6 ) 
                      return "#ffffff";
                  else
                      return "#000000";
              }
              
              }
              
              // ------------------------------------------------------------------------------------- 
              // MduiLogHMDevices
              // ------------------------------------------------------------------------------------- 
              
              class MduiShowIcal extends MduiBase {
              
              constructor() {
                  super();
              }
              
              doInit() {
                super.doInit();
              
                // const
                this.DEBUG = false;
                this.VERSION = '1.0/2020-03-22';
                this.NAME = 'mduiShowIcal';
                this.DAY_MILLISECONDS = 60 * 60 * 24 * 1000;
              
                // -----------------------  
                // optional: KONFIGURATION
                // -----------------------  
                                     // state-Pfad unter dem die States angelegt werden  
                this.STATE_PATH      = '0_userdata.0.mdui.showIcal.'; 
                                     // Anzahl der Table/List Ordner mit eigenem Filter/View
                this.MAX_LOG_FOLDER  = 3;   
                                     // max.Anzahl der Zeilen für die Table/List Ausgabe
                this.MAX_TABLE_ROWS  = 200; 
                                     // Objekt-Pfad zum ical.x.data.table
                this.ICAL_TABLE      = 'ical.0.data.table';
                                     // siehe: https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#formatdate
                this.DATE_FORMAT     = 'W DD.MM.YYYY hh:mm';
                                     // optional können dem Kalendar noch Icons und abweichende
                                     // Farben angegeben werden (diese überschreiben jene aus iCal)
                                     // 'icon'     : 'Icon-Name' (MDCSS/Google WebFont)
                                     // 'calColor' : *#rrggbb' abweichende Kalendarfarbe 
                                     // 'ignore'   : true|false Kalendar komplett ignorieren
                this.CALENDAR        = {'mdui-Abfall'      : {'icon':'delete_outline', 'calcolor':'orange' },
                                        'mdui-Geburtstage' : {'icon':'cake'},
                                        'Familie'          : {'ignore':true}
                                         
                                       };
              
                // -----------------------  
                // ENDE KONFIGURATION
                // -----------------------  
              
                // var
                this.logs = [];
                for (let i=0; i<=this.MAX_LOG_FOLDER && i<10; i++) 
                    this.logs.push({filter:'' });
                
              
                // init der states
                this.states.push( { id:'version',     common:{name:'installed script-version', write:false, def:this.VERSION} } );
                this.states.push( { id:'updatePressed',common:{name:'update button pressed', write:true, type:'boolean', def:'false', role:'button' }} );
                
                let defFilter;
                for (let i=0; i<=this.MAX_LOG_FOLDER && i<10; i++) {
                    switch (i) {
                        case 1 : defFilter = ':Abfall:'; break;   
                        case 2 : defFilter = 'Geburtstag'; break;   
                        case 3 : defFilter = ''; break;   
                        default: defFilter = undefined;
                    }
                    this.states.push( { id:'log'+i+'.table',      common:{name:'ioBroker-log as table', write:false, role:'html' }} );
                    this.states.push( { id:'log'+i+'.list',       common:{name:'ioBroker-log as list', write:false, role:'html' }} );
                    this.states.push( { id:'log'+i+'.count',      common:{name:'ioBroker-log count', write:false, type:'number', def:'0' }} );
                    this.states.push( { id:'log'+i+'.filter',     common:{name:'ioBroker-log filter', write:true, def:defFilter}} );
                    this.states.push( { id:'log'+i+'.lastUpdate', common:{name:'ioBroker-log last update', write:false, def:'0' }} );
                }
              
                return true;  
              }
              
              // start the script/class
              doStart() {
                  super.doStart();
                  
                  // subscriber erzeugen
                  this.subscribe( on( this.STATE_PATH+'updatePressed', obj => { this.onUpdate(obj) } ));
                  this.subscribe( on( new RegExp( this.STATE_PATH+'*.filter' ), obj => { this.onFilter(obj) } ));
                  this.subscribe( on( this.ICAL_TABLE, obj => { this.onIcalTable(obj) } ));
              
                  this.onBuildHTML();
                  return true;
              }
              
              // stop the script/class
              doStop() {
                  super.doStop();
                  return true;
              }
              
              // 
              onUpdate(obj) {
                  if (obj.state.val===true) {
                      this.onBuildHTML();
                  }
                  this.setState('updatePressed', false);
              }
              
              // filter, sort events
              onFilter(obj) {
                this.onBuildHTML();
              }
              
              // Ical table hat sich geändert
              onIcalTable(obj) {
                this.onBuildHTML();
              }
              
              
              
              // creates the HTML states for every log
              /*
              'date' => "→ 16.10.2017" 
              'event' => "9.30 - 16.30 Uhr Stopka " 
              '_class' => "ical_Kerstin ical_today" 
              '_date' => "2017-10-16T07:30:00.000Z" 
              '_end' => "2017-10-16T14:30:00.000Z" 
              '_section' => "" 
              '_IDID' => "040000008200E00074C5B7101A82E008000000007645DC55A6DFC44FB2EC6FEA9EFEA33C100000007688316058136F42AD128D91103543C9" 
              '_allDay' => "false" 
              '_rule' => " " 
              '_calName' => "Kerstin" 
              
              Optionen der ical-Instanz:
                  'daysPreview' => "7"
                  'colorize' => "false"
                  'defColor' => "white"
                  'fulltime' => " 00:00"
                  'dataPaddingWithZeros' => "true"
                  'replaceDates' => "false"
                  'language' => "de"
                  'everyCalOneColor' => "true"
                  'calendars' (array) 
                      '0' (array) 
                          'name' => "Abfall"
                          'url' => "https://calendar.google.com/calendar/ical/ruo0ddgalu03qq2ehpm8imqnk4%40group.calendar.google.com/private-a30aac0367f8b50cfd7373f6222d29b4/basic.ics"
                          'user' => ""
                          'pass' => ""
                          'sslignore' => ""
                          'color' => ""
              */
              
              isSameDay(d1,d2) {
                  return (d1.getDate()==d2.getDate()) && (d1.getMonth()==d2.getMonth()) && (d1.getFullYear()==d2.getFullYear());
              }
              
              getWeekNumber( date ) {
                  let d = new Date(date);
                  d.setHours(0,0,0);
                  d.setDate(d.getDate()+4-(d.getDay()||7));
                  return Math.ceil((((d-new Date(d.getFullYear(),0,1))/8.64e7)+1)/7);
              };            
              
              //
              buildEntry( entry ) {
                  const WEEKDAY_NAMES = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
                  const MONTH_NAMES = ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"];
              
                  let beginDate = new Date( entry.beginDateISO );
                  entry.beginTime = beginDate.getTime();
                  entry.beginWeekDay = beginDate.getDay(); // 0=Sonntag 6=Samstag
                  entry.beginWeekDayName = WEEKDAY_NAMES[entry.beginWeekDay]; 
                  entry.beginDay = beginDate.getDate();
                  entry.beginMonth = beginDate.getMonth();
                  entry.beginMonthName = MONTH_NAMES[entry.beginMonth]; 
                  entry.beginYear = beginDate.getFullYear();
                  entry.beginHour = beginDate.getHours();
                  entry.beginMinute = beginDate.getMinutes();
                  entry.beginDate = formatDate(beginDate,  this.DATE_FORMAT);
              
                  let currDate = new Date( entry.currDateISO );
                  entry.currTime = currDate.getTime();
                  entry.currWeekDay = currDate.getDay(); // 0=Sonntag 6=Samstag
                  entry.currWeekDayName = WEEKDAY_NAMES[entry.currWeekDay]; 
                  entry.currDay = currDate.getDate();
                  entry.currMonth = currDate.getMonth();
                  entry.currMonthName = MONTH_NAMES[entry.currMonth]; 
                  entry.currYear = currDate.getFullYear();
                  entry.currHour = currDate.getHours();
                  entry.currMinute = currDate.getMinutes();
                  entry.currDate = formatDate(currDate,  this.DATE_FORMAT);
                  entry.currDateOnly = entry.currYear*10000+entry.currMonth*100+entry.currDay;
              
              
                  let endDate = new Date( entry.endDateISO );
                  //allDay Korrektur: liefert immer einen Tag zu viel
                  if (entry.allDay && endDate.getHours()==0) endDate.setTime( endDate.getTime() - this.DAY_MILLISECONDS);
                  entry.endTime = endDate.getTime();
                  entry.endWeekDay = endDate.getDay(); // 0=Sonntag 6=Samstag
                  entry.endDay = endDate.getDate();
                  entry.endMonth = endDate.getMonth();
                  entry.endYear = endDate.getFullYear();
                  entry.endHour = endDate.getHours();
                  entry.endMinute = endDate.getMinutes();
                  entry.endDate = formatDate(endDate, this.DATE_FORMAT);
              
                  // 
                  if (entry.currWeekDay==0 || entry.currWeekDay==6) entry.dayColor = '#f44336'
                  else entry.dayColor = 'inherited';
              
                  // 
                  if (entry.currWeekDay==1) entry.week = this.getWeekNumber(currDate)+'.W';
                  else entry.week = '';
              
                  // 
                  if (entry.currTime < Date.now() ) entry.opacity = '.66'
                  else entry.opacity = '1';
              
                  // Zeitraumangabe berechnen
                  entry.hint = '';
                  if ( !this.isSameDay(beginDate, endDate) ) {
                          // mehrtägig
                          if (entry.allDay)
                              entry.timeSpan = 'ganztägig ';
                          else if ( this.isSameDay(beginDate, currDate) ) 
                                  entry.timeSpan = 'ab ' + formatDate(beginDate,'hh:mm');
                               else if ( this.isSameDay(endDate, currDate) ) 
                                        entry.timeSpan = 'bis ' + formatDate(endDate,'hh:mm');
                                    else 
                                         entry.timeSpan = 'ganztägig ';
                      } else {
                          // an einem Tag
                          if (entry.allDay)
                              entry.timeSpan = 'ganztägig';
                          else if ( (entry.beginHour!=entry.endHour) || (entry.beginMinute!=entry.endMinute)  ) 
                                   entry.timeSpan = formatDate(beginDate,'hh:mm') + '-' + formatDate(endDate,'hh:mm');
                               else   
                                   entry.timeSpan = formatDate(beginDate,'hh:mm');
                      }
                  return entry;        
              };
              
              
              onBuildHTML() { try {
              
                  let json = [];  
                  let calTable = getState(this.ICAL_TABLE);
                  let inst     = getObject("system.adapter."+this.ICAL_TABLE.substr(0,6));
                  let instopt  = inst.native;
                  let calendar = {};
                  let cal      = {};
                  let calOptions = {};
                  let todayDate = new Date();
                  let today = todayDate.getFullYear()*10000+todayDate.getMonth()*100+todayDate.getDate();
              
              
                  for (var i = 0; i < calTable.val.length; i++) { 
                    cal = calTable.val[i];
                    let entry = {};
                    if ( cal._calName != calendar.name ) {
                          calendar = {};
                          // color suchen
                          for (let c = 0; c < instopt.calendars.length; c++ ) {
                              if (cal._calName == instopt.calendars[c].name ) {
                                  calendar = instopt.calendars[c];
                                  break;
                              }
                          }
                          // options suchen
                          if (this.CALENDAR.hasOwnProperty(cal._calName)) calOptions = this.CALENDAR[cal._calName];
                          else calOptions={};
                      }    
                      if (calOptions.hasOwnProperty('ignore') && calOptions.ignore ) continue;
              
                      if (calOptions.hasOwnProperty('calcolor')) entry.calColor = calOptions.calcolor;
                      else if (calendar.color !== "") entry.calColor = calendar.color;
                           else entry.calColor = '#000000';
                      entry.color = this.getFontColor( entry.calColor ); 
                      if (calOptions.hasOwnProperty('icon')) entry.icon = calOptions.icon;
                      else entry.icon='';
              
                      entry.date = cal.date;
                      entry.event = cal.event;
                      entry.calName = cal._calName;
                      entry.beginDateISO = cal._date;
                      entry.currDateISO = cal._date;
                      entry.endDateISO  = cal._end;
                      entry.allDay  = cal._allDay; 
                      entry.location = cal.location;
              
                      entry = this.buildEntry( entry);
              
                      if (entry.currDateOnly >= today)
                          json.push( entry );
              
                      // Listenansicht
                      // in calTable steht nur ein Eintrag für jeden Beginn, für die List-Darstellung
                      // sind diese auch je Tag notwendig - hier jetzt bilden 
                      if ( (entry.beginDay!=entry.endDay) || (entry.beginMonth!=entry.endMonth) || (entry.beginYear!=entry.endYear) ) {
                          let currTime = new Date(entry.beginDateISO).getTime() + this.DAY_MILLISECONDS;
                          let endTime = new Date(entry.endDateISO).getTime();
                          if (entry.allDay) endTime -= + this.DAY_MILLISECONDS;
                          let dayMax=Math.trunc( 2 + (endTime - currTime) /this. DAY_MILLISECONDS); 
                          entry.hint += ' (Tag 1/'+dayMax+')';
                          let dayCount=2; 
                          while (currTime <= endTime && dayCount<100) {
                              let newEntry = {};
                              Object.assign(newEntry, entry);
                              newEntry.currDateISO = new Date(currTime).toISOString();
                              newEntry = this.buildEntry( newEntry );
                              newEntry.hint += ' (Tag '+dayCount+'/'+dayMax+')';
                              if (newEntry.currDateOnly >= today)
                                  json.push( newEntry );
                              currTime = currTime + this.DAY_MILLISECONDS;
                              dayCount++;
                          }
              
                      }
                  }
              
                  // sortieren
                  json.sort( (l,r) => {
                            let lv=l['currTime'],rv=r['currTime'];
                            return ((lv < rv) ? -1 : (lv > rv) ? 1 : 0);
                        } );
                      
                // build table/list HTML
                for (let i=0; i<=this.MAX_LOG_FOLDER && i<10; i++) {
                    let log = this.logs[i];
                    log.filter = '';
                    log.ts = 0;
                    log.idState = 'log'+i;
                    if (this.existState(log.idState+'.filter')) log.filter = this.getState(log.idState+'.filter').val;
                    if (this.existState(log.idState+'.lastClear')) log.ts = this.getState(log.idState+'.lastClear').val;
              
                    this.convertJSON2HTML(json, log);
                }
              } catch(err) { this.logError( 'onBuildHTML: '+err.message ); }  }
              
              
              // color date event calName beginDate endDate allDay
              convertJSON2HTML(json, log) {
              const tmpTable = {
              header : 
              `<tr>
              <th style="text-align:right;"></th>
              <th style="text-align:left;"></th>
              <th style="text-align:left;"></th>
              <th style="text-align:left;"></th>
              <th style="text-align:left;"></th>
              <th style="text-align:left; min-width:12em;">Betreff</th>
              <th style="text-align:left;">Zeit</th>
              <th style="text-align:left;">Ort</th>
              <th style="text-align:left;">Kalendar</th>
              <th style="text-align:left;"></th>
              </tr>`,
              row : 
              `<tr>
              <td style="text-align:right;">
                 <span style="display:{showDay}; color:{dayColor}; font-size:1.5em; opacity:1; font-weight:bold;">{currDay}</span>
              </td>
              <td>
                 <span style="display:{showDay}; font-size:0.8em; margin-top:0.3em; margin-left:4px; opacity:.8;">{currMonthName}</span>
              </td>
              <td>
                 <span style="display:{showDay}; font-size:0.8em; margin-top:0.3em; opacity:.8;">{currWeekDayName}</span>
              </td>
              <td>
                <span style="display:inline-block; width:.8em; height:.8em; margin-top:0.3em; background:{calColor}; border-radius:50%;">&nbsp;</span>
              </td>
              <td>
                <i class='material-icons mdui-center {color}' style='font-size:1.2em;'>{icon}</i>
              </td>
              <td>{event}</td>
              <td><span style="font-size:1.0em; opacity:.8;">{timeSpan} {hint}</span></td>
              <td>{location}</td>
              <td><span style="font-size:0.8em; opacity:.8;color:{calColor};">{calName}</span></td>
              <td></td>
              </tr>`
              }
              
              const tmpList = {
              row : 
              `<div class="mdui-listitem" style="font-size:1em; width:100%; display:flex; opacity:{opacity};">
                <div style="min-width:3.5em;">
                  <div style="display:{showDay}; color:{dayColor};">
                    <span style="font-size:1.5em; opacity:1; font-weight:bold;">{currDay}</span>
                    <span style="font-size:0.8em; margin:4px; opacity:.8;">{currMonthName}<br/>
                    {currWeekDayName}</span>
                  </div>
                  <div style="display:{showDay}; text-align:right; font-size:0.6em; opacity:.6;">{week}</div>
                </div>
                <div style="min-width:1.2em;">
                  <div style="width:.8em; height:.8em;  margin:.1em; text-align:center; background:{calColor}; border-radius:50%;">&nbsp;</div>
                  <div class="mdui-icon" style="font-size:1.1em; text-align:center; margin-top:0.33em;">{icon}</div>
                </div>
                <div style="width:100%; margin-left:.25em;">
                  <div style="">
                    <div style="font-size:1.1em;">{event}</div>
                  </div>
                  <div style="width:100%; display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between;">
                    <div style="font-size:1.0em; opacity:.8;">
                      {timeSpan}
                      <span style="font-size:0.8em;">{hint} {location}</span>
                    </div>
                    <div style="font-size:0.8em; opacity:.8;color:{calColor};">{calName}</div>
                  </div>
                </div>
              </div>`}
                  // build htmlTable and htmlList
                  let htmlTable  = "<table><thead>"+tmpTable.header+"</thead><tbody>";
                  for (let [key, value] of Object.entries(log)) htmlTable = htmlTable.replace(new RegExp('{'+key+'}','g'),value);
                 
                  let htmlList  = "";
                  let entry, tr;
                  let count = 0;
                  // filter as regex?
                  if ( log.filter!==undefined && typeof log.filter == 'string' && log.filter.startsWith('/') && log.filter.endsWith('/') && (log.filter.length>=2) )  {
                      log.filter = new RegExp(log.filter.substr(1,log.filter.length-2), 'i');
                  }
              
                  let lastEntry = {};
                  for (var i = 0; i < json.length && count<this.MAX_TABLE_ROWS; i++) { 
                      entry = json[i];
                      if (this.fitsFilter(':' + entry.currDate + ':' + entry.event +':'+entry.calName + ':' + entry.location + ':',log.filter)) {
                          entry.showDay = (lastEntry=={}) || (entry.currDay!=lastEntry.currDay) || (entry.currMonth!=lastEntry.currMonth) || (entry.currYear!=lastEntry.currYear)?'flex':'none';
                          lastEntry = entry;
                          tr = tmpTable.row;    
                          for (let [key, value] of Object.entries(entry)) tr = tr.replace(new RegExp('{'+key+'}','g'),value);
                          htmlTable+=tr;
                          tr = tmpList.row;    
                          for (let [key, value] of Object.entries(entry)) tr = tr.replace(new RegExp('{'+key+'}','g'),value);
                          htmlList+=tr;
                          count++;
                      }
                  }
                  htmlTable+="</body></table>";    
                  this.setState(log.idState+'.table', htmlTable);  
                  this.setState(log.idState+'.list', htmlList);  
                  this.setState(log.idState+'.count', count);  
                  this.setState(log.idState+'.lastUpdate', +new Date());  
              }
              
              }
              
              
              // create instance and start
              var mduiShowIcal = new MduiShowIcal( );
              mduiShowIcal.start();
              
              // on script stop, stop instance too
              onStop(function () { 
                  mduiShowIcal.stop(); 
              }, 1000 );
          
          E 1 Reply Last reply Reply Quote 0
          • E
            Ente @sigi234 last edited by Ente

            @sigi234

            Skript läuft. Vielen Dank.

            Tut mir leid sigi. Wie bekomme ich das nun in meine vis integriert. Entschuldige bitte die Dummy-Frage.

            sigi234 1 Reply Last reply Reply Quote 0
            • sigi234
              sigi234 Forum Testing Most Active @Ente last edited by

              @Ente sagte in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

              @sigi234

              Skript läuft. Vielen Dank.

              Tut mir leid sigi. Wie bekomme ich das nun in meine vis integriert. Entschuldige bitte die Dummy-Frage.

              Es werden States für n-Logs erzeugt, jedem, Log kann ein Standardfilter mitgegeben werden. In jedem Log-Ordner
              befindet sich ein list-HTML State, welcher direkt in der vis angezeigt werden kann (jeweils im basic-string (unescaped) Widget).

              E 1 Reply Last reply Reply Quote 0
              • E
                Ente @sigi234 last edited by Ente

                @sigi234 said in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                @Ente sagte in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                @sigi234

                Skript läuft. Vielen Dank.

                Tut mir leid sigi. Wie bekomme ich das nun in meine vis integriert. Entschuldige bitte die Dummy-Frage.

                Es werden States für n-Logs erzeugt, jedem, Log kann ein Standardfilter mitgegeben werden. In jedem Log-Ordner
                befindet sich ein list-HTML State, welcher direkt in der vis angezeigt werden kann (jeweils im basic-string (unescaped) Widget).

                Genau das habe ich gerade gefunden. Es zeigt auch die Termine an,

                feb6d00b-f448-415c-a618-733025c42ac5-image.png

                leider nicht so wie in dem Bild im 1. Post. bzw. wie hier:

                https://forum.iobroker.net/topic/31635/vorlage-mdcss-v2-ical-kalendar-anzeigen/15
                1ad94760-95e1-46fb-ac36-f89d3a9b77ad-image.png

                Ich vermute mal, dass ich das im Skript selbst ändern muss. Mal sehen.

                Edit: Das Datum erscheint schon einmal. Jetzt will ich noch die Farben ändern. Den Filter habe ich auch nicht.

                sigi234 1 Reply Last reply Reply Quote 0
                • sigi234
                  sigi234 Forum Testing Most Active @Ente last edited by sigi234

                  @Ente

                  Hast du die Vorlage heruntergeladen und als View importiert?

                  https://github.com/Uhula/ioBroker-Material-Design-Style/tree/master/templates/MduiShowIcal

                  E 1 Reply Last reply Reply Quote 0
                  • E
                    Ente @sigi234 last edited by

                    @sigi234 said in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                    @Ente

                    Hast du die Vorlage heruntergeladen und als View importiert?

                    https://github.com/Uhula/ioBroker-Material-Design-Style/tree/master/templates/MduiShowIcal

                    Ja, den JS von MduiShowIcal_Tableview.json und als View importiert. Das Ergebnis, naja:

                    0ac27e47-3617-4816-886a-1fdd63e62982-image.png

                    Das ganze verstehe ich nicht. Das Anzeigen der Termine reicht.

                    sigi234 1 Reply Last reply Reply Quote 0
                    • sigi234
                      sigi234 Forum Testing Most Active @Ente last edited by

                      @Ente

                      Welche Version hast du von MDCSS ?

                      E 1 Reply Last reply Reply Quote 0
                      • E
                        Ente @sigi234 last edited by

                        @sigi234 said in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                        @Ente

                        Welche Version hast du von MDCSS ?

                        Äh?? Wo finde ich das?

                        sigi234 1 Reply Last reply Reply Quote 0
                        • sigi234
                          sigi234 Forum Testing Most Active @Ente last edited by

                          @Ente sagte in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                          @sigi234 said in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                          @Ente

                          Welche Version hast du von MDCSS ?

                          Äh?? Wo finde ich das?

                          Screenshot (679)_LI.jpg

                          E 1 Reply Last reply Reply Quote 0
                          • E
                            Ente @sigi234 last edited by Ente

                            @sigi234 said in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                            @Ente sagte in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                            @sigi234 said in [Vorlage] MDCSS v2: ical Kalendar anzeigen:

                            @Ente

                            Welche Version hast du von MDCSS ?

                            Äh?? Wo finde ich das?

                            Screenshot (679)_LI.jpg

                            Hab das Skript jetzt eingefügt. > 2.5

                            Diese Objects habe allerdings ich nicht:

                            a95da2c1-9777-4562-b34b-90108d967337-image.png

                            Bei User.Datea habe ich nur das:

                            82a25b33-1595-4d31-886d-c10049998f3e-image.png

                            Irgendetwas habe ich grundsätzlich falsch gemacht.

                            E 1 Reply Last reply Reply Quote 0
                            • E
                              Ente @Ente last edited by Ente

                              Hallo,

                              wie bekomme ich die Einträge in der view in weiß:

                              3605cf02-589f-4329-93c0-daefbe795cf3-image.png

                              Im Edit-Modus sind sie es.

                              Edit: Gefunden:

                              root.mdui-runtime {
                              --content-background: #f8f8f8;
                              --design-font-color: #000000;
                              --frame-color:#cfcfcf;

                              1 Reply Last reply Reply Quote 0
                              • H
                                hendrik87 last edited by

                                Hallo

                                Gibt es auch eine Möglichkeit sich die freien Tage anzeigen zu lassen?

                                Chaot 1 Reply Last reply Reply Quote 0
                                • Chaot
                                  Chaot @hendrik87 last edited by

                                  @hendrik87 Was meinst du? Die Tage ohne Eintrag?
                                  Habe ich noch nicht probiert, aber versuche doch mal den Filter auf

                                  " "
                                  

                                  zu setzen und schau was passiert.

                                  H 1 Reply Last reply Reply Quote 0
                                  • H
                                    hendrik87 @Chaot last edited by

                                    @chaot

                                    Die Tage wo es keinen Termin zu gibt sollen auch angezeigt werden. Also in meinem Fall der 28, 30, 31, ....
                                    7997e083-d160-4a92-87e6-b6bf2b4b49b2-grafik.png

                                    Eigentlich bin ich auf der Suche nach einem monatsweisen Zeilenkalender.
                                    d82a5fed-789a-4e0b-a9d4-c0f19fb65e11-grafik.png

                                    Da habe ich mit dem MDCSS bislang die beste Lösung gefunden.

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

                                    Support us

                                    ioBroker
                                    Community Adapters
                                    Donate

                                    721
                                    Online

                                    31.9k
                                    Users

                                    80.1k
                                    Topics

                                    1.3m
                                    Posts

                                    material css material ui vis
                                    15
                                    56
                                    6199
                                    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