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.
    • 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

                                  547
                                  Online

                                  31.9k
                                  Users

                                  80.1k
                                  Topics

                                  1.3m
                                  Posts

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