iobroker.ical 1.16.1 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/main.js CHANGED
@@ -1,35 +1,35 @@
1
1
  'use strict';
2
2
 
3
- const ical = require('node-ical');
4
- const crypto = require('node:crypto');
5
- const fs = require('node:fs');
6
- const path = require('node:path');
7
- const https = require('node:https');
8
- const os = require('node:os');
9
-
10
- const utils = require('@iobroker/adapter-core');
3
+ const ical = require('node-ical');
4
+ const crypto = require('node:crypto');
5
+ const fs = require('node:fs');
6
+ const path = require('node:path');
7
+ const https = require('node:https');
8
+ const os = require('node:os');
9
+
10
+ const utils = require('@iobroker/adapter-core');
11
11
  const adapterName = require('./package.json').name.split('.').pop();
12
12
 
13
- const RRule = require('rrule').RRule;
14
- const ce = require('cloneextend');
15
- const axios = require('axios');
13
+ const RRule = require('rrule').RRule;
14
+ const ce = require('cloneextend');
15
+ const axios = require('axios');
16
16
 
17
17
  let adapter;
18
- let stopped = false;
18
+ let stopped = false;
19
19
  let killTimeout = null;
20
20
 
21
21
  function startAdapter(options) {
22
22
  options = options || {};
23
23
 
24
- Object.assign(options,{
25
- name: adapterName,
24
+ Object.assign(options, {
25
+ name: adapterName,
26
26
  unload: function (callback) {
27
27
  stopped = true;
28
28
  callback();
29
29
  },
30
30
  ready: function () {
31
31
  main();
32
- }
32
+ },
33
33
  });
34
34
 
35
35
  adapter = new utils.Adapter(options);
@@ -38,36 +38,189 @@ function startAdapter(options) {
38
38
  }
39
39
 
40
40
  // set when ready
41
- let normal = '';
42
- const warn = '<span style="font-weight: bold; color: red"><span class="icalWarn">';
43
- const prewarn = '<span style="font-weight: bold; color: orange"><span class="icalPreWarn">';
44
- const preprewarn = '<span style="font-weight: bold; color: yellow"><span class="icalPrePreWarn">';
45
-
46
- let datesArray = [];
47
- const events = [];
48
- const dictionary = {
49
- 'today': {'en': 'Today', 'it': 'Oggi', 'es': 'Hoy', 'pl': 'Dzisiaj', 'fr': 'Aujourd\'hui', 'de': 'Heute', 'ru': 'Сегодня', 'nl': 'Vandaag'},
50
- 'tomorrow': {'en': 'Tomorrow', 'it': 'Domani', 'es': 'Mañana', 'pl': 'Jutro', 'fr': 'Demain', 'de': 'Morgen', 'ru': 'Завтра', 'nl': 'Morgen'},
51
- 'dayafter': {'en': 'Day After Tomorrow','it': 'Dopodomani', 'es': 'Pasado mañana', 'pl': 'Pojutrze', 'fr': 'Après demain', 'de': 'Übermorgen', 'ru': 'Послезавтра', 'nl': 'Overmorgen'},
52
- '3days': {'en': 'In 3 days', 'it': 'In 3 giorni', 'es': 'En 3 días', 'pl': 'W 3 dni', 'fr': 'Dans 3 jours', 'de': 'In 3 Tagen', 'ru': 'Через 2 дня', 'nl': 'Over 3 dagen'},
53
- '4days': {'en': 'In 4 days', 'it': 'In 4 giorni', 'es': 'En 4 días', 'pl': 'W 4 dni', 'fr': 'Dans 4 jours', 'de': 'In 4 Tagen', 'ru': 'Через 3 дня', 'nl': 'Over 4 dagen'},
54
- '5days': {'en': 'In 5 days', 'it': 'In 5 giorni', 'es': 'En 5 días', 'pl': 'W ciągu 5 dni', 'fr': 'Dans 5 jours', 'de': 'In 5 Tagen', 'ru': 'Через 4 дня', 'nl': 'Over 5 dagen'},
55
- '6days': {'en': 'In 6 days', 'it': 'In 6 giorni', 'es': 'En 6 días', 'pl': 'W ciągu 6 dni', 'fr': 'Dans 6 jours', 'de': 'In 6 Tagen', 'ru': 'Через 5 дней', 'nl': 'Over 6 dagen'},
56
- 'oneweek': {'en': 'In one week', 'it': 'In una settimana', 'es': 'En una semana', 'pl': 'W jeden tydzień', 'fr': 'Dans une semaine', 'de': 'In einer Woche', 'ru': 'Через неделю', 'nl': 'Binnen een week'},
57
- '1week_left':{'en': 'One week left', 'it': 'Manca una settimana', 'es': 'Queda una semana', 'pl': 'Został jeden tydzień', 'fr': 'Reste une semaine', 'de': 'Noch eine Woche', 'ru': 'Ещё неделя', 'nl': 'Over een week'},
58
- '2week_left':{'en': 'Two weeks left', 'it': 'Due settimane rimaste', 'es': 'Dos semanas restantes', 'pl': 'Zostały dwa tygodnie', 'fr': 'Il reste deux semaines', 'de': 'Noch zwei Wochen', 'ru': 'Ещё две недели', 'nl': 'Over twee weken'},
59
- '3week_left':{'en': 'Three weeks left', 'it': 'Tre settimane rimanenti', 'es': 'Tres semanas quedan', 'pl': 'Pozostały trzy tygodnie', 'fr': 'Trois semaines restantes', 'de': 'Noch drei Wochen', 'ru': 'Ещё три недели', 'nl': 'Over drie weken'},
60
- '4week_left':{'en': 'Four weeks left', 'it': 'Quattro settimane rimaste', 'es': 'Cuatro semanas quedan', 'pl': 'Pozostały cztery tygodnie', 'fr': 'Quatre semaines à gauche', 'de': 'Noch vier Wochen', 'ru': 'Ещё три недели', 'nl': 'Over vier weken'},
61
- '5week_left':{'en': 'Five weeks left', 'it': 'Cinque settimane rimaste', 'es': 'Quedan cinco semanas', 'pl': 'Pozostało pięć tygodni', 'fr': 'Cinq semaines à gauche', 'de': 'Noch fünf Wochen', 'ru': 'Ещё пять недель', 'nl': 'Over vijf weken'},
62
- '6week_left':{'en': 'Six weeks left', 'it': 'Sei settimane a sinistra', 'es': 'Seis semanas restantes','pl': 'Pozostało sześć tygodni', 'fr': 'Six semaines à gauche', 'de': 'Noch sechs Wochen','ru': 'Ещё шесть недель', 'nl': 'Over zes weken'},
63
- 'left': {'en': 'left', 'it': 'sinistra', 'es': 'izquierda', 'pl': 'lewo', 'fr': 'la gauche', 'de': ' ', 'ru': 'осталось', 'nl': 'over'},
64
- 'still': {'en': ' ', 'it': '', 'es': '', 'pl': '', 'fr': '', 'de': 'Noch', 'ru': ' ', 'nl': 'nog'},
65
- 'days': {'en': 'days', 'it': 'Giorni', 'es': 'dias', 'pl': 'dni', 'fr': 'journées', 'de': 'Tage', 'ru': 'дней', 'nl': 'dagen'},
66
- 'day': {'en': 'day', 'it': 'giorno', 'es': 'día', 'pl': 'dzień', 'fr': 'journée', 'de': 'Tag', 'ru': 'день', 'nl': 'dag'},
67
- 'hours': {'en': 'hours', 'it': 'ore', 'es': 'horas', 'pl': 'godziny', 'fr': 'heures', 'de': 'Stunden', 'ru': 'часов', 'nl': 'uren'},
68
- 'hour': {'en': 'hour', 'it': 'ora', 'es': 'hora', 'pl': 'godzina', 'fr': 'heure', 'de': 'Stunde', 'ru': 'час', 'nl': 'uur'},
69
- 'minute': {'en': 'minute', 'it': 'minuto', 'es': 'minuto', 'pl': 'minuta', 'fr': 'minute', 'de': 'Minute', 'ru': 'минута', 'nl': 'minuut'},
70
- 'minutes': {'en': 'minutes', 'it': 'minuti', 'es': 'minutos', 'pl': 'minutos', 'fr': 'minutes', 'de': 'Minuten', 'ru': 'минуты', 'nl': 'minuten'}
41
+ let normal = '';
42
+ const warn = '<span style="font-weight: bold; color: red"><span class="icalWarn">';
43
+ const prewarn = '<span style="font-weight: bold; color: orange"><span class="icalPreWarn">';
44
+ const preprewarn = '<span style="font-weight: bold; color: yellow"><span class="icalPrePreWarn">';
45
+
46
+ let datesArray = [];
47
+ const events = [];
48
+ const dictionary = {
49
+ today: {
50
+ en: 'Today',
51
+ it: 'Oggi',
52
+ es: 'Hoy',
53
+ pl: 'Dzisiaj',
54
+ fr: "Aujourd'hui",
55
+ de: 'Heute',
56
+ ru: 'Сегодня',
57
+ nl: 'Vandaag',
58
+ },
59
+ tomorrow: {
60
+ en: 'Tomorrow',
61
+ it: 'Domani',
62
+ es: 'Mañana',
63
+ pl: 'Jutro',
64
+ fr: 'Demain',
65
+ de: 'Morgen',
66
+ ru: 'Завтра',
67
+ nl: 'Morgen',
68
+ },
69
+ dayafter: {
70
+ en: 'Day After Tomorrow',
71
+ it: 'Dopodomani',
72
+ es: 'Pasado mañana',
73
+ pl: 'Pojutrze',
74
+ fr: 'Après demain',
75
+ de: 'Übermorgen',
76
+ ru: 'Послезавтра',
77
+ nl: 'Overmorgen',
78
+ },
79
+ '3days': {
80
+ en: 'In 3 days',
81
+ it: 'In 3 giorni',
82
+ es: 'En 3 días',
83
+ pl: 'W 3 dni',
84
+ fr: 'Dans 3 jours',
85
+ de: 'In 3 Tagen',
86
+ ru: 'Через 2 дня',
87
+ nl: 'Over 3 dagen',
88
+ },
89
+ '4days': {
90
+ en: 'In 4 days',
91
+ it: 'In 4 giorni',
92
+ es: 'En 4 días',
93
+ pl: 'W 4 dni',
94
+ fr: 'Dans 4 jours',
95
+ de: 'In 4 Tagen',
96
+ ru: 'Через 3 дня',
97
+ nl: 'Over 4 dagen',
98
+ },
99
+ '5days': {
100
+ en: 'In 5 days',
101
+ it: 'In 5 giorni',
102
+ es: 'En 5 días',
103
+ pl: 'W ciągu 5 dni',
104
+ fr: 'Dans 5 jours',
105
+ de: 'In 5 Tagen',
106
+ ru: 'Через 4 дня',
107
+ nl: 'Over 5 dagen',
108
+ },
109
+ '6days': {
110
+ en: 'In 6 days',
111
+ it: 'In 6 giorni',
112
+ es: 'En 6 días',
113
+ pl: 'W ciągu 6 dni',
114
+ fr: 'Dans 6 jours',
115
+ de: 'In 6 Tagen',
116
+ ru: 'Через 5 дней',
117
+ nl: 'Over 6 dagen',
118
+ },
119
+ oneweek: {
120
+ en: 'In one week',
121
+ it: 'In una settimana',
122
+ es: 'En una semana',
123
+ pl: 'W jeden tydzień',
124
+ fr: 'Dans une semaine',
125
+ de: 'In einer Woche',
126
+ ru: 'Через неделю',
127
+ nl: 'Binnen een week',
128
+ },
129
+ '1week_left': {
130
+ en: 'One week left',
131
+ it: 'Manca una settimana',
132
+ es: 'Queda una semana',
133
+ pl: 'Został jeden tydzień',
134
+ fr: 'Reste une semaine',
135
+ de: 'Noch eine Woche',
136
+ ru: 'Ещё неделя',
137
+ nl: 'Over een week',
138
+ },
139
+ '2week_left': {
140
+ en: 'Two weeks left',
141
+ it: 'Due settimane rimaste',
142
+ es: 'Dos semanas restantes',
143
+ pl: 'Zostały dwa tygodnie',
144
+ fr: 'Il reste deux semaines',
145
+ de: 'Noch zwei Wochen',
146
+ ru: 'Ещё две недели',
147
+ nl: 'Over twee weken',
148
+ },
149
+ '3week_left': {
150
+ en: 'Three weeks left',
151
+ it: 'Tre settimane rimanenti',
152
+ es: 'Tres semanas quedan',
153
+ pl: 'Pozostały trzy tygodnie',
154
+ fr: 'Trois semaines restantes',
155
+ de: 'Noch drei Wochen',
156
+ ru: 'Ещё три недели',
157
+ nl: 'Over drie weken',
158
+ },
159
+ '4week_left': {
160
+ en: 'Four weeks left',
161
+ it: 'Quattro settimane rimaste',
162
+ es: 'Cuatro semanas quedan',
163
+ pl: 'Pozostały cztery tygodnie',
164
+ fr: 'Quatre semaines à gauche',
165
+ de: 'Noch vier Wochen',
166
+ ru: 'Ещё три недели',
167
+ nl: 'Over vier weken',
168
+ },
169
+ '5week_left': {
170
+ en: 'Five weeks left',
171
+ it: 'Cinque settimane rimaste',
172
+ es: 'Quedan cinco semanas',
173
+ pl: 'Pozostało pięć tygodni',
174
+ fr: 'Cinq semaines à gauche',
175
+ de: 'Noch fünf Wochen',
176
+ ru: 'Ещё пять недель',
177
+ nl: 'Over vijf weken',
178
+ },
179
+ '6week_left': {
180
+ en: 'Six weeks left',
181
+ it: 'Sei settimane a sinistra',
182
+ es: 'Seis semanas restantes',
183
+ pl: 'Pozostało sześć tygodni',
184
+ fr: 'Six semaines à gauche',
185
+ de: 'Noch sechs Wochen',
186
+ ru: 'Ещё шесть недель',
187
+ nl: 'Over zes weken',
188
+ },
189
+ left: {
190
+ en: 'left',
191
+ it: 'sinistra',
192
+ es: 'izquierda',
193
+ pl: 'lewo',
194
+ fr: 'la gauche',
195
+ de: ' ',
196
+ ru: 'осталось',
197
+ nl: 'over',
198
+ },
199
+ still: { en: ' ', it: '', es: '', pl: '', fr: '', de: 'Noch', ru: ' ', nl: 'nog' },
200
+ days: { en: 'days', it: 'Giorni', es: 'dias', pl: 'dni', fr: 'journées', de: 'Tage', ru: 'дней', nl: 'dagen' },
201
+ day: { en: 'day', it: 'giorno', es: 'día', pl: 'dzień', fr: 'journée', de: 'Tag', ru: 'день', nl: 'dag' },
202
+ hours: { en: 'hours', it: 'ore', es: 'horas', pl: 'godziny', fr: 'heures', de: 'Stunden', ru: 'часов', nl: 'uren' },
203
+ hour: { en: 'hour', it: 'ora', es: 'hora', pl: 'godzina', fr: 'heure', de: 'Stunde', ru: 'час', nl: 'uur' },
204
+ minute: {
205
+ en: 'minute',
206
+ it: 'minuto',
207
+ es: 'minuto',
208
+ pl: 'minuta',
209
+ fr: 'minute',
210
+ de: 'Minute',
211
+ ru: 'минута',
212
+ nl: 'minuut',
213
+ },
214
+ minutes: {
215
+ en: 'minutes',
216
+ it: 'minuti',
217
+ es: 'minutos',
218
+ pl: 'minutos',
219
+ fr: 'minutes',
220
+ de: 'Minuten',
221
+ ru: 'минуты',
222
+ nl: 'minuten',
223
+ },
71
224
  };
72
225
 
73
226
  function _(text) {
@@ -99,14 +252,12 @@ function _(text) {
99
252
  * 1 : if this > b
100
253
  * NaN : if a or b is an illegal date
101
254
  */
102
- Date.prototype.compare = function(b) {
255
+ Date.prototype.compare = function (b) {
103
256
  if (b.constructor !== Date) {
104
257
  throw new Error('invalid_date');
105
258
  }
106
259
 
107
- return (isFinite(this.valueOf()) && isFinite(b.valueOf()) ?
108
- (this > b) - (this < b) : NaN
109
- );
260
+ return isFinite(this.valueOf()) && isFinite(b.valueOf()) ? (this > b) - (this < b) : NaN;
110
261
  };
111
262
 
112
263
  async function getICal(urlOrFile, user, pass, sslignore, calName, cb) {
@@ -130,95 +281,105 @@ async function getICal(urlOrFile, user, pass, sslignore, calName, cb) {
130
281
  cb && cb(`Cannot read file "${urlOrFile}": ${e}`);
131
282
  }
132
283
  }
133
-
134
284
  } else {
135
285
  // Find out whether SSL certificate errors shall be ignored
136
286
  const options = {
137
287
  method: 'get',
138
- url: urlOrFile
288
+ url: urlOrFile,
139
289
  };
140
290
 
141
291
  if (adapter.config.customUserAgentEnabled && adapter.config.customUserAgent) {
142
292
  options.headers = {
143
- 'User-Agent': adapter.config.customUserAgent
293
+ 'User-Agent': adapter.config.customUserAgent,
144
294
  };
145
295
  }
146
296
 
147
297
  if (sslignore === 'ignore' || sslignore === 'true' || sslignore === true) {
148
298
  options.httpsAgent = new https.Agent({
149
- rejectUnauthorized: false
299
+ rejectUnauthorized: false,
150
300
  });
151
301
  }
152
302
 
153
303
  if (user) {
154
304
  options.auth = {
155
305
  username: user,
156
- password: pass
306
+ password: pass,
157
307
  };
158
308
  }
159
309
 
160
- const calHash = crypto.createHash('md5').update(user + pass + urlOrFile).digest('hex');
161
- const cachedFilename = path.join(os.tmpdir(), 'iob-' + calHash + '.ics');
310
+ const calHash = crypto
311
+ .createHash('md5')
312
+ .update(user + pass + urlOrFile)
313
+ .digest('hex');
314
+ const cachedFilename = path.join(os.tmpdir(), `iob-${calHash}.ics`);
315
+
316
+ axios(options)
317
+ .then(function (response) {
318
+ if (response.data) {
319
+ try {
320
+ fs.writeFileSync(cachedFilename, response.data, 'utf-8');
321
+ adapter.log.debug(
322
+ `Successfully cached content for calendar "${urlOrFile}" as ${cachedFilename}`,
323
+ );
324
+ } catch (err) {
325
+ adapter.log.error(`Cannot write cached file: ${err}`);
326
+ }
327
+
328
+ cb && cb(null, response.data);
329
+ } else {
330
+ cb && cb(`Error reading from URL "${urlOrFile}": Received no data`);
331
+ }
332
+ })
333
+ .catch(error => {
334
+ let cachedContent;
335
+ let cachedDate;
336
+
337
+ if (error.response) {
338
+ // The request was made and the server responded with a status code
339
+ // that falls out of the range of 2xx
340
+ adapter.log.warn(`Error reading from URL "${urlOrFile}": ${error.response.status}`);
341
+ } else if (error.request) {
342
+ // The request was made but no response was received
343
+ // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
344
+ // http.ClientRequest in node.js
345
+ adapter.log.warn(`Error reading from URL "${urlOrFile}"`);
346
+ } else {
347
+ // Something happened in setting up the request that triggered an Error
348
+ adapter.log.warn(`Error reading from URL "${urlOrFile}": ${error.message}`);
349
+ }
162
350
 
163
- axios(options).then(function (response) {
164
- if (response.data) {
165
351
  try {
166
- fs.writeFileSync(cachedFilename, response.data, 'utf-8');
167
- adapter.log.debug(`Successfully cached content for calendar "${urlOrFile}" as ${cachedFilename}`);
352
+ if (fs.existsSync(cachedFilename)) {
353
+ cachedContent = fs.readFileSync(cachedFilename, 'utf-8');
354
+ const stat = fs.statSync(cachedFilename);
355
+ cachedDate = stat.mtime;
356
+ }
168
357
  } catch (err) {
169
- // Ignore
358
+ adapter.log.info(`Cannot read cached calendar file for "${urlOrFile}": ${err.message}`);
170
359
  }
171
360
 
172
- cb && cb(null, response.data);
173
- } else {
174
- cb && cb(`Error reading from URL "${urlOrFile}": Received no data`);
175
- }
176
- }).catch(error => {
177
- let cachedContent;
178
- let cachedDate;
179
-
180
- if (error.response) {
181
- // The request was made and the server responded with a status code
182
- // that falls out of the range of 2xx
183
- adapter.log.warn(`Error reading from URL "${urlOrFile}": ${error.response.status}`);
184
- } else if (error.request) {
185
- // The request was made but no response was received
186
- // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
187
- // http.ClientRequest in node.js
188
- adapter.log.warn(`Error reading from URL "${urlOrFile}"`);
189
- } else {
190
- // Something happened in setting up the request that triggered an Error
191
- adapter.log.warn(`Error reading from URL "${urlOrFile}": ${error.message}`);
192
- }
193
-
194
- try {
195
- if (fs.existsSync(cachedFilename)) {
196
- cachedContent = fs.readFileSync(cachedFilename, 'utf-8');
197
- const stat = fs.statSync(cachedFilename);
198
- cachedDate = stat.mtime;
361
+ if (!cachedContent) {
362
+ return cb && cb(`Cannot read URL: "${urlOrFile}"`);
199
363
  }
200
- } catch (err) {
201
- adapter.log.info(`Cannot read cached calendar file for "${urlOrFile}": ${err.message}`);
202
- }
203
364
 
204
- if (!cachedContent) {
205
- return cb && cb(`Cannot read URL: "${urlOrFile}"`);
206
- }
207
-
208
- adapter.log.info(`Use cached File content for "${urlOrFile}" from ${cachedDate}`);
209
- cb && cb(null, cachedContent);
210
- });
365
+ adapter.log.info(`Use cached File content for "${urlOrFile}" from ${cachedDate}`);
366
+ cb && cb(null, cachedContent);
367
+ });
211
368
  }
212
369
  }
213
370
 
214
371
  function checkICal(urlOrFile, user, pass, sslignore, calName, filter, cb) {
215
- if (stopped) return;
372
+ if (stopped) {
373
+ return;
374
+ }
216
375
  if (typeof user === 'function') {
217
376
  cb = user;
218
377
  user = undefined;
219
378
  }
220
379
  getICal(urlOrFile, user, pass, sslignore, calName, (err, _data) => {
221
- if (stopped) return;
380
+ if (stopped) {
381
+ return;
382
+ }
222
383
  if (err || !_data) {
223
384
  adapter.log.warn(`Error reading "${urlOrFile}": ${err}`);
224
385
  cb(err, calName);
@@ -229,7 +390,9 @@ function checkICal(urlOrFile, user, pass, sslignore, calName, filter, cb) {
229
390
 
230
391
  try {
231
392
  ical.parseICS(_data, (err, data) => {
232
- if (stopped) return;
393
+ if (stopped) {
394
+ return;
395
+ }
233
396
  if (data) {
234
397
  adapter.log.info(`processing URL: ${calName} ${urlOrFile}`);
235
398
  adapter.log.debug(JSON.stringify(data));
@@ -251,8 +414,7 @@ function checkICal(urlOrFile, user, pass, sslignore, calName, filter, cb) {
251
414
  // clear time
252
415
  now2.setHours(0, 0, 0, 0);
253
416
 
254
- setImmediate(() =>
255
- processData(data, realnow, startpreview, endpreview, now2, calName, filter, cb));
417
+ setImmediate(() => processData(data, realnow, startpreview, endpreview, now2, calName, filter, cb));
256
418
  } else {
257
419
  // Ready with processing
258
420
  cb(null, calName);
@@ -266,7 +428,7 @@ function checkICal(urlOrFile, user, pass, sslignore, calName, filter, cb) {
266
428
  }
267
429
 
268
430
  function addOffset(time, offset) {
269
- return new Date(time.getTime() + (offset * 60 * 1000));
431
+ return new Date(time.getTime() + offset * 60 * 1000);
270
432
  }
271
433
 
272
434
  function treatAsUTC(date) {
@@ -276,14 +438,16 @@ function treatAsUTC(date) {
276
438
  }
277
439
 
278
440
  async function processData(data, realnow, startpreview, endpreview, now2, calName, filter, cb) {
279
- if (stopped) return;
441
+ if (stopped) {
442
+ return;
443
+ }
280
444
  let processedEntries = 0;
281
445
  for (const k in data) {
282
446
  const ev = data[k];
283
447
  delete data[k];
284
448
 
285
449
  // only events with summary and a start date are interesting
286
- if ((ev.summary !== undefined) && (ev.type === 'VEVENT') && ev.start && ev.start instanceof Date) {
450
+ if (ev.summary !== undefined && ev.type === 'VEVENT' && ev.start && ev.start instanceof Date) {
287
451
  adapter.log.debug(`ev[${k}]: ${JSON.stringify(ev)}`);
288
452
  if (!ev.end || !(ev.end instanceof Date)) {
289
453
  ev.end = new Date(ev.start.getTime());
@@ -297,7 +461,7 @@ async function processData(data, realnow, startpreview, endpreview, now2, calNam
297
461
  if (ev.datetype === 'date') {
298
462
  // If "whole day event" correct the eventlength to full days
299
463
  const calcStart = new Date(ev.start.getTime());
300
- calcStart.setHours(0,0,0,0);
464
+ calcStart.setHours(0, 0, 0, 0);
301
465
  let calcEnd = new Date(ev.end.getTime());
302
466
  if (calcEnd.getHours() === 0 && calcEnd.getMinutes() === 0 && calcEnd.getSeconds() === 0) {
303
467
  // if end id 0:0:0 then it is considered exclusive, so reduce by 1s
@@ -305,10 +469,12 @@ async function processData(data, realnow, startpreview, endpreview, now2, calNam
305
469
  calcEnd.setDate(calcEnd.getDate() - 1);
306
470
  adapter.log.debug(`Adjust enddate to exclude 0:0:0 for eventlength`);
307
471
  }
308
- calcEnd.setHours(23,59,59,0);
472
+ calcEnd.setHours(23, 59, 59, 0);
309
473
  eventLength = treatAsUTC(calcEnd.getTime()) - treatAsUTC(calcStart.getTime());
310
- eventLength = Math.ceil(eventLength / ( 24 * 60 * 60 * 1000)) * 24 * 60 * 60 * 1000;
311
- adapter.log.debug(`Calculated Date Eventlength = ${eventLength} (${eventLength / ( 24 * 60 * 60 * 1000)} days) for ${calcStart.toString()} - ${calcEnd.toString()}`);
474
+ eventLength = Math.ceil(eventLength / (24 * 60 * 60 * 1000)) * 24 * 60 * 60 * 1000;
475
+ adapter.log.debug(
476
+ `Calculated Date Eventlength = ${eventLength} (${eventLength / (24 * 60 * 60 * 1000)} days) for ${calcStart.toString()} - ${calcEnd.toString()}`,
477
+ );
312
478
  }
313
479
 
314
480
  const options = RRule.parseString(ev.rrule.toString());
@@ -319,7 +485,10 @@ async function processData(data, realnow, startpreview, endpreview, now2, calNam
319
485
  // until=2021-11-09T15:59:59.000Z) so that an event is still considered as TODAY
320
486
  // even thought it ends one second before the next scheduled one.
321
487
  if (options.until !== undefined && options.dtstart !== undefined) {
322
- options.until = addOffset(options.until, options.dtstart.getTimezoneOffset() - options.until.getTimezoneOffset());
488
+ options.until = addOffset(
489
+ options.until,
490
+ options.dtstart.getTimezoneOffset() - options.until.getTimezoneOffset(),
491
+ );
323
492
  }
324
493
  adapter.log.debug(`options: ${JSON.stringify(options)}`);
325
494
 
@@ -332,19 +501,21 @@ async function processData(data, realnow, startpreview, endpreview, now2, calNam
332
501
  if (startpreview < now3) {
333
502
  now3 = startpreview;
334
503
  }
335
- adapter.log.debug(`RRule event:${ev.summary}; start:${ev.start.toString()}; endpreview:${endpreview.toString()}; startpreview:${startpreview.toString()}; now2:${now2.toString()}; now3:${now3.toString()}; rule:${JSON.stringify(rule)}`);
504
+ adapter.log.debug(
505
+ `RRule event:${ev.summary}; start:${ev.start.toString()}; endpreview:${endpreview.toString()}; startpreview:${startpreview.toString()}; now2:${now2.toString()}; now3:${now3.toString()}; rule:${JSON.stringify(rule)}`,
506
+ );
336
507
 
337
508
  let dates = [];
338
509
  try {
339
510
  dates = rule.between(now3, endpreview, true);
340
- } catch(e) {
341
- adapter.log.error(`Issue detected in RRule, event ignored; Please forward debug information to iobroker.ical developer: ${e.stack}
511
+ } catch (e) {
512
+ adapter.log
513
+ .error(`Issue detected in RRule, event ignored; Please forward debug information to iobroker.ical developer: ${e.stack}
342
514
  RRule object: ${JSON.stringify(rule)}
343
515
  now3: ${now3}
344
516
  endpreview: ${endpreview}
345
517
  string: ${ev.rrule.toString()}
346
- options: ${JSON.stringify(options)}`
347
- );
518
+ options: ${JSON.stringify(options)}`);
348
519
  }
349
520
 
350
521
  adapter.log.debug(`dates: ${JSON.stringify(dates)}`);
@@ -362,7 +533,7 @@ options: ${JSON.stringify(options)}`
362
533
  if (ev.datetype === 'date') {
363
534
  // make sure to set the time to 00:00:00 so that
364
535
  // this event will be recognized as a date event
365
- ev2.start.setHours(0,0,0,0);
536
+ ev2.start.setHours(0, 0, 0, 0);
366
537
  } else if (ev.datetype === 'date-time') {
367
538
  // rrule only knows about local time but stores the
368
539
  // datetime in zulu (Z) UTC time strings. Thus we need
@@ -373,7 +544,8 @@ options: ${JSON.stringify(options)}`
373
544
 
374
545
  // Set end date based on length in ms
375
546
  ev2.end = new Date(ev2.start.getTime() + eventLength);
376
- if (ev2.start.getTimezoneOffset() !== ev2.end.getTimezoneOffset()) { // DST difference, we need to correct it
547
+ if (ev2.start.getTimezoneOffset() !== ev2.end.getTimezoneOffset()) {
548
+ // DST difference, we need to correct it
377
549
  ev2.end = addOffset(ev2.end, ev2.end.getTimezoneOffset() - ev2.start.getTimezoneOffset());
378
550
  }
379
551
 
@@ -382,8 +554,10 @@ options: ${JSON.stringify(options)}`
382
554
  // be excluded.
383
555
  let checkDate = true;
384
556
  if (ev2.exdate) {
385
- adapter.log.debug(` ${i}: Event (exdate: ${JSON.stringify(Object.keys(ev2.exdate))}): ${ev2.start.toString()} ${ev2.end.toString()}`);
386
- for(const d in ev2.exdate) {
557
+ adapter.log.debug(
558
+ ` ${i}: Event (exdate: ${JSON.stringify(Object.keys(ev2.exdate))}): ${ev2.start.toString()} ${ev2.end.toString()}`,
559
+ );
560
+ for (const d in ev2.exdate) {
387
561
  const dd = new Date(ev2.exdate[d]);
388
562
  if (dd.getTime() === ev2.start.getTime()) {
389
563
  checkDate = false;
@@ -392,15 +566,19 @@ options: ${JSON.stringify(options)}`
392
566
  }
393
567
  }
394
568
  } else {
395
- adapter.log.debug(` ${i}: Event (NO exdate): ${ev2.start.toString()} ${ev2.end.toString()}`);
569
+ adapter.log.debug(
570
+ ` ${i}: Event (NO exdate): ${ev2.start.toString()} ${ev2.end.toString()}`,
571
+ );
396
572
  }
397
573
 
398
574
  if (checkDate && ev.recurrences) {
399
- for(const dOri in ev.recurrences) {
575
+ for (const dOri in ev.recurrences) {
400
576
  const recurEvent = ev.recurrences[dOri];
401
577
  if (recurEvent.recurrenceid.getTime() === ev2.start.getTime()) {
402
578
  ev2 = ce.clone(recurEvent);
403
- adapter.log.debug(` ${i}: different recurring found replaced with Event:${ev2.start} ${ev2.end}`);
579
+ adapter.log.debug(
580
+ ` ${i}: different recurring found replaced with Event:${ev2.start} ${ev2.end}`,
581
+ );
404
582
  }
405
583
  }
406
584
  }
@@ -413,7 +591,9 @@ options: ${JSON.stringify(options)}`
413
591
  adapter.log.debug('no RRule events inside the time interval');
414
592
  }
415
593
  } else {
416
- adapter.log.debug(`Single event: ${ev.summary}; start:${ev.start}; end:${ev.end}; endpreview:${endpreview}; startpreview:${startpreview}; realnow:${realnow}`);
594
+ adapter.log.debug(
595
+ `Single event: ${ev.summary}; start:${ev.start}; end:${ev.end}; endpreview:${endpreview}; startpreview:${startpreview}; realnow:${realnow}`,
596
+ );
417
597
  // No RRule event
418
598
  await checkDates(ev, endpreview, startpreview, realnow, ' ', calName, filter);
419
599
  }
@@ -426,8 +606,7 @@ options: ${JSON.stringify(options)}`
426
606
  if (!Object.keys(data).length) {
427
607
  cb(null, calName);
428
608
  } else {
429
- setImmediate(() =>
430
- processData(data, realnow, startpreview, endpreview, now2, calName, filter, cb));
609
+ setImmediate(() => processData(data, realnow, startpreview, endpreview, now2, calName, filter, cb));
431
610
  }
432
611
  }
433
612
 
@@ -438,7 +617,10 @@ async function checkDates(ev, endpreview, startpreview, realnow, rule, calName,
438
617
  let date;
439
618
 
440
619
  // chech if sub parameter exists for outlook
441
- if (Object.prototype.hasOwnProperty.call(ev, 'summary') && Object.prototype.hasOwnProperty.call(ev.summary, 'val')) {
620
+ if (
621
+ Object.prototype.hasOwnProperty.call(ev, 'summary') &&
622
+ Object.prototype.hasOwnProperty.call(ev.summary, 'val')
623
+ ) {
442
624
  // yes -> read reason
443
625
  reason = ev.summary.val || '';
444
626
  } else {
@@ -452,18 +634,22 @@ async function checkDates(ev, endpreview, startpreview, realnow, rule, calName,
452
634
  isPrivate = Object.prototype.hasOwnProperty.call(ev, 'class') && ev.class === 'PRIVATE';
453
635
 
454
636
  // If not start point => ignore it
455
- if (!ev.start || !ev.start instanceof Date) {
637
+ if (!ev.start || (!ev.start) instanceof Date) {
456
638
  return;
457
639
  }
458
640
 
459
641
  // If not end point => assume 0:0:0 event and set to same as start
460
- ev.end = new Date(ev.end.getTime()) || new Date(ev.start.getTime());
461
- if (!ev.end || !ev.end instanceof Date) {
642
+ ev.end = new Date(ev.end.getTime());
643
+ if (!ev.end) {
644
+ ev.end = new Date(ev.start.getTime());
645
+ }
646
+ if (!ev.end || (!ev.end) instanceof Date) {
462
647
  return;
463
648
  }
464
649
 
465
650
  // If full day
466
- if (ev.start.getHours() === 0 &&
651
+ if (
652
+ ev.start.getHours() === 0 &&
467
653
  ev.start.getMinutes() === 0 &&
468
654
  ev.start.getSeconds() === 0 &&
469
655
  ev.end.getHours() === 0 &&
@@ -505,32 +691,35 @@ LOCATION:${location}`;
505
691
 
506
692
  // Full day
507
693
  if (fullDay) {
508
-
509
694
  adapter.log.debug(`Event (full day) processing. Start: ${ev.start} End: ${ev.end}`);
510
695
 
511
696
  // event start >= startpreview && < previewtime or end > startpreview && < previewtime ---> display
512
- if ((ev.start < endpreview && ev.start >= startpreview) || (ev.end > startpreview && ev.end <= endpreview) || (ev.start < realnow && ev.end > realnow)) {
697
+ if (
698
+ (ev.start < endpreview && ev.start >= startpreview) ||
699
+ (ev.end > startpreview && ev.end <= endpreview) ||
700
+ (ev.start < realnow && ev.end > realnow)
701
+ ) {
513
702
  // check only full day events
514
703
  if (await checkForEvents(reason, ev, realnow)) {
515
704
  date = formatDate(ev.start, ev.end, true, true);
516
705
 
517
706
  insertSorted(datesArray, {
518
- date: date.text,
519
- event: reason,
520
- _class: `ical_${calName} ${date._class}`,
521
- _date: new Date(ev.start.getTime()),
707
+ date: date.text,
708
+ event: reason,
709
+ _class: `ical_${calName} ${date._class}`,
710
+ _date: new Date(ev.start.getTime()),
522
711
  // add additional Objects, so iobroker.occ can use it
523
- _end: new Date(ev.end.getTime()),
712
+ _end: new Date(ev.end.getTime()),
524
713
  _section: ev.description,
525
- _IDID: ev.uid,
526
- _allDay: true,
714
+ _IDID: ev.uid,
715
+ _allDay: true,
527
716
  _private: isPrivate,
528
- _rule: rule,
717
+ _rule: rule,
529
718
  location: location,
530
719
  // add additional Objects, so iobroker.occ can use it
531
720
  _calName: calName,
532
721
  _calColor: adapter.config.calendars.find(x => x.name === calName).color,
533
- _object: ev
722
+ _object: ev,
534
723
  });
535
724
 
536
725
  adapter.log.debug(`Event (full day) added : ${JSON.stringify(rule)} ${reason} at ${date.text}`);
@@ -539,36 +728,41 @@ LOCATION:${location}`;
539
728
  }
540
729
  } else {
541
730
  // filtered out, because does not belongs to specified time interval
542
- adapter.log.debug(`Event (full day) ${JSON.stringify(rule)} ${reason} at ${ev.start.toString()} filtered out, does not belong to specified time interval`);
731
+ adapter.log.debug(
732
+ `Event (full day) ${JSON.stringify(rule)} ${reason} at ${ev.start.toString()} filtered out, does not belong to specified time interval`,
733
+ );
543
734
  }
544
735
  } else {
545
-
546
736
  adapter.log.debug(`Event (time) processing. Start: ${ev.start} End: ${ev.end}`);
547
737
 
548
738
  // Event with time
549
739
  // Start time >= startpreview && Start time < preview time && End time >= now
550
- if ((ev.start >= startpreview && ev.start < endpreview && ev.end >= realnow) || (ev.end >= realnow && ev.end <= endpreview) || (ev.start < realnow && ev.end > realnow)) {
740
+ if (
741
+ (ev.start >= startpreview && ev.start < endpreview && ev.end >= realnow) ||
742
+ (ev.end >= realnow && ev.end <= endpreview) ||
743
+ (ev.start < realnow && ev.end > realnow)
744
+ ) {
551
745
  // Add to list only if not hidden
552
746
  if (await checkForEvents(reason, ev, realnow)) {
553
747
  date = formatDate(ev.start, ev.end, true, false);
554
748
 
555
749
  insertSorted(datesArray, {
556
- date: date.text,
557
- event: reason,
558
- _class: `ical_${calName} ${date._class}`,
559
- _date: new Date(ev.start.getTime()),
750
+ date: date.text,
751
+ event: reason,
752
+ _class: `ical_${calName} ${date._class}`,
753
+ _date: new Date(ev.start.getTime()),
560
754
  // add additional Objects, so iobroker.occ can use it
561
- _end: new Date(ev.end.getTime()),
755
+ _end: new Date(ev.end.getTime()),
562
756
  _section: ev.description,
563
- _IDID: ev.uid,
564
- _allDay: false,
757
+ _IDID: ev.uid,
758
+ _allDay: false,
565
759
  _private: isPrivate,
566
- _rule: rule,
760
+ _rule: rule,
567
761
  location: location,
568
762
  // add additional Objects, so iobroker.occ can use it
569
763
  _calName: calName,
570
764
  _calColor: adapter.config.calendars.find(x => x.name === calName).color,
571
- _object: ev
765
+ _object: ev,
572
766
  });
573
767
 
574
768
  adapter.log.debug(`Event with time added: ${JSON.stringify(rule)} ${reason} at ${date.text}`);
@@ -577,7 +771,9 @@ LOCATION:${location}`;
577
771
  }
578
772
  } else {
579
773
  // filtered out, because does not belongs to specified time interval
580
- adapter.log.debug(`Event ${JSON.stringify(rule)} ${reason} at ${ev.start.toString()} filtered out, because does not belongs to specified time interval`);
774
+ adapter.log.debug(
775
+ `Event ${JSON.stringify(rule)} ${reason} at ${ev.start.toString()} filtered out, because does not belongs to specified time interval`,
776
+ );
581
777
  }
582
778
  }
583
779
  }
@@ -585,7 +781,7 @@ LOCATION:${location}`;
585
781
  function colorizeDates(date, today, tomorrow, dayafter, col, calName) {
586
782
  const result = {
587
783
  prefix: normal,
588
- suffix: '</span>' + (adapter.config.colorize ? '</span>' : '')
784
+ suffix: `</span>${adapter.config.colorize ? '</span>' : ''}`,
589
785
  };
590
786
  const cmpDate = new Date(date.getTime());
591
787
  cmpDate.setHours(0, 0, 0, 0);
@@ -599,50 +795,47 @@ function colorizeDates(date, today, tomorrow, dayafter, col, calName) {
599
795
  result.prefix = warn;
600
796
  // If configured every calendar has own color
601
797
  if (adapter.config.everyCalOneColor) {
602
- result.suffix += `<span style="font-weight:normal${col ? (`;color:${col}`) : ''}">`;
798
+ result.suffix += `<span style="font-weight:normal${col ? `;color:${col}` : ''}">`;
603
799
  } else {
604
800
  result.suffix += '<span style="font-weight:normal;color:red">';
605
801
  }
606
802
  result.suffix += `<span class="icalWarn2 iCal-${calName}2">`;
607
- } else
608
- // tomorrow
609
- if (cmpDate.compare(tomorrow) === 0) {
803
+ } else if (cmpDate.compare(tomorrow) === 0) {
804
+ // tomorrow
610
805
  result.prefix = prewarn;
611
806
  // If configured every calendar has own color
612
807
  if (adapter.config.everyCalOneColor) {
613
- result.suffix += `<span style="font-weight: normal${col ? (`; color:${col}`) : ''}">`;
808
+ result.suffix += `<span style="font-weight: normal${col ? `; color:${col}` : ''}">`;
614
809
  } else {
615
810
  result.suffix += '<span style="font-weight: normal; color: orange">';
616
811
  }
617
812
  result.suffix += `<span class='icalPreWarn2 iCal-${calName}2'>`;
618
- } else
619
- // day after tomorrow
620
- if (cmpDate.compare(dayafter) === 0) {
813
+ } else if (cmpDate.compare(dayafter) === 0) {
814
+ // day after tomorrow
621
815
  result.prefix = preprewarn;
622
816
  // If configured every calendar has own color
623
817
  if (adapter.config.everyCalOneColor) {
624
- result.suffix += `<span style="font-weight: normal${col ? (`; color:${col}`) : ''}">`;
818
+ result.suffix += `<span style="font-weight: normal${col ? `; color:${col}` : ''}">`;
625
819
  } else {
626
820
  result.suffix += '<span style="font-weight: normal; color: yellow">';
627
821
  }
628
822
  result.suffix += `<span class='icalPrePreWarn2 iCal-${calName}2'>`;
629
- } else
630
- // start time is in the past
631
- if (cmpDate.compare(today) === -1) {
823
+ } else if (cmpDate.compare(today) === -1) {
824
+ // start time is in the past
632
825
  result.prefix = normal;
633
826
  // If configured every calendar has own color
634
827
  if (adapter.config.everyCalOneColor) {
635
- result.suffix += `<span style="font-weight: normal${col ? (`; color:${col}`) : ''}">`;
828
+ result.suffix += `<span style="font-weight: normal${col ? `; color:${col}` : ''}">`;
636
829
  } else {
637
- result.suffix += `<span style="font-weight: normal${adapter.config.defColor ? (`; color:${adapter.config.defColor}`) : ''}">`;
830
+ result.suffix += `<span style="font-weight: normal${adapter.config.defColor ? `; color:${adapter.config.defColor}` : ''}">`;
638
831
  }
639
832
  result.suffix += `<span class='icalNormal2 iCal-${calName}2'>`;
640
833
  } else {
641
834
  // If configured every calendar has own color
642
835
  if (adapter.config.everyCalOneColor) {
643
- result.suffix += `<span style="font-weight: normal${col ? (`; color:${col}`) : ''}">`;
836
+ result.suffix += `<span style="font-weight: normal${col ? `; color:${col}` : ''}">`;
644
837
  } else {
645
- result.suffix += `<span style="font-weight: normal${adapter.config.defColor ? (`; color:${adapter.config.defColor}`) : ''}">`;
838
+ result.suffix += `<span style="font-weight: normal${adapter.config.defColor ? `; color:${adapter.config.defColor}` : ''}">`;
646
839
  }
647
840
  result.suffix += `<span class='icalNormal2 iCal-${calName}2'>`;
648
841
  }
@@ -668,12 +861,15 @@ async function checkForEvents(reason, event, realnow) {
668
861
  let evFound = false;
669
862
  if (exactMatchInEventname) {
670
863
  // calendar entry must be exactly the same as the event
671
- if ((reason === ev.name) || (ignoreCaseInEventname && (reason.toLowerCase() === ev.name.toLowerCase()))) {
864
+ if (reason === ev.name || (ignoreCaseInEventname && reason.toLowerCase() === ev.name.toLowerCase())) {
672
865
  evFound = true;
673
866
  }
674
867
  } else {
675
868
  // event is included in the calendar entry
676
- if ((reason.includes(ev.name)) || (ignoreCaseInEventname && (reason.toLowerCase().includes(ev.name.toLowerCase())))) {
869
+ if (
870
+ reason.includes(ev.name) ||
871
+ (ignoreCaseInEventname && reason.toLowerCase().includes(ev.name.toLowerCase()))
872
+ ) {
677
873
  evFound = true;
678
874
  }
679
875
  }
@@ -689,25 +885,31 @@ async function checkForEvents(reason, event, realnow) {
689
885
  // If full day event
690
886
  // Follow processing only if event is today
691
887
  if (
692
- ((!ev.type || ev.type === 'today') && event.end.getTime() > inXDays.getTime() && event.start.getTime() < inXDaysPlusOne.getTime()) ||
888
+ ((!ev.type || ev.type === 'today') &&
889
+ event.end.getTime() > inXDays.getTime() &&
890
+ event.start.getTime() < inXDaysPlusOne.getTime()) ||
693
891
  (ev.type === 'now' && event.start <= realnow && realnow <= event.end) ||
694
892
  (ev.type === 'later' && event.start > realnow && event.start.getTime() < tomorrow.getTime())
695
893
  ) {
696
- adapter.log.debug(`${ev.type ? ev.type : `day ${ev.day}`} Event with time: ${event.start} ${realnow} ${event.end}`);
894
+ adapter.log.debug(
895
+ `${ev.type ? ev.type : `day ${ev.day}`} Event with time: ${event.start} ${realnow} ${event.end}`,
896
+ );
697
897
 
698
898
  // If yet processed
699
899
  if (ev.processed) {
700
900
  // nothing to do
701
901
  adapter.log.debug(`Event ${ev.name} already processed`);
702
902
  } else {
703
- adapter.log.debug(`Checking event ${ev.day} ${ev.type} ${ev.name} = ${ev.processed}, state = ${ev.state}`);
903
+ adapter.log.debug(
904
+ `Checking event ${ev.day} ${ev.type} ${ev.name} = ${ev.processed}, state = ${ev.state}`,
905
+ );
704
906
  // Process event
705
907
  ev.processed = true;
706
908
  if (!ev.state) {
707
909
  ev.state = true;
708
910
  const name = `events.${ev.day}.${ev.type ? `${ev.type}.` : ''}${shrinkStateName(ev.name)}`;
709
911
  adapter.log.info(`Set ${name} to true`);
710
- await adapter.setStateAsync(name, {val: true, ack: true});
912
+ await adapter.setStateAsync(name, { val: true, ack: true });
711
913
  if (ev.id) {
712
914
  await setState(ev.id, ev.on, ev.ack);
713
915
  }
@@ -723,10 +925,10 @@ function initEvent(name, display, day, type, id, on, off, ack, callback) {
723
925
  const obj = {
724
926
  name,
725
927
  processed: false,
726
- state: null,
928
+ state: null,
727
929
  display,
728
930
  day,
729
- type
931
+ type,
730
932
  };
731
933
 
732
934
  if (type === 'now' && id) {
@@ -734,7 +936,8 @@ function initEvent(name, display, day, type, id, on, off, ack, callback) {
734
936
  obj.off = off;
735
937
  obj.on = on;
736
938
 
737
- if (typeof ack !== 'boolean') { // backward compatibility
939
+ if (typeof ack !== 'boolean') {
940
+ // backward compatibility
738
941
  ack = true;
739
942
  } else {
740
943
  ack = !!ack;
@@ -750,7 +953,7 @@ function initEvent(name, display, day, type, id, on, off, ack, callback) {
750
953
  adapter.getState(stateName, async (err, state) => {
751
954
  if (err || !state) {
752
955
  obj.state = false;
753
- await adapter.setStateAsync(stateName, {val: false, ack: true});
956
+ await adapter.setStateAsync(stateName, { val: false, ack: true });
754
957
  await setState(id, off, ack);
755
958
  callback && callback(name);
756
959
  } else {
@@ -780,14 +983,16 @@ function syncUserEvents(callback) {
780
983
 
781
984
  // Read all actual events
782
985
  adapter.getStatesOf('', 'events', async (err, states) => {
783
- if (stopped) return;
986
+ if (stopped) {
987
+ return;
988
+ }
784
989
  const toAdd = [];
785
990
  const toDel = [];
786
991
 
787
992
  if (states) {
788
993
  // Add "to delete" all existing events
789
994
  for (let j = 0; j < states.length; j++) {
790
- toDel.push({id: removeNameSpace(states[j]._id), name: states[j].common.name});
995
+ toDel.push({ id: removeNameSpace(states[j]._id), name: states[j].common.name });
791
996
  }
792
997
  }
793
998
 
@@ -796,11 +1001,11 @@ function syncUserEvents(callback) {
796
1001
  for (let day = 0; day < days; day++) {
797
1002
  const name = adapter.config.events[i].name;
798
1003
  if (!day) {
799
- toAdd.push({id: `events.${day}.later.${shrinkStateName(name)}`, name: name});
800
- toAdd.push({id: `events.${day}.today.${shrinkStateName(name)}`, name: name});
801
- toAdd.push({id: `events.${day}.now.${shrinkStateName(name)}`, name: name});
1004
+ toAdd.push({ id: `events.${day}.later.${shrinkStateName(name)}`, name: name });
1005
+ toAdd.push({ id: `events.${day}.today.${shrinkStateName(name)}`, name: name });
1006
+ toAdd.push({ id: `events.${day}.now.${shrinkStateName(name)}`, name: name });
802
1007
  } else {
803
- toAdd.push({id: `events.${day}.${shrinkStateName(name)}`, name: name});
1008
+ toAdd.push({ id: `events.${day}.${shrinkStateName(name)}`, name: name });
804
1009
  }
805
1010
  }
806
1011
  }
@@ -843,13 +1048,13 @@ function syncUserEvents(callback) {
843
1048
  for (let j = 0; j < states.length; j++) {
844
1049
  const event = adapter.config.events[i];
845
1050
  const name = shrinkStateName(event.name);
846
- if (states[j].common.name === event.name &&
1051
+ if (
1052
+ states[j].common.name === event.name &&
847
1053
  ((day > 0 && removeNameSpace(states[j]._id) === `events.${day}.${name}`) ||
848
- (!day && (
849
- removeNameSpace(states[j]._id) === `events.${day}.today.${name}` ||
850
- removeNameSpace(states[j]._id) === `events.${day}.now.${name}` ||
851
- removeNameSpace(states[j]._id) === `events.${day}.later.${name}`
852
- )))
1054
+ (!day &&
1055
+ (removeNameSpace(states[j]._id) === `events.${day}.today.${name}` ||
1056
+ removeNameSpace(states[j]._id) === `events.${day}.now.${name}` ||
1057
+ removeNameSpace(states[j]._id) === `events.${day}.later.${name}`)))
853
1058
  ) {
854
1059
  if (event.enabled === 'true') {
855
1060
  event.enabled = true;
@@ -865,9 +1070,11 @@ function syncUserEvents(callback) {
865
1070
  }
866
1071
 
867
1072
  // if settings does not changed
868
- if (states[j].native &&
1073
+ if (
1074
+ states[j].native &&
869
1075
  states[j].native.enabled === event.enabled &&
870
- states[j].native.display === event.display) {
1076
+ states[j].native.display === event.display
1077
+ ) {
871
1078
  // remove it from "toAdd"
872
1079
  removeFromToAdd(removeNameSpace(states[j]._id));
873
1080
  }
@@ -882,13 +1089,13 @@ function syncUserEvents(callback) {
882
1089
  for (let j = 0; j < adapter.config.events.length; j++) {
883
1090
  const configItem = adapter.config.events[j];
884
1091
  if (configItem.name === toAdd[i].name) {
885
- if (configItem.enabled === 'true') {
1092
+ if (configItem.enabled === 'true') {
886
1093
  configItem.enabled = true;
887
1094
  }
888
1095
  if (configItem.enabled === 'false') {
889
1096
  configItem.enabled = false;
890
1097
  }
891
- if (configItem.display === 'true') {
1098
+ if (configItem.display === 'true') {
892
1099
  configItem.display = true;
893
1100
  }
894
1101
  if (configItem.display === 'false') {
@@ -897,19 +1104,18 @@ function syncUserEvents(callback) {
897
1104
 
898
1105
  // Add or update state
899
1106
  try {
900
- const id = await adapter.setObjectAsync(toAdd[i].id,
901
- {
902
- type: 'state',
903
- common: {
904
- name: toAdd[i].name,
905
- type: 'boolean',
906
- role: 'indicator'
907
- },
908
- native: {
909
- enabled: configItem.enabled,
910
- display: configItem.display
911
- }
912
- });
1107
+ const id = await adapter.setObjectAsync(toAdd[i].id, {
1108
+ type: 'state',
1109
+ common: {
1110
+ name: toAdd[i].name,
1111
+ type: 'boolean',
1112
+ role: 'indicator',
1113
+ },
1114
+ native: {
1115
+ enabled: configItem.enabled,
1116
+ display: configItem.display,
1117
+ },
1118
+ });
913
1119
  adapter.log.info(`Event "${id.id}" created`);
914
1120
  } catch (err) {
915
1121
  adapter.log.warn(`Event "${toAdd[i].id}" could ne be created: ${err}`);
@@ -931,12 +1137,52 @@ function syncUserEvents(callback) {
931
1137
  if (event.enabled) {
932
1138
  if (!day) {
933
1139
  count += 3;
934
- initEvent(event.name, event.display, 0, 'today', null, null, null, null,() => !--count && callback());
935
- initEvent(event.name, event.display, 0, 'now', event.id, event.on, event.off, event.ack,() => !--count && callback());
936
- initEvent(event.name, event.display, 0, 'later', null, null, null, null,() => !--count && callback());
1140
+ initEvent(
1141
+ event.name,
1142
+ event.display,
1143
+ 0,
1144
+ 'today',
1145
+ null,
1146
+ null,
1147
+ null,
1148
+ null,
1149
+ () => !--count && callback(),
1150
+ );
1151
+ initEvent(
1152
+ event.name,
1153
+ event.display,
1154
+ 0,
1155
+ 'now',
1156
+ event.id,
1157
+ event.on,
1158
+ event.off,
1159
+ event.ack,
1160
+ () => !--count && callback(),
1161
+ );
1162
+ initEvent(
1163
+ event.name,
1164
+ event.display,
1165
+ 0,
1166
+ 'later',
1167
+ null,
1168
+ null,
1169
+ null,
1170
+ null,
1171
+ () => !--count && callback(),
1172
+ );
937
1173
  } else {
938
1174
  count++;
939
- initEvent(event.name, event.display, day, null, null, null, null, null,() => !--count && callback());
1175
+ initEvent(
1176
+ event.name,
1177
+ event.display,
1178
+ day,
1179
+ null,
1180
+ null,
1181
+ null,
1182
+ null,
1183
+ null,
1184
+ () => !--count && callback(),
1185
+ );
940
1186
  }
941
1187
  }
942
1188
  }
@@ -955,15 +1201,15 @@ function buildFilter(filter, filterregex) {
955
1201
  const list = (filter || '').split(';');
956
1202
  for (let i = 0; i < list.length; i++) {
957
1203
  const item = list[i].trim();
958
- if(!item) {
1204
+ if (!item) {
959
1205
  continue;
960
1206
  }
961
- if(prep) {
1207
+ if (prep) {
962
1208
  prep += '|';
963
1209
  }
964
1210
  prep += `(${item})`;
965
1211
  }
966
- if(prep) {
1212
+ if (prep) {
967
1213
  prep = `/${prep}/g`;
968
1214
  }
969
1215
  }
@@ -973,7 +1219,7 @@ function buildFilter(filter, filterregex) {
973
1219
  const s = prep.split('/');
974
1220
  ret = new RegExp(s[1], s[2]);
975
1221
  } catch (e) {
976
- adapter.log.error(`invalid filter: ${prep}`);
1222
+ adapter.log.error(`invalid filter ${prep}: ${e}`);
977
1223
  }
978
1224
  }
979
1225
 
@@ -996,14 +1242,17 @@ function readAll() {
996
1242
  for (let i = 0; i < adapter.config.calendars.length; i++) {
997
1243
  if (adapter.config.calendars[i].url) {
998
1244
  count++;
999
- adapter.log.debug(`reading calendar from URL: ${adapter.config.calendars[i].url}, color: ${adapter.config.calendars[i].color}`);
1245
+ adapter.log.debug(
1246
+ `reading calendar from URL: ${adapter.config.calendars[i].url}, color: ${adapter.config.calendars[i].color}`,
1247
+ );
1000
1248
  checkICal(
1001
1249
  adapter.config.calendars[i].url,
1002
1250
  adapter.config.calendars[i].user,
1003
1251
  adapter.config.calendars[i].pass,
1004
1252
  adapter.config.calendars[i].sslignore,
1005
1253
  adapter.config.calendars[i].name,
1006
- buildFilter(adapter.config.calendars[i].filter, adapter.config.calendars[i].filterregex), (err) => {
1254
+ buildFilter(adapter.config.calendars[i].filter, adapter.config.calendars[i].filterregex),
1255
+ err => {
1007
1256
  if (err) {
1008
1257
  errCnt++;
1009
1258
  }
@@ -1021,7 +1270,8 @@ function readAll() {
1021
1270
  adapter.log.debug('displaying dates because of callback');
1022
1271
  displayDates();
1023
1272
  }
1024
- });
1273
+ },
1274
+ );
1025
1275
  }
1026
1276
  }
1027
1277
  }
@@ -1034,9 +1284,10 @@ function readAll() {
1034
1284
  }
1035
1285
 
1036
1286
  // Read one calendar
1287
+ /*
1037
1288
  function readOne(url) {
1038
1289
  datesArray = [];
1039
- checkICal(url, (err) => {
1290
+ checkICal(url, err => {
1040
1291
  if (err) {
1041
1292
  adapter.log.info('Calender could not be processed, Do not clean up events.');
1042
1293
  killTimeout && clearTimeout(killTimeout);
@@ -1049,22 +1300,23 @@ function readOne(url) {
1049
1300
  displayDates();
1050
1301
  });
1051
1302
  }
1303
+ */
1052
1304
 
1053
1305
  function formatDate(_date, _end, withTime, fullDay) {
1054
- let day = _date.getDate();
1306
+ let day = _date.getDate();
1055
1307
  let month = _date.getMonth() + 1;
1056
- let year = _date.getFullYear();
1308
+ let year = _date.getFullYear();
1057
1309
 
1058
- const endday = _end.getDate();
1310
+ const endday = _end.getDate();
1059
1311
  const endmonth = _end.getMonth() + 1;
1060
- const endyear = _end.getFullYear();
1312
+ const endyear = _end.getFullYear();
1061
1313
  let _time = '';
1062
1314
  const now = new Date();
1063
1315
  const alreadyStarted = _date < now && _end > now;
1064
1316
  const arrowAlreadyStarted = adapter.config.arrowAlreadyStarted;
1065
1317
 
1066
1318
  if (withTime) {
1067
- let hours = _date.getHours();
1319
+ let hours = _date.getHours();
1068
1320
  let minutes = _date.getMinutes();
1069
1321
 
1070
1322
  if (adapter.config.fulltime && fullDay) {
@@ -1073,7 +1325,7 @@ function formatDate(_date, _end, withTime, fullDay) {
1073
1325
  if (!alreadyStarted) {
1074
1326
  if (adapter.config.dataPaddingWithZeros) {
1075
1327
  if (hours < 10) {
1076
- hours = `0${hours.toString()}`;
1328
+ hours = `0${hours.toString()}`;
1077
1329
  }
1078
1330
  }
1079
1331
  if (minutes < 10) {
@@ -1118,7 +1370,9 @@ function formatDate(_date, _end, withTime, fullDay) {
1118
1370
  start.setHours(0, 0, 1, 0);
1119
1371
  const fullTimeDiff = timeDiff;
1120
1372
  timeDiff = treatAsUTC(_end.getTime()) - treatAsUTC(start.getTime());
1121
- adapter.log.debug(` time difference: ${timeDiff} (${_date}-${_end} / ${start}) --> ${timeDiff / (24 * 60 * 60 * 1000)}`);
1373
+ adapter.log.debug(
1374
+ ` time difference: ${timeDiff} (${_date}-${_end} / ${start}) --> ${timeDiff / (24 * 60 * 60 * 1000)}`,
1375
+ );
1122
1376
  if (fullTimeDiff >= 24 * 60 * 60 * 1000) {
1123
1377
  _time += `+${Math.floor(timeDiff / (24 * 60 * 60 * 1000))}`;
1124
1378
  }
@@ -1130,17 +1384,19 @@ function formatDate(_date, _end, withTime, fullDay) {
1130
1384
  }
1131
1385
  let _class = '';
1132
1386
  const d = new Date();
1133
- d.setHours(0,0,0,0);
1387
+ d.setHours(0, 0, 0, 0);
1134
1388
  const d2 = new Date();
1135
1389
  d2.setDate(d.getDate() + 1);
1136
1390
  let todayOnly = false;
1137
- if (day === d.getDate() &&
1138
- month === (d.getMonth() + 1) &&
1139
- year === d.getFullYear() &&
1140
- endday === d2.getDate() &&
1141
- endmonth === (d2.getMonth() + 1) &&
1142
- endyear === d2.getFullYear() &&
1143
- fullDay) {
1391
+ if (
1392
+ day === d.getDate() &&
1393
+ month === d.getMonth() + 1 &&
1394
+ year === d.getFullYear() &&
1395
+ endday === d2.getDate() &&
1396
+ endmonth === d2.getMonth() + 1 &&
1397
+ endyear === d2.getFullYear() &&
1398
+ fullDay
1399
+ ) {
1144
1400
  todayOnly = true;
1145
1401
  }
1146
1402
  adapter.log.debug(` todayOnly = ${todayOnly}: (${_date}-${_end}), alreadyStarted=${alreadyStarted}`);
@@ -1150,91 +1406,99 @@ function formatDate(_date, _end, withTime, fullDay) {
1150
1406
  _class = 'ical_today';
1151
1407
  }
1152
1408
 
1153
- if (day === d.getDate() &&
1154
- month === (d.getMonth() + 1) &&
1155
- year === d.getFullYear()) {
1409
+ if (day === d.getDate() && month === d.getMonth() + 1 && year === d.getFullYear()) {
1156
1410
  _class = 'ical_today';
1157
1411
  }
1158
1412
 
1159
1413
  d.setDate(d.getDate() + 1);
1160
- if (day === d.getDate() &&
1161
- month === (d.getMonth() + 1) &&
1162
- year === d.getFullYear()) {
1414
+ if (day === d.getDate() && month === d.getMonth() + 1 && year === d.getFullYear()) {
1163
1415
  _class = 'ical_tomorrow';
1164
1416
  }
1165
1417
 
1166
1418
  d.setDate(d.getDate() + 1);
1167
- if (day === d.getDate() &&
1168
- month === (d.getMonth() + 1) &&
1169
- year === d.getFullYear()) {
1419
+ if (day === d.getDate() && month === d.getMonth() + 1 && year === d.getFullYear()) {
1170
1420
  _class = 'ical_dayafter';
1171
1421
  }
1172
1422
 
1173
1423
  d.setDate(d.getDate() + 1);
1174
- if (day === d.getDate() &&
1175
- month === (d.getMonth() + 1) &&
1176
- year === d.getFullYear()) {
1424
+ if (day === d.getDate() && month === d.getMonth() + 1 && year === d.getFullYear()) {
1177
1425
  _class = 'ical_3days';
1178
1426
  }
1179
1427
 
1180
1428
  d.setDate(d.getDate() + 1);
1181
- if (day === d.getDate() &&
1182
- month === (d.getMonth() + 1) &&
1183
- year === d.getFullYear()) {
1429
+ if (day === d.getDate() && month === d.getMonth() + 1 && year === d.getFullYear()) {
1184
1430
  _class = 'ical_4days';
1185
1431
  }
1186
1432
 
1187
1433
  d.setDate(d.getDate() + 1);
1188
- if (day === d.getDate() &&
1189
- month === (d.getMonth() + 1) &&
1190
- year === d.getFullYear()) {
1434
+ if (day === d.getDate() && month === d.getMonth() + 1 && year === d.getFullYear()) {
1191
1435
  _class = 'ical_5days';
1192
1436
  }
1193
1437
 
1194
1438
  d.setDate(d.getDate() + 1);
1195
- if (day === d.getDate() &&
1196
- month === (d.getMonth() + 1) &&
1197
- year === d.getFullYear()) {
1439
+ if (day === d.getDate() && month === d.getMonth() + 1 && year === d.getFullYear()) {
1198
1440
  _class = 'ical_6days';
1199
1441
  }
1200
1442
 
1201
1443
  d.setDate(d.getDate() + 1);
1202
- if (day === d.getDate() &&
1203
- month === (d.getMonth() + 1) &&
1204
- year === d.getFullYear()) {
1444
+ if (day === d.getDate() && month === d.getMonth() + 1 && year === d.getFullYear()) {
1205
1445
  _class = 'ical_oneweek';
1206
1446
  }
1207
1447
  if (adapter.config.replaceDates) {
1208
- if (_class === 'ical_today') {
1209
- return {text: `${(arrowAlreadyStarted && alreadyStarted && !todayOnly) ? '&#8594; ' : ''}${_('today')}${_time}`, _class: _class};
1448
+ if (_class === 'ical_today') {
1449
+ return {
1450
+ text: `${arrowAlreadyStarted && alreadyStarted && !todayOnly ? '&#8594; ' : ''}${_('today')}${_time}`,
1451
+ _class: _class,
1452
+ };
1210
1453
  }
1211
1454
  if (_class === 'ical_tomorrow') {
1212
- return {text: `${(arrowAlreadyStarted && alreadyStarted) ? '&#8594; ' : ''}${_('tomorrow')}${_time}`, _class: _class};
1455
+ return {
1456
+ text: `${arrowAlreadyStarted && alreadyStarted ? '&#8594; ' : ''}${_('tomorrow')}${_time}`,
1457
+ _class: _class,
1458
+ };
1213
1459
  }
1214
1460
  if (_class === 'ical_dayafter') {
1215
- return {text: `${(arrowAlreadyStarted && alreadyStarted) ? '&#8594; ' : ''}${_('dayafter')}${_time}`, _class: _class};
1461
+ return {
1462
+ text: `${arrowAlreadyStarted && alreadyStarted ? '&#8594; ' : ''}${_('dayafter')}${_time}`,
1463
+ _class: _class,
1464
+ };
1216
1465
  }
1217
- if (_class === 'ical_3days') {
1218
- return {text: `${(arrowAlreadyStarted && alreadyStarted) ? '&#8594; ' : ''}${_('3days')}${_time}`, _class: _class};
1466
+ if (_class === 'ical_3days') {
1467
+ return {
1468
+ text: `${arrowAlreadyStarted && alreadyStarted ? '&#8594; ' : ''}${_('3days')}${_time}`,
1469
+ _class: _class,
1470
+ };
1219
1471
  }
1220
- if (_class === 'ical_4days') {
1221
- return {text: `${(arrowAlreadyStarted && alreadyStarted) ? '&#8594; ' : ''}${_('4days')}${_time}`, _class: _class};
1472
+ if (_class === 'ical_4days') {
1473
+ return {
1474
+ text: `${arrowAlreadyStarted && alreadyStarted ? '&#8594; ' : ''}${_('4days')}${_time}`,
1475
+ _class: _class,
1476
+ };
1222
1477
  }
1223
- if (_class === 'ical_5days') {
1224
- return {text: `${(arrowAlreadyStarted && alreadyStarted) ? '&#8594; ' : ''}${_('5days')}${_time}`, _class: _class};
1478
+ if (_class === 'ical_5days') {
1479
+ return {
1480
+ text: `${arrowAlreadyStarted && alreadyStarted ? '&#8594; ' : ''}${_('5days')}${_time}`,
1481
+ _class: _class,
1482
+ };
1225
1483
  }
1226
- if (_class === 'ical_6days') {
1227
- return {text: `${(arrowAlreadyStarted && alreadyStarted) ? '&#8594; ' : ''}${_('6days')}${_time}`, _class: _class};
1484
+ if (_class === 'ical_6days') {
1485
+ return {
1486
+ text: `${arrowAlreadyStarted && alreadyStarted ? '&#8594; ' : ''}${_('6days')}${_time}`,
1487
+ _class: _class,
1488
+ };
1228
1489
  }
1229
- if (_class === 'ical_oneweek') {
1230
- return {text: `${(arrowAlreadyStarted && alreadyStarted) ? '&#8594; ' : ''}${_('oneweek')}${_time}`, _class: _class};
1490
+ if (_class === 'ical_oneweek') {
1491
+ return {
1492
+ text: `${arrowAlreadyStarted && alreadyStarted ? '&#8594; ' : ''}${_('oneweek')}${_time}`,
1493
+ _class: _class,
1494
+ };
1231
1495
  }
1232
1496
  }
1233
1497
  } else {
1234
1498
  // check if date is in the past and if so we show the end time instead
1235
1499
  _class = 'ical_today';
1236
- const dateDiff = (treatAsUTC(_end.getTime()) - treatAsUTC(Date.now()));
1237
- let daysleft = Math.round( dateDiff/ (1000 * 60 * 60 * 24));
1500
+ const dateDiff = treatAsUTC(_end.getTime()) - treatAsUTC(Date.now());
1501
+ let daysleft = Math.round(dateDiff / (1000 * 60 * 60 * 24));
1238
1502
  const hoursleft = Math.round(dateDiff / (1000 * 60 * 60));
1239
1503
  const minutesleft = Math.round(dateDiff / (1000 * 60));
1240
1504
 
@@ -1245,7 +1509,7 @@ function formatDate(_date, _end, withTime, fullDay) {
1245
1509
 
1246
1510
  let text;
1247
1511
  if (adapter.config.replaceDates) {
1248
- const _left = (_('left') !== ' ' ? ` ${_('left')}` : '');
1512
+ const _left = _('left') !== ' ' ? ` ${_('left')}` : '';
1249
1513
  if (daysleft === 42) {
1250
1514
  text = _('6week_left');
1251
1515
  } else if (daysleft === 35) {
@@ -1297,9 +1561,9 @@ function formatDate(_date, _end, withTime, fullDay) {
1297
1561
  if (_end.getHours() === 0 && _end.getMinutes() === 0 && _end.getSeconds() === 0 && fullDay) {
1298
1562
  const secondBeforeEnd = new Date(_end.getTime());
1299
1563
  secondBeforeEnd.setSeconds(secondBeforeEnd.getSeconds() - 1);
1300
- day = secondBeforeEnd.getDate();
1564
+ day = secondBeforeEnd.getDate();
1301
1565
  month = secondBeforeEnd.getMonth() + 1;
1302
- year = secondBeforeEnd.getFullYear();
1566
+ year = secondBeforeEnd.getFullYear();
1303
1567
  adapter.log.debug(`Adjust enddate to exclude 0:0:0 end: ${secondBeforeEnd.toString()}`);
1304
1568
  } else {
1305
1569
  day = _end.getDate();
@@ -1308,15 +1572,15 @@ function formatDate(_date, _end, withTime, fullDay) {
1308
1572
  }
1309
1573
 
1310
1574
  if (adapter.config.dataPaddingWithZeros) {
1311
- if (day < 10) {
1312
- day = `0${day.toString()}`;
1575
+ if (day < 10) {
1576
+ day = `0${day.toString()}`;
1313
1577
  }
1314
1578
  if (month < 10) {
1315
1579
  month = `0${month.toString()}`;
1316
1580
  }
1317
1581
  }
1318
1582
 
1319
- text = `${(arrowAlreadyStarted) ? '&#8594; ' : ''}${day}.${month}.`;
1583
+ text = `${arrowAlreadyStarted ? '&#8594; ' : ''}${day}.${month}.`;
1320
1584
  if (!adapter.config.hideYear) {
1321
1585
  text += year;
1322
1586
  }
@@ -1325,11 +1589,11 @@ function formatDate(_date, _end, withTime, fullDay) {
1325
1589
  if (adapter.config.fulltime && fullDay) {
1326
1590
  text += ` ${adapter.config.fulltime}`;
1327
1591
  } else {
1328
- let endhours = _end.getHours();
1592
+ let endhours = _end.getHours();
1329
1593
  let endminutes = _end.getMinutes();
1330
1594
  if (adapter.config.dataPaddingWithZeros) {
1331
- if (endhours < 10) {
1332
- endhours = `0${endhours.toString()}`;
1595
+ if (endhours < 10) {
1596
+ endhours = `0${endhours.toString()}`;
1333
1597
  }
1334
1598
  }
1335
1599
  if (endminutes < 10) {
@@ -1340,12 +1604,12 @@ function formatDate(_date, _end, withTime, fullDay) {
1340
1604
  }
1341
1605
  }
1342
1606
 
1343
- return {text: text, _class: _class};
1607
+ return { text: text, _class: _class };
1344
1608
  }
1345
1609
 
1346
1610
  if (adapter.config.dataPaddingWithZeros) {
1347
- if (day < 10) {
1348
- day = `0${day.toString()}`;
1611
+ if (day < 10) {
1612
+ day = `0${day.toString()}`;
1349
1613
  }
1350
1614
  if (month < 10) {
1351
1615
  month = `0${month.toString()}`;
@@ -1353,8 +1617,8 @@ function formatDate(_date, _end, withTime, fullDay) {
1353
1617
  }
1354
1618
 
1355
1619
  return {
1356
- text: `${day}.${month}${(adapter.config.hideYear) ? '.' : `.${year}`}${_time}`,
1357
- _class: _class
1620
+ text: `${day}.${month}${adapter.config.hideYear ? '.' : `.${year}`}${_time}`,
1621
+ _class: _class,
1358
1622
  };
1359
1623
  }
1360
1624
 
@@ -1390,7 +1654,9 @@ async function setState(id, val, ack, cb) {
1390
1654
 
1391
1655
  // Show event as text
1392
1656
  async function displayDates() {
1393
- if (stopped) return;
1657
+ if (stopped) {
1658
+ return;
1659
+ }
1394
1660
 
1395
1661
  let todayEventCounter = 0;
1396
1662
  let tomorrowEventCounter = 0;
@@ -1415,7 +1681,10 @@ async function displayDates() {
1415
1681
  adapter.log.debug(`displayDates: TODAY - ${datesArray[t].event} (${datesArray[t]._date})`);
1416
1682
  todayEventCounter++;
1417
1683
  }
1418
- if (datesArray[t]._end.getTime() > tomorrow.getTime() && datesArray[t]._date.getTime() < dayAfterTomorrow.getTime()) {
1684
+ if (
1685
+ datesArray[t]._end.getTime() > tomorrow.getTime() &&
1686
+ datesArray[t]._date.getTime() < dayAfterTomorrow.getTime()
1687
+ ) {
1419
1688
  adapter.log.debug(`displayDates: TOMORROW - ${datesArray[t].event} (${datesArray[t]._date})`);
1420
1689
  tomorrowEventCounter++;
1421
1690
  }
@@ -1427,29 +1696,31 @@ async function displayDates() {
1427
1696
 
1428
1697
  adapter.log.debug(`Dates array (data.table): ${JSON.stringify(datesArray)}`);
1429
1698
 
1430
- await adapter.setStateAsync('data.table', {val: JSON.stringify(datesArray), ack: true});
1431
- await adapter.setStateAsync('data.html', {val: brSeparatedList(datesArray), ack: true});
1432
- await adapter.setStateAsync('data.text', {val: crlfSeparatedList(datesArray), ack: true});
1699
+ await adapter.setStateAsync('data.table', { val: JSON.stringify(datesArray), ack: true });
1700
+ await adapter.setStateAsync('data.html', { val: brSeparatedList(datesArray), ack: true });
1701
+ await adapter.setStateAsync('data.text', { val: crlfSeparatedList(datesArray), ack: true });
1433
1702
  } else {
1434
- await adapter.setStateAsync('data.table', {val: '[]', ack: true});
1435
- await adapter.setStateAsync('data.html', {val: '', ack: true});
1436
- await adapter.setStateAsync('data.text', {val: '', ack: true});
1703
+ await adapter.setStateAsync('data.table', { val: '[]', ack: true });
1704
+ await adapter.setStateAsync('data.html', { val: '', ack: true });
1705
+ await adapter.setStateAsync('data.text', { val: '', ack: true });
1437
1706
  }
1438
1707
 
1439
- await adapter.setStateAsync('data.count', {val: todayEventCounter, ack: true});
1440
- await adapter.setStateAsync('data.countTomorrow', {val: tomorrowEventCounter, ack: true});
1441
- await adapter.setStateAsync('data.countYesterday', {val: yesterdayEventCounter, ack: true});
1708
+ await adapter.setStateAsync('data.count', { val: todayEventCounter, ack: true });
1709
+ await adapter.setStateAsync('data.countTomorrow', { val: tomorrowEventCounter, ack: true });
1710
+ await adapter.setStateAsync('data.countYesterday', { val: yesterdayEventCounter, ack: true });
1442
1711
 
1443
1712
  // set not processed events to false
1444
1713
  for (let j = 0; j < events.length; j++) {
1445
- adapter.log.debug(`Checking unprocessed event ${events[j].day} ${events[j].type} ${events[j].name} = ${events[j].processed}, state = ${events[j].state}`);
1714
+ adapter.log.debug(
1715
+ `Checking unprocessed event ${events[j].day} ${events[j].type} ${events[j].name} = ${events[j].processed}, state = ${events[j].state}`,
1716
+ );
1446
1717
  if (!events[j].processed && events[j].state) {
1447
1718
  const ev = events[j];
1448
1719
  ev.state = false;
1449
1720
  // Set to false
1450
1721
  const name = `events.${ev.day}.${ev.type ? `${ev.type}.` : ''}${shrinkStateName(ev.name)}`;
1451
1722
  adapter.log.info(`Set ${name} to false`);
1452
- await adapter.setStateAsync(name, {val: false, ack: true});
1723
+ await adapter.setStateAsync(name, { val: false, ack: true });
1453
1724
  await setState(ev.id, ev.off, ev.ack);
1454
1725
  }
1455
1726
  }
@@ -1473,7 +1744,7 @@ function insertSorted(arr, element) {
1473
1744
  if (arr.length === 1) {
1474
1745
  arr.push(element);
1475
1746
  } else {
1476
- for (let i = 0; i < arr.length - 1; i++){
1747
+ for (let i = 0; i < arr.length - 1; i++) {
1477
1748
  if (arr[i]._date <= element._date && element._date < arr[i + 1]._date) {
1478
1749
  arr.splice(i + 1, 0, element);
1479
1750
  element = null;
@@ -1489,8 +1760,8 @@ function insertSorted(arr, element) {
1489
1760
  }
1490
1761
 
1491
1762
  function brSeparatedList(datesArray) {
1492
- let text = '';
1493
- const today = new Date();
1763
+ let text = '';
1764
+ const today = new Date();
1494
1765
  const tomorrow = new Date();
1495
1766
  const dayAfter = new Date();
1496
1767
  today.setHours(0, 0, 0, 0);
@@ -1533,8 +1804,8 @@ function brSeparatedList(datesArray) {
1533
1804
  }
1534
1805
 
1535
1806
  function crlfSeparatedList(datesArray) {
1536
- let text = '';
1537
- const today = new Date();
1807
+ let text = '';
1808
+ const today = new Date();
1538
1809
  const tomorrow = new Date();
1539
1810
  const dayafter = new Date();
1540
1811
  today.setHours(0, 0, 0, 0);
@@ -1545,14 +1816,16 @@ function crlfSeparatedList(datesArray) {
1545
1816
 
1546
1817
  for (let i = 0; i < datesArray.length; i++) {
1547
1818
  const date = formatDate(datesArray[i]._date, datesArray[i]._end, true, datesArray[i]._allDay);
1819
+ // TODO why doing all this stuff about color and then its unused?
1820
+ /*
1548
1821
  let color = adapter.config.defColor;
1549
1822
  for (let j = 0; j < adapter.config.calendars.length; j++) {
1550
- // TODO why doing all this stuff and then its unused?
1551
1823
  if (adapter.config.calendars[j].name === datesArray[i]._calName) {
1552
1824
  color = adapter.config.calendars[j].color;
1553
1825
  break;
1554
1826
  }
1555
1827
  }
1828
+ */
1556
1829
 
1557
1830
  if (text) {
1558
1831
  text += '\n';
@@ -1564,18 +1837,17 @@ function crlfSeparatedList(datesArray) {
1564
1837
  }
1565
1838
 
1566
1839
  function main() {
1567
- normal = `<span style="font-weight: bold${adapter.config.defColor ? (`; color: ${adapter.config.defColor}`) : ''}"><span class="icalNormal">`;
1840
+ normal = `<span style="font-weight: bold${adapter.config.defColor ? `; color: ${adapter.config.defColor}` : ''}"><span class="icalNormal">`;
1568
1841
 
1569
1842
  adapter.config.language = adapter.config.language || 'en';
1570
1843
  adapter.config.daysPast = parseInt(adapter.config.daysPast) || 0;
1571
1844
 
1572
1845
  const helpFilePath = '/UPLOAD_FILES_HERE.txt';
1573
- adapter.fileExistsAsync(adapter.namespace, helpFilePath)
1574
- .then(fileExists => {
1575
- if (!fileExists) {
1576
- adapter.writeFileAsync(adapter.namespace, helpFilePath, 'Place your *.ics files in this directory');
1577
- }
1578
- });
1846
+ adapter.fileExistsAsync(adapter.namespace, helpFilePath).then(fileExists => {
1847
+ if (!fileExists) {
1848
+ adapter.writeFileAsync(adapter.namespace, helpFilePath, 'Place your *.ics files in this directory');
1849
+ }
1850
+ });
1579
1851
 
1580
1852
  adapter.delObjectAsync('trigger'); // removed deprecated subscribe state (created in previous versions)
1581
1853