iobroker.javascript 8.9.2 → 9.0.1
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/README.md +7 -3
- package/admin/assets/{createSvgIcon-BdRvDw53.js → createSvgIcon-BQT-7-GS.js} +1 -1
- package/admin/assets/{docs-6na4NFtj.js → docs-BrInh2Pn.js} +2 -2
- package/admin/assets/index-BzKS5vx-.js +1329 -0
- package/admin/assets/index-CfuHVX2B.js +193 -0
- package/admin/assets/index-CuCs5aLs.js +5 -0
- package/admin/assets/index-tExaxF69.js +930 -0
- package/admin/assets/inheritsLoose--KnFDOw1.js +36 -0
- package/admin/assets/{useTheme-Cl1QmYFL.js → useTheme-DF6qfrtI.js} +1 -1
- package/admin/custom/assets/{Components-ChpTW7sE.js → Components-D9kRsHNY.js} +1 -1
- package/admin/custom/assets/{DefaultPropsProvider-CHpMCMgA.js → DefaultPropsProvider-9qubdy-V.js} +2 -2
- package/admin/custom/assets/{FilledInput-CtcQVKyj.js → FilledInput-BpuM_GyB.js} +1 -1
- package/admin/custom/assets/Tabs-CvEv0KOT.js +138 -0
- package/admin/custom/assets/ThemeProvider-DZTpMR8n.js +29 -0
- package/admin/custom/assets/{createSvgIcon-C_vAELFU.js → createSvgIcon-BQThUM-f.js} +1 -1
- package/admin/custom/assets/hostInit-CrAs5YZS.js +1 -1
- package/admin/custom/assets/index-BXmu6lpn.js +904 -0
- package/admin/custom/assets/{index-DwsbskQy.js → index-DIWNdd4a.js} +1 -1
- package/admin/custom/assets/index-DZqbj5K4.js +55 -0
- package/admin/custom/assets/{index-D5apCzjJ.js → index-Dbe-II7_.js} +6 -6
- package/admin/custom/assets/index-sawv1cUe.js +1399 -0
- package/admin/custom/assets/{virtualExposes-BPncCdUy.js → virtualExposes-BMKIjWrE.js} +2 -2
- package/admin/custom/customComponents.js +2 -2
- package/admin/custom/i18n/de.json +29 -29
- package/admin/custom/i18n/es.json +29 -29
- package/admin/custom/i18n/fr.json +29 -29
- package/admin/custom/i18n/it.json +29 -29
- package/admin/custom/i18n/nl.json +29 -29
- package/admin/custom/i18n/pl.json +29 -29
- package/admin/custom/i18n/pt.json +29 -29
- package/admin/custom/i18n/ru.json +29 -29
- package/admin/custom/i18n/uk.json +29 -29
- package/admin/custom/i18n/zh-cn.json +29 -29
- package/admin/google-blockly/blockly_compressed.js +875 -887
- package/admin/google-blockly/blocks_compressed.js +38 -41
- package/admin/google-blockly/javascript_compressed.js +19 -54
- package/admin/google-blockly/media/delete-icon.svg +1 -0
- package/admin/google-blockly/media/foldout-icon.svg +1 -0
- package/admin/google-blockly/media/resize-handle.svg +3 -0
- package/admin/i18n/de.json +61 -0
- package/admin/i18n/en.json +61 -0
- package/admin/i18n/es.json +61 -0
- package/admin/i18n/fr.json +61 -0
- package/admin/i18n/it.json +61 -0
- package/admin/i18n/nl.json +61 -0
- package/admin/i18n/pl.json +61 -0
- package/admin/i18n/pt.json +61 -0
- package/admin/i18n/ru.json +61 -0
- package/admin/i18n/uk.json +61 -0
- package/admin/i18n/zh-cn.json +61 -0
- package/admin/jsonConfig.json +2 -0
- package/admin/mf-manifest.json +1 -1
- package/admin/remoteEntry.js +2 -2
- package/admin/tab.html +4 -4
- package/admin/vsFont/README.md +1 -1
- package/admin/vsFont/createJson.js +1 -1
- package/build-backend/lib/consts.js +346 -0
- package/build-backend/lib/consts.js.map +1 -0
- package/build-backend/lib/convert.js +120 -0
- package/build-backend/lib/convert.js.map +1 -0
- package/build-backend/lib/debug.js +163 -0
- package/build-backend/lib/debug.js.map +1 -0
- package/{lib → build-backend/lib}/debugger.js +261 -232
- package/build-backend/lib/debugger.js.map +1 -0
- package/build-backend/lib/eventObj.js +177 -0
- package/build-backend/lib/eventObj.js.map +1 -0
- package/build-backend/lib/inspect.js +728 -0
- package/build-backend/lib/inspect.js.map +1 -0
- package/build-backend/lib/javascript.d.ts +1972 -0
- package/{lib → build-backend/lib}/mirror.js +185 -182
- package/build-backend/lib/mirror.js.map +1 -0
- package/build-backend/lib/nodeModulesManagement.js +25 -0
- package/build-backend/lib/nodeModulesManagement.js.map +1 -0
- package/build-backend/lib/patternCompareFunctions.js +321 -0
- package/build-backend/lib/patternCompareFunctions.js.map +1 -0
- package/build-backend/lib/protectFs.js +477 -0
- package/build-backend/lib/protectFs.js.map +1 -0
- package/build-backend/lib/request.js +89 -0
- package/build-backend/lib/request.js.map +1 -0
- package/{lib → build-backend/lib}/sandbox.js +2046 -1852
- package/build-backend/lib/sandbox.js.map +1 -0
- package/build-backend/lib/scheduler.js +553 -0
- package/build-backend/lib/scheduler.js.map +1 -0
- package/build-backend/lib/tools.js +183 -0
- package/build-backend/lib/tools.js.map +1 -0
- package/build-backend/lib/typescriptSettings.js +39 -0
- package/build-backend/lib/typescriptSettings.js.map +1 -0
- package/build-backend/lib/typescriptTools.js +435 -0
- package/build-backend/lib/typescriptTools.js.map +1 -0
- package/build-backend/lib/utils.js +66 -0
- package/build-backend/lib/utils.js.map +1 -0
- package/{lib → build-backend/lib}/words.js +23 -30
- package/build-backend/lib/words.js.map +1 -0
- package/build-backend/main.js +2671 -0
- package/build-backend/main.js.map +1 -0
- package/build-backend/types.d.ts +742 -0
- package/docs/de/README.md +1 -1
- package/docs/en/README.md +1 -1
- package/docs/en/javascript.md +10 -6
- package/docs/en/upgrade-guide.md +5 -2
- package/docs/ru/README.md +1 -1
- package/install/installTypings.js +34 -47
- package/io-package.json +14 -14
- package/package.json +14 -14
- package/admin/assets/index-DCkkMRRa.js +0 -1335
- package/admin/assets/index-DJfSBoBB.js +0 -192
- package/admin/assets/index-DTiA4WdK.js +0 -930
- package/admin/assets/index-qABB1JVe.js +0 -5
- package/admin/assets/inheritsLoose-BW-3V39H.js +0 -36
- package/admin/custom/assets/Tabs-C1KOyWRi.js +0 -137
- package/admin/custom/assets/ThemeProvider-Buvx5nSd.js +0 -29
- package/admin/custom/assets/index-BGCRznKh.js +0 -904
- package/admin/custom/assets/index-DfBPYXqA.js +0 -55
- package/admin/custom/assets/index-jIr6kOLK.js +0 -1398
- package/admin/i18n/de/flat.txt +0 -427
- package/admin/i18n/de/translations.json +0 -429
- package/admin/i18n/en/flat.txt +0 -427
- package/admin/i18n/en/translations.json +0 -429
- package/admin/i18n/es/flat.txt +0 -427
- package/admin/i18n/es/translations.json +0 -429
- package/admin/i18n/flat.txt +0 -427
- package/admin/i18n/fr/flat.txt +0 -427
- package/admin/i18n/fr/translations.json +0 -429
- package/admin/i18n/it/flat.txt +0 -427
- package/admin/i18n/it/translations.json +0 -429
- package/admin/i18n/nl/flat.txt +0 -427
- package/admin/i18n/nl/translations.json +0 -429
- package/admin/i18n/pl/flat.txt +0 -427
- package/admin/i18n/pl/translations.json +0 -429
- package/admin/i18n/pt/flat.txt +0 -427
- package/admin/i18n/pt/translations.json +0 -429
- package/admin/i18n/ru/flat.txt +0 -427
- package/admin/i18n/ru/translations.json +0 -429
- package/admin/i18n/uk/flat.txt +0 -427
- package/admin/i18n/uk/translations.json +0 -429
- package/admin/i18n/zh-cn/flat.txt +0 -427
- package/admin/i18n/zh-cn/translations.json +0 -429
- package/lib/adapter-config.d.ts +0 -16
- package/lib/consts.js +0 -83
- package/lib/convert.js +0 -106
- package/lib/debug.js +0 -154
- package/lib/eventObj.js +0 -201
- package/lib/inspect.js +0 -688
- package/lib/javascript.d.ts +0 -1858
- package/lib/nodeModulesManagement.js +0 -26
- package/lib/patternCompareFunctions.js +0 -391
- package/lib/protectFs.js +0 -401
- package/lib/request.js +0 -72
- package/lib/scheduler.js +0 -447
- package/lib/tools.js +0 -192
- package/lib/typescriptSettings.js +0 -44
- package/lib/typescriptTools.js +0 -529
- package/lib/utils.js +0 -87
- package/main.js +0 -2653
package/lib/scheduler.js
DELETED
|
@@ -1,447 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// const DEFAULT = {
|
|
4
|
-
// time: {
|
|
5
|
-
// exactTime: false,
|
|
6
|
-
//
|
|
7
|
-
// start: '00:00',
|
|
8
|
-
// end: '23:59',
|
|
9
|
-
//
|
|
10
|
-
// mode: 'hours',
|
|
11
|
-
// interval: 1,
|
|
12
|
-
// },
|
|
13
|
-
// period: {
|
|
14
|
-
// once: '',
|
|
15
|
-
// days: 1,
|
|
16
|
-
// dows: '',
|
|
17
|
-
// dates: '',
|
|
18
|
-
// weeks: 0,
|
|
19
|
-
// months: '',
|
|
20
|
-
//
|
|
21
|
-
// years: 0,
|
|
22
|
-
// yearMonth: 0,
|
|
23
|
-
// yearDate: 0,
|
|
24
|
-
// },
|
|
25
|
-
// valid: {
|
|
26
|
-
// from: '',
|
|
27
|
-
// to: ''
|
|
28
|
-
// }
|
|
29
|
-
// };
|
|
30
|
-
|
|
31
|
-
class Scheduler {
|
|
32
|
-
constructor(log, DateTest, suncalc, latitude, longitude) {
|
|
33
|
-
this.list = {};
|
|
34
|
-
this.Date = DateTest || Date;
|
|
35
|
-
this.suncalc = suncalc;
|
|
36
|
-
this.latitude = latitude;
|
|
37
|
-
this.longitude = longitude;
|
|
38
|
-
this.log = log || {
|
|
39
|
-
debug: function (text) {console.log(text);},
|
|
40
|
-
info: function (text) {console.log(text);},
|
|
41
|
-
log: function (text) {console.log(text);},
|
|
42
|
-
warn: function (text) {console.warn(text);},
|
|
43
|
-
error: function (text) {console.error(text);},
|
|
44
|
-
silly: function (text) {console.log(text);}
|
|
45
|
-
};
|
|
46
|
-
this._setAstroVars();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
_getId() {
|
|
50
|
-
return Math.round(Math.random() * 1000000) + '.' + this.Date.now();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
recalculate() {
|
|
54
|
-
const count = Object.keys(this.list).length;
|
|
55
|
-
if (count && !this.timer) {
|
|
56
|
-
const d = new this.Date();
|
|
57
|
-
d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone
|
|
58
|
-
d.setSeconds(0);
|
|
59
|
-
d.setMinutes(d.getMinutes() + 1);
|
|
60
|
-
this.timer = setTimeout((notBefore) => this.checkSchedules(notBefore), d.getTime() - this.Date.now(), d.getTime());
|
|
61
|
-
} else if (!count && this.timer) {
|
|
62
|
-
clearTimeout(this.timer);
|
|
63
|
-
this.timer = null;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
getContext() {
|
|
68
|
-
const now = new this.Date();
|
|
69
|
-
return {
|
|
70
|
-
now: now.getTime(),
|
|
71
|
-
minutesOfDay: now.getHours() * 60 + now.getMinutes(),
|
|
72
|
-
y: now.getFullYear(),
|
|
73
|
-
M: now.getMonth(),
|
|
74
|
-
d: now.getDate(),
|
|
75
|
-
h: now.getHours(),
|
|
76
|
-
m: now.getMinutes(),
|
|
77
|
-
dow: now.getDay()
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
checkSchedules(notBeforeTime) {
|
|
82
|
-
const context = this.getContext();
|
|
83
|
-
|
|
84
|
-
// Work around for not that precise RTCs in some system
|
|
85
|
-
if (notBeforeTime !== undefined && context.now < notBeforeTime) {
|
|
86
|
-
this.timer = setTimeout((notBefore) =>
|
|
87
|
-
this.checkSchedules(notBefore), notBeforeTime - this.Date.now(), notBeforeTime);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
for (const id in this.list) {
|
|
92
|
-
if (!Object.prototype.hasOwnProperty.call(this.list, id)) {
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (this.checkSchedule(context, this.list[id])) {
|
|
96
|
-
setImmediate(id => this.list[id] && typeof this.list[id].cb === 'function' && this.list[id].cb(id), id);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const d = new this.Date();
|
|
101
|
-
d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone
|
|
102
|
-
d.setSeconds(0);
|
|
103
|
-
d.setMinutes(d.getMinutes() + 1);
|
|
104
|
-
this.timer = setTimeout((notBefore) =>
|
|
105
|
-
this.checkSchedules(notBefore), d.getTime() - this.Date.now(), d.getTime());
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
monthDiff(d1, d2) {
|
|
109
|
-
let months;
|
|
110
|
-
months = (d2.getFullYear() - d1.getFullYear()) * 12;
|
|
111
|
-
months -= d1.getMonth() + 1;
|
|
112
|
-
months += d2.getMonth();
|
|
113
|
-
return months <= 0 ? 0 : months;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
checkSchedule(context, schedule) {
|
|
117
|
-
if (schedule.valid) {
|
|
118
|
-
if (schedule.valid.from && !this.isPast(context, schedule.valid.from) && !this.isToday(context, schedule.valid.from)) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
// "to" this.Date is in the past => delete it from list
|
|
122
|
-
if (schedule.valid.to && this.isPast(context, schedule.valid.to)) {
|
|
123
|
-
delete this.list[schedule.id];
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if (schedule.period) {
|
|
128
|
-
if (schedule.period.once && !this.isToday(context, schedule.period.once)) {
|
|
129
|
-
if (this.isPast(context, schedule.period.once)) {
|
|
130
|
-
delete this.list[schedule.id];
|
|
131
|
-
}
|
|
132
|
-
return;
|
|
133
|
-
} else if (schedule.period.days) {
|
|
134
|
-
if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) {
|
|
135
|
-
return;
|
|
136
|
-
} else
|
|
137
|
-
if (schedule.period.days > 1) {
|
|
138
|
-
const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24) + 0.5);
|
|
139
|
-
if (diff % schedule.period.days) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
} else if (schedule.period.weeks) {
|
|
144
|
-
if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
if (schedule.period.weeks > 1) {
|
|
148
|
-
const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24 * 7) + 0.5);
|
|
149
|
-
if (diff % schedule.period.weeks) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
} else if (schedule.period.months) {
|
|
154
|
-
if (Array.isArray(schedule.period.months) && !schedule.period.months.includes(context.M)) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
if (schedule.period.fromDate && typeof schedule.period.months === 'number' && schedule.period.months > 1) {
|
|
158
|
-
const diff = this.monthDiff(schedule.period.fromDate, new this.Date(context.now));
|
|
159
|
-
if (diff % schedule.period.months) {
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (schedule.period.dates && !schedule.period.dates.includes(context.d)) {
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
} else if (schedule.period.years) {
|
|
167
|
-
if (schedule.period.yearMonth !== undefined && schedule.period.yearMonth !== context.M) {
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
if (schedule.period.yearDate && schedule.period.yearDate !== context.d) {
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if (schedule.period.fromDate && typeof schedule.period.years === 'number' && schedule.period.years > 1) {
|
|
174
|
-
const diff = Math.floor(this.monthDiff(schedule.period.fromDate, new this.Date(context.now)) / 12);
|
|
175
|
-
if (diff % schedule.period.years) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (schedule.time) {
|
|
183
|
-
let start = schedule.time.start;
|
|
184
|
-
let end = schedule.time.end;
|
|
185
|
-
const now = new this.Date(context.now);
|
|
186
|
-
const astroNameStart = this._getAstroName(start);
|
|
187
|
-
const astroNameEnd = this._getAstroName(end);
|
|
188
|
-
|
|
189
|
-
if (now.getDate() !== this.todaysAstroTimes['sunrise'].getDate()) {
|
|
190
|
-
this._setAstroVars();
|
|
191
|
-
}
|
|
192
|
-
if (astroNameStart) {
|
|
193
|
-
let times = this.todaysAstroTimes;
|
|
194
|
-
if (times[astroNameStart].getDate() !== now.getDate()) {
|
|
195
|
-
times = this.yesterdaysAstroTimes;
|
|
196
|
-
}
|
|
197
|
-
start = times[astroNameStart];
|
|
198
|
-
start = start.getHours() * 60 + start.getMinutes();
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (astroNameEnd) {
|
|
202
|
-
let times = this.todaysAstroTimes;
|
|
203
|
-
if (times[astroNameEnd].getDate() !== now.getDate()) {
|
|
204
|
-
times = this.yesterdaysAstroTimes;
|
|
205
|
-
}
|
|
206
|
-
end = times[astroNameEnd];
|
|
207
|
-
end = end.getHours() * 60 + end.getMinutes();
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
start = start || 0;
|
|
211
|
-
end = end || (60 * 24);
|
|
212
|
-
|
|
213
|
-
if (schedule.time.exactTime) {
|
|
214
|
-
if (context.minutesOfDay !== start) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
} else {
|
|
218
|
-
if (start >= context.minutesOfDay || (end && end < context.minutesOfDay)) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
if (schedule.time.mode === 60) {
|
|
222
|
-
if (schedule.time.interval > 1 && ((context.minutesOfDay - start) % schedule.time.interval)) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
} else
|
|
226
|
-
if (schedule.time.mode === 3600) {
|
|
227
|
-
if ((context.minutesOfDay - start) % (schedule.time.interval * 60)) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return true;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
string2date(date) {
|
|
237
|
-
let parts = date.split('.');
|
|
238
|
-
let d;
|
|
239
|
-
if (parts.length !== 3) {
|
|
240
|
-
parts = date.split('-');
|
|
241
|
-
d = new this.Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10));
|
|
242
|
-
} else {
|
|
243
|
-
d = new this.Date(parseInt(parts[2], 10), parseInt(parts[1], 10) - 1, parseInt(parts[0], 10));
|
|
244
|
-
}
|
|
245
|
-
return {y: d.getFullYear(), M: d.getMonth(), d: d.getDate()};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
isPast(context, date) {
|
|
249
|
-
if (date) {
|
|
250
|
-
if (date.y < context.y) {
|
|
251
|
-
return true;
|
|
252
|
-
} else if (date.y === context.y) {
|
|
253
|
-
if (date.M < context.M) {
|
|
254
|
-
return true;
|
|
255
|
-
} else if (date.M === context.M) {
|
|
256
|
-
if (date.d < context.d) {
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
isToday(context, date) {
|
|
265
|
-
return date && date.y === context.y && date.M === context.M && date.d === context.d;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
add(schedule, scriptName, cb) {
|
|
269
|
-
if (typeof schedule === 'string') {
|
|
270
|
-
try {
|
|
271
|
-
schedule = JSON.parse(schedule);
|
|
272
|
-
} catch (e) {
|
|
273
|
-
this.log.error('Cannot parse schedule: ' + schedule);
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
const id = this._getId();
|
|
279
|
-
if (typeof schedule !== 'object' || !schedule.period) {
|
|
280
|
-
return this.log.error('Invalid schedule structure: ' + JSON.stringify(schedule));
|
|
281
|
-
}
|
|
282
|
-
const context = this.getContext();
|
|
283
|
-
const sch = JSON.parse(JSON.stringify(schedule));
|
|
284
|
-
sch.scriptName = scriptName;
|
|
285
|
-
sch.original = JSON.stringify(schedule);
|
|
286
|
-
sch.id = id;
|
|
287
|
-
sch.cb = cb;
|
|
288
|
-
|
|
289
|
-
if (sch.time && sch.time.start) {
|
|
290
|
-
const astroNameStart = this._getAstroName(sch.time.start);
|
|
291
|
-
if (sch.time.start.includes(':')) {
|
|
292
|
-
const parts = sch.time.start.split(':');
|
|
293
|
-
sch.time.start = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
|
|
294
|
-
} else if (astroNameStart) {
|
|
295
|
-
sch.time.start = astroNameStart;
|
|
296
|
-
} else {
|
|
297
|
-
this.log.error('unknown astro event "' + sch.time.start + '"');
|
|
298
|
-
return null;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (sch.time && sch.time.end) {
|
|
303
|
-
const astroNameEnd = this._getAstroName(sch.time.end);
|
|
304
|
-
if (sch.time.end.includes(':')) {
|
|
305
|
-
const parts = sch.time.end.split(':');
|
|
306
|
-
sch.time.end = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
|
|
307
|
-
} else if (astroNameEnd) {
|
|
308
|
-
sch.time.end = astroNameEnd;
|
|
309
|
-
} else {
|
|
310
|
-
this.log.error('unknown astro event "' + sch.time.end + '"');
|
|
311
|
-
return null;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
if (sch.time.mode === 'minutes') {
|
|
315
|
-
sch.time.mode = 60;
|
|
316
|
-
} else if (sch.time.mode === 'hours') {
|
|
317
|
-
sch.time.mode = 3600;
|
|
318
|
-
}
|
|
319
|
-
sch.period.once = sch.period.once && this.string2date(sch.period.once);
|
|
320
|
-
|
|
321
|
-
if (sch.valid) {
|
|
322
|
-
sch.valid.from = sch.valid.from && this.string2date(sch.valid.from);
|
|
323
|
-
sch.valid.to = sch.valid.to && this.string2date(sch.valid.to);
|
|
324
|
-
|
|
325
|
-
if (this.isPast(context, sch.valid.to)) {
|
|
326
|
-
this.log.warn('End of schedule is in the past');
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
if ((typeof sch.period.days === 'number' && sch.period.days > 1)) {
|
|
330
|
-
// fromDate must be unix time
|
|
331
|
-
sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d).getTime();
|
|
332
|
-
} else if (typeof sch.period.weeks === 'number' && sch.period.weeks > 1) {
|
|
333
|
-
sch.valid.fromDate = sch.valid.from ? new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d) : new this.Date();
|
|
334
|
-
//sch.valid.fromDate.setDate(-sch.valid.fromDate.getDate() - sch.valid.fromDate.getDay());
|
|
335
|
-
// fromDate must be unix time
|
|
336
|
-
sch.valid.fromDate = sch.valid.fromDate.getTime();
|
|
337
|
-
} else if (typeof sch.period.months === 'number' && sch.period.months > 1) {
|
|
338
|
-
// fromDate must be object
|
|
339
|
-
sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d);
|
|
340
|
-
} else if (typeof sch.period.years === 'number' && sch.period.years > 1) {
|
|
341
|
-
// fromDate must be object
|
|
342
|
-
sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
if (sch.period && (
|
|
346
|
-
(typeof sch.period.days === 'number' && sch.period.days > 1) ||
|
|
347
|
-
(typeof sch.period.weeks === 'number' && sch.period.weeks > 1) ||
|
|
348
|
-
(typeof sch.period.months === 'number' && sch.period.months > 1) ||
|
|
349
|
-
(typeof sch.period.years === 'number' && sch.period.years > 1)
|
|
350
|
-
) && (
|
|
351
|
-
!sch.valid || !sch.valid.fromDate
|
|
352
|
-
)) {
|
|
353
|
-
this.log.warn('Invalid Schedule definition: Period day/weeks/months/years only allowed with a valid.from date!');
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
if (sch.period.dows) {
|
|
357
|
-
try {
|
|
358
|
-
sch.period.dows = JSON.parse(sch.period.dows);
|
|
359
|
-
} catch (e) {
|
|
360
|
-
this.log.error('Cannot parse day of weeks: ' + sch.period.dows);
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
if (!Array.isArray(sch.period.dows)) {
|
|
364
|
-
this.log.error('day of weeks is no array: ' + JSON.stringify(sch.period.dows));
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
if (sch.period.months && typeof sch.period.months !== 'number') { // can be number or array-string
|
|
369
|
-
try {
|
|
370
|
-
sch.period.months = JSON.parse(sch.period.months);
|
|
371
|
-
} catch (e) {
|
|
372
|
-
this.log.error('Cannot parse day of months: ' + sch.period.months);
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
sch.period.months = sch.period.months.map(m => m - 1);
|
|
376
|
-
}
|
|
377
|
-
if (sch.period.dates) {
|
|
378
|
-
try {
|
|
379
|
-
sch.period.dates = JSON.parse(sch.period.dates);
|
|
380
|
-
} catch (e) {
|
|
381
|
-
this.log.error('Cannot parse day of dates: ' + sch.period.dates);
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
sch.period.yearMonth = sch.period.yearMonth && (sch.period.yearMonth - 1);
|
|
386
|
-
this.list[id] = sch;
|
|
387
|
-
this.recalculate();
|
|
388
|
-
return id;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
remove(id) {
|
|
392
|
-
if (typeof id === 'object' && id.type === 'schedule' && typeof id.id === 'string' && id.id.startsWith('schedule_')) {
|
|
393
|
-
if (this.list[id.id.substring('schedule_'.length)]) {
|
|
394
|
-
delete this.list[id.id.substring('schedule_'.length)];
|
|
395
|
-
this.recalculate();
|
|
396
|
-
return true;
|
|
397
|
-
} else {
|
|
398
|
-
return false;
|
|
399
|
-
}
|
|
400
|
-
} else
|
|
401
|
-
if (typeof id === 'string' && this.list[id]) {
|
|
402
|
-
delete this.list[id];
|
|
403
|
-
this.recalculate();
|
|
404
|
-
return true;
|
|
405
|
-
} else {
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
getList() {
|
|
411
|
-
return Object.keys(this.list)
|
|
412
|
-
.map(id => ({id: 'schedule_' + id, type: 'schedule', schedule: this.list[id].original, scriptId: this.list[id].scriptId}));
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
get(id) {
|
|
416
|
-
if (id && typeof id === 'object' && id.type === 'schedule' && typeof id.id === 'string' && id.id.startsWith('schedule_')) {
|
|
417
|
-
return this.list[id.id.substring('schedule_'.length)];
|
|
418
|
-
} else if (typeof id === 'string') {
|
|
419
|
-
return this.list[id];
|
|
420
|
-
} else {
|
|
421
|
-
return null;
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
_setAstroVars() {
|
|
426
|
-
const todayNoon = new this.Date();
|
|
427
|
-
const yesterdayNoon = new this.Date();
|
|
428
|
-
todayNoon.setHours(12, 0, 0, 0);
|
|
429
|
-
yesterdayNoon.setHours(-12, 0, 0, 0);
|
|
430
|
-
this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude);
|
|
431
|
-
this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude);
|
|
432
|
-
this.astroList = this.astroList || Object.keys(this.todaysAstroTimes);
|
|
433
|
-
this.astroListLow = this.astroListLow || this.astroList.map(key => key.toLowerCase());
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
_getAstroName(evt) {
|
|
437
|
-
if (typeof evt === 'string') {
|
|
438
|
-
const pos = this.astroListLow.indexOf(evt.toLowerCase());
|
|
439
|
-
if (pos > -1) {
|
|
440
|
-
return this.astroList[pos];
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
return null;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
module.exports = Scheduler;
|
package/lib/tools.js
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('node:fs');
|
|
4
|
-
const path = require('node:path');
|
|
5
|
-
const crypto = require('node:crypto');
|
|
6
|
-
const https = require('node:https');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Tests whether the given variable is a real object and not an Array
|
|
10
|
-
* @param {any} it The variable to test
|
|
11
|
-
* @returns {it is Record<string, any>}
|
|
12
|
-
*/
|
|
13
|
-
function isObject(it) {
|
|
14
|
-
// This is necessary because:
|
|
15
|
-
// typeof null === 'object'
|
|
16
|
-
// typeof [] === 'object'
|
|
17
|
-
// [] instanceof Object === true
|
|
18
|
-
return Object.prototype.toString.call(it) === '[object Object]';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Tests whether the given variable is really an Array
|
|
23
|
-
* @param {any} it The variable to test
|
|
24
|
-
* @returns {it is any[]}
|
|
25
|
-
*/
|
|
26
|
-
function isArray(it) {
|
|
27
|
-
if (Array.isArray != null) {
|
|
28
|
-
return Array.isArray(it);
|
|
29
|
-
}
|
|
30
|
-
return Object.prototype.toString.call(it) === '[object Array]';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Finds all matches of a regular expression and returns the matched groups
|
|
35
|
-
* @param {RegExp} regex The regular expression to match against the string
|
|
36
|
-
* @param {string} string The string to test
|
|
37
|
-
*/
|
|
38
|
-
function matchAll(regex, string) {
|
|
39
|
-
const ret = [];
|
|
40
|
-
let match;
|
|
41
|
-
do {
|
|
42
|
-
match = regex.exec(string);
|
|
43
|
-
match && ret.push(match.slice(1));
|
|
44
|
-
} while (match);
|
|
45
|
-
return ret;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Enumerates all files matching a given predicate
|
|
50
|
-
* @param {string} rootDir The directory to start in
|
|
51
|
-
* @param {(filename: string) => boolean} [predicate]
|
|
52
|
-
*/
|
|
53
|
-
function enumFilesRecursiveSync(rootDir, predicate) {
|
|
54
|
-
const ret = [];
|
|
55
|
-
try {
|
|
56
|
-
const filesAndDirs = fs.readdirSync(rootDir);
|
|
57
|
-
for (const f of filesAndDirs) {
|
|
58
|
-
const fullPath = path.join(rootDir, f);
|
|
59
|
-
|
|
60
|
-
if (fs.statSync(fullPath).isDirectory()) {
|
|
61
|
-
Array.prototype.push.apply(ret, enumFilesRecursiveSync(fullPath, predicate));
|
|
62
|
-
} else if (typeof predicate === 'function' && predicate(fullPath)) {
|
|
63
|
-
ret.push(fullPath);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
} catch (err) {
|
|
67
|
-
console.error(`Cannot read directory: "${rootDir}": ${err}`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return ret;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Promisifies a callback-style function with parameters (err, result)
|
|
75
|
-
* @param {(...args: any[]) => any} fn The callback-style function to promisify
|
|
76
|
-
* @param {*} [context] The value of `this` in the function
|
|
77
|
-
*/
|
|
78
|
-
function promisify(fn, context) {
|
|
79
|
-
return function (...args) {
|
|
80
|
-
// @ts-ignore We want this behavior
|
|
81
|
-
context = context || this;
|
|
82
|
-
return new Promise((resolve, reject) => {
|
|
83
|
-
try {
|
|
84
|
-
fn.apply(context, [...args, (error, result) => {
|
|
85
|
-
if (error) {
|
|
86
|
-
if (typeof error === 'string') {
|
|
87
|
-
return reject(new Error(error));
|
|
88
|
-
}
|
|
89
|
-
return reject(error);
|
|
90
|
-
} else {
|
|
91
|
-
return resolve(result);
|
|
92
|
-
}
|
|
93
|
-
}]);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
reject(error);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Promisifies a callback-style function without an error parameter
|
|
103
|
-
* @param {(...args: any[]) => any} fn The callback-style function to promisify
|
|
104
|
-
* @param {*} [context] The value of `this` in the function
|
|
105
|
-
*/
|
|
106
|
-
function promisifyNoError(fn, context) {
|
|
107
|
-
return function(...args) {
|
|
108
|
-
// @ts-ignore We want this behavior
|
|
109
|
-
context = context || this;
|
|
110
|
-
return new Promise(resolve => {
|
|
111
|
-
try {
|
|
112
|
-
fn.apply(context, [...args, result => resolve(result)]);
|
|
113
|
-
} catch (error) {
|
|
114
|
-
resolve(); // what to do in this case??
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Creates an MD5 hash of a script source which can be used to check whether the source of a compiled language changed
|
|
122
|
-
* @param {string} source The source code to hash
|
|
123
|
-
* @returns {string}
|
|
124
|
-
*/
|
|
125
|
-
function hashSource(source) {
|
|
126
|
-
return crypto.createHash('md5').update(source).digest('hex');
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function getHttpRequestConfig(url, options) {
|
|
130
|
-
const timeoutMs = (options && !isNaN(options.timeout)) ? options.timeout : 2000;
|
|
131
|
-
|
|
132
|
-
const config = {
|
|
133
|
-
method: 'get',
|
|
134
|
-
url,
|
|
135
|
-
validateStatus: (status) => status >= 200,
|
|
136
|
-
responseType: (options && options.responseType) ? options.responseType : 'text',
|
|
137
|
-
responseEncoding: 'utf8',
|
|
138
|
-
timeout: timeoutMs,
|
|
139
|
-
//signal: AbortSignal.timeout(timeoutMs), // connection related timeouts
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
if (!options.headers) {
|
|
143
|
-
options.headers = {};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (options && options.basicAuth) {
|
|
147
|
-
config.auth = {
|
|
148
|
-
username: options.basicAuth.user,
|
|
149
|
-
password: options.basicAuth.password,
|
|
150
|
-
};
|
|
151
|
-
} else if (options.bearerAuth) {
|
|
152
|
-
options.headers['Authorization'] = `Bearer ${options.bearerAuth}`;
|
|
153
|
-
} else {
|
|
154
|
-
const uri = new URL(url);
|
|
155
|
-
if (uri.username && uri.password) {
|
|
156
|
-
const username = decodeURIComponent(uri.username);
|
|
157
|
-
const password = decodeURIComponent(uri.password);
|
|
158
|
-
|
|
159
|
-
config.url = config.url.replace(`${uri.protocol}//${username}:${password}@`, `${uri.protocol}//`);
|
|
160
|
-
config.auth = {
|
|
161
|
-
username,
|
|
162
|
-
password,
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Set default headers
|
|
168
|
-
config.headers = {
|
|
169
|
-
'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:109.0) Gecko/20100101 Firefox/121.0',
|
|
170
|
-
...options.headers,
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// Certificate validation
|
|
174
|
-
if (options && typeof options?.validateCertificate !== 'undefined') {
|
|
175
|
-
config.httpsAgent = new https.Agent({
|
|
176
|
-
rejectUnauthorized: options.validateCertificate,
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return config;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
module.exports = {
|
|
184
|
-
isArray,
|
|
185
|
-
isObject,
|
|
186
|
-
matchAll,
|
|
187
|
-
enumFilesRecursiveSync,
|
|
188
|
-
promisify,
|
|
189
|
-
promisifyNoError,
|
|
190
|
-
hashSource,
|
|
191
|
-
getHttpRequestConfig,
|
|
192
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
const typescript = require('typescript');
|
|
2
|
-
|
|
3
|
-
// NodeJS 18+ supports the features of ES2022
|
|
4
|
-
// consider changing this, so we get to support the newest features too
|
|
5
|
-
const targetTsLib = 'es2022';
|
|
6
|
-
|
|
7
|
-
/** @type {typescript.CompilerOptions} */
|
|
8
|
-
const tsCompilerOptions = {
|
|
9
|
-
// don't compile faulty scripts
|
|
10
|
-
noEmitOnError: true,
|
|
11
|
-
// emit declarations for global scripts
|
|
12
|
-
declaration: true,
|
|
13
|
-
// This enables TS users to `import * as ... from` and `import ... from`
|
|
14
|
-
esModuleInterop: true,
|
|
15
|
-
// This flag was introduced in TS 4.4 and may break a lot of legacy scripts
|
|
16
|
-
// Better keep it turned off
|
|
17
|
-
useUnknownInCatchVariables: false,
|
|
18
|
-
// In order to run scripts as a NodeJS vm.Script,
|
|
19
|
-
// we MUST target ES5, otherwise the compiled
|
|
20
|
-
// scripts may include `import` keywords, which are not
|
|
21
|
-
// supported by vm.Script.
|
|
22
|
-
target: typescript.ScriptTarget.ES5,
|
|
23
|
-
// This is required for QueryResults to be iterable (https://github.com/ioBroker/ioBroker.javascript/pull/663#issuecomment-721645705)
|
|
24
|
-
downlevelIteration: true,
|
|
25
|
-
lib: [`lib.${targetTsLib}.d.ts`],
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const jsDeclarationCompilerOptions = Object.assign(
|
|
29
|
-
{}, tsCompilerOptions,
|
|
30
|
-
{
|
|
31
|
-
// we only care about the declarations
|
|
32
|
-
emitDeclarationOnly: true,
|
|
33
|
-
// allow errors
|
|
34
|
-
noEmitOnError: false,
|
|
35
|
-
noImplicitAny: false,
|
|
36
|
-
strict: false,
|
|
37
|
-
}
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
module.exports = {
|
|
41
|
-
targetTsLib,
|
|
42
|
-
tsCompilerOptions,
|
|
43
|
-
jsDeclarationCompilerOptions,
|
|
44
|
-
};
|