@iobroker/adapter-react-v5 7.0.2 → 7.1.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/Components/404.d.ts +3 -2
- package/Components/404.js +3 -2
- package/Components/ColorPicker.d.ts +22 -8
- package/Components/ColorPicker.js +34 -17
- package/Components/ComplexCron.js +24 -24
- package/Components/CopyToClipboard.d.ts +10 -1
- package/Components/CopyToClipboard.js +17 -8
- package/Components/CustomModal.d.ts +1 -1
- package/Components/CustomModal.js +8 -8
- package/Components/FileBrowser.d.ts +11 -11
- package/Components/FileBrowser.js +135 -152
- package/Components/FileViewer.js +34 -23
- package/Components/Icon.d.ts +16 -2
- package/Components/Icon.js +19 -8
- package/Components/IconPicker.js +10 -14
- package/Components/IconSelector.d.ts +1 -1
- package/Components/IconSelector.js +64 -74
- package/Components/Image.d.ts +8 -4
- package/Components/Image.js +13 -32
- package/Components/Loader.d.ts +2 -2
- package/Components/Loader.js +21 -18
- package/Components/Loaders/MV.d.ts +6 -1
- package/Components/Loaders/MV.js +23 -7
- package/Components/Loaders/PT.d.ts +7 -2
- package/Components/Loaders/PT.js +20 -7
- package/Components/Loaders/Vendor.d.ts +2 -2
- package/Components/Loaders/Vendor.js +15 -7
- package/Components/Logo.js +16 -18
- package/Components/MDUtils.d.ts +1 -1
- package/Components/MDUtils.js +8 -4
- package/Components/ObjectBrowser.d.ts +40 -39
- package/Components/ObjectBrowser.js +550 -435
- package/Components/Router.d.ts +1 -3
- package/Components/Router.js +3 -1
- package/Components/SaveCloseButtons.d.ts +3 -3
- package/Components/SaveCloseButtons.js +3 -3
- package/Components/Schedule.d.ts +15 -15
- package/Components/Schedule.js +177 -154
- package/Components/SelectWithIcon.d.ts +2 -2
- package/Components/SelectWithIcon.js +45 -34
- package/Components/SimpleCron/index.js +83 -43
- package/Components/TabContainer.js +2 -2
- package/Components/TabContent.js +1 -1
- package/Components/TabHeader.js +1 -1
- package/Components/TableResize.d.ts +2 -2
- package/Components/TableResize.js +5 -5
- package/Components/TextWithIcon.d.ts +1 -1
- package/Components/TextWithIcon.js +10 -8
- package/Components/ToggleThemeMenu.d.ts +2 -2
- package/Components/ToggleThemeMenu.js +3 -3
- package/Components/TreeTable.d.ts +18 -18
- package/Components/TreeTable.js +76 -72
- package/Components/UploadImage.d.ts +2 -2
- package/Components/UploadImage.js +25 -21
- package/Components/Utils.d.ts +42 -22
- package/Components/Utils.js +66 -65
- package/Components/withWidth.d.ts +2 -2
- package/Components/withWidth.js +10 -6
- package/Dialogs/ComplexCron.d.ts +2 -2
- package/Dialogs/ComplexCron.js +3 -3
- package/Dialogs/Confirm.d.ts +4 -4
- package/Dialogs/Confirm.js +18 -8
- package/Dialogs/Cron.d.ts +3 -3
- package/Dialogs/Cron.js +21 -17
- package/Dialogs/Error.d.ts +3 -3
- package/Dialogs/Error.js +6 -4
- package/Dialogs/Message.d.ts +3 -3
- package/Dialogs/Message.js +6 -4
- package/Dialogs/SelectFile.d.ts +4 -4
- package/Dialogs/SelectFile.js +6 -4
- package/Dialogs/SelectID.d.ts +12 -10
- package/Dialogs/SelectID.js +12 -8
- package/Dialogs/SimpleCron.d.ts +2 -2
- package/Dialogs/SimpleCron.js +2 -2
- package/Dialogs/TextInput.d.ts +2 -2
- package/Dialogs/TextInput.js +3 -3
- package/GenericApp.d.ts +19 -13
- package/GenericApp.js +128 -85
- package/LegacyConnection.d.ts +240 -248
- package/LegacyConnection.js +500 -525
- package/README.md +1264 -1171
- package/Theme.d.ts +1 -1
- package/Theme.js +9 -12
- package/assets/devices.json +1 -0
- package/assets/rooms.json +1 -0
- package/craco-module-federation.js +3 -12
- package/i18n/de.json +434 -434
- package/i18n/en.json +434 -434
- package/i18n/es.json +434 -434
- package/i18n/fr.json +434 -434
- package/i18n/it.json +434 -434
- package/i18n/nl.json +434 -434
- package/i18n/pl.json +434 -434
- package/i18n/pt.json +434 -434
- package/i18n/ru.json +434 -434
- package/i18n/uk.json +434 -434
- package/i18n/zh-cn.json +434 -434
- package/i18n.d.ts +26 -19
- package/i18n.js +28 -22
- package/icons/IconAdapter.js +2 -2
- package/icons/IconAlias.js +2 -2
- package/icons/IconChannel.js +2 -2
- package/icons/IconClearFilter.js +2 -2
- package/icons/IconClosed.js +2 -2
- package/icons/IconCopy.js +2 -2
- package/icons/IconDevice.js +2 -2
- package/icons/IconDocument.js +2 -2
- package/icons/IconDocumentReadOnly.js +2 -2
- package/icons/IconExpert.js +2 -2
- package/icons/IconFx.js +2 -2
- package/icons/IconInstance.js +2 -2
- package/icons/IconLogout.js +2 -2
- package/icons/IconNoIcon.js +2 -2
- package/icons/IconOpen.d.ts +2 -2
- package/icons/IconOpen.js +2 -2
- package/icons/IconProps.d.ts +4 -3
- package/icons/IconState.d.ts +2 -2
- package/icons/IconState.js +2 -2
- package/index.css +3 -2
- package/package.json +4 -4
- package/src/Components/404.tsx +32 -31
- package/src/Components/ColorPicker.tsx +142 -114
- package/src/Components/ComplexCron.tsx +174 -137
- package/src/Components/CopyToClipboard.tsx +22 -9
- package/src/Components/CustomModal.tsx +76 -69
- package/src/Components/FileBrowser.tsx +959 -852
- package/src/Components/FileViewer.tsx +146 -127
- package/src/Components/Icon.tsx +80 -52
- package/src/Components/IconPicker.tsx +83 -67
- package/src/Components/IconSelector.tsx +159 -141
- package/src/Components/Image.tsx +43 -26
- package/src/Components/Loader.tsx +56 -32
- package/src/Components/Logo.tsx +62 -52
- package/src/Components/MDUtils.tsx +10 -6
- package/src/Components/ObjectBrowser.tsx +3198 -2478
- package/src/Components/Router.tsx +11 -11
- package/src/Components/SaveCloseButtons.tsx +43 -39
- package/src/Components/Schedule.tsx +1091 -853
- package/src/Components/SelectWithIcon.tsx +135 -93
- package/src/Components/TabContainer.tsx +22 -20
- package/src/Components/TabContent.tsx +13 -12
- package/src/Components/TabHeader.tsx +10 -9
- package/src/Components/TableResize.tsx +52 -37
- package/src/Components/TextWithIcon.tsx +30 -19
- package/src/Components/ToggleThemeMenu.tsx +31 -13
- package/src/Components/TreeTable.tsx +468 -385
- package/src/Components/UploadImage.tsx +153 -121
- package/src/Components/Utils.tsx +135 -127
- package/src/Components/loader.css +40 -31
- package/src/Components/withWidth.tsx +23 -12
- package/src/Connection.tsx +1 -3
- package/src/Dialogs/ComplexCron.tsx +55 -61
- package/src/Dialogs/Confirm.tsx +88 -65
- package/src/Dialogs/Cron.tsx +122 -112
- package/src/Dialogs/Error.tsx +37 -42
- package/src/Dialogs/Message.tsx +39 -37
- package/src/Dialogs/SelectFile.tsx +95 -85
- package/src/Dialogs/SelectID.tsx +141 -129
- package/src/Dialogs/SimpleCron.tsx +44 -44
- package/src/Dialogs/TextInput.tsx +60 -68
- package/src/GenericApp.tsx +342 -242
- package/src/LegacyConnection.tsx +972 -842
- package/src/Prompt.tsx +3 -1
- package/src/Theme.tsx +19 -26
- package/src/icons/IconAdapter.tsx +16 -14
- package/src/icons/IconAlias.tsx +16 -14
- package/src/icons/IconChannel.tsx +55 -16
- package/src/icons/IconClearFilter.tsx +17 -15
- package/src/icons/IconClosed.tsx +16 -11
- package/src/icons/IconCopy.tsx +16 -11
- package/src/icons/IconDevice.tsx +121 -22
- package/src/icons/IconDocument.tsx +16 -11
- package/src/icons/IconDocumentReadOnly.tsx +21 -12
- package/src/icons/IconExpert.tsx +20 -12
- package/src/icons/IconFx.tsx +16 -14
- package/src/icons/IconInstance.tsx +16 -14
- package/src/icons/IconLogout.tsx +20 -18
- package/src/icons/IconNoIcon.tsx +16 -14
- package/src/icons/IconOpen.tsx +17 -12
- package/src/icons/IconProps.tsx +4 -3
- package/src/icons/IconState.tsx +34 -13
- package/src/index.css +3 -2
- package/tasks.js +91 -0
- package/types.d.ts +141 -0
- package/Components/Loaders/PT.css +0 -109
- package/Components/Loaders/Vendor.css +0 -13
- package/Components/loader.css +0 -222
- package/Components/types.d.ts +0 -82
- package/assets/devices/Alarm Systems.svg +0 -19
- package/assets/devices/Amplifier.svg +0 -22
- package/assets/devices/Awnings.svg +0 -5
- package/assets/devices/Battery Status.svg +0 -5
- package/assets/devices/Ceiling Spotlights.svg +0 -16
- package/assets/devices/Chandelier.svg +0 -7
- package/assets/devices/Climate.svg +0 -12
- package/assets/devices/Coffee Makers.svg +0 -6
- package/assets/devices/Cold Water.svg +0 -31
- package/assets/devices/Computer.svg +0 -21
- package/assets/devices/Consumption.svg +0 -8
- package/assets/devices/Curtains.svg +0 -43
- package/assets/devices/Dishwashers.svg +0 -12
- package/assets/devices/Doors.svg +0 -6
- package/assets/devices/Doorstep.svg +0 -35
- package/assets/devices/Dryer.svg +0 -14
- package/assets/devices/Fan.svg +0 -20
- package/assets/devices/Floor Lamps.svg +0 -5
- package/assets/devices/Garage Doors.svg +0 -9
- package/assets/devices/Gates.svg +0 -32
- package/assets/devices/Hairdryer.svg +0 -23
- package/assets/devices/Handle.svg +0 -6
- package/assets/devices/Hanging Lamps.svg +0 -9
- package/assets/devices/Heater.svg +0 -44
- package/assets/devices/Hoods.svg +0 -12
- package/assets/devices/Hot Water.svg +0 -10
- package/assets/devices/Humidity.svg +0 -41
- package/assets/devices/Iron.svg +0 -5
- package/assets/devices/Irrigation.svg +0 -23
- package/assets/devices/Led Strip.svg +0 -31
- package/assets/devices/Light.svg +0 -30
- package/assets/devices/Lightings.svg +0 -46
- package/assets/devices/Lock.svg +0 -19
- package/assets/devices/Louvre.svg +0 -7
- package/assets/devices/Mowing Machine.svg +0 -9
- package/assets/devices/Music.svg +0 -13
- package/assets/devices/Outdoor Blinds.svg +0 -7
- package/assets/devices/People.svg +0 -19
- package/assets/devices/Pool.svg +0 -8
- package/assets/devices/Power Consumption.svg +0 -13
- package/assets/devices/Printer.svg +0 -10
- package/assets/devices/Pump.svg +0 -10
- package/assets/devices/Receiver.svg +0 -19
- package/assets/devices/Sconces.svg +0 -10
- package/assets/devices/Security.svg +0 -34
- package/assets/devices/Shading.svg +0 -5
- package/assets/devices/Shutters.svg +0 -11
- package/assets/devices/SmokeDetector.svg +0 -13
- package/assets/devices/Sockets.svg +0 -13
- package/assets/devices/Speaker.svg +0 -35
- package/assets/devices/Stove.svg +0 -12
- package/assets/devices/Table Lamps.svg +0 -12
- package/assets/devices/Temperature Sensors.svg +0 -28
- package/assets/devices/Tv.svg +0 -8
- package/assets/devices/Vacuum Cleaner.svg +0 -16
- package/assets/devices/Ventilation.svg +0 -12
- package/assets/devices/Washing Machines.svg +0 -16
- package/assets/devices/Water Consumption.svg +0 -6
- package/assets/devices/Water Heater.svg +0 -8
- package/assets/devices/Water.svg +0 -40
- package/assets/devices/Weather.svg +0 -28
- package/assets/devices/Window.svg +0 -8
- package/assets/rooms/Anteroom.svg +0 -53
- package/assets/rooms/Attic.svg +0 -21
- package/assets/rooms/Balcony.svg +0 -13
- package/assets/rooms/Barn.svg +0 -6
- package/assets/rooms/Basement.svg +0 -5
- package/assets/rooms/Bathroom.svg +0 -38
- package/assets/rooms/Bedroom.svg +0 -5
- package/assets/rooms/Boiler Room.svg +0 -13
- package/assets/rooms/Carport.svg +0 -17
- package/assets/rooms/Cellar.svg +0 -89
- package/assets/rooms/Chamber.svg +0 -9
- package/assets/rooms/Corridor.svg +0 -53
- package/assets/rooms/Dining Area.svg +0 -37
- package/assets/rooms/Dining Room.svg +0 -37
- package/assets/rooms/Dining.svg +0 -37
- package/assets/rooms/Dressing Room.svg +0 -5
- package/assets/rooms/Driveway.svg +0 -15
- package/assets/rooms/Entrance.svg +0 -44
- package/assets/rooms/Equipment Room.svg +0 -15
- package/assets/rooms/Front Yard.svg +0 -64
- package/assets/rooms/Gallery.svg +0 -14
- package/assets/rooms/Garage.svg +0 -20
- package/assets/rooms/Garden.svg +0 -13
- package/assets/rooms/Ground Floor.svg +0 -95
- package/assets/rooms/Guest Bathroom.svg +0 -33
- package/assets/rooms/Guest Room.svg +0 -5
- package/assets/rooms/Gym.svg +0 -5
- package/assets/rooms/Hall.svg +0 -19
- package/assets/rooms/Home Theater.svg +0 -8
- package/assets/rooms/Kitchen.svg +0 -18
- package/assets/rooms/Laundry Room.svg +0 -12
- package/assets/rooms/Living Area.svg +0 -11
- package/assets/rooms/Living Room.svg +0 -10
- package/assets/rooms/Locker Room.svg +0 -17
- package/assets/rooms/Nursery.svg +0 -5
- package/assets/rooms/Office.svg +0 -8
- package/assets/rooms/Outdoors.svg +0 -7
- package/assets/rooms/Playroom.svg +0 -6
- package/assets/rooms/Pool.svg +0 -8
- package/assets/rooms/Rear Wall.svg +0 -30
- package/assets/rooms/Second Floor.svg +0 -95
- package/assets/rooms/Shed.svg +0 -16
- package/assets/rooms/Sleeping Area.svg +0 -22
- package/assets/rooms/Stairway.svg +0 -5
- package/assets/rooms/Stairwell.svg +0 -15
- package/assets/rooms/Storeroom.svg +0 -5
- package/assets/rooms/Summer House.svg +0 -27
- package/assets/rooms/Swimming Pool.svg +0 -21
- package/assets/rooms/Terrace.svg +0 -7
- package/assets/rooms/Toilet.svg +0 -10
- package/assets/rooms/Upstairs.svg +0 -6
- package/assets/rooms/Wardrobe.svg +0 -60
- package/assets/rooms/Washroom.svg +0 -20
- package/assets/rooms/Wc.svg +0 -10
- package/assets/rooms/Windscreen.svg +0 -60
- package/assets/rooms/Workshop.svg +0 -23
- package/assets/rooms/Workspace.svg +0 -8
package/src/LegacyConnection.tsx
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* MIT License
|
|
5
5
|
*
|
|
6
|
-
|
|
6
|
+
*/
|
|
7
7
|
|
|
8
8
|
import { type HostInfo } from '@iobroker/js-controller-common-db/build/esm/lib/common/tools';
|
|
9
9
|
import { type FilteredNotificationInformation } from '@iobroker/js-controller-common/build/esm/lib/common/notificationHandler';
|
|
10
|
+
import type { IoBJson } from '@iobroker/types/build/config';
|
|
10
11
|
|
|
11
12
|
declare global {
|
|
12
13
|
interface Window {
|
|
@@ -18,6 +19,32 @@ declare global {
|
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
export type CompactSystemRepositoryEntry = {
|
|
23
|
+
link: string;
|
|
24
|
+
hash?: string;
|
|
25
|
+
stable?: boolean;
|
|
26
|
+
json:
|
|
27
|
+
| {
|
|
28
|
+
_repoInfo: {
|
|
29
|
+
stable?: boolean;
|
|
30
|
+
name?: ioBroker.StringOrTranslated;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
| null
|
|
34
|
+
| undefined;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type CompactSystemRepository = {
|
|
38
|
+
_id: ioBroker.HostObject['_id'];
|
|
39
|
+
common: {
|
|
40
|
+
name: ioBroker.HostCommon['name'];
|
|
41
|
+
dontDelete: boolean;
|
|
42
|
+
};
|
|
43
|
+
native: {
|
|
44
|
+
repositories: Record<string, CompactSystemRepositoryEntry>;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
|
|
21
48
|
/** Possible progress states. */
|
|
22
49
|
export const PROGRESS = {
|
|
23
50
|
/** The socket is connecting. */
|
|
@@ -33,7 +60,7 @@ export const PROGRESS = {
|
|
|
33
60
|
};
|
|
34
61
|
|
|
35
62
|
const PERMISSION_ERROR = 'permissionError';
|
|
36
|
-
const NOT_CONNECTED
|
|
63
|
+
const NOT_CONNECTED = 'notConnectedError';
|
|
37
64
|
const TIMEOUT_FOR_ADMIN4 = 1300;
|
|
38
65
|
|
|
39
66
|
export const ERRORS = {
|
|
@@ -41,10 +68,7 @@ export const ERRORS = {
|
|
|
41
68
|
NOT_CONNECTED,
|
|
42
69
|
};
|
|
43
70
|
|
|
44
|
-
export type BinaryStateChangeHandler = (
|
|
45
|
-
id: string,
|
|
46
|
-
base64: string | null,
|
|
47
|
-
) => void;
|
|
71
|
+
export type BinaryStateChangeHandler = (id: string, base64: string | null) => void;
|
|
48
72
|
|
|
49
73
|
function fixAdminUI(obj: ioBroker.AdapterObject): ioBroker.AdapterObject {
|
|
50
74
|
// @ts-expect-error it is deprecated, but still could appear
|
|
@@ -98,7 +122,12 @@ function fixAdminUI(obj: ioBroker.AdapterObject): ioBroker.AdapterObject {
|
|
|
98
122
|
}
|
|
99
123
|
|
|
100
124
|
// @ts-expect-error it is deprecated, but still could appear
|
|
101
|
-
obj.common.adminUI
|
|
125
|
+
if (obj.common.adminUI) {
|
|
126
|
+
console.debug(
|
|
127
|
+
// @ts-expect-error it is deprecated, but still could appear
|
|
128
|
+
`Please add to "${obj._id.replace(/\.\d+$/, '')}" common.adminUI=${JSON.stringify(obj.common.adminUI)}`,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
102
131
|
}
|
|
103
132
|
return obj;
|
|
104
133
|
}
|
|
@@ -110,9 +139,7 @@ export function pattern2RegEx(pattern: string): string {
|
|
|
110
139
|
const startsWithWildcard = pattern[0] === '*';
|
|
111
140
|
const endsWithWildcard = pattern[pattern.length - 1] === '*';
|
|
112
141
|
|
|
113
|
-
pattern = pattern
|
|
114
|
-
.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&')
|
|
115
|
-
.replace(/\*/g, '.*');
|
|
142
|
+
pattern = pattern.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*');
|
|
116
143
|
|
|
117
144
|
return (startsWithWildcard ? '' : '^') + pattern + (endsWithWildcard ? '' : '$');
|
|
118
145
|
}
|
|
@@ -166,7 +193,7 @@ export interface ConnectOptions {
|
|
|
166
193
|
uuid?: string;
|
|
167
194
|
}
|
|
168
195
|
|
|
169
|
-
export interface SocketClient{
|
|
196
|
+
export interface SocketClient {
|
|
170
197
|
connect(url?: string, options?: ConnectOptions): void;
|
|
171
198
|
close(): void;
|
|
172
199
|
destroy(): void;
|
|
@@ -200,7 +227,7 @@ interface Promises {
|
|
|
200
227
|
cert?: Promise<{ name: string; type: 'public' | 'private' | 'chained' | '' }[]> | null;
|
|
201
228
|
webName?: Promise<string> | null;
|
|
202
229
|
compactInstances?: Promise<Record<string, ioBroker.InstanceObject>> | null;
|
|
203
|
-
getCompactSystemRepositories?: Promise<
|
|
230
|
+
getCompactSystemRepositories?: Promise<CompactSystemRepository> | null;
|
|
204
231
|
systemConfigPromise?: Promise<ioBroker.SystemConfigObject> | null;
|
|
205
232
|
hostsCompact?: Promise<ioBroker.HostObject[]> | null;
|
|
206
233
|
uuid?: Promise<string | undefined>;
|
|
@@ -229,7 +256,13 @@ class Connection {
|
|
|
229
256
|
|
|
230
257
|
private _promises: Promises = {};
|
|
231
258
|
|
|
232
|
-
private readonly _instanceSubscriptions: Record<
|
|
259
|
+
private readonly _instanceSubscriptions: Record<
|
|
260
|
+
string,
|
|
261
|
+
{
|
|
262
|
+
messageType: string;
|
|
263
|
+
callback: (data: Record<string, any>, sourceInstance: string, messageType: string) => void;
|
|
264
|
+
}[]
|
|
265
|
+
>;
|
|
233
266
|
|
|
234
267
|
private props: ConnectionProps;
|
|
235
268
|
|
|
@@ -251,24 +284,40 @@ class Connection {
|
|
|
251
284
|
|
|
252
285
|
private connected: boolean = false;
|
|
253
286
|
|
|
254
|
-
private readonly statesSubscribes: Record<
|
|
287
|
+
private readonly statesSubscribes: Record<
|
|
288
|
+
string,
|
|
289
|
+
{ reg: RegExp; cbs: (ioBroker.StateChangeHandler | BinaryStateChangeHandler)[] }
|
|
290
|
+
> = {};
|
|
255
291
|
|
|
256
|
-
private readonly objectsSubscribes: Record<
|
|
292
|
+
private readonly objectsSubscribes: Record<
|
|
293
|
+
string,
|
|
294
|
+
{
|
|
295
|
+
reg: RegExp;
|
|
296
|
+
cbs: ((id: string, obj: ioBroker.Object | null | undefined, oldObj?: ioBroker.Object | null) => void)[];
|
|
297
|
+
}
|
|
298
|
+
> = {};
|
|
257
299
|
|
|
258
|
-
private readonly filesSubscribes: Record<
|
|
300
|
+
private readonly filesSubscribes: Record<
|
|
301
|
+
string,
|
|
302
|
+
{ regId: RegExp; cbs: ioBroker.FileChangeHandler[]; regFilePattern: RegExp }
|
|
303
|
+
> = {};
|
|
259
304
|
|
|
260
305
|
private onConnectionHandlers: ((connected: boolean) => void)[] = [];
|
|
261
306
|
|
|
262
307
|
private onLogHandlers: ((message: string) => void)[] = [];
|
|
263
308
|
|
|
264
|
-
private readonly onProgress: (
|
|
309
|
+
private readonly onProgress: (progress: number) => void;
|
|
265
310
|
|
|
266
|
-
private readonly onError: (
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
311
|
+
private readonly onError: (
|
|
312
|
+
err:
|
|
313
|
+
| string
|
|
314
|
+
| {
|
|
315
|
+
message: string;
|
|
316
|
+
operation: string;
|
|
317
|
+
type: string;
|
|
318
|
+
id: string;
|
|
319
|
+
},
|
|
320
|
+
) => void;
|
|
272
321
|
|
|
273
322
|
private loaded: boolean = false;
|
|
274
323
|
|
|
@@ -299,34 +348,42 @@ class Connection {
|
|
|
299
348
|
public systemConfig: ioBroker.SystemConfigObject | null = null;
|
|
300
349
|
|
|
301
350
|
constructor(props: ConnectionProps) {
|
|
302
|
-
props
|
|
303
|
-
this.props
|
|
351
|
+
props = props || { protocol: window.location.protocol, host: window.location.hostname };
|
|
352
|
+
this.props = props;
|
|
304
353
|
|
|
305
|
-
this.autoSubscribes
|
|
354
|
+
this.autoSubscribes = this.props.autoSubscribes || [];
|
|
306
355
|
this.autoSubscribeLog = this.props.autoSubscribeLog || false;
|
|
307
356
|
|
|
308
|
-
this.props.protocol
|
|
309
|
-
this.props.host
|
|
310
|
-
this.props.port
|
|
311
|
-
|
|
357
|
+
this.props.protocol = this.props.protocol || window.location.protocol;
|
|
358
|
+
this.props.host = this.props.host || window.location.hostname;
|
|
359
|
+
this.props.port =
|
|
360
|
+
this.props.port ||
|
|
361
|
+
(window.location.port === '3000' ? (Connection.isWeb() ? 8082 : 8081) : window.location.port);
|
|
362
|
+
this.props.ioTimeout = Math.max(this.props.ioTimeout || 20000, 20000);
|
|
312
363
|
this.props.cmdTimeout = Math.max(this.props.cmdTimeout || 5000, 5000);
|
|
313
364
|
this._instanceSubscriptions = {};
|
|
314
365
|
|
|
315
366
|
// breaking change. Do not load all objects by default is true
|
|
316
367
|
this.doNotLoadAllObjects = this.props.doNotLoadAllObjects === undefined ? true : this.props.doNotLoadAllObjects;
|
|
317
|
-
this.doNotLoadACL
|
|
368
|
+
this.doNotLoadACL = this.props.doNotLoadACL === undefined ? true : this.props.doNotLoadACL;
|
|
318
369
|
|
|
319
370
|
this.states = {};
|
|
320
371
|
this._waitForFirstConnection = new Promise(resolve => {
|
|
321
372
|
this._waitForFirstConnectionResolve = resolve;
|
|
322
373
|
});
|
|
323
374
|
this.onProgress = this.props.onProgress || (() => {});
|
|
324
|
-
this.onError =
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
375
|
+
this.onError =
|
|
376
|
+
this.props.onError ||
|
|
377
|
+
((
|
|
378
|
+
err:
|
|
379
|
+
| string
|
|
380
|
+
| {
|
|
381
|
+
message: string;
|
|
382
|
+
operation: string;
|
|
383
|
+
type: string;
|
|
384
|
+
id: string;
|
|
385
|
+
},
|
|
386
|
+
) => console.error(err));
|
|
330
387
|
this.admin5only = this.props.admin5only || false;
|
|
331
388
|
|
|
332
389
|
this.startSocket();
|
|
@@ -334,15 +391,18 @@ class Connection {
|
|
|
334
391
|
|
|
335
392
|
/**
|
|
336
393
|
* Checks if this connection is running in a web adapter and not in an admin.
|
|
337
|
-
*
|
|
394
|
+
*
|
|
395
|
+
* @returns True if running in a web adapter or in a socketio adapter.
|
|
338
396
|
*/
|
|
339
397
|
static isWeb(): boolean {
|
|
340
398
|
const adapterName: string | undefined = window.adapterName;
|
|
341
|
-
return
|
|
399
|
+
return (
|
|
400
|
+
adapterName === 'material' ||
|
|
342
401
|
adapterName === 'vis' ||
|
|
343
402
|
adapterName?.startsWith('vis-') ||
|
|
344
403
|
adapterName === 'echarts-show' ||
|
|
345
|
-
window.socketUrl !== undefined
|
|
404
|
+
window.socketUrl !== undefined
|
|
405
|
+
);
|
|
346
406
|
}
|
|
347
407
|
|
|
348
408
|
/**
|
|
@@ -379,15 +439,12 @@ class Connection {
|
|
|
379
439
|
let protocol = this.props.protocol.replace(':', '');
|
|
380
440
|
let path = window.location.pathname;
|
|
381
441
|
|
|
382
|
-
if (
|
|
383
|
-
window.location.hostname === 'iobroker.net' ||
|
|
384
|
-
window.location.hostname === 'iobroker.pro'
|
|
385
|
-
) {
|
|
442
|
+
if (window.location.hostname === 'iobroker.net' || window.location.hostname === 'iobroker.pro') {
|
|
386
443
|
path = '';
|
|
387
444
|
} else {
|
|
388
445
|
// if web adapter, socket io could be on another port or even host
|
|
389
446
|
if (window.socketUrl) {
|
|
390
|
-
const parsed = new URL(window.socketUrl as string);
|
|
447
|
+
const parsed = new URL((window as any).socketUrl as string);
|
|
391
448
|
host = parsed.hostname;
|
|
392
449
|
port = parsed.port;
|
|
393
450
|
protocol = parsed.protocol.replace(':', '');
|
|
@@ -418,23 +475,20 @@ class Connection {
|
|
|
418
475
|
|
|
419
476
|
const url = port ? `${protocol}://${host}:${port}${path}` : `${protocol}://${host}${path}`;
|
|
420
477
|
|
|
421
|
-
this._socket = window.io.connect(
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
uuid: this.props.uuid,
|
|
429
|
-
},
|
|
430
|
-
);
|
|
478
|
+
this._socket = window.io.connect(url, {
|
|
479
|
+
path: path.endsWith('/') ? `${path}socket.io` : `${path}/socket.io`,
|
|
480
|
+
query: 'ws=true',
|
|
481
|
+
name: this.props.name,
|
|
482
|
+
timeout: this.props.ioTimeout,
|
|
483
|
+
uuid: this.props.uuid,
|
|
484
|
+
});
|
|
431
485
|
|
|
432
486
|
this._socket.on('connect', (noTimeout: boolean | undefined) => {
|
|
433
487
|
// If the user is not admin, it takes some time to install the handlers, because all rights must be checked
|
|
434
488
|
if (noTimeout !== true) {
|
|
435
|
-
setTimeout(
|
|
436
|
-
|
|
437
|
-
.then(info => {
|
|
489
|
+
setTimeout(
|
|
490
|
+
() =>
|
|
491
|
+
this.getVersion().then(info => {
|
|
438
492
|
const [major, minor, patch] = info.version.split('.');
|
|
439
493
|
const v = parseInt(major, 10) * 10000 + parseInt(minor, 10) * 100 + parseInt(patch, 10);
|
|
440
494
|
if (v < 40102) {
|
|
@@ -442,12 +496,18 @@ class Connection {
|
|
|
442
496
|
// possible this is an old version of admin
|
|
443
497
|
this.onPreConnect(false, false);
|
|
444
498
|
} else {
|
|
445
|
-
this._socket.emit('authenticate', (isOk: boolean, isSecure: boolean) =>
|
|
499
|
+
this._socket.emit('authenticate', (isOk: boolean, isSecure: boolean) =>
|
|
500
|
+
this.onPreConnect(isOk, isSecure),
|
|
501
|
+
);
|
|
446
502
|
}
|
|
447
|
-
}),
|
|
503
|
+
}),
|
|
504
|
+
500,
|
|
505
|
+
);
|
|
448
506
|
} else {
|
|
449
507
|
// iobroker websocket waits, till all handlers are installed
|
|
450
|
-
this._socket.emit('authenticate', (isOk: boolean, isSecure: boolean) =>
|
|
508
|
+
this._socket.emit('authenticate', (isOk: boolean, isSecure: boolean) =>
|
|
509
|
+
this.onPreConnect(isOk, isSecure),
|
|
510
|
+
);
|
|
451
511
|
}
|
|
452
512
|
});
|
|
453
513
|
|
|
@@ -464,14 +524,13 @@ class Connection {
|
|
|
464
524
|
});
|
|
465
525
|
|
|
466
526
|
this._socket.on('disconnect', () => {
|
|
467
|
-
this.connected
|
|
527
|
+
this.connected = false;
|
|
468
528
|
this.subscribed = false;
|
|
469
529
|
this.onProgress(PROGRESS.CONNECTING);
|
|
470
530
|
this.onConnectionHandlers.forEach(cb => cb(false));
|
|
471
531
|
});
|
|
472
532
|
|
|
473
|
-
this._socket.on('reauthenticate', () =>
|
|
474
|
-
Connection.authenticate());
|
|
533
|
+
this._socket.on('reauthenticate', () => Connection.authenticate());
|
|
475
534
|
|
|
476
535
|
this._socket.on('log', message => {
|
|
477
536
|
this.props.onLog && this.props.onLog(message);
|
|
@@ -492,8 +551,7 @@ class Connection {
|
|
|
492
551
|
}
|
|
493
552
|
});
|
|
494
553
|
|
|
495
|
-
this._socket.on('connect_error', (err: string) =>
|
|
496
|
-
console.error(`Connect error: ${err}`));
|
|
554
|
+
this._socket.on('connect_error', (err: string) => console.error(`Connect error: ${err}`));
|
|
497
555
|
|
|
498
556
|
this._socket.on('permissionError', (err: { operation: string; type: string; id?: string }) =>
|
|
499
557
|
this.onError({
|
|
@@ -501,34 +559,43 @@ class Connection {
|
|
|
501
559
|
operation: err.operation,
|
|
502
560
|
type: err.type,
|
|
503
561
|
id: err.id || '',
|
|
504
|
-
})
|
|
562
|
+
}),
|
|
563
|
+
);
|
|
505
564
|
|
|
506
565
|
this._socket.on('objectChange', (id: string, obj: ioBroker.Object | null) =>
|
|
507
|
-
setTimeout(() => this.objectChange(id, obj), 0)
|
|
566
|
+
setTimeout(() => this.objectChange(id, obj), 0),
|
|
567
|
+
);
|
|
508
568
|
|
|
509
|
-
this._socket.on('stateChange', (id: string, state) =>
|
|
510
|
-
setTimeout(() => this.stateChange(id, state), 0));
|
|
569
|
+
this._socket.on('stateChange', (id: string, state) => setTimeout(() => this.stateChange(id, state), 0));
|
|
511
570
|
|
|
512
571
|
this._socket.on('im', (messageType: string, from: string, data) =>
|
|
513
|
-
setTimeout(() => this.instanceMessage(messageType, from, data), 0)
|
|
572
|
+
setTimeout(() => this.instanceMessage(messageType, from, data), 0),
|
|
573
|
+
);
|
|
514
574
|
|
|
515
575
|
this._socket.on('fileChange', (id: string, fileName: string, size: number | null) =>
|
|
516
|
-
setTimeout(() => this.fileChange(id, fileName, size), 0)
|
|
576
|
+
setTimeout(() => this.fileChange(id, fileName, size), 0),
|
|
577
|
+
);
|
|
517
578
|
|
|
518
|
-
this._socket.on(
|
|
519
|
-
|
|
579
|
+
this._socket.on(
|
|
580
|
+
'cmdStdout',
|
|
581
|
+
(id: string, text: string) => this.onCmdStdoutHandler && this.onCmdStdoutHandler(id, text),
|
|
582
|
+
);
|
|
520
583
|
|
|
521
|
-
this._socket.on(
|
|
522
|
-
|
|
584
|
+
this._socket.on(
|
|
585
|
+
'cmdStderr',
|
|
586
|
+
(id: string, text: string) => this.onCmdStderrHandler && this.onCmdStderrHandler(id, text),
|
|
587
|
+
);
|
|
523
588
|
|
|
524
|
-
this._socket.on(
|
|
525
|
-
|
|
589
|
+
this._socket.on(
|
|
590
|
+
'cmdExit',
|
|
591
|
+
(id: string, exitCode: number) => this.onCmdExitHandler && this.onCmdExitHandler(id, exitCode),
|
|
592
|
+
);
|
|
526
593
|
}
|
|
527
594
|
|
|
528
595
|
/**
|
|
529
596
|
* Called internally.
|
|
530
597
|
*/
|
|
531
|
-
private onPreConnect(
|
|
598
|
+
private onPreConnect(_isOk: boolean, isSecure: boolean): void {
|
|
532
599
|
if (this._authTimer) {
|
|
533
600
|
clearTimeout(this._authTimer);
|
|
534
601
|
this._authTimer = null;
|
|
@@ -546,12 +613,12 @@ class Connection {
|
|
|
546
613
|
this.loadTimer = null;
|
|
547
614
|
this.loadCounter++;
|
|
548
615
|
if (this.loadCounter < 10) {
|
|
549
|
-
this.onConnect();
|
|
616
|
+
void this.onConnect().catch(e => this.onError(e));
|
|
550
617
|
}
|
|
551
618
|
}, 1000);
|
|
552
619
|
|
|
553
620
|
if (!this.loaded) {
|
|
554
|
-
this.onConnect();
|
|
621
|
+
void this.onConnect().catch(e => this.onError(e));
|
|
555
622
|
}
|
|
556
623
|
} else {
|
|
557
624
|
this.onProgress(PROGRESS.READY);
|
|
@@ -571,19 +638,13 @@ class Connection {
|
|
|
571
638
|
* Checks if running in ioBroker cloud
|
|
572
639
|
*/
|
|
573
640
|
static isCloud(): boolean {
|
|
574
|
-
if (
|
|
575
|
-
window.location.hostname.includes('amazonaws.com') ||
|
|
576
|
-
window.location.hostname.includes('iobroker.in')
|
|
577
|
-
) {
|
|
641
|
+
if (window.location.hostname.includes('amazonaws.com') || window.location.hostname.includes('iobroker.in')) {
|
|
578
642
|
return true;
|
|
579
643
|
}
|
|
580
644
|
if (typeof window.socketUrl === 'undefined') {
|
|
581
645
|
return false;
|
|
582
646
|
}
|
|
583
|
-
return (
|
|
584
|
-
window.socketUrl.includes('iobroker.in') ||
|
|
585
|
-
window.socketUrl.includes('amazonaws')
|
|
586
|
-
);
|
|
647
|
+
return window.socketUrl.includes('iobroker.in') || window.socketUrl.includes('amazonaws');
|
|
587
648
|
}
|
|
588
649
|
|
|
589
650
|
/**
|
|
@@ -610,19 +671,21 @@ class Connection {
|
|
|
610
671
|
}
|
|
611
672
|
return new Promise((resolve, reject) => {
|
|
612
673
|
this._socket.emit('getUserPermissions', (err: string | null, acl: Record<string, any> | null) =>
|
|
613
|
-
|
|
674
|
+
err ? reject(new Error(err)) : resolve(acl),
|
|
675
|
+
);
|
|
614
676
|
});
|
|
615
677
|
}
|
|
616
678
|
|
|
617
679
|
/**
|
|
618
680
|
* Called internally.
|
|
619
681
|
*/
|
|
620
|
-
private async onConnect() {
|
|
682
|
+
private async onConnect(): Promise<void> {
|
|
621
683
|
let acl: Record<string, any> | null | undefined;
|
|
622
684
|
try {
|
|
623
685
|
acl = await this._getUserPermissions();
|
|
624
|
-
} catch (
|
|
625
|
-
|
|
686
|
+
} catch (e) {
|
|
687
|
+
const knownError = e as Error;
|
|
688
|
+
this.onError(`Cannot read user permissions: ${knownError.message}`);
|
|
626
689
|
return;
|
|
627
690
|
}
|
|
628
691
|
if (!this.doNotLoadACL) {
|
|
@@ -668,9 +731,7 @@ class Connection {
|
|
|
668
731
|
|
|
669
732
|
if (/^(en|de|ru|pt|nl|fr|it|es|pl|uk)-?/.test(this.systemLang)) {
|
|
670
733
|
this.systemLang = this.systemLang.substr(0, 2) as ioBroker.Languages;
|
|
671
|
-
} else if (
|
|
672
|
-
!/^(en|de|ru|pt|nl|fr|it|es|pl|uk|zh-cn)$/.test(this.systemLang)
|
|
673
|
-
) {
|
|
734
|
+
} else if (!/^(en|de|ru|pt|nl|fr|it|es|pl|uk|zh-cn)$/.test(this.systemLang)) {
|
|
674
735
|
this.systemLang = 'en';
|
|
675
736
|
}
|
|
676
737
|
}
|
|
@@ -693,9 +754,8 @@ class Connection {
|
|
|
693
754
|
|
|
694
755
|
/**
|
|
695
756
|
* Called internally.
|
|
696
|
-
* @private
|
|
697
757
|
*/
|
|
698
|
-
static authenticate() {
|
|
758
|
+
private static authenticate(): void {
|
|
699
759
|
if (window.location.search.includes('&href=')) {
|
|
700
760
|
window.location.href = `${window.location.protocol}//${window.location.host}${window.location.pathname}${window.location.search}${window.location.hash}`;
|
|
701
761
|
} else {
|
|
@@ -705,13 +765,14 @@ class Connection {
|
|
|
705
765
|
|
|
706
766
|
/**
|
|
707
767
|
* Subscribe to changes of the given state.
|
|
768
|
+
*
|
|
769
|
+
* @param id The ioBroker state ID or array of states
|
|
770
|
+
* @param binary Set to true if the given state is binary and requires Base64 decoding
|
|
771
|
+
* @param cb The callback
|
|
708
772
|
*/
|
|
709
773
|
subscribeState(
|
|
710
|
-
/** The ioBroker state ID. */
|
|
711
774
|
id: string | string[],
|
|
712
|
-
/** Set to true if the given state is binary and requires Base64 decoding. */
|
|
713
775
|
binary: boolean | ioBroker.StateChangeHandler | BinaryStateChangeHandler,
|
|
714
|
-
/** The callback. */
|
|
715
776
|
cb?: ioBroker.StateChangeHandler | BinaryStateChangeHandler,
|
|
716
777
|
): void {
|
|
717
778
|
if (typeof binary === 'function') {
|
|
@@ -749,8 +810,7 @@ class Connection {
|
|
|
749
810
|
toSubscribe.push(_id);
|
|
750
811
|
}
|
|
751
812
|
} else {
|
|
752
|
-
!this.statesSubscribes[_id].cbs.includes(cb) &&
|
|
753
|
-
this.statesSubscribes[_id].cbs.push(cb);
|
|
813
|
+
!this.statesSubscribes[_id].cbs.includes(cb) && this.statesSubscribes[_id].cbs.push(cb);
|
|
754
814
|
}
|
|
755
815
|
}
|
|
756
816
|
|
|
@@ -770,10 +830,14 @@ class Connection {
|
|
|
770
830
|
.catch(e => console.error(`Cannot getBinaryState "${ids[i]}": ${JSON.stringify(e)}`));
|
|
771
831
|
}
|
|
772
832
|
} else {
|
|
773
|
-
this._socket.emit(
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
833
|
+
this._socket.emit(
|
|
834
|
+
Connection.isWeb() ? 'getStates' : 'getForeignStates',
|
|
835
|
+
id,
|
|
836
|
+
(err: string | null, states: Record<string, ioBroker.State>) => {
|
|
837
|
+
err && console.error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`);
|
|
838
|
+
states && Object.keys(states).forEach(_id => (cb as ioBroker.StateChangeHandler)(_id, states[_id]));
|
|
839
|
+
},
|
|
840
|
+
);
|
|
777
841
|
}
|
|
778
842
|
}
|
|
779
843
|
|
|
@@ -825,11 +889,17 @@ class Connection {
|
|
|
825
889
|
|
|
826
890
|
return new Promise((resolve, reject) => {
|
|
827
891
|
if (typeof cb === 'function' && this.connected) {
|
|
828
|
-
this._socket.emit(
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
892
|
+
this._socket.emit(
|
|
893
|
+
Connection.isWeb() ? 'getStates' : 'getForeignStates',
|
|
894
|
+
id,
|
|
895
|
+
(err: string | null, states: Record<string, ioBroker.State>) => {
|
|
896
|
+
err && console.error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`);
|
|
897
|
+
states && Object.keys(states).forEach(_id => cb(_id, states[_id]));
|
|
898
|
+
states
|
|
899
|
+
? resolve()
|
|
900
|
+
: reject(new Error(`Cannot getForeignStates "${id}": ${JSON.stringify(err)}`));
|
|
901
|
+
},
|
|
902
|
+
);
|
|
833
903
|
} else {
|
|
834
904
|
this.connected ? reject(new Error('callback is not a function')) : reject(new Error('not connected'));
|
|
835
905
|
}
|
|
@@ -880,13 +950,11 @@ class Connection {
|
|
|
880
950
|
|
|
881
951
|
/**
|
|
882
952
|
* Subscribe to changes of the given object.
|
|
953
|
+
*
|
|
954
|
+
* @param id The ioBroker object ID or array of objects
|
|
955
|
+
* @param cb The callback
|
|
883
956
|
*/
|
|
884
|
-
subscribeObject(
|
|
885
|
-
/** The ioBroker object ID. */
|
|
886
|
-
id: string | string[],
|
|
887
|
-
/** The callback. */
|
|
888
|
-
cb: ioBroker.ObjectChangeHandler,
|
|
889
|
-
): Promise<void> {
|
|
957
|
+
subscribeObject(id: string | string[], cb: ioBroker.ObjectChangeHandler): Promise<void> {
|
|
890
958
|
let ids: string[];
|
|
891
959
|
if (!Array.isArray(id)) {
|
|
892
960
|
ids = [id];
|
|
@@ -904,8 +972,7 @@ class Connection {
|
|
|
904
972
|
this.objectsSubscribes[_id] = { reg: new RegExp(reg), cbs: [cb] };
|
|
905
973
|
toSubscribe.push(_id);
|
|
906
974
|
} else {
|
|
907
|
-
!this.objectsSubscribes[_id].cbs.includes(cb) &&
|
|
908
|
-
this.objectsSubscribes[_id].cbs.push(cb);
|
|
975
|
+
!this.objectsSubscribes[_id].cbs.includes(cb) && this.objectsSubscribes[_id].cbs.push(cb);
|
|
909
976
|
}
|
|
910
977
|
}
|
|
911
978
|
if (this.connected && toSubscribe.length) {
|
|
@@ -917,13 +984,11 @@ class Connection {
|
|
|
917
984
|
|
|
918
985
|
/**
|
|
919
986
|
* Unsubscribes all or the given callback from changes of the given object.
|
|
987
|
+
*
|
|
988
|
+
* @param id The ioBroker object ID or array of objects
|
|
989
|
+
* @param cb The callback
|
|
920
990
|
*/
|
|
921
|
-
unsubscribeObject(
|
|
922
|
-
/** The ioBroker object ID. */
|
|
923
|
-
id: string | string[],
|
|
924
|
-
/** The callback. */
|
|
925
|
-
cb?: ioBroker.ObjectChangeHandler,
|
|
926
|
-
): Promise<void> {
|
|
991
|
+
unsubscribeObject(id: string | string[], cb?: ioBroker.ObjectChangeHandler): Promise<void> {
|
|
927
992
|
let ids: string[];
|
|
928
993
|
if (!Array.isArray(id)) {
|
|
929
994
|
ids = [id];
|
|
@@ -958,20 +1023,14 @@ class Connection {
|
|
|
958
1023
|
/**
|
|
959
1024
|
* Called internally.
|
|
960
1025
|
*/
|
|
961
|
-
private fileChange(
|
|
962
|
-
id: string,
|
|
963
|
-
fileName: string,
|
|
964
|
-
size: number | null,
|
|
965
|
-
) {
|
|
1026
|
+
private fileChange(id: string, fileName: string, size: number | null): void {
|
|
966
1027
|
for (const sub of Object.values(this.filesSubscribes)) {
|
|
967
1028
|
if (sub.regId.test(id) && sub.regFilePattern.test(fileName)) {
|
|
968
1029
|
for (const cb of sub.cbs) {
|
|
969
1030
|
try {
|
|
970
1031
|
cb(id, fileName, size);
|
|
971
1032
|
} catch (e) {
|
|
972
|
-
console.error(
|
|
973
|
-
`Error by callback of fileChange: ${e}`,
|
|
974
|
-
);
|
|
1033
|
+
console.error(`Error by callback of fileChange: ${e}`);
|
|
975
1034
|
}
|
|
976
1035
|
}
|
|
977
1036
|
}
|
|
@@ -980,9 +1039,10 @@ class Connection {
|
|
|
980
1039
|
|
|
981
1040
|
/**
|
|
982
1041
|
* Subscribe to changes of the files.
|
|
983
|
-
*
|
|
984
|
-
* @param
|
|
985
|
-
* @param
|
|
1042
|
+
*
|
|
1043
|
+
* @param id The ioBroker state ID for meta-object. Could be a pattern
|
|
1044
|
+
* @param filePattern Pattern or file name, like 'main/*' or 'main/visViews.json`
|
|
1045
|
+
* @param cb The callback.
|
|
986
1046
|
*/
|
|
987
1047
|
async subscribeFiles(
|
|
988
1048
|
/** The ioBroker state ID for meta-object. Could be a pattern */
|
|
@@ -991,7 +1051,7 @@ class Connection {
|
|
|
991
1051
|
filePattern: string | string[],
|
|
992
1052
|
/** The callback. */
|
|
993
1053
|
cb: ioBroker.FileChangeHandler,
|
|
994
|
-
) {
|
|
1054
|
+
): Promise<void> {
|
|
995
1055
|
if (typeof cb !== 'function') {
|
|
996
1056
|
throw new Error('The state change handler must be a function!');
|
|
997
1057
|
}
|
|
@@ -1015,26 +1075,23 @@ class Connection {
|
|
|
1015
1075
|
|
|
1016
1076
|
toSubscribe.push(pattern);
|
|
1017
1077
|
} else {
|
|
1018
|
-
!this.filesSubscribes[key].cbs.includes(cb) &&
|
|
1019
|
-
this.filesSubscribes[key].cbs.push(cb);
|
|
1078
|
+
!this.filesSubscribes[key].cbs.includes(cb) && this.filesSubscribes[key].cbs.push(cb);
|
|
1020
1079
|
}
|
|
1021
1080
|
}
|
|
1022
1081
|
if (this.connected && toSubscribe.length) {
|
|
1023
1082
|
this._socket.emit('subscribeFiles', id, toSubscribe);
|
|
1024
1083
|
}
|
|
1084
|
+
return Promise.resolve();
|
|
1025
1085
|
}
|
|
1026
1086
|
|
|
1027
1087
|
/**
|
|
1028
1088
|
* Unsubscribes the given callback from changes of files.
|
|
1029
|
-
*
|
|
1030
|
-
* @param
|
|
1031
|
-
* @param
|
|
1089
|
+
*
|
|
1090
|
+
* @param id The ioBroker state ID.
|
|
1091
|
+
* @param filePattern Pattern or file name, like 'main/*' or 'main/visViews.json`
|
|
1092
|
+
* @param cb The callback.
|
|
1032
1093
|
*/
|
|
1033
|
-
unsubscribeFiles(
|
|
1034
|
-
id: string,
|
|
1035
|
-
filePattern: string,
|
|
1036
|
-
cb?: ioBroker.FileChangeHandler,
|
|
1037
|
-
): void {
|
|
1094
|
+
unsubscribeFiles(id: string, filePattern: string, cb?: ioBroker.FileChangeHandler): void {
|
|
1038
1095
|
let filePatterns: string[];
|
|
1039
1096
|
if (Array.isArray(filePattern)) {
|
|
1040
1097
|
filePatterns = filePattern;
|
|
@@ -1056,8 +1113,7 @@ class Connection {
|
|
|
1056
1113
|
|
|
1057
1114
|
if (!sub.cbs || !sub.cbs.length) {
|
|
1058
1115
|
delete this.filesSubscribes[key];
|
|
1059
|
-
this.connected &&
|
|
1060
|
-
toUnsubscribe.push(pattern);
|
|
1116
|
+
this.connected && toUnsubscribe.push(pattern);
|
|
1061
1117
|
}
|
|
1062
1118
|
}
|
|
1063
1119
|
}
|
|
@@ -1070,10 +1126,7 @@ class Connection {
|
|
|
1070
1126
|
/**
|
|
1071
1127
|
* Called internally.
|
|
1072
1128
|
*/
|
|
1073
|
-
private objectChange(
|
|
1074
|
-
id: string,
|
|
1075
|
-
obj: ioBroker.Object | null,
|
|
1076
|
-
) {
|
|
1129
|
+
private objectChange(id: string, obj: ioBroker.Object | null): void {
|
|
1077
1130
|
// update main.objects cache
|
|
1078
1131
|
if (!this.objects) {
|
|
1079
1132
|
return;
|
|
@@ -1112,24 +1165,25 @@ class Connection {
|
|
|
1112
1165
|
});
|
|
1113
1166
|
|
|
1114
1167
|
if (changed && this.props.onObjectChange) {
|
|
1115
|
-
this.props.onObjectChange(id, obj);
|
|
1168
|
+
void this.props.onObjectChange(id, obj);
|
|
1116
1169
|
}
|
|
1117
1170
|
}
|
|
1118
1171
|
|
|
1119
1172
|
/**
|
|
1120
1173
|
* Called internally.
|
|
1121
1174
|
*/
|
|
1122
|
-
private stateChange(
|
|
1123
|
-
id: string,
|
|
1124
|
-
state: ioBroker.State | null,
|
|
1125
|
-
): void {
|
|
1175
|
+
private stateChange(id: string, state: ioBroker.State | null): void {
|
|
1126
1176
|
for (const task in this.statesSubscribes) {
|
|
1127
|
-
if (
|
|
1177
|
+
if (
|
|
1178
|
+
Object.prototype.hasOwnProperty.call(this.statesSubscribes, task) &&
|
|
1179
|
+
this.statesSubscribes[task].reg.test(id)
|
|
1180
|
+
) {
|
|
1128
1181
|
this.statesSubscribes[task].cbs.forEach(cb => {
|
|
1129
1182
|
try {
|
|
1130
|
-
(cb as ioBroker.StateChangeHandler)(id, state);
|
|
1183
|
+
void (cb as ioBroker.StateChangeHandler)(id, state);
|
|
1131
1184
|
} catch (e) {
|
|
1132
|
-
|
|
1185
|
+
const knownError = e as Error;
|
|
1186
|
+
console.error(`Error by callback of stateChange: ${knownError?.message}`);
|
|
1133
1187
|
}
|
|
1134
1188
|
});
|
|
1135
1189
|
}
|
|
@@ -1138,11 +1192,12 @@ class Connection {
|
|
|
1138
1192
|
|
|
1139
1193
|
/**
|
|
1140
1194
|
* Called internally.
|
|
1141
|
-
*
|
|
1142
|
-
* @param
|
|
1143
|
-
* @param
|
|
1195
|
+
*
|
|
1196
|
+
* @param messageType The message type
|
|
1197
|
+
* @param sourceInstance The source instance
|
|
1198
|
+
* @param data Payload
|
|
1144
1199
|
*/
|
|
1145
|
-
instanceMessage(messageType: string, sourceInstance: string, data: Record<string, any>) {
|
|
1200
|
+
instanceMessage(messageType: string, sourceInstance: string, data: Record<string, any>): void {
|
|
1146
1201
|
if (this._instanceSubscriptions[sourceInstance]) {
|
|
1147
1202
|
this._instanceSubscriptions[sourceInstance].forEach(sub => {
|
|
1148
1203
|
if (sub.messageType === messageType) {
|
|
@@ -1154,15 +1209,13 @@ class Connection {
|
|
|
1154
1209
|
|
|
1155
1210
|
/**
|
|
1156
1211
|
* Gets all states.
|
|
1212
|
+
*
|
|
1213
|
+
* @param pattern The pattern to filter states
|
|
1214
|
+
* @param disableProgressUpdate Don't call onProgress() when done
|
|
1157
1215
|
*/
|
|
1158
|
-
getStates(
|
|
1159
|
-
/** The pattern to filter states. */
|
|
1160
|
-
pattern?: string | boolean,
|
|
1161
|
-
/** don't call onProgress() when done */
|
|
1162
|
-
disableProgressUpdate?: boolean,
|
|
1163
|
-
): Promise<Record<string, ioBroker.State>> {
|
|
1216
|
+
getStates(pattern?: string | boolean, disableProgressUpdate?: boolean): Promise<Record<string, ioBroker.State>> {
|
|
1164
1217
|
if (!this.connected) {
|
|
1165
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1218
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1166
1219
|
}
|
|
1167
1220
|
|
|
1168
1221
|
if (typeof pattern === 'boolean') {
|
|
@@ -1174,83 +1227,79 @@ class Connection {
|
|
|
1174
1227
|
this._socket.emit('getStates', pattern, (err: string | null, res: Record<string, ioBroker.State>) => {
|
|
1175
1228
|
this.states = res;
|
|
1176
1229
|
!disableProgressUpdate && this.onProgress(PROGRESS.STATES_LOADED);
|
|
1177
|
-
err ? reject(err) : resolve(this.states);
|
|
1230
|
+
err ? reject(new Error(err)) : resolve(this.states);
|
|
1178
1231
|
});
|
|
1179
1232
|
});
|
|
1180
1233
|
}
|
|
1181
1234
|
|
|
1182
1235
|
/**
|
|
1183
1236
|
* Gets the given state.
|
|
1237
|
+
*
|
|
1238
|
+
* @param id The state ID
|
|
1184
1239
|
*/
|
|
1185
|
-
getState(
|
|
1186
|
-
/** The state ID. */
|
|
1187
|
-
id: string,
|
|
1188
|
-
): Promise<ioBroker.State | null> {
|
|
1240
|
+
getState(id: string): Promise<ioBroker.State | null> {
|
|
1189
1241
|
if (!this.connected) {
|
|
1190
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1242
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1191
1243
|
}
|
|
1192
1244
|
if (id && id === this.ignoreState) {
|
|
1193
|
-
return Promise.resolve(this.simStates[id] || { val: null, ack: true } as ioBroker.State);
|
|
1245
|
+
return Promise.resolve(this.simStates[id] || ({ val: null, ack: true } as ioBroker.State));
|
|
1194
1246
|
}
|
|
1195
1247
|
return new Promise((resolve, reject) => {
|
|
1196
1248
|
this._socket.emit('getState', id, (err: string | null, state: ioBroker.State) =>
|
|
1197
|
-
|
|
1249
|
+
err ? reject(new Error(err)) : resolve(state),
|
|
1250
|
+
);
|
|
1198
1251
|
});
|
|
1199
1252
|
}
|
|
1200
1253
|
|
|
1201
1254
|
/**
|
|
1202
|
-
* @deprecated since js-controller 5.0. Use files instead.
|
|
1203
1255
|
* Get the given binary state.
|
|
1256
|
+
*
|
|
1257
|
+
* @deprecated since js-controller 5.0. Use files instead.
|
|
1258
|
+
* @param id The state ID.
|
|
1204
1259
|
*/
|
|
1205
|
-
getBinaryState(
|
|
1206
|
-
/** The state ID. */
|
|
1207
|
-
id: string,
|
|
1208
|
-
): Promise<string> {
|
|
1260
|
+
getBinaryState(id: string): Promise<string> {
|
|
1209
1261
|
if (!this.connected) {
|
|
1210
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1262
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1211
1263
|
}
|
|
1212
1264
|
|
|
1213
1265
|
// the data will come in base64
|
|
1214
1266
|
return new Promise((resolve, reject) => {
|
|
1215
1267
|
this._socket.emit('getBinaryState', id, (err: string | null, base64: string) =>
|
|
1216
|
-
|
|
1268
|
+
err ? reject(new Error(err)) : resolve(base64),
|
|
1269
|
+
);
|
|
1217
1270
|
});
|
|
1218
1271
|
}
|
|
1219
1272
|
|
|
1220
1273
|
/**
|
|
1221
|
-
* @deprecated since js-controller 5.0. Use files instead.
|
|
1222
1274
|
* Set the given binary state.
|
|
1275
|
+
*
|
|
1276
|
+
* @deprecated since js-controller 5.0. Use files instead.
|
|
1277
|
+
* @param id The state ID.
|
|
1278
|
+
* @param base64 The Base64 encoded binary data.
|
|
1223
1279
|
*/
|
|
1224
|
-
setBinaryState(
|
|
1225
|
-
/** The state ID. */
|
|
1226
|
-
id: string,
|
|
1227
|
-
/** The Base64 encoded binary data. */
|
|
1228
|
-
base64: string,
|
|
1229
|
-
): Promise<void> {
|
|
1280
|
+
setBinaryState(id: string, base64: string): Promise<void> {
|
|
1230
1281
|
if (!this.connected) {
|
|
1231
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1282
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1232
1283
|
}
|
|
1233
1284
|
|
|
1234
1285
|
// the data will come in base64
|
|
1235
1286
|
return new Promise((resolve, reject) => {
|
|
1236
1287
|
this._socket.emit('setBinaryState', id, base64, (err: string | null) =>
|
|
1237
|
-
|
|
1288
|
+
err ? reject(new Error(err)) : resolve(),
|
|
1289
|
+
);
|
|
1238
1290
|
});
|
|
1239
1291
|
}
|
|
1240
1292
|
|
|
1241
1293
|
/**
|
|
1242
1294
|
* Sets the given state value.
|
|
1295
|
+
*
|
|
1296
|
+
* @param id The state ID
|
|
1297
|
+
* @param val The state value
|
|
1298
|
+
* @param ack The acknowledgment flag
|
|
1243
1299
|
*/
|
|
1244
|
-
setState(
|
|
1245
|
-
/** The state ID. */
|
|
1246
|
-
id: string,
|
|
1247
|
-
/** The state value. */
|
|
1248
|
-
val: string | number | boolean | ioBroker.SettableState | null,
|
|
1249
|
-
/** The acknowledgment flag. */
|
|
1250
|
-
ack?: boolean,
|
|
1251
|
-
): Promise<void> {
|
|
1300
|
+
setState(id: string, val: string | number | boolean | ioBroker.SettableState | null, ack?: boolean): Promise<void> {
|
|
1252
1301
|
if (!this.connected) {
|
|
1253
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1302
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1254
1303
|
}
|
|
1255
1304
|
|
|
1256
1305
|
// extra handling for "nothing_selected" state for vis
|
|
@@ -1276,11 +1325,9 @@ class Connection {
|
|
|
1276
1325
|
if (this.statesSubscribes[id]) {
|
|
1277
1326
|
for (const cb of this.statesSubscribes[id].cbs) {
|
|
1278
1327
|
try {
|
|
1279
|
-
(cb as ioBroker.StateChangeHandler)(id, state
|
|
1328
|
+
void (cb as ioBroker.StateChangeHandler)(id, state);
|
|
1280
1329
|
} catch (e) {
|
|
1281
|
-
console.error(
|
|
1282
|
-
`Error by callback of stateChanged: ${e}`,
|
|
1283
|
-
);
|
|
1330
|
+
console.error(`Error by callback of stateChanged: ${e}`);
|
|
1284
1331
|
}
|
|
1285
1332
|
}
|
|
1286
1333
|
}
|
|
@@ -1289,50 +1336,50 @@ class Connection {
|
|
|
1289
1336
|
}
|
|
1290
1337
|
|
|
1291
1338
|
return new Promise((resolve, reject) => {
|
|
1292
|
-
this._socket.emit('setState', id, val, (err: string | null) =>
|
|
1293
|
-
(err ? reject(err) : resolve()));
|
|
1339
|
+
this._socket.emit('setState', id, val, (err: string | null) => (err ? reject(new Error(err)) : resolve()));
|
|
1294
1340
|
});
|
|
1295
1341
|
}
|
|
1296
1342
|
|
|
1297
1343
|
/**
|
|
1298
1344
|
* Gets all objects.
|
|
1345
|
+
*
|
|
1346
|
+
* @param update Set to true to retrieve all objects from the server (instead of using the local cache)
|
|
1347
|
+
* @param disableProgressUpdate Don't call onProgress() when done
|
|
1299
1348
|
*/
|
|
1300
|
-
getObjects(
|
|
1301
|
-
/** Set to true to retrieve all objects from the server (instead of using the local cache). */
|
|
1302
|
-
update?: boolean,
|
|
1303
|
-
/** don't call onProgress() when done */
|
|
1304
|
-
disableProgressUpdate?: boolean,
|
|
1305
|
-
): Promise<Record<string, ioBroker.Object>> {
|
|
1349
|
+
getObjects(update?: boolean, disableProgressUpdate?: boolean): Promise<Record<string, ioBroker.Object>> {
|
|
1306
1350
|
if (!this.connected) {
|
|
1307
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1351
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1308
1352
|
}
|
|
1309
1353
|
return new Promise((resolve, reject) => {
|
|
1310
1354
|
if (!update && this.objects) {
|
|
1311
1355
|
resolve(this.objects);
|
|
1312
1356
|
} else {
|
|
1313
|
-
this._socket.emit(
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1357
|
+
this._socket.emit(
|
|
1358
|
+
Connection.isWeb() ? 'getObjects' : 'getAllObjects',
|
|
1359
|
+
(err: string | null, res: Record<string, ioBroker.Object>) => {
|
|
1360
|
+
this.objects = res;
|
|
1361
|
+
disableProgressUpdate && this.onProgress(PROGRESS.OBJECTS_LOADED);
|
|
1362
|
+
err ? reject(new Error(err)) : resolve(this.objects);
|
|
1363
|
+
},
|
|
1364
|
+
);
|
|
1318
1365
|
}
|
|
1319
1366
|
});
|
|
1320
1367
|
}
|
|
1321
1368
|
|
|
1322
1369
|
/**
|
|
1323
1370
|
* Gets objects by list of IDs.
|
|
1371
|
+
*
|
|
1372
|
+
* @param list Array of object IDs to retrieve
|
|
1324
1373
|
*/
|
|
1325
|
-
getObjectsById(
|
|
1326
|
-
/** Array of object IDs to retrieve. */
|
|
1327
|
-
list: string[],
|
|
1328
|
-
): Promise<Record<string, ioBroker.Object>> {
|
|
1374
|
+
getObjectsById(list: string[]): Promise<Record<string, ioBroker.Object>> {
|
|
1329
1375
|
if (!this.connected) {
|
|
1330
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1376
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1331
1377
|
}
|
|
1332
1378
|
|
|
1333
1379
|
return new Promise((resolve, reject) => {
|
|
1334
1380
|
this._socket.emit('getObjects', list, (err: string | null, res: Record<string, ioBroker.Object>) =>
|
|
1335
|
-
|
|
1381
|
+
err ? reject(new Error(err)) : resolve(res),
|
|
1382
|
+
);
|
|
1336
1383
|
});
|
|
1337
1384
|
}
|
|
1338
1385
|
|
|
@@ -1350,11 +1397,16 @@ class Connection {
|
|
|
1350
1397
|
// re-subscribe states
|
|
1351
1398
|
const ids = Object.keys(this.statesSubscribes);
|
|
1352
1399
|
ids.forEach(id => this._socket.emit('subscribe', id));
|
|
1353
|
-
ids.length &&
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1400
|
+
ids.length &&
|
|
1401
|
+
this._socket.emit(
|
|
1402
|
+
Connection.isWeb() ? 'getStates' : 'getForeignStates',
|
|
1403
|
+
ids,
|
|
1404
|
+
(err: string | null, states: Record<string, ioBroker.State>) => {
|
|
1405
|
+
err && console.error(`Cannot getForeignStates: ${JSON.stringify(err)}`);
|
|
1406
|
+
// inform about states
|
|
1407
|
+
states && Object.keys(states).forEach(id => this.stateChange(id, states[id]));
|
|
1408
|
+
},
|
|
1409
|
+
);
|
|
1358
1410
|
} else if (!isEnable && this.subscribed) {
|
|
1359
1411
|
this.subscribed = false;
|
|
1360
1412
|
// un-subscribe objects
|
|
@@ -1370,53 +1422,51 @@ class Connection {
|
|
|
1370
1422
|
|
|
1371
1423
|
/**
|
|
1372
1424
|
* Requests log updates.
|
|
1425
|
+
*
|
|
1426
|
+
* @param isEnabled Set to true to get logs
|
|
1373
1427
|
*/
|
|
1374
|
-
requireLog(
|
|
1375
|
-
/** Set to true to get logs. */
|
|
1376
|
-
isEnabled: boolean,
|
|
1377
|
-
): Promise<void> {
|
|
1428
|
+
requireLog(isEnabled: boolean): Promise<void> {
|
|
1378
1429
|
if (!this.connected) {
|
|
1379
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1430
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1380
1431
|
}
|
|
1381
1432
|
return new Promise((resolve, reject) => {
|
|
1382
1433
|
this._socket.emit('requireLog', isEnabled, (err: string | null) =>
|
|
1383
|
-
|
|
1434
|
+
err ? reject(new Error(err)) : resolve(),
|
|
1435
|
+
);
|
|
1384
1436
|
});
|
|
1385
1437
|
}
|
|
1386
1438
|
|
|
1387
1439
|
/**
|
|
1388
1440
|
* Deletes the given object.
|
|
1441
|
+
*
|
|
1442
|
+
* @param id The object ID
|
|
1443
|
+
* @param maintenance Force deletion of non-conform IDs
|
|
1389
1444
|
*/
|
|
1390
|
-
delObject(
|
|
1391
|
-
/** The object ID. */
|
|
1392
|
-
id: string,
|
|
1393
|
-
/** Force deletion of non-conform IDs. */
|
|
1394
|
-
maintenance?: boolean,
|
|
1395
|
-
): Promise<void> {
|
|
1445
|
+
delObject(id: string, maintenance?: boolean): Promise<void> {
|
|
1396
1446
|
if (!this.connected) {
|
|
1397
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1447
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1398
1448
|
}
|
|
1399
1449
|
return new Promise((resolve, reject) => {
|
|
1400
1450
|
this._socket.emit('delObject', id, { maintenance: !!maintenance }, (err: string | null) =>
|
|
1401
|
-
|
|
1451
|
+
err ? reject(new Error(err)) : resolve(),
|
|
1452
|
+
);
|
|
1402
1453
|
});
|
|
1403
1454
|
}
|
|
1404
1455
|
|
|
1405
1456
|
/**
|
|
1406
1457
|
* Deletes the given object and all its children.
|
|
1458
|
+
*
|
|
1459
|
+
* @param id The object ID
|
|
1460
|
+
* @param maintenance Force deletion of non-conform IDs
|
|
1407
1461
|
*/
|
|
1408
|
-
delObjects(
|
|
1409
|
-
/** The object ID. */
|
|
1410
|
-
id: string,
|
|
1411
|
-
/** Force deletion of non-conform IDs. */
|
|
1412
|
-
maintenance?: boolean,
|
|
1413
|
-
): Promise<void> {
|
|
1462
|
+
delObjects(id: string, maintenance?: boolean): Promise<void> {
|
|
1414
1463
|
if (!this.connected) {
|
|
1415
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1464
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1416
1465
|
}
|
|
1417
1466
|
return new Promise((resolve, reject) => {
|
|
1418
1467
|
this._socket.emit('delObjects', id, { maintenance: !!maintenance }, (err: string | null) =>
|
|
1419
|
-
|
|
1468
|
+
err ? reject(new Error(err)) : resolve(),
|
|
1469
|
+
);
|
|
1420
1470
|
});
|
|
1421
1471
|
}
|
|
1422
1472
|
|
|
@@ -1425,11 +1475,11 @@ class Connection {
|
|
|
1425
1475
|
*/
|
|
1426
1476
|
setObject(id: string, obj: ioBroker.SettableObject): Promise<void> {
|
|
1427
1477
|
if (!this.connected) {
|
|
1428
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1478
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1429
1479
|
}
|
|
1430
1480
|
|
|
1431
1481
|
if (!obj) {
|
|
1432
|
-
return Promise.reject('Null object is not allowed');
|
|
1482
|
+
return Promise.reject(new Error('Null object is not allowed'));
|
|
1433
1483
|
}
|
|
1434
1484
|
|
|
1435
1485
|
obj = JSON.parse(JSON.stringify(obj));
|
|
@@ -1445,8 +1495,7 @@ class Connection {
|
|
|
1445
1495
|
}
|
|
1446
1496
|
|
|
1447
1497
|
return new Promise((resolve, reject) => {
|
|
1448
|
-
this._socket.emit('setObject', id, obj, (err: string | null) =>
|
|
1449
|
-
(err ? reject(err) : resolve()));
|
|
1498
|
+
this._socket.emit('setObject', id, obj, (err: string | null) => (err ? reject(new Error(err)) : resolve()));
|
|
1450
1499
|
});
|
|
1451
1500
|
}
|
|
1452
1501
|
|
|
@@ -1455,7 +1504,7 @@ class Connection {
|
|
|
1455
1504
|
*/
|
|
1456
1505
|
getObject(id: string): Promise<ioBroker.Object> {
|
|
1457
1506
|
if (!this.connected) {
|
|
1458
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1507
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1459
1508
|
}
|
|
1460
1509
|
if (id && id === this.ignoreState) {
|
|
1461
1510
|
return Promise.resolve({
|
|
@@ -1474,19 +1523,18 @@ class Connection {
|
|
|
1474
1523
|
|
|
1475
1524
|
return new Promise((resolve, reject) => {
|
|
1476
1525
|
this._socket.emit('getObject', id, (err: string | null, obj: ioBroker.Object) =>
|
|
1477
|
-
|
|
1526
|
+
err ? reject(new Error(err)) : resolve(obj),
|
|
1527
|
+
);
|
|
1478
1528
|
});
|
|
1479
1529
|
}
|
|
1480
1530
|
|
|
1481
1531
|
/**
|
|
1482
1532
|
* Get all instances of the given adapter or all instances of all adapters.
|
|
1533
|
+
*
|
|
1534
|
+
* @param adapter The name of the adapter
|
|
1535
|
+
* @param update Force update
|
|
1483
1536
|
*/
|
|
1484
|
-
getAdapterInstances(
|
|
1485
|
-
/** The name of the adapter. */
|
|
1486
|
-
adapter?: string | boolean,
|
|
1487
|
-
/** Force update. */
|
|
1488
|
-
update?: boolean,
|
|
1489
|
-
): Promise<ioBroker.InstanceObject[]> {
|
|
1537
|
+
getAdapterInstances(adapter?: string | boolean, update?: boolean): Promise<ioBroker.InstanceObject[]> {
|
|
1490
1538
|
if (typeof adapter === 'boolean') {
|
|
1491
1539
|
update = adapter;
|
|
1492
1540
|
adapter = '';
|
|
@@ -1498,7 +1546,7 @@ class Connection {
|
|
|
1498
1546
|
}
|
|
1499
1547
|
|
|
1500
1548
|
if (!this.connected) {
|
|
1501
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1549
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1502
1550
|
}
|
|
1503
1551
|
|
|
1504
1552
|
this._promises[`instances_${adapter}`] = new Promise((resolve, reject) => {
|
|
@@ -1509,17 +1557,23 @@ class Connection {
|
|
|
1509
1557
|
`system.adapter.${adapter ? `${adapter}.` : ''}\u9999`,
|
|
1510
1558
|
'instance',
|
|
1511
1559
|
)
|
|
1512
|
-
.then(items =>
|
|
1513
|
-
|
|
1560
|
+
.then(items =>
|
|
1561
|
+
resolve(Object.keys(items).map(id => fixAdminUI(items[id] as ioBroker.AdapterObject))),
|
|
1562
|
+
)
|
|
1563
|
+
.catch(e => reject(new Error(e)));
|
|
1514
1564
|
}, TIMEOUT_FOR_ADMIN4);
|
|
1515
1565
|
|
|
1516
|
-
this._socket.emit(
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1566
|
+
this._socket.emit(
|
|
1567
|
+
'getAdapterInstances',
|
|
1568
|
+
adapter,
|
|
1569
|
+
(err: string | null, instances: ioBroker.InstanceObject[]) => {
|
|
1570
|
+
if (timeout) {
|
|
1571
|
+
clearTimeout(timeout);
|
|
1572
|
+
timeout = null;
|
|
1573
|
+
err ? reject(new Error(err)) : resolve(instances);
|
|
1574
|
+
}
|
|
1575
|
+
},
|
|
1576
|
+
);
|
|
1523
1577
|
});
|
|
1524
1578
|
|
|
1525
1579
|
return this._promises[`instances_${adapter}`] as Promise<ioBroker.InstanceObject[]>;
|
|
@@ -1527,15 +1581,13 @@ class Connection {
|
|
|
1527
1581
|
|
|
1528
1582
|
/**
|
|
1529
1583
|
* Get adapters with the given name or all adapters.
|
|
1584
|
+
*
|
|
1585
|
+
* @param adapter The name of the adapter
|
|
1586
|
+
* @param update Force update
|
|
1530
1587
|
*/
|
|
1531
|
-
getAdapters(
|
|
1532
|
-
/** The name of the adapter. */
|
|
1533
|
-
adapter?: string | boolean,
|
|
1534
|
-
/** Force update. */
|
|
1535
|
-
update?: boolean,
|
|
1536
|
-
): Promise<ioBroker.AdapterObject[]> {
|
|
1588
|
+
getAdapters(adapter?: string | boolean, update?: boolean): Promise<ioBroker.AdapterObject[]> {
|
|
1537
1589
|
if (Connection.isWeb()) {
|
|
1538
|
-
return Promise.reject('Allowed only in admin');
|
|
1590
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
1539
1591
|
}
|
|
1540
1592
|
|
|
1541
1593
|
if (typeof adapter === 'boolean') {
|
|
@@ -1550,28 +1602,24 @@ class Connection {
|
|
|
1550
1602
|
}
|
|
1551
1603
|
|
|
1552
1604
|
if (!this.connected) {
|
|
1553
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1605
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1554
1606
|
}
|
|
1555
1607
|
|
|
1556
1608
|
this._promises[`adapter_${adapter}`] = new Promise((resolve, reject) => {
|
|
1557
1609
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
1558
1610
|
timeout = null;
|
|
1559
|
-
this.getObjectView(
|
|
1560
|
-
`system.adapter.${adapter}.`,
|
|
1561
|
-
`system.adapter.${adapter}.\u9999`,
|
|
1562
|
-
'adapter',
|
|
1563
|
-
)
|
|
1611
|
+
this.getObjectView(`system.adapter.${adapter}.`, `system.adapter.${adapter}.\u9999`, 'adapter')
|
|
1564
1612
|
.then(items => {
|
|
1565
1613
|
resolve(Object.keys(items).map(id => fixAdminUI(items[id] as ioBroker.AdapterObject)));
|
|
1566
1614
|
})
|
|
1567
|
-
.catch(e => reject(e));
|
|
1615
|
+
.catch(e => reject(new Error(e)));
|
|
1568
1616
|
}, TIMEOUT_FOR_ADMIN4);
|
|
1569
1617
|
|
|
1570
1618
|
this._socket.emit('getAdapters', adapter, (err: string | null, adapters: ioBroker.AdapterObject[]) => {
|
|
1571
1619
|
if (timeout) {
|
|
1572
1620
|
clearTimeout(timeout);
|
|
1573
1621
|
timeout = null;
|
|
1574
|
-
err ? reject(err) : resolve(adapters);
|
|
1622
|
+
err ? reject(new Error(err)) : resolve(adapters);
|
|
1575
1623
|
}
|
|
1576
1624
|
});
|
|
1577
1625
|
});
|
|
@@ -1582,10 +1630,7 @@ class Connection {
|
|
|
1582
1630
|
/**
|
|
1583
1631
|
* Called internally.
|
|
1584
1632
|
*/
|
|
1585
|
-
private _renameGroups(
|
|
1586
|
-
objs: RenameGroupObject[],
|
|
1587
|
-
cb: (err: string | null) => void,
|
|
1588
|
-
) {
|
|
1633
|
+
private _renameGroups(objs: RenameGroupObject[], cb: (err: string | null) => void): void {
|
|
1589
1634
|
if (!objs || !objs.length) {
|
|
1590
1635
|
cb && cb(null);
|
|
1591
1636
|
} else {
|
|
@@ -1607,20 +1652,22 @@ class Connection {
|
|
|
1607
1652
|
|
|
1608
1653
|
/**
|
|
1609
1654
|
* Rename a group.
|
|
1655
|
+
*
|
|
1610
1656
|
* @param id The id.
|
|
1611
|
-
* @param
|
|
1612
|
-
* @param
|
|
1657
|
+
* @param newId The new id.
|
|
1658
|
+
* @param newName The new name.
|
|
1613
1659
|
*/
|
|
1614
1660
|
async renameGroup(id: string, newId: string, newName: ioBroker.StringOrTranslated): Promise<void> {
|
|
1615
1661
|
if (Connection.isWeb()) {
|
|
1616
|
-
return Promise.reject('Allowed only in admin');
|
|
1662
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
1617
1663
|
}
|
|
1618
1664
|
|
|
1619
1665
|
const groups = await this.getGroups(true);
|
|
1620
1666
|
if (groups.length) {
|
|
1621
1667
|
// find all elements
|
|
1622
|
-
const groupsToRename: RenameGroupObject[] = (groups as RenameGroupObject[])
|
|
1623
|
-
|
|
1668
|
+
const groupsToRename: RenameGroupObject[] = (groups as RenameGroupObject[]).filter(group =>
|
|
1669
|
+
group._id.startsWith(`${id}.`),
|
|
1670
|
+
);
|
|
1624
1671
|
|
|
1625
1672
|
groupsToRename.forEach(group => {
|
|
1626
1673
|
group.newId = (newId + group._id.substring(id.length)) as ioBroker.ObjectIDs.Group;
|
|
@@ -1628,7 +1675,8 @@ class Connection {
|
|
|
1628
1675
|
|
|
1629
1676
|
await new Promise((resolve, reject) => {
|
|
1630
1677
|
this._renameGroups(groupsToRename, (err: string | null) =>
|
|
1631
|
-
|
|
1678
|
+
err ? reject(new Error(err)) : resolve(null),
|
|
1679
|
+
);
|
|
1632
1680
|
});
|
|
1633
1681
|
const obj = groups.find(group => group._id === id);
|
|
1634
1682
|
|
|
@@ -1640,8 +1688,7 @@ class Connection {
|
|
|
1640
1688
|
obj.common.name = newName;
|
|
1641
1689
|
}
|
|
1642
1690
|
|
|
1643
|
-
return this.setObject(obj._id, obj)
|
|
1644
|
-
.then(() => this.delObject(id));
|
|
1691
|
+
return this.setObject(obj._id, obj).then(() => this.delObject(id));
|
|
1645
1692
|
}
|
|
1646
1693
|
}
|
|
1647
1694
|
|
|
@@ -1650,36 +1697,31 @@ class Connection {
|
|
|
1650
1697
|
|
|
1651
1698
|
/**
|
|
1652
1699
|
* Sends a message to a specific instance or all instances of some specific adapter.
|
|
1653
|
-
*
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
command: string,
|
|
1660
|
-
/** The message data to send. */
|
|
1661
|
-
data: any,
|
|
1662
|
-
): Promise<{ result?: any; error?: string }> {
|
|
1700
|
+
*
|
|
1701
|
+
* @param instance The instance to send this message to.
|
|
1702
|
+
* @param command Command name of the target instance.
|
|
1703
|
+
* @param data The message data to send.
|
|
1704
|
+
*/
|
|
1705
|
+
sendTo(instance: string, command: string, data: any): Promise<{ result?: any; error?: string }> {
|
|
1663
1706
|
if (!this.connected) {
|
|
1664
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1707
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1665
1708
|
}
|
|
1666
1709
|
return new Promise(resolve => {
|
|
1667
1710
|
this._socket.emit('sendTo', instance, command, data, (result: { result?: any; error?: string }) =>
|
|
1668
|
-
resolve(result)
|
|
1711
|
+
resolve(result),
|
|
1712
|
+
);
|
|
1669
1713
|
});
|
|
1670
1714
|
}
|
|
1671
1715
|
|
|
1672
1716
|
/**
|
|
1673
1717
|
* Extend an object and create it if it might not exist.
|
|
1718
|
+
*
|
|
1719
|
+
* @param id The id.
|
|
1720
|
+
* @param obj The object.
|
|
1674
1721
|
*/
|
|
1675
|
-
extendObject(
|
|
1676
|
-
/** The id. */
|
|
1677
|
-
id: string,
|
|
1678
|
-
/** The object. */
|
|
1679
|
-
obj: ioBroker.PartialObject,
|
|
1680
|
-
): Promise<void> {
|
|
1722
|
+
extendObject(id: string, obj: ioBroker.PartialObject): Promise<void> {
|
|
1681
1723
|
if (!this.connected) {
|
|
1682
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1724
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1683
1725
|
}
|
|
1684
1726
|
|
|
1685
1727
|
obj = JSON.parse(JSON.stringify(obj));
|
|
@@ -1696,7 +1738,8 @@ class Connection {
|
|
|
1696
1738
|
|
|
1697
1739
|
return new Promise((resolve, reject) => {
|
|
1698
1740
|
this._socket.emit('extendObject', id, obj, (err: string | null) =>
|
|
1699
|
-
|
|
1741
|
+
err ? reject(new Error(err)) : resolve(),
|
|
1742
|
+
);
|
|
1700
1743
|
});
|
|
1701
1744
|
}
|
|
1702
1745
|
|
|
@@ -1732,7 +1775,8 @@ class Connection {
|
|
|
1732
1775
|
|
|
1733
1776
|
/**
|
|
1734
1777
|
* Set the handler for standard output of a command.
|
|
1735
|
-
*
|
|
1778
|
+
*
|
|
1779
|
+
* @param handler The handler.
|
|
1736
1780
|
*/
|
|
1737
1781
|
registerCmdStdoutHandler(handler: (id: string, text: string) => void): void {
|
|
1738
1782
|
this.onCmdStdoutHandler = handler;
|
|
@@ -1747,7 +1791,8 @@ class Connection {
|
|
|
1747
1791
|
|
|
1748
1792
|
/**
|
|
1749
1793
|
* Set the handler for standard error of a command.
|
|
1750
|
-
*
|
|
1794
|
+
*
|
|
1795
|
+
* @param handler The handler.
|
|
1751
1796
|
*/
|
|
1752
1797
|
registerCmdStderrHandler(handler: (id: string, text: string) => void): void {
|
|
1753
1798
|
this.onCmdStderrHandler = handler;
|
|
@@ -1756,7 +1801,7 @@ class Connection {
|
|
|
1756
1801
|
/**
|
|
1757
1802
|
* Unset the handler for standard error of a command.
|
|
1758
1803
|
*/
|
|
1759
|
-
unregisterCmdStderrHandler() {
|
|
1804
|
+
unregisterCmdStderrHandler(): void {
|
|
1760
1805
|
this.onCmdStderrHandler = undefined;
|
|
1761
1806
|
}
|
|
1762
1807
|
|
|
@@ -1788,7 +1833,7 @@ class Connection {
|
|
|
1788
1833
|
}
|
|
1789
1834
|
|
|
1790
1835
|
if (!this.connected) {
|
|
1791
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1836
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1792
1837
|
}
|
|
1793
1838
|
|
|
1794
1839
|
this._promises[`enums_${_enum || 'all'}`] = new Promise((resolve, reject) => {
|
|
@@ -1807,8 +1852,10 @@ class Connection {
|
|
|
1807
1852
|
_res[res.rows[i].id] = res.rows[i].value;
|
|
1808
1853
|
}
|
|
1809
1854
|
resolve(_res);
|
|
1855
|
+
} else if (err) {
|
|
1856
|
+
reject(new Error(err));
|
|
1810
1857
|
} else {
|
|
1811
|
-
reject(
|
|
1858
|
+
reject(new Error('Invalid response while getting enums'));
|
|
1812
1859
|
}
|
|
1813
1860
|
},
|
|
1814
1861
|
);
|
|
@@ -1819,10 +1866,11 @@ class Connection {
|
|
|
1819
1866
|
|
|
1820
1867
|
/**
|
|
1821
1868
|
* Query a predefined object view.
|
|
1869
|
+
*
|
|
1822
1870
|
* @param design design - 'system' or other designs like `custom`.
|
|
1823
1871
|
* @param type The type of object.
|
|
1824
1872
|
* @param start The start ID.
|
|
1825
|
-
* @param
|
|
1873
|
+
* @param end The end ID.
|
|
1826
1874
|
*/
|
|
1827
1875
|
getObjectViewCustom(
|
|
1828
1876
|
/** The design: 'system' or other designs like `custom`. */
|
|
@@ -1835,34 +1883,38 @@ class Connection {
|
|
|
1835
1883
|
end?: string,
|
|
1836
1884
|
): Promise<Record<string, ioBroker.Object>> {
|
|
1837
1885
|
return new Promise((resolve, reject) => {
|
|
1838
|
-
this._socket.emit(
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1886
|
+
this._socket.emit(
|
|
1887
|
+
'getObjectView',
|
|
1888
|
+
design,
|
|
1889
|
+
type,
|
|
1890
|
+
{ startkey: start, endkey: end },
|
|
1891
|
+
(err: string | null, res: { rows: { value: ioBroker.Object; id: string }[] }) => {
|
|
1892
|
+
if (!err) {
|
|
1893
|
+
const _res: Record<string, ioBroker.Object> = {};
|
|
1894
|
+
if (res && res.rows) {
|
|
1895
|
+
for (let i = 0; i < res.rows.length; i++) {
|
|
1896
|
+
_res[res.rows[i].id] = res.rows[i].value;
|
|
1897
|
+
}
|
|
1844
1898
|
}
|
|
1899
|
+
resolve(_res);
|
|
1900
|
+
} else {
|
|
1901
|
+
reject(new Error(err));
|
|
1845
1902
|
}
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
reject(err);
|
|
1849
|
-
}
|
|
1850
|
-
});
|
|
1903
|
+
},
|
|
1904
|
+
);
|
|
1851
1905
|
});
|
|
1852
1906
|
}
|
|
1853
1907
|
|
|
1854
1908
|
/**
|
|
1855
1909
|
* Query a predefined object view.
|
|
1910
|
+
*
|
|
1856
1911
|
* @param type The type of object.
|
|
1857
1912
|
* @param start The start ID.
|
|
1858
|
-
* @param
|
|
1913
|
+
* @param end The end ID.
|
|
1859
1914
|
*/
|
|
1860
1915
|
getObjectViewSystem(
|
|
1861
|
-
/** The type of object. */
|
|
1862
1916
|
type: ioBroker.ObjectType,
|
|
1863
|
-
/** The start ID. */
|
|
1864
1917
|
start: string,
|
|
1865
|
-
/** The end ID. */
|
|
1866
1918
|
end?: string,
|
|
1867
1919
|
): Promise<Record<string, ioBroker.Object>> {
|
|
1868
1920
|
return this.getObjectViewCustom('system', type, start, end);
|
|
@@ -1870,31 +1922,30 @@ class Connection {
|
|
|
1870
1922
|
|
|
1871
1923
|
/**
|
|
1872
1924
|
* @deprecated since version 1.1.15, cause parameter order does not match backend
|
|
1925
|
+
*
|
|
1873
1926
|
* Query a predefined object view.
|
|
1874
|
-
* @param
|
|
1875
|
-
* @param
|
|
1876
|
-
* @param
|
|
1877
|
-
* @returns {Promise<Record<string, ioBroker.Object>>}
|
|
1927
|
+
* @param start The start ID.
|
|
1928
|
+
* @param end The end ID.
|
|
1929
|
+
* @param type The type of object.
|
|
1878
1930
|
*/
|
|
1879
1931
|
getObjectView(start: string, end: string, type: ioBroker.ObjectType): Promise<Record<string, ioBroker.Object>> {
|
|
1880
1932
|
if (!this.connected) {
|
|
1881
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1933
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1882
1934
|
}
|
|
1883
1935
|
|
|
1884
1936
|
start = start || '';
|
|
1885
|
-
end
|
|
1937
|
+
end = end || '\u9999';
|
|
1886
1938
|
return this.getObjectViewCustom('system', type, start, end);
|
|
1887
1939
|
}
|
|
1888
1940
|
|
|
1889
1941
|
/**
|
|
1890
1942
|
* Get the stored certificates.
|
|
1943
|
+
*
|
|
1944
|
+
* @param update Force update.
|
|
1891
1945
|
*/
|
|
1892
|
-
getCertificates(
|
|
1893
|
-
/** Force update. */
|
|
1894
|
-
update?: boolean,
|
|
1895
|
-
): Promise<{ name: string; type: 'public' | 'private' | 'chained' | '' }[]> {
|
|
1946
|
+
getCertificates(update?: boolean): Promise<{ name: string; type: 'public' | 'private' | 'chained' | '' }[]> {
|
|
1896
1947
|
if (Connection.isWeb()) {
|
|
1897
|
-
return Promise.reject('Allowed only in admin');
|
|
1948
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
1898
1949
|
}
|
|
1899
1950
|
|
|
1900
1951
|
if (this._promises.cert && !update) {
|
|
@@ -1902,50 +1953,53 @@ class Connection {
|
|
|
1902
1953
|
}
|
|
1903
1954
|
|
|
1904
1955
|
if (!this.connected) {
|
|
1905
|
-
return Promise.reject(NOT_CONNECTED);
|
|
1956
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1906
1957
|
}
|
|
1907
1958
|
|
|
1908
|
-
this._promises.cert = this.getObject('system.certificates')
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1959
|
+
this._promises.cert = this.getObject('system.certificates').then(res => {
|
|
1960
|
+
const certs: { name: string; type: 'public' | 'private' | 'chained' | '' }[] = [];
|
|
1961
|
+
if (res && res.native && res.native.certificates) {
|
|
1962
|
+
Object.keys(res.native.certificates).forEach(c => {
|
|
1963
|
+
const cert: string = res.native.certificates[c];
|
|
1964
|
+
if (!cert) {
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
const _cert: { name: string; type: 'public' | 'private' | 'chained' | '' } = {
|
|
1968
|
+
name: c,
|
|
1969
|
+
type: '',
|
|
1970
|
+
};
|
|
1971
|
+
// If it is a filename, it could be everything
|
|
1972
|
+
if (cert.length < 700 && (cert.includes('/') || cert.includes('\\'))) {
|
|
1973
|
+
if (c.toLowerCase().includes('private')) {
|
|
1974
|
+
_cert.type = 'private';
|
|
1975
|
+
} else if (cert.toLowerCase().includes('private')) {
|
|
1976
|
+
_cert.type = 'private';
|
|
1977
|
+
} else if (c.toLowerCase().includes('public')) {
|
|
1978
|
+
_cert.type = 'public';
|
|
1979
|
+
} else if (cert.toLowerCase().includes('public')) {
|
|
1980
|
+
_cert.type = 'public';
|
|
1916
1981
|
}
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
_cert.type = '
|
|
1929
|
-
} else if (cert.toLowerCase().includes('public')) {
|
|
1930
|
-
_cert.type = 'public';
|
|
1931
|
-
}
|
|
1932
|
-
certs.push(_cert);
|
|
1933
|
-
} else {
|
|
1934
|
-
_cert.type = (cert.substring(0, '-----BEGIN RSA PRIVATE KEY'.length) === '-----BEGIN RSA PRIVATE KEY' || cert.substring(0, '-----BEGIN PRIVATE KEY'.length) === '-----BEGIN PRIVATE KEY') ? 'private' : 'public';
|
|
1935
|
-
|
|
1936
|
-
if (_cert.type === 'public') {
|
|
1937
|
-
const m = cert.split('-----END CERTIFICATE-----');
|
|
1938
|
-
if (m.filter((t: string) => t.replace(/\r\n|\r|\n/, '').trim()).length > 1) {
|
|
1939
|
-
_cert.type = 'chained';
|
|
1940
|
-
}
|
|
1982
|
+
certs.push(_cert);
|
|
1983
|
+
} else {
|
|
1984
|
+
_cert.type =
|
|
1985
|
+
cert.substring(0, '-----BEGIN RSA PRIVATE KEY'.length) === '-----BEGIN RSA PRIVATE KEY' ||
|
|
1986
|
+
cert.substring(0, '-----BEGIN PRIVATE KEY'.length) === '-----BEGIN PRIVATE KEY'
|
|
1987
|
+
? 'private'
|
|
1988
|
+
: 'public';
|
|
1989
|
+
|
|
1990
|
+
if (_cert.type === 'public') {
|
|
1991
|
+
const m = cert.split('-----END CERTIFICATE-----');
|
|
1992
|
+
if (m.filter((t: string) => t.replace(/\r\n|\r|\n/, '').trim()).length > 1) {
|
|
1993
|
+
_cert.type = 'chained';
|
|
1941
1994
|
}
|
|
1942
|
-
|
|
1943
|
-
certs.push(_cert);
|
|
1944
1995
|
}
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1996
|
+
|
|
1997
|
+
certs.push(_cert);
|
|
1998
|
+
}
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
return certs;
|
|
2002
|
+
});
|
|
1949
2003
|
|
|
1950
2004
|
return this._promises.cert;
|
|
1951
2005
|
}
|
|
@@ -1953,21 +2007,17 @@ class Connection {
|
|
|
1953
2007
|
/**
|
|
1954
2008
|
* Get the logs from a host (only for admin connection).
|
|
1955
2009
|
*/
|
|
1956
|
-
getLogs(
|
|
1957
|
-
host: string,
|
|
1958
|
-
linesNumber?: number,
|
|
1959
|
-
): Promise<string[]> {
|
|
2010
|
+
getLogs(host: string, linesNumber?: number): Promise<string[]> {
|
|
1960
2011
|
if (Connection.isWeb()) {
|
|
1961
|
-
return Promise.reject('Allowed only in admin');
|
|
2012
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
1962
2013
|
}
|
|
1963
2014
|
|
|
1964
2015
|
if (!this.connected) {
|
|
1965
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2016
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1966
2017
|
}
|
|
1967
2018
|
|
|
1968
2019
|
return new Promise(resolve => {
|
|
1969
|
-
this._socket.emit('sendToHost', host, 'getLogs', linesNumber || 200, (lines: string[]) =>
|
|
1970
|
-
resolve(lines));
|
|
2020
|
+
this._socket.emit('sendToHost', host, 'getLogs', linesNumber || 200, (lines: string[]) => resolve(lines));
|
|
1971
2021
|
});
|
|
1972
2022
|
}
|
|
1973
2023
|
|
|
@@ -1976,14 +2026,15 @@ class Connection {
|
|
|
1976
2026
|
*/
|
|
1977
2027
|
getLogsFiles(host: string): Promise<string[]> {
|
|
1978
2028
|
if (Connection.isWeb()) {
|
|
1979
|
-
return Promise.reject('Allowed only in admin');
|
|
2029
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
1980
2030
|
}
|
|
1981
2031
|
if (!this.connected) {
|
|
1982
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2032
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1983
2033
|
}
|
|
1984
2034
|
return new Promise((resolve, reject) => {
|
|
1985
2035
|
this._socket.emit('readLogs', host, (err: string | null, files: string[]) =>
|
|
1986
|
-
|
|
2036
|
+
err ? reject(new Error(err)) : resolve(files),
|
|
2037
|
+
);
|
|
1987
2038
|
});
|
|
1988
2039
|
}
|
|
1989
2040
|
|
|
@@ -1992,14 +2043,15 @@ class Connection {
|
|
|
1992
2043
|
*/
|
|
1993
2044
|
delLogs(host: string): Promise<void> {
|
|
1994
2045
|
if (Connection.isWeb()) {
|
|
1995
|
-
return Promise.reject('Allowed only in admin');
|
|
2046
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
1996
2047
|
}
|
|
1997
2048
|
if (!this.connected) {
|
|
1998
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2049
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
1999
2050
|
}
|
|
2000
2051
|
return new Promise((resolve, reject) => {
|
|
2001
2052
|
this._socket.emit('sendToHost', host, 'delLogs', null, (error: string | null) =>
|
|
2002
|
-
|
|
2053
|
+
error ? reject(new Error(error)) : resolve(),
|
|
2054
|
+
);
|
|
2003
2055
|
});
|
|
2004
2056
|
}
|
|
2005
2057
|
|
|
@@ -2008,139 +2060,144 @@ class Connection {
|
|
|
2008
2060
|
*/
|
|
2009
2061
|
readMetaItems(): Promise<ioBroker.MetaObject[]> {
|
|
2010
2062
|
if (!this.connected) {
|
|
2011
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2063
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2012
2064
|
}
|
|
2013
2065
|
return new Promise((resolve, reject) => {
|
|
2014
|
-
this._socket.emit(
|
|
2015
|
-
|
|
2066
|
+
this._socket.emit(
|
|
2067
|
+
'getObjectView',
|
|
2068
|
+
'system',
|
|
2069
|
+
'meta',
|
|
2070
|
+
{ startkey: '', endkey: '\u9999' },
|
|
2071
|
+
(err: string | null, objs: { rows: { value: ioBroker.MetaObject; id: string }[] }) =>
|
|
2072
|
+
err
|
|
2073
|
+
? reject(new Error(err))
|
|
2074
|
+
: resolve(
|
|
2075
|
+
objs.rows &&
|
|
2076
|
+
objs.rows.map((obj: { value: ioBroker.MetaObject; id: string }) => obj.value),
|
|
2077
|
+
),
|
|
2078
|
+
);
|
|
2016
2079
|
});
|
|
2017
2080
|
}
|
|
2018
2081
|
|
|
2019
2082
|
/**
|
|
2020
2083
|
* Read the directory of an adapter.
|
|
2084
|
+
*
|
|
2085
|
+
* @param adapter The adapter name.
|
|
2086
|
+
* @param fileName The directory name.
|
|
2021
2087
|
*/
|
|
2022
|
-
readDir(
|
|
2023
|
-
/** The adapter name. */
|
|
2024
|
-
adapter: string,
|
|
2025
|
-
/** The directory name. */
|
|
2026
|
-
fileName: string,
|
|
2027
|
-
): Promise<ioBroker.ReadDirResult[]> {
|
|
2088
|
+
readDir(adapter: string, fileName: string): Promise<ioBroker.ReadDirResult[]> {
|
|
2028
2089
|
if (!this.connected) {
|
|
2029
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2090
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2030
2091
|
}
|
|
2031
2092
|
return new Promise((resolve, reject) => {
|
|
2032
2093
|
this._socket.emit('readDir', adapter, fileName, (err: string | null, files: ioBroker.ReadDirResult[]) =>
|
|
2033
|
-
|
|
2094
|
+
err ? reject(new Error(err)) : resolve(files),
|
|
2095
|
+
);
|
|
2034
2096
|
});
|
|
2035
2097
|
}
|
|
2036
2098
|
|
|
2037
2099
|
/**
|
|
2038
2100
|
* Read a file of an adapter.
|
|
2101
|
+
*
|
|
2102
|
+
* @param adapter The adapter name.
|
|
2103
|
+
* @param fileName The file name.
|
|
2104
|
+
* @param base64 If it must be a base64 format.
|
|
2039
2105
|
*/
|
|
2040
|
-
readFile(
|
|
2041
|
-
/** The adapter name. */
|
|
2042
|
-
adapter: string,
|
|
2043
|
-
/** The file name. */
|
|
2044
|
-
fileName: string,
|
|
2045
|
-
/** If it must be a base64 format */
|
|
2046
|
-
base64?: boolean,
|
|
2047
|
-
): Promise<string | { data: string; type: string }> {
|
|
2106
|
+
readFile(adapter: string, fileName: string, base64?: boolean): Promise<string | { data: string; type: string }> {
|
|
2048
2107
|
if (!this.connected) {
|
|
2049
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2108
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2050
2109
|
}
|
|
2051
2110
|
return new Promise((resolve, reject) => {
|
|
2052
2111
|
if (!base64) {
|
|
2053
2112
|
this._socket.emit('readFile', adapter, fileName, (err: string | null, data: string, type: string) => {
|
|
2054
|
-
err ? reject(err) : resolve({ data, type });
|
|
2113
|
+
err ? reject(new Error(err)) : resolve({ data, type });
|
|
2055
2114
|
});
|
|
2056
2115
|
} else {
|
|
2057
2116
|
this._socket.emit('readFile64', adapter, fileName, base64, (err: string | null, data: string) =>
|
|
2058
|
-
|
|
2117
|
+
err ? reject(new Error(err)) : resolve(data),
|
|
2118
|
+
);
|
|
2059
2119
|
}
|
|
2060
2120
|
});
|
|
2061
2121
|
}
|
|
2062
2122
|
|
|
2063
2123
|
/**
|
|
2064
2124
|
* Write a file of an adapter.
|
|
2125
|
+
*
|
|
2126
|
+
* @param adapter The adapter name.
|
|
2127
|
+
* @param fileName The file name.
|
|
2128
|
+
* @param data The data (if it's a Buffer, it will be converted to Base64)
|
|
2065
2129
|
*/
|
|
2066
|
-
writeFile64(
|
|
2067
|
-
/** The adapter name. */
|
|
2068
|
-
adapter: string,
|
|
2069
|
-
/** The file name. */
|
|
2070
|
-
fileName: string,
|
|
2071
|
-
/** The data (if it's a Buffer, it will be converted to Base64). */
|
|
2072
|
-
data: Buffer | string,
|
|
2073
|
-
): Promise<void> {
|
|
2130
|
+
writeFile64(adapter: string, fileName: string, data: Buffer | string): Promise<void> {
|
|
2074
2131
|
if (!this.connected) {
|
|
2075
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2132
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2076
2133
|
}
|
|
2077
2134
|
return new Promise((resolve, reject) => {
|
|
2078
2135
|
if (typeof data === 'string') {
|
|
2079
2136
|
this._socket.emit('writeFile', adapter, fileName, data, (err: string | null) =>
|
|
2080
|
-
|
|
2137
|
+
err ? reject(new Error(err)) : resolve(),
|
|
2138
|
+
);
|
|
2081
2139
|
} else {
|
|
2082
2140
|
const base64 = btoa(
|
|
2083
|
-
new Uint8Array(data)
|
|
2084
|
-
.reduce((_data, byte) => _data + String.fromCharCode(byte), ''),
|
|
2141
|
+
new Uint8Array(data).reduce((_data, byte) => _data + String.fromCharCode(byte), ''),
|
|
2085
2142
|
);
|
|
2086
2143
|
|
|
2087
2144
|
this._socket.emit('writeFile64', adapter, fileName, base64, (err: string | null) =>
|
|
2088
|
-
|
|
2145
|
+
err ? reject(new Error(err)) : resolve(),
|
|
2146
|
+
);
|
|
2089
2147
|
}
|
|
2090
2148
|
});
|
|
2091
2149
|
}
|
|
2092
2150
|
|
|
2093
2151
|
/**
|
|
2094
2152
|
* Delete a file of an adapter.
|
|
2153
|
+
*
|
|
2154
|
+
* @param adapter The adapter name.
|
|
2155
|
+
* @param fileName The file name.
|
|
2095
2156
|
*/
|
|
2096
|
-
deleteFile(
|
|
2097
|
-
/** The adapter name. */
|
|
2098
|
-
adapter: string,
|
|
2099
|
-
/** The file name. */
|
|
2100
|
-
fileName: string,
|
|
2101
|
-
): Promise<void> {
|
|
2157
|
+
deleteFile(adapter: string, fileName: string): Promise<void> {
|
|
2102
2158
|
if (!this.connected) {
|
|
2103
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2159
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2104
2160
|
}
|
|
2105
2161
|
return new Promise((resolve, reject) => {
|
|
2106
2162
|
this._socket.emit('unlink', adapter, fileName, (err: string | null) =>
|
|
2107
|
-
|
|
2163
|
+
err ? reject(new Error(err)) : resolve(),
|
|
2164
|
+
);
|
|
2108
2165
|
});
|
|
2109
2166
|
}
|
|
2110
2167
|
|
|
2111
2168
|
/**
|
|
2112
2169
|
* Delete a folder of an adapter.
|
|
2113
2170
|
* All files in folder will be deleted.
|
|
2171
|
+
*
|
|
2172
|
+
* @param adapter The adapter name.
|
|
2173
|
+
* @param folderName The folder name.
|
|
2114
2174
|
*/
|
|
2115
|
-
deleteFolder(
|
|
2116
|
-
/** The adapter name. */
|
|
2117
|
-
adapter: string,
|
|
2118
|
-
/** The file name. */
|
|
2119
|
-
folderName: string,
|
|
2120
|
-
): Promise<void> {
|
|
2175
|
+
deleteFolder(adapter: string, folderName: string): Promise<void> {
|
|
2121
2176
|
if (!this.connected) {
|
|
2122
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2177
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2123
2178
|
}
|
|
2124
2179
|
return new Promise((resolve, reject) => {
|
|
2125
2180
|
this._socket.emit('deleteFolder', adapter, folderName, (err: string | null) =>
|
|
2126
|
-
|
|
2181
|
+
err ? reject(new Error(err)) : resolve(),
|
|
2182
|
+
);
|
|
2127
2183
|
});
|
|
2128
2184
|
}
|
|
2129
2185
|
|
|
2130
2186
|
/**
|
|
2131
2187
|
* Get the list of all hosts.
|
|
2132
|
-
*
|
|
2188
|
+
*
|
|
2189
|
+
* @param update Force update.
|
|
2133
2190
|
*/
|
|
2134
2191
|
getHosts(update?: boolean): Promise<ioBroker.HostObject[]> {
|
|
2135
2192
|
if (Connection.isWeb()) {
|
|
2136
|
-
return Promise.reject('Allowed only in admin');
|
|
2193
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2137
2194
|
}
|
|
2138
2195
|
if (!update && this._promises.hosts) {
|
|
2139
2196
|
return this._promises.hosts;
|
|
2140
2197
|
}
|
|
2141
2198
|
|
|
2142
2199
|
if (!this.connected) {
|
|
2143
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2200
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2144
2201
|
}
|
|
2145
2202
|
|
|
2146
2203
|
this._promises.hosts = new Promise((resolve, reject) => {
|
|
@@ -2149,9 +2206,9 @@ class Connection {
|
|
|
2149
2206
|
'system',
|
|
2150
2207
|
'host',
|
|
2151
2208
|
{ startkey: 'system.host.', endkey: 'system.host.\u9999' },
|
|
2152
|
-
(err: string | null, doc: { rows: { value: ioBroker.HostObject; id: string }[]}) => {
|
|
2209
|
+
(err: string | null, doc: { rows: { value: ioBroker.HostObject; id: string }[] }) => {
|
|
2153
2210
|
if (err) {
|
|
2154
|
-
reject(err);
|
|
2211
|
+
reject(new Error(err));
|
|
2155
2212
|
} else {
|
|
2156
2213
|
resolve(doc.rows.map(item => item.value));
|
|
2157
2214
|
}
|
|
@@ -2164,19 +2221,18 @@ class Connection {
|
|
|
2164
2221
|
|
|
2165
2222
|
/**
|
|
2166
2223
|
* Get the list of all users.
|
|
2224
|
+
*
|
|
2225
|
+
* @param update Force update.
|
|
2167
2226
|
*/
|
|
2168
|
-
getUsers(
|
|
2169
|
-
/** Force update. */
|
|
2170
|
-
update?: boolean,
|
|
2171
|
-
): Promise<ioBroker.UserObject[]> {
|
|
2227
|
+
getUsers(update?: boolean): Promise<ioBroker.UserObject[]> {
|
|
2172
2228
|
if (Connection.isWeb()) {
|
|
2173
|
-
return Promise.reject('Allowed only in admin');
|
|
2229
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2174
2230
|
}
|
|
2175
2231
|
if (!update && this._promises.users) {
|
|
2176
2232
|
return this._promises.users;
|
|
2177
2233
|
}
|
|
2178
2234
|
if (!this.connected) {
|
|
2179
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2235
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2180
2236
|
}
|
|
2181
2237
|
|
|
2182
2238
|
this._promises.users = new Promise((resolve, reject) => {
|
|
@@ -2187,7 +2243,7 @@ class Connection {
|
|
|
2187
2243
|
{ startkey: 'system.user.', endkey: 'system.user.\u9999' },
|
|
2188
2244
|
(err: string | null, doc: { rows: { value: ioBroker.UserObject; id: string }[] }) => {
|
|
2189
2245
|
if (err) {
|
|
2190
|
-
reject(err);
|
|
2246
|
+
reject(new Error(err));
|
|
2191
2247
|
} else {
|
|
2192
2248
|
resolve(doc.rows.map(item => item.value));
|
|
2193
2249
|
}
|
|
@@ -2200,16 +2256,15 @@ class Connection {
|
|
|
2200
2256
|
|
|
2201
2257
|
/**
|
|
2202
2258
|
* Get the list of all groups.
|
|
2259
|
+
*
|
|
2260
|
+
* @param update Force update.
|
|
2203
2261
|
*/
|
|
2204
|
-
getGroups(
|
|
2205
|
-
/** Force update. */
|
|
2206
|
-
update?: boolean,
|
|
2207
|
-
): Promise<ioBroker.GroupObject[]> {
|
|
2262
|
+
getGroups(update?: boolean): Promise<ioBroker.GroupObject[]> {
|
|
2208
2263
|
if (!update && this._promises.groups) {
|
|
2209
2264
|
return this._promises.groups;
|
|
2210
2265
|
}
|
|
2211
2266
|
if (!this.connected) {
|
|
2212
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2267
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2213
2268
|
}
|
|
2214
2269
|
|
|
2215
2270
|
this._promises.groups = new Promise((resolve, reject) => {
|
|
@@ -2220,7 +2275,7 @@ class Connection {
|
|
|
2220
2275
|
{ startkey: 'system.group.', endkey: 'system.group.\u9999' },
|
|
2221
2276
|
(err: string | null, doc: { rows: { value: ioBroker.GroupObject; id: string }[] }) => {
|
|
2222
2277
|
if (err) {
|
|
2223
|
-
reject(err);
|
|
2278
|
+
reject(new Error(err));
|
|
2224
2279
|
} else {
|
|
2225
2280
|
resolve(doc.rows.map(item => item.value));
|
|
2226
2281
|
}
|
|
@@ -2233,16 +2288,14 @@ class Connection {
|
|
|
2233
2288
|
|
|
2234
2289
|
/**
|
|
2235
2290
|
* Get the host information.
|
|
2291
|
+
*
|
|
2292
|
+
* @param host The host name.
|
|
2293
|
+
* @param update Force update.
|
|
2294
|
+
* @param timeoutMs Optional read timeout.
|
|
2236
2295
|
*/
|
|
2237
|
-
getHostInfo(
|
|
2238
|
-
host: string,
|
|
2239
|
-
/** Force update. */
|
|
2240
|
-
update?: boolean,
|
|
2241
|
-
/** optional read timeout. */
|
|
2242
|
-
timeoutMs?: number,
|
|
2243
|
-
): Promise<HostInfo> {
|
|
2296
|
+
getHostInfo(host: string, update?: boolean, timeoutMs?: number): Promise<HostInfo> {
|
|
2244
2297
|
if (Connection.isWeb()) {
|
|
2245
|
-
return Promise.reject('Allowed only in admin');
|
|
2298
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2246
2299
|
}
|
|
2247
2300
|
if (!host.startsWith('system.host.')) {
|
|
2248
2301
|
host += `system.host.${host}`;
|
|
@@ -2253,14 +2306,14 @@ class Connection {
|
|
|
2253
2306
|
}
|
|
2254
2307
|
|
|
2255
2308
|
if (!this.connected) {
|
|
2256
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2309
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2257
2310
|
}
|
|
2258
2311
|
|
|
2259
2312
|
this._promises[`hostInfo_${host}`] = new Promise((resolve, reject) => {
|
|
2260
2313
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
2261
2314
|
if (timeout) {
|
|
2262
2315
|
timeout = null;
|
|
2263
|
-
reject('getHostInfo timeout');
|
|
2316
|
+
reject(new Error('getHostInfo timeout'));
|
|
2264
2317
|
}
|
|
2265
2318
|
}, timeoutMs || this.props.cmdTimeout);
|
|
2266
2319
|
|
|
@@ -2269,9 +2322,9 @@ class Connection {
|
|
|
2269
2322
|
clearTimeout(timeout);
|
|
2270
2323
|
timeout = null;
|
|
2271
2324
|
if (data === PERMISSION_ERROR) {
|
|
2272
|
-
reject('May not read "getHostInfo"');
|
|
2325
|
+
reject(new Error('May not read "getHostInfo"'));
|
|
2273
2326
|
} else if (!data || typeof data !== 'object') {
|
|
2274
|
-
reject('Cannot read "getHostInfo"');
|
|
2327
|
+
reject(new Error('Cannot read "getHostInfo"'));
|
|
2275
2328
|
} else {
|
|
2276
2329
|
resolve(data);
|
|
2277
2330
|
}
|
|
@@ -2284,16 +2337,14 @@ class Connection {
|
|
|
2284
2337
|
|
|
2285
2338
|
/**
|
|
2286
2339
|
* Get the host information (short version).
|
|
2340
|
+
*
|
|
2341
|
+
* @param host The host name.
|
|
2342
|
+
* @param update Force update.
|
|
2343
|
+
* @param timeoutMs Optional read timeout.
|
|
2287
2344
|
*/
|
|
2288
|
-
getHostInfoShort(
|
|
2289
|
-
host: string,
|
|
2290
|
-
/** Force update. */
|
|
2291
|
-
update?: boolean,
|
|
2292
|
-
/** optional read timeout. */
|
|
2293
|
-
timeoutMs?: number,
|
|
2294
|
-
): Promise<HostInfo> {
|
|
2345
|
+
getHostInfoShort(host: string, update?: boolean, timeoutMs?: number): Promise<HostInfo> {
|
|
2295
2346
|
if (Connection.isWeb()) {
|
|
2296
|
-
return Promise.reject('Allowed only in admin');
|
|
2347
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2297
2348
|
}
|
|
2298
2349
|
if (!host.startsWith('system.host.')) {
|
|
2299
2350
|
host += `system.host.${host}`;
|
|
@@ -2303,14 +2354,14 @@ class Connection {
|
|
|
2303
2354
|
}
|
|
2304
2355
|
|
|
2305
2356
|
if (!this.connected) {
|
|
2306
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2357
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2307
2358
|
}
|
|
2308
2359
|
|
|
2309
2360
|
this._promises[`hostInfoShort_${host}`] = new Promise((resolve, reject) => {
|
|
2310
2361
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
2311
2362
|
if (timeout) {
|
|
2312
2363
|
timeout = null;
|
|
2313
|
-
reject('hostInfoShort timeout');
|
|
2364
|
+
reject(new Error('hostInfoShort timeout'));
|
|
2314
2365
|
}
|
|
2315
2366
|
}, timeoutMs || this.props.cmdTimeout);
|
|
2316
2367
|
|
|
@@ -2319,9 +2370,9 @@ class Connection {
|
|
|
2319
2370
|
clearTimeout(timeout);
|
|
2320
2371
|
timeout = null;
|
|
2321
2372
|
if (data === PERMISSION_ERROR) {
|
|
2322
|
-
reject('May not read "getHostInfoShort"');
|
|
2373
|
+
reject(new Error('May not read "getHostInfoShort"'));
|
|
2323
2374
|
} else if (!data || typeof data !== 'object') {
|
|
2324
|
-
reject('Cannot read "getHostInfoShort"');
|
|
2375
|
+
reject(new Error('Cannot read "getHostInfoShort"'));
|
|
2325
2376
|
} else {
|
|
2326
2377
|
resolve(data);
|
|
2327
2378
|
}
|
|
@@ -2334,24 +2385,27 @@ class Connection {
|
|
|
2334
2385
|
|
|
2335
2386
|
/**
|
|
2336
2387
|
* Get the repository.
|
|
2388
|
+
*
|
|
2389
|
+
* @param host The host name.
|
|
2390
|
+
* @param options Options.
|
|
2391
|
+
* @param update Force update.
|
|
2392
|
+
* @param timeoutMs Timeout in ms.
|
|
2337
2393
|
*/
|
|
2338
2394
|
getRepository(
|
|
2339
2395
|
host: string,
|
|
2340
2396
|
options?: { update: boolean; repo: string } | string,
|
|
2341
|
-
/** Force update. */
|
|
2342
2397
|
update?: boolean,
|
|
2343
|
-
/** timeout in ms. */
|
|
2344
2398
|
timeoutMs?: number,
|
|
2345
2399
|
): Promise<Record<string, ioBroker.AdapterObject>> {
|
|
2346
2400
|
if (Connection.isWeb()) {
|
|
2347
|
-
return Promise.reject('Allowed only in admin');
|
|
2401
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2348
2402
|
}
|
|
2349
2403
|
if (!update && this._promises.repo) {
|
|
2350
2404
|
return this._promises.repo;
|
|
2351
2405
|
}
|
|
2352
2406
|
|
|
2353
2407
|
if (!this.connected) {
|
|
2354
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2408
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2355
2409
|
}
|
|
2356
2410
|
|
|
2357
2411
|
if (!host.startsWith('system.host.')) {
|
|
@@ -2362,23 +2416,29 @@ class Connection {
|
|
|
2362
2416
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
2363
2417
|
if (timeout) {
|
|
2364
2418
|
timeout = null;
|
|
2365
|
-
reject('getRepository timeout');
|
|
2419
|
+
reject(new Error('getRepository timeout'));
|
|
2366
2420
|
}
|
|
2367
2421
|
}, timeoutMs || this.props.cmdTimeout);
|
|
2368
2422
|
|
|
2369
|
-
this._socket.emit(
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2423
|
+
this._socket.emit(
|
|
2424
|
+
'sendToHost',
|
|
2425
|
+
host,
|
|
2426
|
+
'getRepository',
|
|
2427
|
+
options,
|
|
2428
|
+
(data: string | Record<string, ioBroker.AdapterObject>) => {
|
|
2429
|
+
if (timeout) {
|
|
2430
|
+
clearTimeout(timeout);
|
|
2431
|
+
timeout = null;
|
|
2432
|
+
if (data === PERMISSION_ERROR) {
|
|
2433
|
+
reject(new Error('May not read "getRepository"'));
|
|
2434
|
+
} else if (!data || typeof data !== 'object') {
|
|
2435
|
+
reject(new Error('Cannot read "getRepository"'));
|
|
2436
|
+
} else {
|
|
2437
|
+
resolve(data);
|
|
2438
|
+
}
|
|
2379
2439
|
}
|
|
2380
|
-
}
|
|
2381
|
-
|
|
2440
|
+
},
|
|
2441
|
+
);
|
|
2382
2442
|
});
|
|
2383
2443
|
|
|
2384
2444
|
return this._promises.repo;
|
|
@@ -2386,16 +2446,14 @@ class Connection {
|
|
|
2386
2446
|
|
|
2387
2447
|
/**
|
|
2388
2448
|
* Get the installed.
|
|
2449
|
+
*
|
|
2450
|
+
* @param host The host name.
|
|
2451
|
+
* @param update Force update.
|
|
2452
|
+
* @param cmdTimeout Timeout in ms.
|
|
2389
2453
|
*/
|
|
2390
|
-
getInstalled(
|
|
2391
|
-
host: string,
|
|
2392
|
-
/** Force update. */
|
|
2393
|
-
update?: boolean,
|
|
2394
|
-
/** timeout in ms */
|
|
2395
|
-
cmdTimeout?: number,
|
|
2396
|
-
): Promise<Record<string, ioBroker.AdapterObject>> {
|
|
2454
|
+
getInstalled(host: string, update?: boolean, cmdTimeout?: number): Promise<Record<string, ioBroker.AdapterObject>> {
|
|
2397
2455
|
if (Connection.isWeb()) {
|
|
2398
|
-
return Promise.reject('Allowed only in admin');
|
|
2456
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2399
2457
|
}
|
|
2400
2458
|
|
|
2401
2459
|
this._promises.installed = this._promises.installed || {};
|
|
@@ -2405,7 +2463,7 @@ class Connection {
|
|
|
2405
2463
|
}
|
|
2406
2464
|
|
|
2407
2465
|
if (!this.connected) {
|
|
2408
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2466
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2409
2467
|
}
|
|
2410
2468
|
|
|
2411
2469
|
if (!host.startsWith('system.host.')) {
|
|
@@ -2416,23 +2474,29 @@ class Connection {
|
|
|
2416
2474
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
2417
2475
|
if (timeout) {
|
|
2418
2476
|
timeout = null;
|
|
2419
|
-
reject('getInstalled timeout');
|
|
2477
|
+
reject(new Error('getInstalled timeout'));
|
|
2420
2478
|
}
|
|
2421
2479
|
}, cmdTimeout || this.props.cmdTimeout);
|
|
2422
2480
|
|
|
2423
|
-
this._socket.emit(
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2481
|
+
this._socket.emit(
|
|
2482
|
+
'sendToHost',
|
|
2483
|
+
host,
|
|
2484
|
+
'getInstalled',
|
|
2485
|
+
null,
|
|
2486
|
+
(data: string | Record<string, ioBroker.AdapterObject>) => {
|
|
2487
|
+
if (timeout) {
|
|
2488
|
+
clearTimeout(timeout);
|
|
2489
|
+
timeout = null;
|
|
2490
|
+
if (data === PERMISSION_ERROR) {
|
|
2491
|
+
reject(new Error('May not read "getInstalled"'));
|
|
2492
|
+
} else if (!data || typeof data !== 'object') {
|
|
2493
|
+
reject(new Error('Cannot read "getInstalled"'));
|
|
2494
|
+
} else {
|
|
2495
|
+
resolve(data);
|
|
2496
|
+
}
|
|
2433
2497
|
}
|
|
2434
|
-
}
|
|
2435
|
-
|
|
2498
|
+
},
|
|
2499
|
+
);
|
|
2436
2500
|
});
|
|
2437
2501
|
|
|
2438
2502
|
return this._promises.installed[host] as Promise<Record<string, ioBroker.AdapterObject>>;
|
|
@@ -2440,21 +2504,19 @@ class Connection {
|
|
|
2440
2504
|
|
|
2441
2505
|
/**
|
|
2442
2506
|
* Rename file or folder in ioBroker DB
|
|
2507
|
+
*
|
|
2508
|
+
* @param adapter Instance name, like `vis-2.0`.
|
|
2509
|
+
* @param oldName The current file name, e.g., main/vis-views.json
|
|
2510
|
+
* @param newName The new file name, e.g., main/vis-views-new.json
|
|
2443
2511
|
*/
|
|
2444
|
-
rename(
|
|
2445
|
-
/** instance name */
|
|
2446
|
-
adapter: string,
|
|
2447
|
-
/** current file name, e.g., main/vis-views.json */
|
|
2448
|
-
oldName: string,
|
|
2449
|
-
/** new file name, e.g., main/vis-views-new.json */
|
|
2450
|
-
newName: string,
|
|
2451
|
-
): Promise<void> {
|
|
2512
|
+
rename(adapter: string, oldName: string, newName: string): Promise<void> {
|
|
2452
2513
|
if (!this.connected) {
|
|
2453
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2514
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2454
2515
|
}
|
|
2455
2516
|
return new Promise((resolve, reject) => {
|
|
2456
2517
|
this._socket.emit('rename', adapter, oldName, newName, (err: string | null) =>
|
|
2457
|
-
|
|
2518
|
+
err ? reject(new Error(err)) : resolve(),
|
|
2519
|
+
);
|
|
2458
2520
|
});
|
|
2459
2521
|
}
|
|
2460
2522
|
|
|
@@ -2470,11 +2532,12 @@ class Connection {
|
|
|
2470
2532
|
newName: string,
|
|
2471
2533
|
): Promise<void> {
|
|
2472
2534
|
if (!this.connected) {
|
|
2473
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2535
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2474
2536
|
}
|
|
2475
2537
|
return new Promise((resolve, reject) => {
|
|
2476
2538
|
this._socket.emit('renameFile', adapter, oldName, newName, (err: string | null) =>
|
|
2477
|
-
|
|
2539
|
+
err ? reject(new Error(err)) : resolve(),
|
|
2540
|
+
);
|
|
2478
2541
|
});
|
|
2479
2542
|
}
|
|
2480
2543
|
|
|
@@ -2492,10 +2555,10 @@ class Connection {
|
|
|
2492
2555
|
cmdTimeout: number,
|
|
2493
2556
|
): Promise<void> {
|
|
2494
2557
|
if (Connection.isWeb()) {
|
|
2495
|
-
return Promise.reject('Allowed only in admin');
|
|
2558
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2496
2559
|
}
|
|
2497
2560
|
if (!this.connected) {
|
|
2498
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2561
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2499
2562
|
}
|
|
2500
2563
|
|
|
2501
2564
|
if (!host.startsWith(host)) {
|
|
@@ -2503,19 +2566,21 @@ class Connection {
|
|
|
2503
2566
|
}
|
|
2504
2567
|
|
|
2505
2568
|
return new Promise((resolve, reject) => {
|
|
2506
|
-
let timeout: ReturnType<typeof setTimeout> | null = cmdTimeout
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2569
|
+
let timeout: ReturnType<typeof setTimeout> | null = cmdTimeout
|
|
2570
|
+
? setTimeout(() => {
|
|
2571
|
+
if (timeout) {
|
|
2572
|
+
timeout = null;
|
|
2573
|
+
reject(new Error('cmdExec timeout'));
|
|
2574
|
+
}
|
|
2575
|
+
}, cmdTimeout)
|
|
2576
|
+
: null;
|
|
2512
2577
|
|
|
2513
2578
|
this._socket.emit('cmdExec', host, cmdId, cmd, null, (err: string | null) => {
|
|
2514
2579
|
if (!cmdTimeout || timeout) {
|
|
2515
2580
|
timeout && clearTimeout(timeout);
|
|
2516
2581
|
timeout = null;
|
|
2517
2582
|
if (err) {
|
|
2518
|
-
reject(err);
|
|
2583
|
+
reject(new Error(err));
|
|
2519
2584
|
} else {
|
|
2520
2585
|
resolve();
|
|
2521
2586
|
}
|
|
@@ -2538,12 +2603,13 @@ class Connection {
|
|
|
2538
2603
|
}
|
|
2539
2604
|
|
|
2540
2605
|
if (!this.connected) {
|
|
2541
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2606
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2542
2607
|
}
|
|
2543
2608
|
|
|
2544
2609
|
this._promises[`supportedFeatures_${feature}`] = new Promise((resolve, reject) => {
|
|
2545
2610
|
this._socket.emit('checkFeatureSupported', feature, (err: string | null, supported: boolean) =>
|
|
2546
|
-
|
|
2611
|
+
err ? reject(new Error(err)) : resolve(supported),
|
|
2612
|
+
);
|
|
2547
2613
|
});
|
|
2548
2614
|
|
|
2549
2615
|
return this._promises[`supportedFeatures_${feature}`] as Promise<boolean>;
|
|
@@ -2554,18 +2620,18 @@ class Connection {
|
|
|
2554
2620
|
*/
|
|
2555
2621
|
async readBaseSettings(host: string): Promise<Record<string, any>> {
|
|
2556
2622
|
if (Connection.isWeb()) {
|
|
2557
|
-
return Promise.reject('Allowed only in admin');
|
|
2623
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2558
2624
|
}
|
|
2559
2625
|
const result = await this.checkFeatureSupported('CONTROLLER_READWRITE_BASE_SETTINGS');
|
|
2560
2626
|
if (result) {
|
|
2561
2627
|
if (!this.connected) {
|
|
2562
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2628
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2563
2629
|
}
|
|
2564
2630
|
return new Promise((resolve, reject) => {
|
|
2565
2631
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
2566
2632
|
if (timeout) {
|
|
2567
2633
|
timeout = null;
|
|
2568
|
-
reject('readBaseSettings timeout');
|
|
2634
|
+
reject(new Error('readBaseSettings timeout'));
|
|
2569
2635
|
}
|
|
2570
2636
|
}, this.props.cmdTimeout);
|
|
2571
2637
|
|
|
@@ -2573,50 +2639,60 @@ class Connection {
|
|
|
2573
2639
|
host = host.replace(/^system\.host\./, '');
|
|
2574
2640
|
}
|
|
2575
2641
|
|
|
2576
|
-
this._socket.emit(
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2642
|
+
this._socket.emit(
|
|
2643
|
+
'sendToHost',
|
|
2644
|
+
host,
|
|
2645
|
+
'readBaseSettings',
|
|
2646
|
+
null,
|
|
2647
|
+
(data: Record<string, any> | string) => {
|
|
2648
|
+
if (timeout) {
|
|
2649
|
+
clearTimeout(timeout);
|
|
2650
|
+
timeout = null;
|
|
2651
|
+
|
|
2652
|
+
if (data === PERMISSION_ERROR) {
|
|
2653
|
+
reject(new Error('May not read "BaseSettings"'));
|
|
2654
|
+
} else if (!data || typeof data !== 'object') {
|
|
2655
|
+
reject(new Error('Cannot read "BaseSettings"'));
|
|
2656
|
+
} else {
|
|
2657
|
+
resolve(data);
|
|
2658
|
+
}
|
|
2587
2659
|
}
|
|
2588
|
-
}
|
|
2589
|
-
|
|
2660
|
+
},
|
|
2661
|
+
);
|
|
2590
2662
|
});
|
|
2591
2663
|
}
|
|
2592
|
-
return Promise.reject('Not supported');
|
|
2664
|
+
return Promise.reject(new Error('Not supported'));
|
|
2593
2665
|
}
|
|
2594
2666
|
|
|
2595
2667
|
/**
|
|
2596
2668
|
* Write the base settings of a given host.
|
|
2597
|
-
*
|
|
2598
|
-
* @param
|
|
2599
|
-
* @
|
|
2669
|
+
*
|
|
2670
|
+
* @param host The host name.
|
|
2671
|
+
* @param config The new base settings.
|
|
2600
2672
|
*/
|
|
2601
|
-
writeBaseSettings(host: string, config:
|
|
2673
|
+
writeBaseSettings(host: string, config: IoBJson): Promise<{ result?: 'ok'; error?: string }> {
|
|
2602
2674
|
if (Connection.isWeb()) {
|
|
2603
|
-
return Promise.reject('Allowed only in admin');
|
|
2675
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2604
2676
|
}
|
|
2605
|
-
return this.checkFeatureSupported('CONTROLLER_READWRITE_BASE_SETTINGS')
|
|
2606
|
-
|
|
2607
|
-
if (
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2677
|
+
return this.checkFeatureSupported('CONTROLLER_READWRITE_BASE_SETTINGS').then(result => {
|
|
2678
|
+
if (result) {
|
|
2679
|
+
if (!this.connected) {
|
|
2680
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2681
|
+
}
|
|
2682
|
+
return new Promise((resolve, reject) => {
|
|
2683
|
+
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
2684
|
+
if (timeout) {
|
|
2685
|
+
timeout = null;
|
|
2686
|
+
reject(new Error('writeBaseSettings timeout'));
|
|
2687
|
+
}
|
|
2688
|
+
}, this.props.cmdTimeout);
|
|
2689
|
+
|
|
2690
|
+
this._socket.emit(
|
|
2691
|
+
'sendToHost',
|
|
2692
|
+
host,
|
|
2693
|
+
'writeBaseSettings',
|
|
2694
|
+
config,
|
|
2695
|
+
(data: { result?: 'ok'; error?: string } | string) => {
|
|
2620
2696
|
if (timeout) {
|
|
2621
2697
|
clearTimeout(timeout);
|
|
2622
2698
|
timeout = null;
|
|
@@ -2629,12 +2705,13 @@ class Connection {
|
|
|
2629
2705
|
resolve(data as { result?: 'ok'; error?: string });
|
|
2630
2706
|
}
|
|
2631
2707
|
}
|
|
2632
|
-
}
|
|
2633
|
-
|
|
2634
|
-
}
|
|
2708
|
+
},
|
|
2709
|
+
);
|
|
2710
|
+
});
|
|
2711
|
+
}
|
|
2635
2712
|
|
|
2636
|
-
|
|
2637
|
-
|
|
2713
|
+
return Promise.reject(new Error('Not supported'));
|
|
2714
|
+
});
|
|
2638
2715
|
}
|
|
2639
2716
|
|
|
2640
2717
|
/**
|
|
@@ -2642,31 +2719,29 @@ class Connection {
|
|
|
2642
2719
|
*/
|
|
2643
2720
|
restartController(host: string): Promise<boolean> {
|
|
2644
2721
|
if (Connection.isWeb()) {
|
|
2645
|
-
return Promise.reject('Allowed only in admin');
|
|
2722
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2646
2723
|
}
|
|
2647
2724
|
return new Promise((resolve, reject) => {
|
|
2648
2725
|
this._socket.emit('sendToHost', host, 'restartController', null, (error: string | null) => {
|
|
2649
|
-
error ? reject(error) : resolve(true);
|
|
2726
|
+
error ? reject(new Error(error)) : resolve(true);
|
|
2650
2727
|
});
|
|
2651
2728
|
});
|
|
2652
2729
|
}
|
|
2653
2730
|
|
|
2654
2731
|
/**
|
|
2655
2732
|
* Read statistics information from host
|
|
2656
|
-
*
|
|
2657
|
-
* @param
|
|
2658
|
-
* @
|
|
2733
|
+
*
|
|
2734
|
+
* @param host Host name
|
|
2735
|
+
* @param typeOfDiag one of none, normal, no-city, extended
|
|
2659
2736
|
*/
|
|
2660
|
-
getDiagData(
|
|
2661
|
-
host: string,
|
|
2662
|
-
typeOfDiag: 'none' | 'normal' | 'no-city' | 'extended',
|
|
2663
|
-
): Promise<Record<string, any>> {
|
|
2737
|
+
getDiagData(host: string, typeOfDiag: 'none' | 'normal' | 'no-city' | 'extended'): Promise<Record<string, any>> {
|
|
2664
2738
|
if (Connection.isWeb()) {
|
|
2665
|
-
return Promise.reject('Allowed only in admin');
|
|
2739
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2666
2740
|
}
|
|
2667
2741
|
return new Promise(resolve => {
|
|
2668
2742
|
this._socket.emit('sendToHost', host, 'getDiagData', typeOfDiag, (result: Record<string, any>) =>
|
|
2669
|
-
resolve(result)
|
|
2743
|
+
resolve(result),
|
|
2744
|
+
);
|
|
2670
2745
|
});
|
|
2671
2746
|
}
|
|
2672
2747
|
|
|
@@ -2675,43 +2750,55 @@ class Connection {
|
|
|
2675
2750
|
*/
|
|
2676
2751
|
getForeignStates(pattern?: string): Promise<Record<string, ioBroker.State>> {
|
|
2677
2752
|
if (!this.connected) {
|
|
2678
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2753
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2679
2754
|
}
|
|
2680
2755
|
if (Connection.isWeb()) {
|
|
2681
2756
|
return new Promise((resolve, reject) => {
|
|
2682
|
-
this._socket.emit(
|
|
2683
|
-
|
|
2757
|
+
this._socket.emit(
|
|
2758
|
+
'getStates',
|
|
2759
|
+
pattern || '*',
|
|
2760
|
+
(err: string | null, states: Record<string, ioBroker.State>) =>
|
|
2761
|
+
err ? reject(new Error(err)) : resolve(states),
|
|
2762
|
+
);
|
|
2684
2763
|
});
|
|
2685
2764
|
}
|
|
2686
2765
|
|
|
2687
2766
|
return new Promise((resolve, reject) => {
|
|
2688
|
-
this._socket.emit(
|
|
2689
|
-
|
|
2767
|
+
this._socket.emit(
|
|
2768
|
+
'getForeignStates',
|
|
2769
|
+
pattern || '*',
|
|
2770
|
+
(err: string | null, states: Record<string, ioBroker.State>) =>
|
|
2771
|
+
err ? reject(new Error(err)) : resolve(states),
|
|
2772
|
+
);
|
|
2690
2773
|
});
|
|
2691
2774
|
}
|
|
2692
2775
|
|
|
2693
2776
|
/**
|
|
2694
2777
|
* Get foreign objects by pattern, by specific type and resolve their enums. (Only admin)
|
|
2695
|
-
* @returns {ioBroker.GetObjectsPromise}
|
|
2696
2778
|
*/
|
|
2697
2779
|
getForeignObjects(pattern: string, type?: ioBroker.ObjectType): Promise<Record<string, ioBroker.State>> {
|
|
2698
2780
|
if (Connection.isWeb()) {
|
|
2699
|
-
return Promise.reject('Allowed only in admin');
|
|
2781
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2700
2782
|
}
|
|
2701
2783
|
|
|
2702
2784
|
if (!this.connected) {
|
|
2703
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2785
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2704
2786
|
}
|
|
2705
2787
|
return new Promise((resolve, reject) => {
|
|
2706
|
-
this._socket.emit(
|
|
2707
|
-
|
|
2788
|
+
this._socket.emit(
|
|
2789
|
+
'getForeignObjects',
|
|
2790
|
+
pattern || '*',
|
|
2791
|
+
type,
|
|
2792
|
+
(err: string | null, states: Record<string, ioBroker.State>) =>
|
|
2793
|
+
err ? reject(new Error(err)) : resolve(states),
|
|
2794
|
+
);
|
|
2708
2795
|
});
|
|
2709
2796
|
}
|
|
2710
2797
|
|
|
2711
2798
|
/**
|
|
2712
2799
|
* Gets the system configuration.
|
|
2713
|
-
*
|
|
2714
|
-
* @
|
|
2800
|
+
*
|
|
2801
|
+
* @param update Force update.
|
|
2715
2802
|
*/
|
|
2716
2803
|
getSystemConfig(update?: boolean): Promise<ioBroker.SystemConfigObject> {
|
|
2717
2804
|
if (!update && this._promises.systemConfig) {
|
|
@@ -2719,16 +2806,15 @@ class Connection {
|
|
|
2719
2806
|
}
|
|
2720
2807
|
|
|
2721
2808
|
if (!this.connected) {
|
|
2722
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2809
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2723
2810
|
}
|
|
2724
2811
|
|
|
2725
|
-
this._promises.systemConfig = this.getObject('system.config')
|
|
2726
|
-
.
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
});
|
|
2812
|
+
this._promises.systemConfig = this.getObject('system.config').then(obj => {
|
|
2813
|
+
const systemConfig: ioBroker.SystemConfigObject = (obj || {}) as ioBroker.SystemConfigObject;
|
|
2814
|
+
systemConfig.common = systemConfig.common || ({} as ioBroker.SystemConfigCommon);
|
|
2815
|
+
systemConfig.native = systemConfig.native || {};
|
|
2816
|
+
return systemConfig;
|
|
2817
|
+
});
|
|
2732
2818
|
|
|
2733
2819
|
return this._promises.systemConfig;
|
|
2734
2820
|
}
|
|
@@ -2736,9 +2822,12 @@ class Connection {
|
|
|
2736
2822
|
/**
|
|
2737
2823
|
* Sets the system configuration.
|
|
2738
2824
|
*/
|
|
2739
|
-
setSystemConfig(
|
|
2740
|
-
|
|
2741
|
-
|
|
2825
|
+
setSystemConfig(
|
|
2826
|
+
obj: ioBroker.SettableObjectWorker<ioBroker.SystemConfigObject>,
|
|
2827
|
+
): Promise<ioBroker.SystemConfigObject> {
|
|
2828
|
+
return this.setObject('system.config', obj).then(
|
|
2829
|
+
() => (this._promises.systemConfig = Promise.resolve(obj as ioBroker.SystemConfigObject)),
|
|
2830
|
+
);
|
|
2742
2831
|
}
|
|
2743
2832
|
|
|
2744
2833
|
/**
|
|
@@ -2751,17 +2840,15 @@ class Connection {
|
|
|
2751
2840
|
/**
|
|
2752
2841
|
* Get the history of a given state.
|
|
2753
2842
|
*/
|
|
2754
|
-
getHistory(
|
|
2755
|
-
id: string,
|
|
2756
|
-
options: ioBroker.GetHistoryOptions,
|
|
2757
|
-
): Promise<ioBroker.GetHistoryResult> {
|
|
2843
|
+
getHistory(id: string, options: ioBroker.GetHistoryOptions): Promise<ioBroker.GetHistoryResult> {
|
|
2758
2844
|
if (!this.connected) {
|
|
2759
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2845
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2760
2846
|
}
|
|
2761
2847
|
|
|
2762
2848
|
return new Promise((resolve, reject) => {
|
|
2763
2849
|
this._socket.emit('getHistory', id, options, (err: string | null, values: ioBroker.GetHistoryResult) =>
|
|
2764
|
-
|
|
2850
|
+
err ? reject(new Error(err)) : resolve(values),
|
|
2851
|
+
);
|
|
2765
2852
|
});
|
|
2766
2853
|
}
|
|
2767
2854
|
|
|
@@ -2773,28 +2860,31 @@ class Connection {
|
|
|
2773
2860
|
options: ioBroker.GetHistoryOptions,
|
|
2774
2861
|
): Promise<{ values: ioBroker.GetHistoryResult; sessionId: string; stepIgnore: number }> {
|
|
2775
2862
|
if (!this.connected) {
|
|
2776
|
-
return Promise.reject(NOT_CONNECTED);
|
|
2863
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2777
2864
|
}
|
|
2778
2865
|
|
|
2779
2866
|
return new Promise((resolve, reject) => {
|
|
2780
|
-
this._socket.emit(
|
|
2781
|
-
|
|
2867
|
+
this._socket.emit(
|
|
2868
|
+
'getHistory',
|
|
2869
|
+
id,
|
|
2870
|
+
options,
|
|
2871
|
+
(err: string | null, values: ioBroker.GetHistoryResult, stepIgnore: number, sessionId: string) =>
|
|
2872
|
+
err ? reject(new Error(err)) : resolve({ values, sessionId, stepIgnore }),
|
|
2873
|
+
);
|
|
2782
2874
|
});
|
|
2783
2875
|
}
|
|
2784
2876
|
|
|
2785
2877
|
/**
|
|
2786
2878
|
* Change the password of the given user.
|
|
2787
2879
|
*/
|
|
2788
|
-
changePassword(
|
|
2789
|
-
user: string,
|
|
2790
|
-
password: string,
|
|
2791
|
-
): Promise<void> {
|
|
2880
|
+
changePassword(user: string, password: string): Promise<void> {
|
|
2792
2881
|
if (Connection.isWeb()) {
|
|
2793
|
-
return Promise.reject('Allowed only in admin');
|
|
2882
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2794
2883
|
}
|
|
2795
2884
|
return new Promise((resolve, reject) => {
|
|
2796
2885
|
this._socket.emit('changePassword', user, password, (err: string | null) =>
|
|
2797
|
-
|
|
2886
|
+
err ? reject(new Error(err)) : resolve(),
|
|
2887
|
+
);
|
|
2798
2888
|
});
|
|
2799
2889
|
}
|
|
2800
2890
|
|
|
@@ -2807,7 +2897,7 @@ class Connection {
|
|
|
2807
2897
|
update?: boolean,
|
|
2808
2898
|
): Promise<string[]> {
|
|
2809
2899
|
if (Connection.isWeb()) {
|
|
2810
|
-
return Promise.reject('Allowed only in admin');
|
|
2900
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2811
2901
|
}
|
|
2812
2902
|
if (!host.startsWith('system.host.')) {
|
|
2813
2903
|
host = `system.host.${host}`;
|
|
@@ -2816,8 +2906,7 @@ class Connection {
|
|
|
2816
2906
|
if (!update && this._promises[`IPs_${host}`]) {
|
|
2817
2907
|
return this._promises[`IPs_${host}`] as Promise<string[]>;
|
|
2818
2908
|
}
|
|
2819
|
-
this._promises[`IPs_${host}`] = this.getObject(host)
|
|
2820
|
-
.then(obj => (obj?.common ? obj.common.address || [] : []));
|
|
2909
|
+
this._promises[`IPs_${host}`] = this.getObject(host).then(obj => (obj?.common ? obj.common.address || [] : []));
|
|
2821
2910
|
|
|
2822
2911
|
return this._promises[`IPs_${host}`] as Promise<string[]>;
|
|
2823
2912
|
}
|
|
@@ -2831,14 +2920,16 @@ class Connection {
|
|
|
2831
2920
|
update?: boolean,
|
|
2832
2921
|
): Promise<{ name: string; address: string; family: 'ipv4' | 'ipv6' }[]> {
|
|
2833
2922
|
if (Connection.isWeb()) {
|
|
2834
|
-
return Promise.reject('Allowed only in admin');
|
|
2923
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2835
2924
|
}
|
|
2836
2925
|
if (ipOrHostName.startsWith('system.host.')) {
|
|
2837
2926
|
ipOrHostName = ipOrHostName.replace(/^system\.host\./, '');
|
|
2838
2927
|
}
|
|
2839
2928
|
|
|
2840
2929
|
if (!update && this._promises[`rIPs_${ipOrHostName}`]) {
|
|
2841
|
-
return this._promises[`rIPs_${ipOrHostName}`] as Promise<
|
|
2930
|
+
return this._promises[`rIPs_${ipOrHostName}`] as Promise<
|
|
2931
|
+
{ name: string; address: string; family: 'ipv4' | 'ipv6' }[]
|
|
2932
|
+
>;
|
|
2842
2933
|
}
|
|
2843
2934
|
this._promises[`rIPs_${ipOrHostName}`] = new Promise(resolve => {
|
|
2844
2935
|
this._socket.emit('getHostByIp', ipOrHostName, (ip: string, host: any) => {
|
|
@@ -2881,7 +2972,9 @@ class Connection {
|
|
|
2881
2972
|
});
|
|
2882
2973
|
});
|
|
2883
2974
|
|
|
2884
|
-
return this._promises[`rIPs_${ipOrHostName}`] as Promise<
|
|
2975
|
+
return this._promises[`rIPs_${ipOrHostName}`] as Promise<
|
|
2976
|
+
{ name: string; address: string; family: 'ipv4' | 'ipv6' }[]
|
|
2977
|
+
>;
|
|
2885
2978
|
}
|
|
2886
2979
|
|
|
2887
2980
|
/**
|
|
@@ -2889,11 +2982,12 @@ class Connection {
|
|
|
2889
2982
|
*/
|
|
2890
2983
|
encrypt(text: string): Promise<string> {
|
|
2891
2984
|
if (Connection.isWeb()) {
|
|
2892
|
-
return Promise.reject('Allowed only in admin');
|
|
2985
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2893
2986
|
}
|
|
2894
2987
|
return new Promise((resolve, reject) => {
|
|
2895
2988
|
this._socket.emit('encrypt', text, (err: string | null, _text: string) =>
|
|
2896
|
-
|
|
2989
|
+
err ? reject(new Error(err)) : resolve(_text),
|
|
2990
|
+
);
|
|
2897
2991
|
});
|
|
2898
2992
|
}
|
|
2899
2993
|
|
|
@@ -2902,52 +2996,57 @@ class Connection {
|
|
|
2902
2996
|
*/
|
|
2903
2997
|
decrypt(encryptedText: string): Promise<string> {
|
|
2904
2998
|
if (Connection.isWeb()) {
|
|
2905
|
-
return Promise.reject('Allowed only in admin');
|
|
2999
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2906
3000
|
}
|
|
2907
3001
|
return new Promise((resolve, reject) => {
|
|
2908
3002
|
this._socket.emit('decrypt', encryptedText, (err: string | null, text: string) =>
|
|
2909
|
-
|
|
3003
|
+
err ? reject(new Error(err)) : resolve(text),
|
|
3004
|
+
);
|
|
2910
3005
|
});
|
|
2911
3006
|
}
|
|
2912
3007
|
|
|
2913
3008
|
/**
|
|
2914
3009
|
* Gets the version.
|
|
2915
|
-
* @returns {Promise<{version: string; serverName: string}>}
|
|
2916
3010
|
*/
|
|
2917
3011
|
getVersion(update?: boolean): Promise<{ version: string; serverName: string }> {
|
|
2918
3012
|
if (update && this._promises.version) {
|
|
2919
3013
|
delete this._promises.version;
|
|
2920
3014
|
}
|
|
2921
3015
|
|
|
2922
|
-
this._promises.version =
|
|
2923
|
-
this.
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
3016
|
+
this._promises.version =
|
|
3017
|
+
this._promises.version ||
|
|
3018
|
+
new Promise((resolve, reject) => {
|
|
3019
|
+
this._socket.emit('getVersion', (err: string | null, version: string, serverName: string) => {
|
|
3020
|
+
// support of old socket.io
|
|
3021
|
+
if (err && !version && typeof err === 'string' && err.match(/\d+\.\d+\.\d+/)) {
|
|
3022
|
+
resolve({ version: err, serverName: 'socketio' });
|
|
3023
|
+
} else {
|
|
3024
|
+
err ? reject(new Error(err)) : resolve({ version, serverName });
|
|
3025
|
+
}
|
|
3026
|
+
});
|
|
2930
3027
|
});
|
|
2931
|
-
});
|
|
2932
3028
|
|
|
2933
3029
|
return this._promises.version;
|
|
2934
3030
|
}
|
|
2935
3031
|
|
|
2936
3032
|
/**
|
|
2937
3033
|
* Gets the web server name.
|
|
2938
|
-
* @returns {Promise<string>}
|
|
2939
3034
|
*/
|
|
2940
3035
|
getWebServerName(): Promise<string> {
|
|
2941
|
-
this._promises.webName =
|
|
2942
|
-
this.
|
|
2943
|
-
|
|
2944
|
-
|
|
3036
|
+
this._promises.webName =
|
|
3037
|
+
this._promises.webName ||
|
|
3038
|
+
new Promise((resolve, reject) => {
|
|
3039
|
+
this._socket.emit('getAdapterName', (err: string | null, name: string) =>
|
|
3040
|
+
err ? reject(new Error(err)) : resolve(name),
|
|
3041
|
+
);
|
|
3042
|
+
});
|
|
2945
3043
|
|
|
2946
3044
|
return this._promises.webName;
|
|
2947
3045
|
}
|
|
2948
3046
|
|
|
2949
3047
|
/**
|
|
2950
3048
|
* Gets the admin version.
|
|
3049
|
+
*
|
|
2951
3050
|
* @deprecated use getVersion()
|
|
2952
3051
|
*/
|
|
2953
3052
|
getAdminVersion(): Promise<{ version: string; serverName: string }> {
|
|
@@ -2956,112 +3055,128 @@ class Connection {
|
|
|
2956
3055
|
}
|
|
2957
3056
|
|
|
2958
3057
|
/**
|
|
2959
|
-
* Change access rights for file
|
|
3058
|
+
* Change access rights for a file
|
|
3059
|
+
*
|
|
3060
|
+
* @param adapter The adapter name.
|
|
3061
|
+
* @param fileName file name with a full path. It could be like vis.0/*
|
|
3062
|
+
* @param options like {mode: 0x644}
|
|
3063
|
+
* @param options.mode Access rights. Default is 0x644
|
|
2960
3064
|
*/
|
|
2961
3065
|
chmodFile(
|
|
2962
|
-
/** adapter name */
|
|
2963
3066
|
adapter: string,
|
|
2964
|
-
|
|
2965
|
-
filename: string,
|
|
2966
|
-
/** like {mode: 0x644} */
|
|
3067
|
+
fileName: string,
|
|
2967
3068
|
options?: { mode: number },
|
|
2968
3069
|
): Promise<{ entries: ioBroker.ChownFileResult[]; id: string }> {
|
|
2969
3070
|
if (Connection.isWeb()) {
|
|
2970
|
-
return Promise.reject('Allowed only in admin');
|
|
3071
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2971
3072
|
}
|
|
2972
3073
|
if (!this.connected) {
|
|
2973
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3074
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2974
3075
|
}
|
|
2975
3076
|
|
|
2976
3077
|
return new Promise((resolve, reject) => {
|
|
2977
|
-
this._socket.emit(
|
|
2978
|
-
|
|
3078
|
+
this._socket.emit(
|
|
3079
|
+
'chmodFile',
|
|
3080
|
+
adapter,
|
|
3081
|
+
fileName,
|
|
3082
|
+
options,
|
|
3083
|
+
(err: string | null, entries: ioBroker.ChownFileResult[], id: string) =>
|
|
3084
|
+
err ? reject(new Error(err)) : resolve({ entries, id }),
|
|
3085
|
+
);
|
|
2979
3086
|
});
|
|
2980
3087
|
}
|
|
2981
3088
|
|
|
2982
3089
|
/**
|
|
2983
|
-
* Change an owner or/and owner group for file
|
|
3090
|
+
* Change an owner or/and owner group for a file
|
|
3091
|
+
*
|
|
3092
|
+
* @param adapter The adapter name.
|
|
3093
|
+
* @param fileName file name with a full path. It could be like vis.0/*
|
|
3094
|
+
* @param options like {owner: 'user', ownerGroup: 'group'}
|
|
3095
|
+
* @param options.owner User name
|
|
3096
|
+
* @param options.ownerGroup Group name
|
|
2984
3097
|
*/
|
|
2985
3098
|
chownFile(
|
|
2986
|
-
/** adapter name */
|
|
2987
3099
|
adapter: string,
|
|
2988
|
-
/** file name with a full path. It could be like vis.0/* */
|
|
2989
3100
|
fileName: string,
|
|
2990
3101
|
options: { owner?: string; ownerGroup?: string },
|
|
2991
3102
|
): Promise<{ entries: ioBroker.ChownFileResult[]; id: string }> {
|
|
2992
3103
|
if (Connection.isWeb()) {
|
|
2993
|
-
return Promise.reject('Allowed only in admin');
|
|
3104
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
2994
3105
|
}
|
|
2995
3106
|
if (!this.connected) {
|
|
2996
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3107
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
2997
3108
|
}
|
|
2998
3109
|
|
|
2999
3110
|
return new Promise((resolve, reject) => {
|
|
3000
|
-
this._socket.emit(
|
|
3001
|
-
|
|
3111
|
+
this._socket.emit(
|
|
3112
|
+
'chownFile',
|
|
3113
|
+
adapter,
|
|
3114
|
+
fileName,
|
|
3115
|
+
options,
|
|
3116
|
+
(err: string | null, entries: ioBroker.ChownFileResult[], id: string) =>
|
|
3117
|
+
err ? reject(new Error(err)) : resolve({ entries, id }),
|
|
3118
|
+
);
|
|
3002
3119
|
});
|
|
3003
3120
|
}
|
|
3004
3121
|
|
|
3005
3122
|
/**
|
|
3006
3123
|
* Check if the file exists
|
|
3124
|
+
*
|
|
3125
|
+
* @param adapter The adapter name.
|
|
3126
|
+
* @param fileName file name with a full path. It could be like vis.0/*
|
|
3007
3127
|
*/
|
|
3008
|
-
fileExists(
|
|
3009
|
-
/** adapter name */
|
|
3010
|
-
adapter: string,
|
|
3011
|
-
/** file name with a full path. It could be like vis.0/* */
|
|
3012
|
-
fileName: string,
|
|
3013
|
-
): Promise<boolean> {
|
|
3128
|
+
fileExists(adapter: string, fileName: string): Promise<boolean> {
|
|
3014
3129
|
if (!this.connected) {
|
|
3015
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3130
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3016
3131
|
}
|
|
3017
3132
|
|
|
3018
3133
|
return new Promise((resolve, reject) => {
|
|
3019
3134
|
this._socket.emit('fileExists', adapter, fileName, (err: string | null, exists: boolean) =>
|
|
3020
|
-
|
|
3135
|
+
err ? reject(new Error(err)) : resolve(exists),
|
|
3136
|
+
);
|
|
3021
3137
|
});
|
|
3022
3138
|
}
|
|
3023
3139
|
|
|
3024
3140
|
/**
|
|
3025
3141
|
* Get the alarm notifications from a host (only for admin connection).
|
|
3026
|
-
* @returns {Promise<any>}
|
|
3027
3142
|
*/
|
|
3028
|
-
getNotifications(
|
|
3029
|
-
host: string,
|
|
3030
|
-
category?: string,
|
|
3031
|
-
): Promise<FilteredNotificationInformation> {
|
|
3143
|
+
getNotifications(host: string, category?: string): Promise<FilteredNotificationInformation> {
|
|
3032
3144
|
if (Connection.isWeb()) {
|
|
3033
|
-
return Promise.reject('Allowed only in admin');
|
|
3145
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3034
3146
|
}
|
|
3035
3147
|
|
|
3036
3148
|
if (!this.connected) {
|
|
3037
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3149
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3038
3150
|
}
|
|
3039
3151
|
return new Promise(resolve => {
|
|
3040
|
-
this._socket.emit(
|
|
3041
|
-
|
|
3152
|
+
this._socket.emit(
|
|
3153
|
+
'sendToHost',
|
|
3154
|
+
host,
|
|
3155
|
+
'getNotifications',
|
|
3156
|
+
{ category },
|
|
3157
|
+
(notifications: FilteredNotificationInformation) => resolve(notifications),
|
|
3158
|
+
);
|
|
3042
3159
|
});
|
|
3043
3160
|
}
|
|
3044
3161
|
|
|
3045
3162
|
/**
|
|
3046
3163
|
* Clear the alarm notifications on a host (only for admin connection).
|
|
3047
|
-
*
|
|
3048
|
-
* @param
|
|
3049
|
-
* @
|
|
3164
|
+
*
|
|
3165
|
+
* @param host The host name.
|
|
3166
|
+
* @param category optional
|
|
3050
3167
|
*/
|
|
3051
|
-
clearNotifications(
|
|
3052
|
-
host: string,
|
|
3053
|
-
category?: string,
|
|
3054
|
-
): Promise<{ result: 'ok' }> {
|
|
3168
|
+
clearNotifications(host: string, category?: string): Promise<{ result: 'ok' }> {
|
|
3055
3169
|
if (Connection.isWeb()) {
|
|
3056
|
-
return Promise.reject('Allowed only in admin');
|
|
3170
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3057
3171
|
}
|
|
3058
3172
|
|
|
3059
3173
|
if (!this.connected) {
|
|
3060
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3174
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3061
3175
|
}
|
|
3062
3176
|
return new Promise(resolve => {
|
|
3063
3177
|
this._socket.emit('sendToHost', host, 'clearNotifications', { category }, (result: { result: 'ok' }) =>
|
|
3064
|
-
resolve(result)
|
|
3178
|
+
resolve(result),
|
|
3179
|
+
);
|
|
3065
3180
|
});
|
|
3066
3181
|
}
|
|
3067
3182
|
|
|
@@ -3070,52 +3185,51 @@ class Connection {
|
|
|
3070
3185
|
*/
|
|
3071
3186
|
getIsEasyModeStrict(): Promise<boolean> {
|
|
3072
3187
|
if (Connection.isWeb()) {
|
|
3073
|
-
return Promise.reject('Allowed only in admin');
|
|
3188
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3074
3189
|
}
|
|
3075
3190
|
if (!this.connected) {
|
|
3076
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3191
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3077
3192
|
}
|
|
3078
3193
|
return new Promise((resolve, reject) => {
|
|
3079
3194
|
this._socket.emit('getIsEasyModeStrict', (error: null | string, isStrict: boolean) =>
|
|
3080
|
-
|
|
3195
|
+
error ? reject(new Error(error)) : resolve(isStrict),
|
|
3196
|
+
);
|
|
3081
3197
|
});
|
|
3082
3198
|
}
|
|
3083
3199
|
|
|
3084
3200
|
/**
|
|
3085
3201
|
* Read easy mode configuration (only for admin connection).
|
|
3086
|
-
* @returns {Promise<any>}
|
|
3087
3202
|
*/
|
|
3088
3203
|
getEasyMode(): Promise<any> {
|
|
3089
3204
|
if (Connection.isWeb()) {
|
|
3090
|
-
return Promise.reject('Allowed only in admin');
|
|
3205
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3091
3206
|
}
|
|
3092
3207
|
if (!this.connected) {
|
|
3093
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3208
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3094
3209
|
}
|
|
3095
3210
|
return new Promise((resolve, reject) => {
|
|
3096
3211
|
this._socket.emit('getEasyMode', (error: string | null, config: any) =>
|
|
3097
|
-
|
|
3212
|
+
error ? reject(new Error(error)) : resolve(config),
|
|
3213
|
+
);
|
|
3098
3214
|
});
|
|
3099
3215
|
}
|
|
3100
3216
|
|
|
3101
3217
|
/**
|
|
3102
3218
|
* Read current user
|
|
3103
|
-
* @returns {Promise<string>}
|
|
3104
3219
|
*/
|
|
3105
3220
|
getCurrentUser(): Promise<string> {
|
|
3106
3221
|
if (!this.connected) {
|
|
3107
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3222
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3108
3223
|
}
|
|
3109
3224
|
|
|
3110
3225
|
return new Promise(resolve => {
|
|
3111
|
-
this._socket.emit('authEnabled', (isSecure: boolean, user: string) =>
|
|
3112
|
-
resolve(user));
|
|
3226
|
+
this._socket.emit('authEnabled', (isSecure: boolean, user: string) => resolve(user));
|
|
3113
3227
|
});
|
|
3114
3228
|
}
|
|
3115
3229
|
|
|
3116
|
-
getCurrentSession(cmdTimeout?: number) {
|
|
3230
|
+
getCurrentSession(cmdTimeout?: number): Promise<{ expireInSec: number }> {
|
|
3117
3231
|
if (!this.connected) {
|
|
3118
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3232
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3119
3233
|
}
|
|
3120
3234
|
|
|
3121
3235
|
return new Promise((resolve, reject) => {
|
|
@@ -3125,7 +3239,7 @@ class Connection {
|
|
|
3125
3239
|
if (timeout) {
|
|
3126
3240
|
timeout = null;
|
|
3127
3241
|
controller.abort();
|
|
3128
|
-
reject('getCurrentSession timeout');
|
|
3242
|
+
reject(new Error('getCurrentSession timeout'));
|
|
3129
3243
|
}
|
|
3130
3244
|
}, cmdTimeout || 5000);
|
|
3131
3245
|
|
|
@@ -3138,25 +3252,24 @@ class Connection {
|
|
|
3138
3252
|
resolve(json);
|
|
3139
3253
|
}
|
|
3140
3254
|
})
|
|
3141
|
-
.catch(e =>
|
|
3142
|
-
reject(`getCurrentSession: ${e}`));
|
|
3255
|
+
.catch(e => reject(new Error(`getCurrentSession: ${e}`)));
|
|
3143
3256
|
});
|
|
3144
3257
|
}
|
|
3145
3258
|
|
|
3146
3259
|
/**
|
|
3147
3260
|
* Read adapter ratings
|
|
3148
|
-
* @returns {Promise<any>}
|
|
3149
3261
|
*/
|
|
3150
3262
|
getRatings(update?: boolean): Promise<any> {
|
|
3151
3263
|
if (Connection.isWeb()) {
|
|
3152
|
-
return Promise.reject('Allowed only in admin');
|
|
3264
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3153
3265
|
}
|
|
3154
3266
|
if (!this.connected) {
|
|
3155
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3267
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3156
3268
|
}
|
|
3157
3269
|
return new Promise((resolve, reject) => {
|
|
3158
3270
|
this._socket.emit('getRatings', update, (err: string | null, ratings: any) =>
|
|
3159
|
-
|
|
3271
|
+
err ? reject(new Error(err)) : resolve(ratings),
|
|
3272
|
+
);
|
|
3160
3273
|
});
|
|
3161
3274
|
}
|
|
3162
3275
|
|
|
@@ -3165,13 +3278,15 @@ class Connection {
|
|
|
3165
3278
|
*/
|
|
3166
3279
|
getCurrentInstance(): Promise<string> {
|
|
3167
3280
|
if (!this.connected) {
|
|
3168
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3281
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3169
3282
|
}
|
|
3170
3283
|
|
|
3171
|
-
this._promises.currentInstance =
|
|
3284
|
+
this._promises.currentInstance =
|
|
3285
|
+
this._promises.currentInstance ||
|
|
3172
3286
|
new Promise((resolve, reject) => {
|
|
3173
3287
|
this._socket.emit('getCurrentInstance', (err: string | null, namespace: string) =>
|
|
3174
|
-
|
|
3288
|
+
err ? reject(new Error(err)) : resolve(namespace),
|
|
3289
|
+
);
|
|
3175
3290
|
});
|
|
3176
3291
|
|
|
3177
3292
|
return this._promises.currentInstance;
|
|
@@ -3180,17 +3295,20 @@ class Connection {
|
|
|
3180
3295
|
// returns very optimized information for adapters to minimize a connection load
|
|
3181
3296
|
getCompactAdapters(update?: boolean): Promise<Record<string, ioBroker.AdapterObject>> {
|
|
3182
3297
|
if (Connection.isWeb()) {
|
|
3183
|
-
return Promise.reject('Allowed only in admin');
|
|
3298
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3184
3299
|
}
|
|
3185
3300
|
if (!update && this._promises.compactAdapters) {
|
|
3186
3301
|
return this._promises.compactAdapters;
|
|
3187
3302
|
}
|
|
3188
3303
|
if (!this.connected) {
|
|
3189
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3304
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3190
3305
|
}
|
|
3191
3306
|
this._promises.compactAdapters = new Promise((resolve, reject) => {
|
|
3192
|
-
this._socket.emit(
|
|
3193
|
-
|
|
3307
|
+
this._socket.emit(
|
|
3308
|
+
'getCompactAdapters',
|
|
3309
|
+
(err: string | null, adapters: Record<string, ioBroker.AdapterObject>) =>
|
|
3310
|
+
err ? reject(new Error(err)) : resolve(adapters),
|
|
3311
|
+
);
|
|
3194
3312
|
});
|
|
3195
3313
|
|
|
3196
3314
|
return this._promises.compactAdapters;
|
|
@@ -3205,24 +3323,27 @@ class Connection {
|
|
|
3205
3323
|
// returns very optimized information for adapters to minimize a connection load
|
|
3206
3324
|
getCompactInstances(update?: boolean): Promise<Record<string, ioBroker.InstanceObject>> {
|
|
3207
3325
|
if (Connection.isWeb()) {
|
|
3208
|
-
return Promise.reject('Allowed only in admin');
|
|
3326
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3209
3327
|
}
|
|
3210
3328
|
if (!update && this._promises.compactInstances) {
|
|
3211
3329
|
return this._promises.compactInstances;
|
|
3212
3330
|
}
|
|
3213
3331
|
if (!this.connected) {
|
|
3214
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3332
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3215
3333
|
}
|
|
3216
3334
|
|
|
3217
3335
|
this._promises.compactInstances = new Promise((resolve, reject) => {
|
|
3218
|
-
this._socket.emit(
|
|
3219
|
-
|
|
3336
|
+
this._socket.emit(
|
|
3337
|
+
'getCompactInstances',
|
|
3338
|
+
(err: string | null, instances: Record<string, ioBroker.InstanceObject>) =>
|
|
3339
|
+
err ? reject(new Error(err)) : resolve(instances),
|
|
3340
|
+
);
|
|
3220
3341
|
});
|
|
3221
3342
|
|
|
3222
3343
|
return this._promises.compactInstances;
|
|
3223
3344
|
}
|
|
3224
3345
|
|
|
3225
|
-
getAdapternInstancesResetCache(adapter?: string) {
|
|
3346
|
+
getAdapternInstancesResetCache(adapter?: string): void {
|
|
3226
3347
|
adapter = adapter || '';
|
|
3227
3348
|
delete this._promises.compactInstances;
|
|
3228
3349
|
delete this._promises[`instances_${adapter}`];
|
|
@@ -3238,7 +3359,7 @@ class Connection {
|
|
|
3238
3359
|
cmdTimeout?: number,
|
|
3239
3360
|
): Promise<Record<string, ioBroker.AdapterObject>> {
|
|
3240
3361
|
if (Connection.isWeb()) {
|
|
3241
|
-
return Promise.reject('Allowed only in admin');
|
|
3362
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3242
3363
|
}
|
|
3243
3364
|
|
|
3244
3365
|
this._promises.installedCompact = this._promises.installedCompact || {};
|
|
@@ -3248,7 +3369,7 @@ class Connection {
|
|
|
3248
3369
|
}
|
|
3249
3370
|
|
|
3250
3371
|
if (!this.connected) {
|
|
3251
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3372
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3252
3373
|
}
|
|
3253
3374
|
|
|
3254
3375
|
if (!host.startsWith('system.host.')) {
|
|
@@ -3259,7 +3380,7 @@ class Connection {
|
|
|
3259
3380
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
3260
3381
|
if (timeout) {
|
|
3261
3382
|
timeout = null;
|
|
3262
|
-
reject('getCompactInstalled timeout');
|
|
3383
|
+
reject(new Error('getCompactInstalled timeout'));
|
|
3263
3384
|
}
|
|
3264
3385
|
}, cmdTimeout || this.props.cmdTimeout);
|
|
3265
3386
|
|
|
@@ -3268,9 +3389,9 @@ class Connection {
|
|
|
3268
3389
|
clearTimeout(timeout);
|
|
3269
3390
|
timeout = null;
|
|
3270
3391
|
if (data === PERMISSION_ERROR) {
|
|
3271
|
-
reject('May not read "getCompactInstalled"');
|
|
3392
|
+
reject(new Error('May not read "getCompactInstalled"'));
|
|
3272
3393
|
} else if (!data || typeof data !== 'object') {
|
|
3273
|
-
reject('Cannot read "getCompactInstalled"');
|
|
3394
|
+
reject(new Error('Cannot read "getCompactInstalled"'));
|
|
3274
3395
|
} else {
|
|
3275
3396
|
resolve(data);
|
|
3276
3397
|
}
|
|
@@ -3283,38 +3404,35 @@ class Connection {
|
|
|
3283
3404
|
|
|
3284
3405
|
// returns very optimized information for adapters to minimize a connection load.
|
|
3285
3406
|
// reads only version of installed adapter
|
|
3286
|
-
getCompactSystemRepositories(
|
|
3287
|
-
update?: boolean,
|
|
3288
|
-
cmdTimeout?: number,
|
|
3289
|
-
): Promise<ioBroker.Object> {
|
|
3407
|
+
getCompactSystemRepositories(update?: boolean, cmdTimeout?: number): Promise<CompactSystemRepository> {
|
|
3290
3408
|
if (Connection.isWeb()) {
|
|
3291
|
-
return Promise.reject('Allowed only in admin');
|
|
3409
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3292
3410
|
}
|
|
3293
3411
|
|
|
3294
3412
|
if (!update && this._promises.getCompactSystemRepositories) {
|
|
3295
|
-
return this._promises.getCompactSystemRepositories
|
|
3413
|
+
return this._promises.getCompactSystemRepositories;
|
|
3296
3414
|
}
|
|
3297
3415
|
|
|
3298
3416
|
if (!this.connected) {
|
|
3299
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3417
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3300
3418
|
}
|
|
3301
3419
|
|
|
3302
3420
|
this._promises.getCompactSystemRepositories = new Promise((resolve, reject) => {
|
|
3303
3421
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
3304
3422
|
if (timeout) {
|
|
3305
3423
|
timeout = null;
|
|
3306
|
-
reject('getCompactSystemRepositories timeout');
|
|
3424
|
+
reject(new Error('getCompactSystemRepositories timeout'));
|
|
3307
3425
|
}
|
|
3308
3426
|
}, cmdTimeout || this.props.cmdTimeout);
|
|
3309
3427
|
|
|
3310
|
-
this._socket.emit('getCompactSystemRepositories', (data:
|
|
3428
|
+
this._socket.emit('getCompactSystemRepositories', (data: CompactSystemRepository | string) => {
|
|
3311
3429
|
if (timeout) {
|
|
3312
3430
|
clearTimeout(timeout);
|
|
3313
3431
|
timeout = null;
|
|
3314
3432
|
if (data === PERMISSION_ERROR) {
|
|
3315
|
-
reject('May not read "getCompactSystemRepositories"');
|
|
3433
|
+
reject(new Error('May not read "getCompactSystemRepositories"'));
|
|
3316
3434
|
} else if (!data || typeof data !== 'object') {
|
|
3317
|
-
reject('Cannot read "getCompactSystemRepositories"');
|
|
3435
|
+
reject(new Error('Cannot read "getCompactSystemRepositories"'));
|
|
3318
3436
|
} else {
|
|
3319
3437
|
resolve(data);
|
|
3320
3438
|
}
|
|
@@ -3332,12 +3450,15 @@ class Connection {
|
|
|
3332
3450
|
}
|
|
3333
3451
|
|
|
3334
3452
|
if (!this.connected) {
|
|
3335
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3453
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3336
3454
|
}
|
|
3337
3455
|
|
|
3338
3456
|
this._promises.systemConfigPromise = new Promise((resolve, reject) => {
|
|
3339
|
-
this._socket.emit(
|
|
3340
|
-
|
|
3457
|
+
this._socket.emit(
|
|
3458
|
+
'getCompactSystemConfig',
|
|
3459
|
+
(err: string | null, systemConfig: ioBroker.SystemConfigObject) =>
|
|
3460
|
+
err ? reject(new Error(err)) : resolve(systemConfig),
|
|
3461
|
+
);
|
|
3341
3462
|
});
|
|
3342
3463
|
|
|
3343
3464
|
return this._promises.systemConfigPromise;
|
|
@@ -3345,10 +3466,10 @@ class Connection {
|
|
|
3345
3466
|
|
|
3346
3467
|
/**
|
|
3347
3468
|
* Get the repository in compact form (only version and icon).
|
|
3348
|
-
*
|
|
3349
|
-
* @param
|
|
3350
|
-
* @param
|
|
3351
|
-
* @
|
|
3469
|
+
*
|
|
3470
|
+
* @param host The host name.
|
|
3471
|
+
* @param update Force update.
|
|
3472
|
+
* @param timeoutMs timeout in ms.
|
|
3352
3473
|
*/
|
|
3353
3474
|
getCompactRepository(
|
|
3354
3475
|
host: string,
|
|
@@ -3356,7 +3477,7 @@ class Connection {
|
|
|
3356
3477
|
timeoutMs?: number,
|
|
3357
3478
|
): Promise<Record<string, { version: string; icon: string }>> {
|
|
3358
3479
|
if (Connection.isWeb()) {
|
|
3359
|
-
return Promise.reject('Allowed only in admin');
|
|
3480
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3360
3481
|
}
|
|
3361
3482
|
|
|
3362
3483
|
if (!update && this._promises.repoCompact) {
|
|
@@ -3364,7 +3485,7 @@ class Connection {
|
|
|
3364
3485
|
}
|
|
3365
3486
|
|
|
3366
3487
|
if (!this.connected) {
|
|
3367
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3488
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3368
3489
|
}
|
|
3369
3490
|
|
|
3370
3491
|
if (!host.startsWith('system.host.')) {
|
|
@@ -3375,29 +3496,33 @@ class Connection {
|
|
|
3375
3496
|
let timeout: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
3376
3497
|
if (timeout) {
|
|
3377
3498
|
timeout = null;
|
|
3378
|
-
reject('getCompactRepository timeout');
|
|
3499
|
+
reject(new Error('getCompactRepository timeout'));
|
|
3379
3500
|
}
|
|
3380
3501
|
}, timeoutMs || this.props.cmdTimeout);
|
|
3381
3502
|
|
|
3382
|
-
this._socket.emit(
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
if (
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3503
|
+
this._socket.emit(
|
|
3504
|
+
'getCompactRepository',
|
|
3505
|
+
host,
|
|
3506
|
+
(data: Record<string, { version: string; icon: string }> | string) => {
|
|
3507
|
+
if (timeout) {
|
|
3508
|
+
clearTimeout(timeout);
|
|
3509
|
+
timeout = null;
|
|
3510
|
+
if (data === PERMISSION_ERROR) {
|
|
3511
|
+
reject(new Error('May not read "getCompactRepository"'));
|
|
3512
|
+
} else if (!data) {
|
|
3513
|
+
reject(new Error('Cannot read "getCompactRepository"'));
|
|
3514
|
+
} else {
|
|
3515
|
+
resolve(data);
|
|
3516
|
+
}
|
|
3392
3517
|
}
|
|
3393
|
-
}
|
|
3394
|
-
|
|
3518
|
+
},
|
|
3519
|
+
);
|
|
3395
3520
|
});
|
|
3396
3521
|
|
|
3397
3522
|
return this._promises.repoCompact;
|
|
3398
3523
|
}
|
|
3399
3524
|
|
|
3400
|
-
getInstalledResetCache() {
|
|
3525
|
+
getInstalledResetCache(): void {
|
|
3401
3526
|
delete this._promises.repoCompact;
|
|
3402
3527
|
delete this._promises.repo;
|
|
3403
3528
|
}
|
|
@@ -3407,19 +3532,20 @@ class Connection {
|
|
|
3407
3532
|
*/
|
|
3408
3533
|
getCompactHosts(update?: boolean): Promise<ioBroker.HostObject[]> {
|
|
3409
3534
|
if (Connection.isWeb()) {
|
|
3410
|
-
return Promise.reject('Allowed only in admin');
|
|
3535
|
+
return Promise.reject(new Error('Allowed only in admin'));
|
|
3411
3536
|
}
|
|
3412
3537
|
if (!update && this._promises.hostsCompact) {
|
|
3413
3538
|
return this._promises.hostsCompact;
|
|
3414
3539
|
}
|
|
3415
3540
|
|
|
3416
3541
|
if (!this.connected) {
|
|
3417
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3542
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3418
3543
|
}
|
|
3419
3544
|
|
|
3420
3545
|
this._promises.hostsCompact = new Promise((resolve, reject) => {
|
|
3421
3546
|
this._socket.emit('getCompactHosts', (err: string | null, hosts: ioBroker.HostObject[]) =>
|
|
3422
|
-
|
|
3547
|
+
err ? reject(new Error(err)) : resolve(hosts),
|
|
3548
|
+
);
|
|
3423
3549
|
});
|
|
3424
3550
|
|
|
3425
3551
|
return this._promises.hostsCompact;
|
|
@@ -3434,34 +3560,30 @@ class Connection {
|
|
|
3434
3560
|
}
|
|
3435
3561
|
|
|
3436
3562
|
if (!this.connected) {
|
|
3437
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3563
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3438
3564
|
}
|
|
3439
3565
|
|
|
3440
|
-
this._promises.uuid = this.getObject('system.meta.uuid')
|
|
3441
|
-
.then(obj => obj?.native?.uuid);
|
|
3566
|
+
this._promises.uuid = this.getObject('system.meta.uuid').then(obj => obj?.native?.uuid);
|
|
3442
3567
|
|
|
3443
3568
|
return this._promises.uuid;
|
|
3444
3569
|
}
|
|
3445
3570
|
|
|
3446
3571
|
/**
|
|
3447
3572
|
* Subscribe on instance message
|
|
3448
|
-
*
|
|
3449
|
-
* @param
|
|
3450
|
-
* @param
|
|
3451
|
-
* @param
|
|
3452
|
-
* @
|
|
3573
|
+
*
|
|
3574
|
+
* @param targetInstance instance, like 'cameras.0'
|
|
3575
|
+
* @param messageType message type like 'startCamera/cam3'
|
|
3576
|
+
* @param data optional data object
|
|
3577
|
+
* @param callback message handler
|
|
3453
3578
|
*/
|
|
3454
3579
|
subscribeOnInstance(
|
|
3455
|
-
/** instance, like 'cameras.0' */
|
|
3456
3580
|
targetInstance: string,
|
|
3457
|
-
/** message type like 'startCamera/cam3' */
|
|
3458
3581
|
messageType: string,
|
|
3459
3582
|
data: any,
|
|
3460
|
-
/** message handler. Could be null if all callbacks for this messageType should be unsubscribed */
|
|
3461
3583
|
callback: (_data: Record<string, any>, sourceInstance: string, _messageType: string) => void,
|
|
3462
|
-
) {
|
|
3584
|
+
): Promise<{ error?: string; accepted?: boolean; heartbeat?: number }> {
|
|
3463
3585
|
if (!this.connected) {
|
|
3464
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3586
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3465
3587
|
}
|
|
3466
3588
|
return new Promise((resolve, reject) => {
|
|
3467
3589
|
this._socket.emit(
|
|
@@ -3471,18 +3593,19 @@ class Connection {
|
|
|
3471
3593
|
data,
|
|
3472
3594
|
(err: string | null, result: { error?: string; accepted?: boolean; heartbeat?: number }) => {
|
|
3473
3595
|
if (err) {
|
|
3474
|
-
reject(err);
|
|
3475
|
-
} else if (result
|
|
3476
|
-
reject(result.error);
|
|
3596
|
+
reject(new Error(err));
|
|
3597
|
+
} else if (result?.error) {
|
|
3598
|
+
reject(new Error(result.error));
|
|
3477
3599
|
} else {
|
|
3478
3600
|
if (!targetInstance.startsWith('system.adapter.')) {
|
|
3479
3601
|
targetInstance = `system.adapter.${targetInstance}`;
|
|
3480
3602
|
}
|
|
3481
3603
|
// save callback
|
|
3482
3604
|
this._instanceSubscriptions[targetInstance] = this._instanceSubscriptions[targetInstance] || [];
|
|
3483
|
-
if (
|
|
3484
|
-
|
|
3485
|
-
|
|
3605
|
+
if (
|
|
3606
|
+
!this._instanceSubscriptions[targetInstance].find(
|
|
3607
|
+
sub => sub.messageType === messageType && sub.callback === callback,
|
|
3608
|
+
)
|
|
3486
3609
|
) {
|
|
3487
3610
|
this._instanceSubscriptions[targetInstance].push({
|
|
3488
3611
|
messageType,
|
|
@@ -3498,13 +3621,14 @@ class Connection {
|
|
|
3498
3621
|
|
|
3499
3622
|
/**
|
|
3500
3623
|
* Unsubscribe from instance message
|
|
3624
|
+
*
|
|
3625
|
+
* @param targetInstance instance, like 'cameras.0'
|
|
3626
|
+
* @param messageType message type like 'startCamera/cam3'
|
|
3627
|
+
* @param callback message handler. Could be null if all callbacks for this messageType should be unsubscribed
|
|
3501
3628
|
*/
|
|
3502
3629
|
unsubscribeFromInstance(
|
|
3503
|
-
/** instance, like 'cameras.0' */
|
|
3504
3630
|
targetInstance: string,
|
|
3505
|
-
/** message type like 'startCamera/cam3' */
|
|
3506
3631
|
messageType?: string,
|
|
3507
|
-
/** message handler. Could be null if all callbacks for this messageType should be unsubscribed */
|
|
3508
3632
|
callback?: (data: Record<string, any>, sourceInstance: string, _messageType: string) => void,
|
|
3509
3633
|
): Promise<boolean> {
|
|
3510
3634
|
if (!targetInstance.startsWith('system.adapter.')) {
|
|
@@ -3514,14 +3638,14 @@ class Connection {
|
|
|
3514
3638
|
const promiseResults: Promise<boolean>[] = [];
|
|
3515
3639
|
do {
|
|
3516
3640
|
deleted = false;
|
|
3517
|
-
const index = this._instanceSubscriptions[targetInstance]?.findIndex(
|
|
3518
|
-
(!messageType || sub.messageType === messageType) && (!callback || sub.callback === callback)
|
|
3641
|
+
const index = this._instanceSubscriptions[targetInstance]?.findIndex(
|
|
3642
|
+
sub => (!messageType || sub.messageType === messageType) && (!callback || sub.callback === callback),
|
|
3643
|
+
);
|
|
3519
3644
|
|
|
3520
3645
|
if (index !== undefined && index !== null && index !== -1) {
|
|
3521
3646
|
deleted = true;
|
|
3522
3647
|
// remember messageType
|
|
3523
|
-
const _messageType =
|
|
3524
|
-
this._instanceSubscriptions[targetInstance][index].messageType;
|
|
3648
|
+
const _messageType = this._instanceSubscriptions[targetInstance][index].messageType;
|
|
3525
3649
|
|
|
3526
3650
|
this._instanceSubscriptions[targetInstance].splice(index, 1);
|
|
3527
3651
|
if (!this._instanceSubscriptions[targetInstance].length) {
|
|
@@ -3529,26 +3653,33 @@ class Connection {
|
|
|
3529
3653
|
}
|
|
3530
3654
|
|
|
3531
3655
|
// try to find another subscription for this instance and messageType
|
|
3532
|
-
const found =
|
|
3656
|
+
const found =
|
|
3657
|
+
this._instanceSubscriptions[targetInstance] &&
|
|
3533
3658
|
this._instanceSubscriptions[targetInstance].find(sub => sub.messageType === _messageType);
|
|
3534
3659
|
|
|
3535
3660
|
if (!found) {
|
|
3536
|
-
promiseResults.push(
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3661
|
+
promiseResults.push(
|
|
3662
|
+
new Promise((resolve, reject) => {
|
|
3663
|
+
this._socket.emit(
|
|
3664
|
+
'clientUnsubscribe',
|
|
3665
|
+
targetInstance,
|
|
3666
|
+
messageType,
|
|
3667
|
+
(err: string | null, wasSubscribed: boolean) => {
|
|
3668
|
+
if (err) {
|
|
3669
|
+
reject(new Error(err));
|
|
3670
|
+
} else {
|
|
3671
|
+
resolve(wasSubscribed);
|
|
3672
|
+
}
|
|
3673
|
+
},
|
|
3674
|
+
);
|
|
3675
|
+
}),
|
|
3676
|
+
);
|
|
3545
3677
|
}
|
|
3546
3678
|
}
|
|
3547
3679
|
} while (deleted && (!callback || !messageType));
|
|
3548
3680
|
|
|
3549
3681
|
if (promiseResults.length) {
|
|
3550
|
-
return Promise.all(promiseResults)
|
|
3551
|
-
.then((results: boolean[]) => results.find(result => result) || false);
|
|
3682
|
+
return Promise.all(promiseResults).then((results: boolean[]) => results.find(result => result) || false);
|
|
3552
3683
|
}
|
|
3553
3684
|
|
|
3554
3685
|
return Promise.resolve(false);
|
|
@@ -3563,25 +3694,24 @@ class Connection {
|
|
|
3563
3694
|
|
|
3564
3695
|
/**
|
|
3565
3696
|
* Logout current user
|
|
3566
|
-
* @returns {Promise<null>}
|
|
3567
3697
|
*/
|
|
3568
3698
|
logout(): Promise<void> {
|
|
3569
3699
|
if (!this.connected) {
|
|
3570
|
-
return Promise.reject(NOT_CONNECTED);
|
|
3700
|
+
return Promise.reject(new Error(NOT_CONNECTED));
|
|
3571
3701
|
}
|
|
3572
3702
|
|
|
3573
3703
|
return new Promise((resolve, reject) => {
|
|
3574
|
-
this._socket.emit('logout', (err: string | null) =>
|
|
3575
|
-
(err ? reject(err) : resolve()));
|
|
3704
|
+
this._socket.emit('logout', (err: string | null) => (err ? reject(new Error(err)) : resolve()));
|
|
3576
3705
|
});
|
|
3577
3706
|
}
|
|
3578
3707
|
|
|
3579
3708
|
/**
|
|
3580
3709
|
* This is a special method for vis.
|
|
3581
3710
|
* It is used to not send to server the changes about "nothing_selected" state
|
|
3711
|
+
*
|
|
3582
3712
|
* @param id The state that has to be ignored by communication
|
|
3583
3713
|
*/
|
|
3584
|
-
setStateToIgnore(id?: string | null) {
|
|
3714
|
+
setStateToIgnore(id?: string | null): void {
|
|
3585
3715
|
this.ignoreState = id || '';
|
|
3586
3716
|
}
|
|
3587
3717
|
}
|