iobroker.javascript 8.9.2 → 9.0.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.
Files changed (119) hide show
  1. package/README.md +7 -3
  2. package/admin/assets/{createSvgIcon-BdRvDw53.js → createSvgIcon-BQT-7-GS.js} +1 -1
  3. package/admin/assets/{docs-6na4NFtj.js → docs-BrInh2Pn.js} +2 -2
  4. package/admin/assets/index-B0RKH_iG.js +1329 -0
  5. package/admin/assets/index-CfuHVX2B.js +193 -0
  6. package/admin/assets/index-CuCs5aLs.js +5 -0
  7. package/admin/assets/index-tExaxF69.js +930 -0
  8. package/admin/assets/inheritsLoose--KnFDOw1.js +36 -0
  9. package/admin/assets/{useTheme-Cl1QmYFL.js → useTheme-DF6qfrtI.js} +1 -1
  10. package/admin/custom/assets/{Components-ChpTW7sE.js → Components-D9kRsHNY.js} +1 -1
  11. package/admin/custom/assets/{DefaultPropsProvider-CHpMCMgA.js → DefaultPropsProvider-9qubdy-V.js} +2 -2
  12. package/admin/custom/assets/{FilledInput-CtcQVKyj.js → FilledInput-BpuM_GyB.js} +1 -1
  13. package/admin/custom/assets/Tabs-CvEv0KOT.js +138 -0
  14. package/admin/custom/assets/ThemeProvider-DZTpMR8n.js +29 -0
  15. package/admin/custom/assets/{createSvgIcon-C_vAELFU.js → createSvgIcon-BQThUM-f.js} +1 -1
  16. package/admin/custom/assets/hostInit-CrAs5YZS.js +1 -1
  17. package/admin/custom/assets/{index-DwsbskQy.js → index-DIWNdd4a.js} +1 -1
  18. package/admin/custom/assets/index-DZqbj5K4.js +55 -0
  19. package/admin/custom/assets/{index-D5apCzjJ.js → index-Dbe-II7_.js} +6 -6
  20. package/admin/custom/assets/index-az76fZMP.js +904 -0
  21. package/admin/custom/assets/index-sawv1cUe.js +1399 -0
  22. package/admin/custom/assets/{virtualExposes-BPncCdUy.js → virtualExposes-BMKIjWrE.js} +2 -2
  23. package/admin/custom/customComponents.js +2 -2
  24. package/admin/custom/i18n/de.json +29 -29
  25. package/admin/custom/i18n/es.json +29 -29
  26. package/admin/custom/i18n/fr.json +29 -29
  27. package/admin/custom/i18n/it.json +29 -29
  28. package/admin/custom/i18n/nl.json +29 -29
  29. package/admin/custom/i18n/pl.json +29 -29
  30. package/admin/custom/i18n/pt.json +29 -29
  31. package/admin/custom/i18n/ru.json +29 -29
  32. package/admin/custom/i18n/uk.json +29 -29
  33. package/admin/custom/i18n/zh-cn.json +29 -29
  34. package/admin/google-blockly/blockly_compressed.js +875 -887
  35. package/admin/google-blockly/blocks_compressed.js +38 -41
  36. package/admin/google-blockly/javascript_compressed.js +19 -54
  37. package/admin/google-blockly/media/delete-icon.svg +1 -0
  38. package/admin/google-blockly/media/foldout-icon.svg +1 -0
  39. package/admin/google-blockly/media/resize-handle.svg +3 -0
  40. package/admin/jsonConfig.json +2 -0
  41. package/admin/mf-manifest.json +1 -1
  42. package/admin/remoteEntry.js +2 -2
  43. package/admin/tab.html +4 -4
  44. package/admin/vsFont/README.md +1 -1
  45. package/admin/vsFont/createJson.js +1 -1
  46. package/build-backend/lib/consts.js +346 -0
  47. package/build-backend/lib/consts.js.map +1 -0
  48. package/build-backend/lib/convert.js +120 -0
  49. package/build-backend/lib/convert.js.map +1 -0
  50. package/build-backend/lib/debug.js +163 -0
  51. package/build-backend/lib/debug.js.map +1 -0
  52. package/{lib → build-backend/lib}/debugger.js +261 -232
  53. package/build-backend/lib/debugger.js.map +1 -0
  54. package/build-backend/lib/eventObj.js +177 -0
  55. package/build-backend/lib/eventObj.js.map +1 -0
  56. package/build-backend/lib/inspect.js +728 -0
  57. package/build-backend/lib/inspect.js.map +1 -0
  58. package/build-backend/lib/javascript.d.ts +1972 -0
  59. package/{lib → build-backend/lib}/mirror.js +185 -182
  60. package/build-backend/lib/mirror.js.map +1 -0
  61. package/build-backend/lib/nodeModulesManagement.js +25 -0
  62. package/build-backend/lib/nodeModulesManagement.js.map +1 -0
  63. package/build-backend/lib/patternCompareFunctions.js +321 -0
  64. package/build-backend/lib/patternCompareFunctions.js.map +1 -0
  65. package/build-backend/lib/protectFs.js +477 -0
  66. package/build-backend/lib/protectFs.js.map +1 -0
  67. package/build-backend/lib/request.js +89 -0
  68. package/build-backend/lib/request.js.map +1 -0
  69. package/{lib → build-backend/lib}/sandbox.js +2046 -1852
  70. package/build-backend/lib/sandbox.js.map +1 -0
  71. package/build-backend/lib/scheduler.js +553 -0
  72. package/build-backend/lib/scheduler.js.map +1 -0
  73. package/build-backend/lib/tools.js +183 -0
  74. package/build-backend/lib/tools.js.map +1 -0
  75. package/build-backend/lib/typescriptSettings.js +39 -0
  76. package/build-backend/lib/typescriptSettings.js.map +1 -0
  77. package/build-backend/lib/typescriptTools.js +435 -0
  78. package/build-backend/lib/typescriptTools.js.map +1 -0
  79. package/build-backend/lib/utils.js +66 -0
  80. package/build-backend/lib/utils.js.map +1 -0
  81. package/{lib → build-backend/lib}/words.js +23 -30
  82. package/build-backend/lib/words.js.map +1 -0
  83. package/build-backend/main.js +2671 -0
  84. package/build-backend/main.js.map +1 -0
  85. package/build-backend/types.d.ts +742 -0
  86. package/docs/de/README.md +1 -1
  87. package/docs/en/README.md +1 -1
  88. package/docs/en/javascript.md +10 -6
  89. package/docs/ru/README.md +1 -1
  90. package/install/installTypings.js +34 -47
  91. package/io-package.json +14 -14
  92. package/package.json +14 -14
  93. package/admin/assets/index-DCkkMRRa.js +0 -1335
  94. package/admin/assets/index-DJfSBoBB.js +0 -192
  95. package/admin/assets/index-DTiA4WdK.js +0 -930
  96. package/admin/assets/index-qABB1JVe.js +0 -5
  97. package/admin/assets/inheritsLoose-BW-3V39H.js +0 -36
  98. package/admin/custom/assets/Tabs-C1KOyWRi.js +0 -137
  99. package/admin/custom/assets/ThemeProvider-Buvx5nSd.js +0 -29
  100. package/admin/custom/assets/index-BGCRznKh.js +0 -904
  101. package/admin/custom/assets/index-DfBPYXqA.js +0 -55
  102. package/admin/custom/assets/index-jIr6kOLK.js +0 -1398
  103. package/lib/adapter-config.d.ts +0 -16
  104. package/lib/consts.js +0 -83
  105. package/lib/convert.js +0 -106
  106. package/lib/debug.js +0 -154
  107. package/lib/eventObj.js +0 -201
  108. package/lib/inspect.js +0 -688
  109. package/lib/javascript.d.ts +0 -1858
  110. package/lib/nodeModulesManagement.js +0 -26
  111. package/lib/patternCompareFunctions.js +0 -391
  112. package/lib/protectFs.js +0 -401
  113. package/lib/request.js +0 -72
  114. package/lib/scheduler.js +0 -447
  115. package/lib/tools.js +0 -192
  116. package/lib/typescriptSettings.js +0 -44
  117. package/lib/typescriptTools.js +0 -529
  118. package/lib/utils.js +0 -87
  119. package/main.js +0 -2653
