iobroker.js-controller 4.0.19 → 4.0.23
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/conf/sources-dist.json +157 -121
- package/io-package.json +36 -36
- package/lib/setup/setupBackup.js +52 -29
- package/lib/setup/setupRepo.js +3 -5
- package/main.js +7 -3
- package/package.json +12 -12
package/io-package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "js-controller",
|
|
4
|
-
"version": "4.0.
|
|
4
|
+
"version": "4.0.23",
|
|
5
5
|
"platform": "Javascript/Node.js",
|
|
6
6
|
"controller": true,
|
|
7
7
|
"mode": "daemon",
|
|
@@ -19,31 +19,43 @@
|
|
|
19
19
|
"zh-cn": "JS控制器"
|
|
20
20
|
},
|
|
21
21
|
"news": {
|
|
22
|
-
"4.0.
|
|
23
|
-
"en": "
|
|
24
|
-
"de": "
|
|
25
|
-
"ru": "
|
|
26
|
-
"pt": "
|
|
27
|
-
"nl": "
|
|
28
|
-
"fr": "
|
|
29
|
-
"it": "
|
|
30
|
-
"es": "
|
|
31
|
-
"pl": "
|
|
32
|
-
"zh-cn": "
|
|
22
|
+
"4.0.23": {
|
|
23
|
+
"en": "normalize JSONL options to prevent issues because of admin adding empty setting objects\nPrevent some crash cases reported by Sentry",
|
|
24
|
+
"de": "Normalisieren Sie JSONL-Optionen, um Probleme zu vermeiden, weil der Administrator leere Einstellungsobjekte hinzufügt\nVerhindern Sie einige von Sentry gemeldete Absturzfälle",
|
|
25
|
+
"ru": "нормализуйте параметры JSONL, чтобы предотвратить проблемы из-за того, что администратор добавляет пустые объекты настроек\nПредотвращение некоторых случаев сбоев, о которых сообщает Sentry.",
|
|
26
|
+
"pt": "normalize as opções JSONL para evitar problemas devido ao administrador adicionar objetos de configuração vazios\nPrevenir alguns casos de travamento relatados pelo Sentinela",
|
|
27
|
+
"nl": "normaliseer JSONL-opties om problemen te voorkomen omdat de beheerder lege instellingsobjecten toevoegt\nVoorkom enkele door Sentry gemelde crashgevallen",
|
|
28
|
+
"fr": "normaliser les options JSONL pour éviter les problèmes dus à l'ajout par l'administrateur d'objets de réglage vides\nEmpêcher certains cas de plantage signalés par Sentry",
|
|
29
|
+
"it": "normalizzare le opzioni JSONL per evitare problemi dovuti all'aggiunta di oggetti di impostazione vuoti da parte dell'amministratore\nPrevenire alcuni casi di crash segnalati da Sentry",
|
|
30
|
+
"es": "normalice las opciones de JSONL para evitar problemas debido a que el administrador agrega objetos de configuración vacíos\nEvitar algunos casos de bloqueo informados por Sentry",
|
|
31
|
+
"pl": "znormalizować opcje JSONL, aby zapobiec problemom z powodu dodania przez administratora pustych obiektów ustawień\nZapobiegaj niektórym przypadkom awarii zgłaszanych przez Sentry",
|
|
32
|
+
"zh-cn": "规范化 JSONL 选项以防止由于管理员添加空设置对象而出现问题\n防止 Sentry 报告的一些崩溃案例"
|
|
33
|
+
},
|
|
34
|
+
"4.0.21": {
|
|
35
|
+
"en": "Fix Backup Restore crash case",
|
|
36
|
+
"de": "Beheben Sie den Absturzfall der Sicherungswiederherstellung",
|
|
37
|
+
"ru": "Исправить случай сбоя восстановления резервной копии",
|
|
38
|
+
"pt": "Corrigir caso de falha de restauração de backup",
|
|
39
|
+
"nl": "Fix Backup Herstel crashgeval",
|
|
40
|
+
"fr": "Correction du cas de plantage de restauration de sauvegarde",
|
|
41
|
+
"it": "Risolto il caso di arresto anomalo del ripristino del backup",
|
|
42
|
+
"es": "Solucionar caso de bloqueo de restauración de copia de seguridad",
|
|
43
|
+
"pl": "Napraw przypadek awarii przywracania kopii zapasowej",
|
|
44
|
+
"zh-cn": "修复备份还原崩溃案例"
|
|
33
45
|
},
|
|
34
|
-
"4.0.
|
|
35
|
-
"en": "
|
|
36
|
-
"de": "
|
|
37
|
-
"ru": "
|
|
38
|
-
"pt": "
|
|
39
|
-
"nl": "
|
|
40
|
-
"fr": "
|
|
41
|
-
"it": "
|
|
42
|
-
"es": "
|
|
43
|
-
"pl": "
|
|
44
|
-
"zh-cn": "
|
|
46
|
+
"4.0.20": {
|
|
47
|
+
"en": "Add missing axios dependency\nOnly log an error if an error is happening when activating/deactivating adapter via .alive states\nFix edge case in redis simulator MULTI/EXEC logic\nPrevent some crash cases reported by Sentry",
|
|
48
|
+
"de": "Fehlende Axios-Abhängigkeit hinzugefügt\nProtokollieren Sie nur dann einen Fehler, wenn beim Aktivieren/Deaktivieren des Adapters über .alive-Zustände ein Fehler auftritt\nGrenzfall in der MULTI/EXEC-Logik des Redis-Simulators behoben\nVerhindern Sie einige von Sentry gemeldete Absturzfälle",
|
|
49
|
+
"ru": "Добавить отсутствующую зависимость axios\nРегистрировать ошибку только в том случае, если ошибка возникает при активации/деактивации адаптера через состояния .alive.\nИсправить пограничный случай в логике MULTI/EXEC симулятора Redis.\nПредотвращение некоторых случаев сбоев, о которых сообщает Sentry.",
|
|
50
|
+
"pt": "Adicionar dependência de axios ausente\nApenas registre um erro se ocorrer um erro ao ativar/desativar o adaptador por meio de estados .alive\nCorrigir caso de borda na lógica MULTI/EXEC do simulador redis\nPrevenir alguns casos de travamento relatados pelo Sentinela",
|
|
51
|
+
"nl": "Ontbrekende axios-afhankelijkheid toevoegen\nLog alleen een fout in als er een fout optreedt bij het activeren/deactiveren van de adapter via .alive states\nRandgeval repareren in redis-simulator MULTI/EXEC-logica\nVoorkom enkele door Sentry gemelde crashgevallen",
|
|
52
|
+
"fr": "Ajouter la dépendance axios manquante\nEnregistrez une erreur uniquement si une erreur se produit lors de l'activation/de la désactivation de l'adaptateur via les états .alive\nCorrection du cas limite dans la logique MULTI/EXEC du simulateur redis\nEmpêcher certains cas de plantage signalés par Sentry",
|
|
53
|
+
"it": "Aggiungi la dipendenza assio mancante\nRegistra un errore solo se si verifica un errore durante l'attivazione/disattivazione dell'adattatore tramite stati .alive\nRisolto il problema con il caso limite nella logica MULTI/EXEC del simulatore Redis\nPrevenire alcuni casi di crash segnalati da Sentry",
|
|
54
|
+
"es": "Agregar la dependencia de axios faltante\nSolo registre un error si ocurre un error al activar/desactivar el adaptador a través de estados .alive\nArreglar el caso de borde en la lógica MULTI / EXEC del simulador redis\nEvitar algunos casos de bloqueo informados por Sentry",
|
|
55
|
+
"pl": "Dodaj brakującą zależność axios\nZapisuj błąd tylko wtedy, gdy wystąpi błąd podczas aktywacji/dezaktywacji adaptera przez stany .alive\nNapraw obudowę krawędziową w symulatorze redis, logika MULTI/EXEC\nZapobiegaj niektórym przypadkom awarii zgłaszanych przez Sentry",
|
|
56
|
+
"zh-cn": "添加缺少的 axios 依赖项\n只有在通过 .alive 状态激活/停用适配器时发生错误时才记录错误\n修复 redis 模拟器 MULTI/EXEC 逻辑中的边缘情况\n防止 Sentry 报告的一些崩溃案例"
|
|
45
57
|
},
|
|
46
|
-
"4.0.
|
|
58
|
+
"4.0.19": {
|
|
47
59
|
"en": "see CHANGELOG.md",
|
|
48
60
|
"de": "siehe CHANGELOG.md",
|
|
49
61
|
"ru": "см. CHANGELOG.md",
|
|
@@ -90,18 +102,6 @@
|
|
|
90
102
|
"es": "ver CHANGELOG.md",
|
|
91
103
|
"pl": "zobacz CHANGELOG.md",
|
|
92
104
|
"zh-cn": "看到CHANGELOG.md"
|
|
93
|
-
},
|
|
94
|
-
"3.0.20": {
|
|
95
|
-
"en": "see CHANGELOG.md",
|
|
96
|
-
"de": "Siehe CHANGELOG.md",
|
|
97
|
-
"ru": "см. CHANGELOG.md",
|
|
98
|
-
"pt": "veja CHANGELOG.md",
|
|
99
|
-
"nl": "zie CHANGELOG.md",
|
|
100
|
-
"fr": "voir CHANGELOG.md",
|
|
101
|
-
"it": "vedi CHANGELOG.md",
|
|
102
|
-
"es": "ver CHANGELOG.md",
|
|
103
|
-
"pl": "zobacz CHANGELOG.md",
|
|
104
|
-
"zh-cn": "看到CHANGELOG.md"
|
|
105
105
|
}
|
|
106
106
|
},
|
|
107
107
|
"desc": {
|
package/lib/setup/setupBackup.js
CHANGED
|
@@ -14,7 +14,6 @@ const pathLib = require('path');
|
|
|
14
14
|
const hostname = tools.getHostName();
|
|
15
15
|
const Upload = require('./setupUpload');
|
|
16
16
|
const { EXIT_CODES } = require('@iobroker/js-controller-common');
|
|
17
|
-
const path = require('path');
|
|
18
17
|
const cpPromise = require('promisify-child-process');
|
|
19
18
|
|
|
20
19
|
// We cannot use relative paths for the backup locations, as they used by both
|
|
@@ -125,14 +124,18 @@ class BackupRestore {
|
|
|
125
124
|
copyFileSync(source, target) {
|
|
126
125
|
let targetFile = target;
|
|
127
126
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (fs.
|
|
131
|
-
|
|
127
|
+
try {
|
|
128
|
+
// if target is a directory a new file with the same name will be created
|
|
129
|
+
if (fs.existsSync(target)) {
|
|
130
|
+
if (fs.statSync(target).isDirectory()) {
|
|
131
|
+
targetFile = pathLib.join(target, pathLib.basename(source));
|
|
132
|
+
}
|
|
132
133
|
}
|
|
133
|
-
}
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
fs.writeFileSync(targetFile, fs.readFileSync(source));
|
|
136
|
+
} catch (e) {
|
|
137
|
+
console.error(`Could not copy ${targetFile} to ${source}: ${e.message}`);
|
|
138
|
+
}
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
copyFolderRecursiveSync(source, target) {
|
|
@@ -149,10 +152,13 @@ class BackupRestore {
|
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
// copy
|
|
152
|
-
if (fs.statSync(source).isDirectory()) {
|
|
155
|
+
if (fs.existsSync(source) && fs.statSync(source).isDirectory()) {
|
|
153
156
|
files = fs.readdirSync(source);
|
|
154
157
|
files.forEach(file => {
|
|
155
158
|
const curSource = pathLib.join(source, file);
|
|
159
|
+
if (!fs.existsSync(curSource)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
156
162
|
if (fs.statSync(curSource).isDirectory()) {
|
|
157
163
|
this.copyFolderRecursiveSync(curSource, targetFolder);
|
|
158
164
|
} else {
|
|
@@ -600,7 +606,11 @@ class BackupRestore {
|
|
|
600
606
|
}
|
|
601
607
|
const files = fs.readdirSync(root + path);
|
|
602
608
|
for (const file of files) {
|
|
603
|
-
const
|
|
609
|
+
const fName = pathLib.join(root, path, file);
|
|
610
|
+
if (!fs.existsSync(fName)) {
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
const stat = fs.statSync(fName);
|
|
604
614
|
if (stat.isDirectory()) {
|
|
605
615
|
try {
|
|
606
616
|
await this._uploadUserFiles(root, `${path}/${file}`);
|
|
@@ -623,22 +633,35 @@ class BackupRestore {
|
|
|
623
633
|
}
|
|
624
634
|
|
|
625
635
|
_copyBackupedFiles(backupDir) {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
}
|
|
630
|
-
const dirs = fs.readdirSync(backupDir);
|
|
631
|
-
|
|
632
|
-
dirs.forEach(dir => {
|
|
633
|
-
if (dir === 'files') {
|
|
636
|
+
try {
|
|
637
|
+
if (!fs.existsSync(backupDir)) {
|
|
638
|
+
console.log('No additional files to restore');
|
|
634
639
|
return;
|
|
635
640
|
}
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
641
|
+
const dirs = fs.readdirSync(backupDir);
|
|
642
|
+
|
|
643
|
+
dirs.forEach(dir => {
|
|
644
|
+
if (dir === 'files') {
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
const path = pathLib.join(backupDir, dir);
|
|
648
|
+
let stat;
|
|
649
|
+
try {
|
|
650
|
+
if (!fs.existsSync(path)) {
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
stat = fs.statSync(path);
|
|
654
|
+
} catch (err) {
|
|
655
|
+
console.error(`Ignoring ${path} because can not get file type: ${err.message}`);
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
if (stat.isDirectory()) {
|
|
659
|
+
this.copyFolderRecursiveSync(path, this.configDir);
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
} catch (err) {
|
|
663
|
+
console.error(`Ignoring ${backupDir} because can not read directory: ${err.message}`);
|
|
664
|
+
}
|
|
642
665
|
}
|
|
643
666
|
|
|
644
667
|
/**
|
|
@@ -720,7 +743,7 @@ class BackupRestore {
|
|
|
720
743
|
console.log('Forced restore - executing setup ...');
|
|
721
744
|
try {
|
|
722
745
|
await cpPromise.exec(
|
|
723
|
-
`"${process.execPath}" "${
|
|
746
|
+
`"${process.execPath}" "${pathLib.join(controllerDir, `${tools.appName.toLowerCase()}.js`)}" setup`
|
|
724
747
|
);
|
|
725
748
|
} catch (e) {
|
|
726
749
|
console.error(
|
|
@@ -743,7 +766,7 @@ class BackupRestore {
|
|
|
743
766
|
* @private
|
|
744
767
|
*/
|
|
745
768
|
async _removeAllAdapters(controllerDir) {
|
|
746
|
-
const nodeModulePath =
|
|
769
|
+
const nodeModulePath = pathLib.join(controllerDir, '..');
|
|
747
770
|
const nodeModuleDirs = fs.readdirSync(nodeModulePath, { withFileTypes: true });
|
|
748
771
|
// we need to uninstall current adapters to get exact the same system as before backup
|
|
749
772
|
for (const dir of nodeModuleDirs) {
|
|
@@ -753,7 +776,7 @@ class BackupRestore {
|
|
|
753
776
|
dir.name !== `${tools.appName.toLowerCase()}.js-controller`
|
|
754
777
|
) {
|
|
755
778
|
try {
|
|
756
|
-
const packJson = fs.readJsonSync(
|
|
779
|
+
const packJson = fs.readJsonSync(pathLib.join(nodeModulePath, dir.name, 'package.json'));
|
|
757
780
|
console.log(`Removing current installation of ${packJson.name}`);
|
|
758
781
|
await tools.uninstallNodeModule(packJson.name);
|
|
759
782
|
} catch {
|
|
@@ -775,7 +798,7 @@ class BackupRestore {
|
|
|
775
798
|
*/
|
|
776
799
|
_ensureCompatibility(controllerDir, backupHostname, backupObjects, force) {
|
|
777
800
|
try {
|
|
778
|
-
const ioPackJson = fs.readJsonSync(
|
|
801
|
+
const ioPackJson = fs.readJsonSync(pathLib.join(controllerDir, 'io-package.json'));
|
|
779
802
|
const hostObj = backupObjects.find(obj => obj.id === `system.host.${backupHostname}`);
|
|
780
803
|
if (hostObj.value.common.installedVersion !== ioPackJson.common.version) {
|
|
781
804
|
if (!force) {
|
|
@@ -912,7 +935,7 @@ class BackupRestore {
|
|
|
912
935
|
},
|
|
913
936
|
err => {
|
|
914
937
|
if (err) {
|
|
915
|
-
console.error(`host.${hostname} Cannot extract from file "${name}"`);
|
|
938
|
+
console.error(`host.${hostname} Cannot extract from file "${name}": ${err.message}`);
|
|
916
939
|
return void this.processExit(9);
|
|
917
940
|
}
|
|
918
941
|
if (!fs.existsSync(`${tmpDir}/backup/backup.json`)) {
|
|
@@ -1075,7 +1098,7 @@ class BackupRestore {
|
|
|
1075
1098
|
},
|
|
1076
1099
|
err => {
|
|
1077
1100
|
if (err) {
|
|
1078
|
-
console.error(`host.${hostname} Cannot extract from file "${name}"`);
|
|
1101
|
+
console.error(`host.${hostname} Cannot extract from file "${name}": ${err.message}`);
|
|
1079
1102
|
return void this.processExit(9);
|
|
1080
1103
|
}
|
|
1081
1104
|
if (!fs.existsSync(`${tmpDir}/backup/backup.json`)) {
|
package/lib/setup/setupRepo.js
CHANGED
|
@@ -187,7 +187,7 @@ function Repo(options) {
|
|
|
187
187
|
} else {
|
|
188
188
|
repoUrl = repoUrl || systemConfig.common.activeRepo;
|
|
189
189
|
|
|
190
|
-
if (
|
|
190
|
+
if (!Array.isArray(repoUrl)) {
|
|
191
191
|
repoUrl = [repoUrl];
|
|
192
192
|
}
|
|
193
193
|
|
|
@@ -324,9 +324,7 @@ function Repo(options) {
|
|
|
324
324
|
(obj.common.activeRepo &&
|
|
325
325
|
typeof obj.common.activeRepo === 'string' &&
|
|
326
326
|
obj.common.activeRepo === repoName) ||
|
|
327
|
-
(obj.common.activeRepo &&
|
|
328
|
-
typeof obj.common.activeRepo === 'object' &&
|
|
329
|
-
obj.common.activeRepo.includes(repoName))
|
|
327
|
+
(obj.common.activeRepo && Array.isArray(obj.common.activeRepo) && obj.common.activeRepo.includes(repoName))
|
|
330
328
|
) {
|
|
331
329
|
throw new Error(`Cannot delete active repository: ${repoName}`);
|
|
332
330
|
} else {
|
|
@@ -418,7 +416,7 @@ function Repo(options) {
|
|
|
418
416
|
sysConfigObj.common &&
|
|
419
417
|
((typeof sysConfigObj.common.activeRepo === 'string' &&
|
|
420
418
|
sysConfigObj.common.activeRepo === oldName) ||
|
|
421
|
-
(
|
|
419
|
+
(Array.isArray(sysConfigObj.common.activeRepo) &&
|
|
422
420
|
sysConfigObj.common.activeRepo.includes(oldName)))
|
|
423
421
|
) {
|
|
424
422
|
if (typeof sysConfigObj.common.activeRepo === 'string') {
|
package/main.js
CHANGED
|
@@ -408,8 +408,10 @@ function createStates(onConnect) {
|
|
|
408
408
|
);
|
|
409
409
|
obj.from = hostObjectPrefix;
|
|
410
410
|
obj.ts = Date.now();
|
|
411
|
-
objects.setObject(
|
|
412
|
-
|
|
411
|
+
objects.setObject(
|
|
412
|
+
obj._id,
|
|
413
|
+
obj,
|
|
414
|
+
err => err && logger.error(`${hostLogPrefix} Cannot set object: ${err}`)
|
|
413
415
|
);
|
|
414
416
|
}
|
|
415
417
|
}
|
|
@@ -767,7 +769,7 @@ function createObjects(onConnect) {
|
|
|
767
769
|
delete hostAdapter[id];
|
|
768
770
|
}
|
|
769
771
|
}
|
|
770
|
-
} else if (obj
|
|
772
|
+
} else if (obj && obj.type === 'host' && obj.common && obj.common.installedVersion) {
|
|
771
773
|
// host object changed
|
|
772
774
|
// TODO: remove this shim if 4.0 is old enough
|
|
773
775
|
if (controllerVersions[id]) {
|
|
@@ -1464,6 +1466,8 @@ function setIPs(ipList) {
|
|
|
1464
1466
|
!err &&
|
|
1465
1467
|
oldObj &&
|
|
1466
1468
|
oldObj.common &&
|
|
1469
|
+
oldObj.native &&
|
|
1470
|
+
oldObj.native.hardware &&
|
|
1467
1471
|
(!isDeepStrictEqual(oldObj.native.hardware.networkInterfaces, networkInterfaces) ||
|
|
1468
1472
|
!isDeepStrictEqual(oldObj.common.address, _ipList))
|
|
1469
1473
|
) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.js-controller",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.23",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=12.0.0"
|
|
6
6
|
},
|
|
@@ -17,16 +17,16 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@alcalzone/esbuild-register": "^2.5.1-1",
|
|
20
|
-
"@iobroker/db-objects-file": "4.0.
|
|
21
|
-
"@iobroker/db-objects-jsonl": "4.0.
|
|
22
|
-
"@iobroker/db-objects-redis": "4.0.
|
|
23
|
-
"@iobroker/db-states-file": "4.0.
|
|
24
|
-
"@iobroker/db-states-jsonl": "4.0.
|
|
25
|
-
"@iobroker/db-states-redis": "4.0.
|
|
26
|
-
"@iobroker/js-controller-adapter": "4.0.
|
|
27
|
-
"@iobroker/js-controller-cli": "4.0.
|
|
28
|
-
"@iobroker/js-controller-common": "4.0.
|
|
29
|
-
"@iobroker/js-controller-common-db": "4.0.
|
|
20
|
+
"@iobroker/db-objects-file": "4.0.23",
|
|
21
|
+
"@iobroker/db-objects-jsonl": "4.0.23",
|
|
22
|
+
"@iobroker/db-objects-redis": "4.0.23",
|
|
23
|
+
"@iobroker/db-states-file": "4.0.23",
|
|
24
|
+
"@iobroker/db-states-jsonl": "4.0.23",
|
|
25
|
+
"@iobroker/db-states-redis": "4.0.23",
|
|
26
|
+
"@iobroker/js-controller-adapter": "4.0.23",
|
|
27
|
+
"@iobroker/js-controller-cli": "4.0.23",
|
|
28
|
+
"@iobroker/js-controller-common": "4.0.23",
|
|
29
|
+
"@iobroker/js-controller-common-db": "4.0.23",
|
|
30
30
|
"@iobroker/plugin-base": "~1.2.1",
|
|
31
31
|
"@iobroker/plugin-sentry": "~1.2.0",
|
|
32
32
|
"axios": "^0.24.0",
|
|
@@ -112,5 +112,5 @@
|
|
|
112
112
|
"iobroker.js",
|
|
113
113
|
"main.js"
|
|
114
114
|
],
|
|
115
|
-
"gitHead": "
|
|
115
|
+
"gitHead": "ea1a72ac2d74317ad16234f7aeac90632374614c"
|
|
116
116
|
}
|