@@ -0,0 +1,553 @@
1
+ "use strict";
2
+ // const DEFAULT = {
3
+ // time: {
4
+ // exactTime: false,
5
+ //
6
+ // start: '00:00',
7
+ // end: '23:59',
8
+ //
9
+ // mode: 'hours',
10
+ // interval: 1,
11
+ // },
12
+ // period: {
13
+ // once: '',
14
+ // days: 1,
15
+ // dows: '',
16
+ // dates: '',
17
+ // weeks: 0,
18
+ // months: '',
19
+ //
20
+ // years: 0,
21
+ // yearMonth: 0,
22
+ // yearDate: 0,
23
+ // },
24
+ // valid: {
25
+ // from: '',
26
+ // to: ''
27
+ // }
28
+ // };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.Scheduler = void 0;
31
+ class Scheduler {
32
+ list;
33
+ Date;
34
+ suncalc;
35
+ latitude;
36
+ longitude;
37
+ log;
38
+ timer = null;
39
+ todaysAstroTimes;
40
+ yesterdaysAstroTimes;
41
+ astroList;
42
+ astroListLow;
43
+ constructor(log, DateTest, suncalc, latitude, longitude) {
44
+ this.list = {};
45
+ this.Date = DateTest || Date;
46
+ this.suncalc = suncalc;
47
+ this.latitude = latitude;
48
+ this.longitude = longitude;
49
+ this.log = log || {
50
+ debug: function (text) {
51
+ console.log(text);
52
+ },
53
+ info: function (text) {
54
+ console.log(text);
55
+ },
56
+ log: function (text) {
57
+ console.log(text);
58
+ },
59
+ warn: function (text) {
60
+ console.warn(text);
61
+ },
62
+ error: function (text) {
63
+ console.error(text);
64
+ },
65
+ silly: function (text) {
66
+ console.log(text);
67
+ },
68
+ };
69
+ // this._setAstroVars();
70
+ const todayNoon = new this.Date();
71
+ const yesterdayNoon = new this.Date();
72
+ todayNoon.setHours(12, 0, 0, 0);
73
+ yesterdayNoon.setHours(-12, 0, 0, 0);
74
+ this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude);
75
+ this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude);
76
+ this.astroList = [
77
+ 'dawn',
78
+ 'dusk',
79
+ 'goldenHour',
80
+ 'goldenHourEnd',
81
+ 'nadir',
82
+ 'nauticalDawn',
83
+ 'nauticalDusk',
84
+ 'night',
85
+ 'nightEnd',
86
+ 'solarNoon',
87
+ 'sunrise',
88
+ 'sunriseEnd',
89
+ 'sunset',
90
+ 'sunsetStart',
91
+ ];
92
+ this.astroListLow = [
93
+ 'dawn',
94
+ 'dusk',
95
+ 'goldenhour',
96
+ 'goldenhourend',
97
+ 'nadir',
98
+ 'nauticaldawn',
99
+ 'nauticaldusk',
100
+ 'night',
101
+ 'nightend',
102
+ 'solarnoon',
103
+ 'sunrise',
104
+ 'sunriseend',
105
+ 'sunset',
106
+ 'sunsetstart',
107
+ ];
108
+ }
109
+ _getId() {
110
+ return `${Math.round(Math.random() * 1000000)}.${this.Date.now()}`;
111
+ }
112
+ recalculate() {
113
+ const count = Object.keys(this.list).length;
114
+ if (count && !this.timer) {
115
+ const d = new this.Date();
116
+ d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone
117
+ d.setSeconds(0);
118
+ d.setMinutes(d.getMinutes() + 1);
119
+ this.timer = setTimeout(notBefore => this.checkSchedules(notBefore), d.getTime() - this.Date.now(), d.getTime());
120
+ }
121
+ else if (!count && this.timer) {
122
+ clearTimeout(this.timer);
123
+ this.timer = null;
124
+ }
125
+ }
126
+ getContext() {
127
+ const now = new this.Date();
128
+ return {
129
+ now: now.getTime(),
130
+ minutesOfDay: now.getHours() * 60 + now.getMinutes(),
131
+ y: now.getFullYear(),
132
+ M: now.getMonth(),
133
+ d: now.getDate(),
134
+ h: now.getHours(),
135
+ m: now.getMinutes(),
136
+ dow: now.getDay(),
137
+ };
138
+ }
139
+ checkSchedules(notBeforeTime) {
140
+ const context = this.getContext();
141
+ // Work around for not those precise RTCs in some system
142
+ if (notBeforeTime !== undefined && context.now < notBeforeTime) {
143
+ this.timer = setTimeout(notBefore => this.checkSchedules(notBefore), notBeforeTime - this.Date.now(), notBeforeTime);
144
+ return;
145
+ }
146
+ for (const id in this.list) {
147
+ if (!Object.prototype.hasOwnProperty.call(this.list, id)) {
148
+ continue;
149
+ }
150
+ if (this.checkSchedule(context, this.list[id])) {
151
+ setImmediate(id => this.list[id] && typeof this.list[id].cb === 'function' && this.list[id].cb(id), id);
152
+ }
153
+ }
154
+ const d = new this.Date();
155
+ d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone
156
+ d.setSeconds(0);
157
+ d.setMinutes(d.getMinutes() + 1);
158
+ this.timer = setTimeout(notBefore => this.checkSchedules(notBefore), d.getTime() - this.Date.now(), d.getTime());
159
+ }
160
+ monthDiff(d1, d2) {
161
+ let months;
162
+ months = (d2.getFullYear() - d1.getFullYear()) * 12;
163
+ months -= d1.getMonth() + 1;
164
+ months += d2.getMonth();
165
+ return months <= 0 ? 0 : months;
166
+ }
167
+ checkSchedule(context, schedule) {
168
+ if (schedule.valid) {
169
+ if (schedule.valid.from &&
170
+ !this.isPast(context, schedule.valid.from) &&
171
+ !this.isToday(context, schedule.valid.from)) {
172
+ return false;
173
+ }
174
+ // "to" this.Date is in the past => delete it from a list
175
+ if (schedule.valid.to && this.isPast(context, schedule.valid.to)) {
176
+ delete this.list[schedule.id];
177
+ return false;
178
+ }
179
+ }
180
+ if (schedule.period) {
181
+ if (schedule.period.once && !this.isToday(context, schedule.period.once)) {
182
+ if (this.isPast(context, schedule.period.once)) {
183
+ delete this.list[schedule.id];
184
+ }
185
+ return false;
186
+ }
187
+ else if (schedule.period.days) {
188
+ if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) {
189
+ return false;
190
+ }
191
+ else if (schedule.period.days > 1) {
192
+ // @ts-expect-error period of days cannot be without valid fromDate
193
+ const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24) + 0.5);
194
+ if (diff % schedule.period.days) {
195
+ return false;
196
+ }
197
+ }
198
+ }
199
+ else if (schedule.period.weeks) {
200
+ if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) {
201
+ return false;
202
+ }
203
+ if (schedule.period.weeks > 1) {
204
+ // @ts-expect-error period of weeks cannot be without valid fromDate
205
+ const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24 * 7) + 0.5);
206
+ if (diff % schedule.period.weeks) {
207
+ return false;
208
+ }
209
+ }
210
+ }
211
+ else if (schedule.period.months) {
212
+ if (Array.isArray(schedule.period.months) && !schedule.period.months.includes(context.M)) {
213
+ return false;
214
+ }
215
+ if (schedule.period.fromDate &&
216
+ typeof schedule.period.months === 'number' &&
217
+ schedule.period.months > 1) {
218
+ const diff = this.monthDiff(schedule.period.fromDate, new this.Date(context.now));
219
+ if (diff % schedule.period.months) {
220
+ return false;
221
+ }
222
+ }
223
+ if (schedule.period.dates && !schedule.period.dates.includes(context.d)) {
224
+ return false;
225
+ }
226
+ }
227
+ else if (schedule.period.years) {
228
+ if (schedule.period.yearMonth !== undefined && schedule.period.yearMonth !== context.M) {
229
+ return false;
230
+ }
231
+ if (schedule.period.yearDate && schedule.period.yearDate !== context.d) {
232
+ return false;
233
+ }
234
+ if (schedule.period.fromDate &&
235
+ typeof schedule.period.years === 'number' &&
236
+ schedule.period.years > 1) {
237
+ const diff = Math.floor(this.monthDiff(schedule.period.fromDate, new this.Date(context.now)) / 12);
238
+ if (diff % schedule.period.years) {
239
+ return false;
240
+ }
241
+ }
242
+ }
243
+ }
244
+ if (schedule.time) {
245
+ let start;
246
+ let end;
247
+ const now = new this.Date(context.now);
248
+ if (now.getDate() !== this.todaysAstroTimes.sunrise.getDate()) {
249
+ this._setAstroVars();
250
+ }
251
+ if (typeof schedule.time.start === 'string') {
252
+ const astroNameStart = this._getAstroName(schedule.time.start);
253
+ if (astroNameStart) {
254
+ let times = this.todaysAstroTimes;
255
+ if (times[astroNameStart].getDate() !== now.getDate()) {
256
+ times = this.yesterdaysAstroTimes;
257
+ }
258
+ const startDate = times[astroNameStart];
259
+ start = startDate.getHours() * 60 + startDate.getMinutes();
260
+ }
261
+ else {
262
+ this.log.error(`unknown astro event "${schedule.time.start}"`);
263
+ return false;
264
+ }
265
+ }
266
+ else {
267
+ start = schedule.time.start;
268
+ }
269
+ if (typeof schedule.time.end === 'string') {
270
+ const astroNameEnd = this._getAstroName(schedule.time.end);
271
+ if (astroNameEnd) {
272
+ let times = this.todaysAstroTimes;
273
+ if (times[astroNameEnd].getDate() !== now.getDate()) {
274
+ times = this.yesterdaysAstroTimes;
275
+ }
276
+ const endDate = times[astroNameEnd];
277
+ end = endDate.getHours() * 60 + endDate.getMinutes();
278
+ }
279
+ else {
280
+ this.log.error(`unknown astro event "${schedule.time.end}"`);
281
+ return false;
282
+ }
283
+ }
284
+ else {
285
+ end = schedule.time.end;
286
+ }
287
+ start = start || 0;
288
+ end = end || 60 * 24;
289
+ if (schedule.time.exactTime) {
290
+ if (context.minutesOfDay !== start) {
291
+ return false;
292
+ }
293
+ }
294
+ else {
295
+ if (start >= context.minutesOfDay || (end && end < context.minutesOfDay)) {
296
+ return false;
297
+ }
298
+ if (schedule.time.mode === 60) {
299
+ if (schedule.time.interval > 1 && (context.minutesOfDay - start) % schedule.time.interval) {
300
+ return false;
301
+ }
302
+ }
303
+ else if (schedule.time.mode === 3600) {
304
+ if ((context.minutesOfDay - start) % (schedule.time.interval * 60)) {
305
+ return false;
306
+ }
307
+ }
308
+ }
309
+ }
310
+ return true;
311
+ }
312
+ string2date(date) {
313
+ let parts = date.split('.');
314
+ let d;
315
+ if (parts.length !== 3) {
316
+ parts = date.split('-');
317
+ d = new this.Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10));
318
+ }
319
+ else {
320
+ d = new this.Date(parseInt(parts[2], 10), parseInt(parts[1], 10) - 1, parseInt(parts[0], 10));
321
+ }
322
+ return { y: d.getFullYear(), M: d.getMonth(), d: d.getDate() };
323
+ }
324
+ isPast(context, date) {
325
+ if (date) {
326
+ if (date.y < context.y) {
327
+ return true;
328
+ }
329
+ if (date.y === context.y) {
330
+ if (date.M < context.M) {
331
+ return true;
332
+ }
333
+ if (date.M === context.M) {
334
+ if (date.d < context.d) {
335
+ return true;
336
+ }
337
+ }
338
+ }
339
+ }
340
+ return false;
341
+ }
342
+ isToday(context, date) {
343
+ return date && date.y === context.y && date.M === context.M && date.d === context.d;
344
+ }
345
+ add(schedule, scriptName, cb) {
346
+ let oSchedule;
347
+ if (typeof schedule === 'string') {
348
+ try {
349
+ oSchedule = JSON.parse(schedule);
350
+ }
351
+ catch {
352
+ this.log.error(`Cannot parse schedule: ${schedule}`);
353
+ return null;
354
+ }
355
+ }
356
+ else {
357
+ oSchedule = schedule;
358
+ }
359
+ const id = this._getId();
360
+ if (typeof oSchedule !== 'object' || !oSchedule.period) {
361
+ this.log.error(`Invalid schedule structure: ${JSON.stringify(oSchedule)}`);
362
+ return null;
363
+ }
364
+ const context = this.getContext();
365
+ const sch = JSON.parse(JSON.stringify(oSchedule));
366
+ sch.scriptName = scriptName;
367
+ sch.original = JSON.stringify(oSchedule);
368
+ sch.id = id;
369
+ sch.cb = cb;
370
+ if (oSchedule.time?.start) {
371
+ const astroNameStart = this._getAstroName(oSchedule.time.start);
372
+ if (astroNameStart && sch.time) {
373
+ sch.time.start = astroNameStart;
374
+ }
375
+ else if (oSchedule.time.start.includes(':')) {
376
+ const parts = oSchedule.time.start.split(':');
377
+ if (sch.time) {
378
+ sch.time.start = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
379
+ }
380
+ }
381
+ else {
382
+ this.log.error(`unknown astro event "${oSchedule.time.start}"`);
383
+ return null;
384
+ }
385
+ }
386
+ if (oSchedule.time?.end) {
387
+ const astroNameEnd = this._getAstroName(oSchedule.time.end);
388
+ if (astroNameEnd && sch.time) {
389
+ sch.time.end = astroNameEnd;
390
+ }
391
+ else if (oSchedule.time.end.includes(':')) {
392
+ const parts = oSchedule.time.end.split(':');
393
+ if (sch.time) {
394
+ sch.time.end = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
395
+ }
396
+ }
397
+ else {
398
+ this.log.error(`unknown astro event "${oSchedule.time.end}"`);
399
+ return null;
400
+ }
401
+ }
402
+ if (sch.time) {
403
+ if (oSchedule.time.mode === 'minutes') {
404
+ sch.time.mode = 60;
405
+ }
406
+ else if (oSchedule.time.mode === 'hours') {
407
+ sch.time.mode = 3600;
408
+ }
409
+ }
410
+ if (oSchedule.period.once) {
411
+ sch.period.once = this.string2date(oSchedule.period.once);
412
+ }
413
+ if (oSchedule.valid && sch.valid) {
414
+ if (oSchedule.valid.from) {
415
+ sch.valid.from = this.string2date(oSchedule.valid.from);
416
+ }
417
+ if (oSchedule.valid.to) {
418
+ sch.valid.to = this.string2date(oSchedule.valid.to);
419
+ }
420
+ if (this.isPast(context, sch.valid.to)) {
421
+ this.log.warn('End of schedule is in the past');
422
+ return null;
423
+ }
424
+ if (typeof oSchedule.period.days === 'number' && oSchedule.period.days > 1 && sch.valid.from) {
425
+ // fromDate must be unix time
426
+ sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d).getTime();
427
+ }
428
+ else if (typeof oSchedule.period.weeks === 'number' && oSchedule.period.weeks > 1) {
429
+ const fromDate = sch.valid.from
430
+ ? new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d)
431
+ : new this.Date();
432
+ //sch.valid.fromDate.setDate(-sch.valid.fromDate.getDate() - sch.valid.fromDate.getDay());
433
+ // fromDate must be unix time
434
+ sch.valid.fromDate = fromDate.getTime();
435
+ }
436
+ else if (sch.valid.from && typeof oSchedule.period.months === 'number' && oSchedule.period.months > 1) {
437
+ // fromDate must be object
438
+ sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d);
439
+ }
440
+ else if (sch.valid.from && typeof oSchedule.period.years === 'number' && oSchedule.period.years > 1) {
441
+ // fromDate must be object
442
+ sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d);
443
+ }
444
+ }
445
+ if (sch.period &&
446
+ ((typeof sch.period.days === 'number' && sch.period.days > 1) ||
447
+ (typeof sch.period.weeks === 'number' && sch.period.weeks > 1) ||
448
+ (typeof sch.period.months === 'number' && sch.period.months > 1) ||
449
+ (typeof sch.period.years === 'number' && sch.period.years > 1)) &&
450
+ (!sch.valid || !sch.valid.fromDate)) {
451
+ this.log.warn('Invalid Schedule definition: Period day/weeks/months/years only allowed with a valid.from date!');
452
+ return null;
453
+ }
454
+ if (oSchedule.period.dows) {
455
+ try {
456
+ sch.period.dows = JSON.parse(oSchedule.period.dows);
457
+ }
458
+ catch {
459
+ this.log.error(`Cannot parse day of weeks: ${JSON.stringify(sch.period.dows)}`);
460
+ return null;
461
+ }
462
+ if (!Array.isArray(sch.period.dows)) {
463
+ this.log.error(`day of weeks is no array: ${JSON.stringify(sch.period.dows)}`);
464
+ return null;
465
+ }
466
+ }
467
+ if (oSchedule.period.months && typeof oSchedule.period.months !== 'number') {
468
+ // can be number or array-string
469
+ try {
470
+ sch.period.months = JSON.parse(oSchedule.period.months);
471
+ }
472
+ catch {
473
+ this.log.error(`Cannot parse day of months: ${JSON.stringify(sch.period.months)}`);
474
+ return null;
475
+ }
476
+ sch.period.months = sch.period.months.map(m => m - 1);
477
+ }
478
+ if (oSchedule.period.dates) {
479
+ try {
480
+ sch.period.dates = JSON.parse(oSchedule.period.dates);
481
+ }
482
+ catch {
483
+ this.log.error(`Cannot parse day of dates: ${JSON.stringify(sch.period.dates)}`);
484
+ return null;
485
+ }
486
+ }
487
+ if (oSchedule.period.yearMonth) {
488
+ sch.period.yearMonth = oSchedule.period.yearMonth - 1;
489
+ }
490
+ this.list[id] = sch;
491
+ this.recalculate();
492
+ return id;
493
+ }
494
+ remove(id) {
495
+ if (typeof id === 'object' &&
496
+ id.type === 'schedule' &&
497
+ typeof id.id === 'string' &&
498
+ id.id.startsWith('schedule_')) {
499
+ if (this.list[id.id.substring('schedule_'.length)]) {
500
+ delete this.list[id.id.substring('schedule_'.length)];
501
+ this.recalculate();
502
+ return true;
503
+ }
504
+ return false;
505
+ }
506
+ if (typeof id === 'string' && this.list[id]) {
507
+ delete this.list[id];
508
+ this.recalculate();
509
+ return true;
510
+ }
511
+ return false;
512
+ }
513
+ getList() {
514
+ return Object.keys(this.list).map(id => ({
515
+ id: `schedule_${id}`,
516
+ type: 'schedule',
517
+ schedule: this.list[id].original,
518
+ scriptName: this.list[id].scriptName,
519
+ }));
520
+ }
521
+ get(id) {
522
+ if (id &&
523
+ typeof id === 'object' &&
524
+ id.type === 'schedule' &&
525
+ typeof id.id === 'string' &&
526
+ id.id.startsWith('schedule_')) {
527
+ return this.list[id.id.substring('schedule_'.length)];
528
+ }
529
+ if (typeof id === 'string') {
530
+ return this.list[id];
531
+ }
532
+ return null;
533
+ }
534
+ _setAstroVars() {
535
+ const todayNoon = new this.Date();
536
+ const yesterdayNoon = new this.Date();
537
+ todayNoon.setHours(12, 0, 0, 0);
538
+ yesterdayNoon.setHours(-12, 0, 0, 0);
539
+ this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude);
540
+ this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude);
541
+ }
542
+ _getAstroName(evt) {
543
+ if (typeof evt === 'string') {
544
+ const pos = this.astroListLow.indexOf(evt.toLowerCase());
545
+ if (pos > -1) {
546
+ return this.astroList[pos];
547
+ }
548
+ }
549
+ return null;
550
+ }
551
+ }
552
+ exports.Scheduler = Scheduler;
553
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/lib/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["// const DEFAULT = {\n// time: {\n// exactTime: false,\n//\n// start: '00:00',\n// end: '23:59',\n//\n// mode: 'hours',\n// interval: 1,\n// },\n// period: {\n// once: '',\n// days: 1,\n// dows: '',\n// dates: '',\n// weeks: 0,\n// months: '',\n//\n// years: 0,\n// yearMonth: 0,\n// yearDate: 0,\n// },\n// valid: {\n// from: '',\n// to: ''\n// }\n// };\n\nimport type {\n GetMoonIlluminationResult,\n GetMoonPositionResult,\n GetMoonTimes,\n GetSunPositionResult,\n GetTimesResult,\n} from 'suncalc';\n\ninterface SunCalc {\n getTimes: (date: Date, latitude: number, longitude: number, height?: number) => GetTimesResult;\n addTime: (angleInDegrees: number, morningName: string, eveningName: string) => void;\n getPosition: (timeAndDate: Date, latitude: number, longitude: number) => GetSunPositionResult;\n getMoonPosition: (timeAndDate: Date, latitude: number, longitude: number) => GetMoonPositionResult;\n getMoonIllumination: (timeAndDate: Date) => GetMoonIlluminationResult;\n getMoonTimes: (date: Date, latitude: number, longitude: number, inUTC?: boolean) => GetMoonTimes;\n}\n\nexport type AstroEventName =\n | 'dawn'\n | 'dusk'\n | 'goldenHour'\n | 'goldenHourEnd'\n | 'nadir'\n | 'nauticalDawn'\n | 'nauticalDusk'\n | 'night'\n | 'nightEnd'\n | 'solarNoon'\n | 'sunrise'\n | 'sunriseEnd'\n | 'sunset'\n | 'sunsetStart';\n\ntype AstroEventNameLow =\n | 'dawn'\n | 'dusk'\n | 'goldenhour'\n | 'goldenhourend'\n | 'nadir'\n | 'nauticaldawn'\n | 'nauticaldusk'\n | 'night'\n | 'nightend'\n | 'solarnoon'\n | 'sunrise'\n | 'sunriseend'\n | 'sunset'\n | 'sunsetstart';\n\ntype SchedulerContext = {\n now: number;\n minutesOfDay: number;\n y: number;\n M: number;\n d: number;\n h: number;\n m: number;\n dow: number;\n};\n\nexport type SchedulerRule = {\n time: {\n start?: string;\n end?: string;\n mode?: 'minutes' | 'hours';\n interval?: number;\n exactTime?: boolean;\n };\n period: {\n once?: string;\n\n days?: number;\n dows?: string;\n dates?: string;\n weeks?: number;\n months?: string;\n\n years?: number;\n yearMonth?: number;\n yearDate?: number;\n };\n valid?: {\n from?: string;\n to?: string;\n };\n};\n\ntype SchedulerRuleParsed = {\n id: string;\n original: string;\n period: {\n fromDate?: Date;\n months?: number | number[];\n days?: number;\n dows?: number[];\n weeks?: number;\n years?: number;\n yearMonth?: number;\n yearDate?: number;\n dates?: number[];\n once?: { y: number; M: number; d: number };\n };\n time?: {\n exactTime: boolean;\n start: number | AstroEventName;\n end: number | AstroEventName;\n mode: 60 | 3600;\n interval: number;\n };\n valid?: {\n from?: { y: number; M: number; d: number };\n to?: { y: number; M: number; d: number };\n fromDate?: number | Date;\n };\n scriptName: string;\n cb: (id: string) => void;\n};\n\nexport type ScheduleName = {\n id: `schedule_${string}`;\n type: 'schedule';\n schedule: string;\n scriptName: string;\n};\n\nexport class Scheduler {\n private readonly list: Record<string, SchedulerRuleParsed>;\n private readonly Date: typeof Date;\n private readonly suncalc: SunCalc;\n private readonly latitude: number;\n private readonly longitude: number;\n private log: {\n debug: (text: string) => void;\n info: (text: string) => void;\n warn: (text: string) => void;\n error: (text: string) => void;\n silly: (text: string) => void;\n };\n private timer: NodeJS.Timeout | null = null;\n private todaysAstroTimes: Record<AstroEventName, Date>;\n private yesterdaysAstroTimes: Record<AstroEventName, Date>;\n private readonly astroList: AstroEventName[] | undefined;\n private astroListLow: AstroEventNameLow[] | undefined;\n\n constructor(\n log: {\n debug: (text: string) => void;\n info: (text: string) => void;\n warn: (text: string) => void;\n error: (text: string) => void;\n silly: (text: string) => void;\n },\n DateTest: typeof Date | null,\n suncalc: SunCalc,\n latitude: number,\n longitude: number,\n ) {\n this.list = {};\n this.Date = DateTest || Date;\n this.suncalc = suncalc;\n this.latitude = latitude;\n this.longitude = longitude;\n this.log = log || {\n debug: function (text: string): void {\n console.log(text);\n },\n info: function (text: string): void {\n console.log(text);\n },\n log: function (text: string): void {\n console.log(text);\n },\n warn: function (text: string): void {\n console.warn(text);\n },\n error: function (text: string): void {\n console.error(text);\n },\n silly: function (text: string): void {\n console.log(text);\n },\n };\n\n // this._setAstroVars();\n const todayNoon = new this.Date();\n const yesterdayNoon = new this.Date();\n todayNoon.setHours(12, 0, 0, 0);\n yesterdayNoon.setHours(-12, 0, 0, 0);\n this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude);\n this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude);\n\n this.astroList = [\n 'dawn',\n 'dusk',\n 'goldenHour',\n 'goldenHourEnd',\n 'nadir',\n 'nauticalDawn',\n 'nauticalDusk',\n 'night',\n 'nightEnd',\n 'solarNoon',\n 'sunrise',\n 'sunriseEnd',\n 'sunset',\n 'sunsetStart',\n ];\n this.astroListLow = [\n 'dawn',\n 'dusk',\n 'goldenhour',\n 'goldenhourend',\n 'nadir',\n 'nauticaldawn',\n 'nauticaldusk',\n 'night',\n 'nightend',\n 'solarnoon',\n 'sunrise',\n 'sunriseend',\n 'sunset',\n 'sunsetstart',\n ];\n }\n\n _getId(): string {\n return `${Math.round(Math.random() * 1000000)}.${this.Date.now()}`;\n }\n\n recalculate(): void {\n const count = Object.keys(this.list).length;\n if (count && !this.timer) {\n const d = new this.Date();\n d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone\n d.setSeconds(0);\n d.setMinutes(d.getMinutes() + 1);\n this.timer = setTimeout(\n notBefore => this.checkSchedules(notBefore),\n d.getTime() - this.Date.now(),\n d.getTime(),\n );\n } else if (!count && this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n getContext(): SchedulerContext {\n const now = new this.Date();\n return {\n now: now.getTime(),\n minutesOfDay: now.getHours() * 60 + now.getMinutes(),\n y: now.getFullYear(),\n M: now.getMonth(),\n d: now.getDate(),\n h: now.getHours(),\n m: now.getMinutes(),\n dow: now.getDay(),\n };\n }\n\n checkSchedules(notBeforeTime?: number): void {\n const context = this.getContext();\n\n // Work around for not those precise RTCs in some system\n if (notBeforeTime !== undefined && context.now < notBeforeTime) {\n this.timer = setTimeout(\n notBefore => this.checkSchedules(notBefore),\n notBeforeTime - this.Date.now(),\n notBeforeTime,\n );\n return;\n }\n\n for (const id in this.list) {\n if (!Object.prototype.hasOwnProperty.call(this.list, id)) {\n continue;\n }\n if (this.checkSchedule(context, this.list[id])) {\n setImmediate(id => this.list[id] && typeof this.list[id].cb === 'function' && this.list[id].cb(id), id);\n }\n }\n\n const d = new this.Date();\n d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone\n d.setSeconds(0);\n d.setMinutes(d.getMinutes() + 1);\n this.timer = setTimeout(\n notBefore => this.checkSchedules(notBefore),\n d.getTime() - this.Date.now(),\n d.getTime(),\n );\n }\n\n monthDiff(d1: Date, d2: Date): number {\n let months: number;\n months = (d2.getFullYear() - d1.getFullYear()) * 12;\n months -= d1.getMonth() + 1;\n months += d2.getMonth();\n return months <= 0 ? 0 : months;\n }\n\n checkSchedule(context: SchedulerContext, schedule: SchedulerRuleParsed): boolean {\n if (schedule.valid) {\n if (\n schedule.valid.from &&\n !this.isPast(context, schedule.valid.from) &&\n !this.isToday(context, schedule.valid.from)\n ) {\n return false;\n }\n // \"to\" this.Date is in the past => delete it from a list\n if (schedule.valid.to && this.isPast(context, schedule.valid.to)) {\n delete this.list[schedule.id];\n return false;\n }\n }\n if (schedule.period) {\n if (schedule.period.once && !this.isToday(context, schedule.period.once)) {\n if (this.isPast(context, schedule.period.once)) {\n delete this.list[schedule.id];\n }\n return false;\n } else if (schedule.period.days) {\n if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) {\n return false;\n } else if (schedule.period.days > 1) {\n // @ts-expect-error period of days cannot be without valid fromDate\n const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24) + 0.5);\n if (diff % schedule.period.days) {\n return false;\n }\n }\n } else if (schedule.period.weeks) {\n if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) {\n return false;\n }\n if (schedule.period.weeks > 1) {\n // @ts-expect-error period of weeks cannot be without valid fromDate\n const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24 * 7) + 0.5);\n if (diff % schedule.period.weeks) {\n return false;\n }\n }\n } else if (schedule.period.months) {\n if (Array.isArray(schedule.period.months) && !schedule.period.months.includes(context.M)) {\n return false;\n }\n if (\n schedule.period.fromDate &&\n typeof schedule.period.months === 'number' &&\n schedule.period.months > 1\n ) {\n const diff = this.monthDiff(schedule.period.fromDate, new this.Date(context.now));\n if (diff % schedule.period.months) {\n return false;\n }\n }\n if (schedule.period.dates && !schedule.period.dates.includes(context.d)) {\n return false;\n }\n } else if (schedule.period.years) {\n if (schedule.period.yearMonth !== undefined && schedule.period.yearMonth !== context.M) {\n return false;\n }\n if (schedule.period.yearDate && schedule.period.yearDate !== context.d) {\n return false;\n }\n if (\n schedule.period.fromDate &&\n typeof schedule.period.years === 'number' &&\n schedule.period.years > 1\n ) {\n const diff = Math.floor(this.monthDiff(schedule.period.fromDate, new this.Date(context.now)) / 12);\n if (diff % schedule.period.years) {\n return false;\n }\n }\n }\n }\n\n if (schedule.time) {\n let start: number;\n let end: number;\n const now = new this.Date(context.now);\n if (now.getDate() !== this.todaysAstroTimes.sunrise.getDate()) {\n this._setAstroVars();\n }\n if (typeof schedule.time.start === 'string') {\n const astroNameStart = this._getAstroName(schedule.time.start);\n if (astroNameStart) {\n let times = this.todaysAstroTimes;\n\n if (times[astroNameStart].getDate() !== now.getDate()) {\n times = this.yesterdaysAstroTimes;\n }\n const startDate: Date = times[astroNameStart];\n start = startDate.getHours() * 60 + startDate.getMinutes();\n } else {\n this.log.error(`unknown astro event \"${schedule.time.start}\"`);\n return false;\n }\n } else {\n start = schedule.time.start;\n }\n if (typeof schedule.time.end === 'string') {\n const astroNameEnd = this._getAstroName(schedule.time.end);\n if (astroNameEnd) {\n let times = this.todaysAstroTimes;\n if (times[astroNameEnd].getDate() !== now.getDate()) {\n times = this.yesterdaysAstroTimes;\n }\n const endDate: Date = times[astroNameEnd];\n end = endDate.getHours() * 60 + endDate.getMinutes();\n } else {\n this.log.error(`unknown astro event \"${schedule.time.end}\"`);\n return false;\n }\n } else {\n end = schedule.time.end;\n }\n\n start = start || 0;\n end = end || 60 * 24;\n\n if (schedule.time.exactTime) {\n if (context.minutesOfDay !== start) {\n return false;\n }\n } else {\n if (start >= context.minutesOfDay || (end && end < context.minutesOfDay)) {\n return false;\n }\n if (schedule.time.mode === 60) {\n if (schedule.time.interval > 1 && (context.minutesOfDay - start) % schedule.time.interval) {\n return false;\n }\n } else if (schedule.time.mode === 3600) {\n if ((context.minutesOfDay - start) % (schedule.time.interval * 60)) {\n return false;\n }\n }\n }\n }\n return true;\n }\n\n string2date(date: string): { y: number; M: number; d: number } {\n let parts = date.split('.');\n let d: Date;\n if (parts.length !== 3) {\n parts = date.split('-');\n d = new this.Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10));\n } else {\n d = new this.Date(parseInt(parts[2], 10), parseInt(parts[1], 10) - 1, parseInt(parts[0], 10));\n }\n return { y: d.getFullYear(), M: d.getMonth(), d: d.getDate() };\n }\n\n isPast(context: SchedulerContext, date: { y: number; M: number; d: number } | undefined): boolean {\n if (date) {\n if (date.y < context.y) {\n return true;\n }\n if (date.y === context.y) {\n if (date.M < context.M) {\n return true;\n }\n if (date.M === context.M) {\n if (date.d < context.d) {\n return true;\n }\n }\n }\n }\n return false;\n }\n\n isToday(context: SchedulerContext, date: { y: number; M: number; d: number }): boolean {\n return date && date.y === context.y && date.M === context.M && date.d === context.d;\n }\n\n add(schedule: SchedulerRule | string, scriptName: string, cb: (id: string) => void): string | null {\n let oSchedule: SchedulerRule;\n if (typeof schedule === 'string') {\n try {\n oSchedule = JSON.parse(schedule);\n } catch {\n this.log.error(`Cannot parse schedule: ${schedule}`);\n return null;\n }\n } else {\n oSchedule = schedule;\n }\n\n const id = this._getId();\n if (typeof oSchedule !== 'object' || !oSchedule.period) {\n this.log.error(`Invalid schedule structure: ${JSON.stringify(oSchedule)}`);\n return null;\n }\n const context = this.getContext();\n const sch: SchedulerRuleParsed = JSON.parse(JSON.stringify(oSchedule));\n sch.scriptName = scriptName;\n sch.original = JSON.stringify(oSchedule);\n sch.id = id;\n sch.cb = cb;\n\n if (oSchedule.time?.start) {\n const astroNameStart = this._getAstroName(oSchedule.time.start);\n if (astroNameStart && sch.time) {\n sch.time.start = astroNameStart;\n } else if (oSchedule.time.start.includes(':')) {\n const parts = oSchedule.time.start.split(':');\n if (sch.time) {\n sch.time.start = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);\n }\n } else {\n this.log.error(`unknown astro event \"${oSchedule.time.start}\"`);\n return null;\n }\n }\n\n if (oSchedule.time?.end) {\n const astroNameEnd = this._getAstroName(oSchedule.time.end);\n if (astroNameEnd && sch.time) {\n sch.time.end = astroNameEnd;\n } else if (oSchedule.time.end.includes(':')) {\n const parts = oSchedule.time.end.split(':');\n if (sch.time) {\n sch.time.end = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);\n }\n } else {\n this.log.error(`unknown astro event \"${oSchedule.time.end}\"`);\n return null;\n }\n }\n\n if (sch.time) {\n if (oSchedule.time.mode === 'minutes') {\n sch.time.mode = 60;\n } else if (oSchedule.time.mode === 'hours') {\n sch.time.mode = 3600;\n }\n }\n\n if (oSchedule.period.once) {\n sch.period.once = this.string2date(oSchedule.period.once);\n }\n\n if (oSchedule.valid && sch.valid) {\n if (oSchedule.valid.from) {\n sch.valid.from = this.string2date(oSchedule.valid.from);\n }\n if (oSchedule.valid.to) {\n sch.valid.to = this.string2date(oSchedule.valid.to);\n }\n\n if (this.isPast(context, sch.valid.to)) {\n this.log.warn('End of schedule is in the past');\n return null;\n }\n\n if (typeof oSchedule.period.days === 'number' && oSchedule.period.days > 1 && sch.valid.from) {\n // fromDate must be unix time\n sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d).getTime();\n } else if (typeof oSchedule.period.weeks === 'number' && oSchedule.period.weeks > 1) {\n const fromDate: Date = sch.valid.from\n ? new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d)\n : new this.Date();\n //sch.valid.fromDate.setDate(-sch.valid.fromDate.getDate() - sch.valid.fromDate.getDay());\n // fromDate must be unix time\n sch.valid.fromDate = fromDate.getTime();\n } else if (sch.valid.from && typeof oSchedule.period.months === 'number' && oSchedule.period.months > 1) {\n // fromDate must be object\n sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d);\n } else if (sch.valid.from && typeof oSchedule.period.years === 'number' && oSchedule.period.years > 1) {\n // fromDate must be object\n sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d);\n }\n }\n if (\n sch.period &&\n ((typeof sch.period.days === 'number' && sch.period.days > 1) ||\n (typeof sch.period.weeks === 'number' && sch.period.weeks > 1) ||\n (typeof sch.period.months === 'number' && sch.period.months > 1) ||\n (typeof sch.period.years === 'number' && sch.period.years > 1)) &&\n (!sch.valid || !sch.valid.fromDate)\n ) {\n this.log.warn(\n 'Invalid Schedule definition: Period day/weeks/months/years only allowed with a valid.from date!',\n );\n return null;\n }\n\n if (oSchedule.period.dows) {\n try {\n sch.period.dows = JSON.parse(oSchedule.period.dows);\n } catch {\n this.log.error(`Cannot parse day of weeks: ${JSON.stringify(sch.period.dows)}`);\n return null;\n }\n if (!Array.isArray(sch.period.dows)) {\n this.log.error(`day of weeks is no array: ${JSON.stringify(sch.period.dows)}`);\n return null;\n }\n }\n\n if (oSchedule.period.months && typeof oSchedule.period.months !== 'number') {\n // can be number or array-string\n try {\n sch.period.months = JSON.parse(oSchedule.period.months) as number[];\n } catch {\n this.log.error(`Cannot parse day of months: ${JSON.stringify(sch.period.months)}`);\n return null;\n }\n sch.period.months = sch.period.months.map(m => m - 1);\n }\n\n if (oSchedule.period.dates) {\n try {\n sch.period.dates = JSON.parse(oSchedule.period.dates) as number[];\n } catch {\n this.log.error(`Cannot parse day of dates: ${JSON.stringify(sch.period.dates)}`);\n return null;\n }\n }\n if (oSchedule.period.yearMonth) {\n sch.period.yearMonth = oSchedule.period.yearMonth - 1;\n }\n this.list[id] = sch;\n this.recalculate();\n return id;\n }\n\n remove(id: string | ScheduleName): boolean {\n if (\n typeof id === 'object' &&\n id.type === 'schedule' &&\n typeof id.id === 'string' &&\n id.id.startsWith('schedule_')\n ) {\n if (this.list[id.id.substring('schedule_'.length)]) {\n delete this.list[id.id.substring('schedule_'.length)];\n this.recalculate();\n return true;\n }\n return false;\n }\n if (typeof id === 'string' && this.list[id]) {\n delete this.list[id];\n this.recalculate();\n return true;\n }\n return false;\n }\n\n getList(): ScheduleName[] {\n return Object.keys(this.list).map(id => ({\n id: `schedule_${id}`,\n type: 'schedule',\n schedule: this.list[id].original,\n scriptName: this.list[id].scriptName,\n }));\n }\n\n get(id: string | ScheduleName): SchedulerRuleParsed | null {\n if (\n id &&\n typeof id === 'object' &&\n id.type === 'schedule' &&\n typeof id.id === 'string' &&\n id.id.startsWith('schedule_')\n ) {\n return this.list[id.id.substring('schedule_'.length)];\n }\n if (typeof id === 'string') {\n return this.list[id];\n }\n return null;\n }\n\n private _setAstroVars(): void {\n const todayNoon = new this.Date();\n const yesterdayNoon = new this.Date();\n todayNoon.setHours(12, 0, 0, 0);\n yesterdayNoon.setHours(-12, 0, 0, 0);\n this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude);\n this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude);\n }\n\n private _getAstroName(evt: string): AstroEventName | null {\n if (typeof evt === 'string') {\n const pos = (this.astroListLow as string[]).indexOf(evt.toLowerCase() as AstroEventNameLow);\n if (pos > -1) {\n return (this.astroList as string[])[pos] as AstroEventName;\n }\n }\n return null;\n }\n}\n"]}