matterbridge-example-dynamic-platform 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -9
- package/README.md +4 -2
- package/dist/{platform.js → module.js} +3 -0
- package/npm-shrinkwrap.json +3 -3
- package/package.json +3 -3
- package/dist/index.js +0 -4
- package/dist/jestHelpers.js +0 -231
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD024 MD033 -->
|
|
2
|
+
|
|
1
3
|
# <img src="matterbridge.svg" alt="Matterbridge Logo" width="64px" height="64px"> Matterbridge dynamic platform example plugin changelog
|
|
2
4
|
|
|
3
5
|
[](https://www.npmjs.com/package/matterbridge-example-dynamic-platform)
|
|
@@ -17,31 +19,46 @@
|
|
|
17
19
|
|
|
18
20
|
All notable changes to this project will be documented in this file.
|
|
19
21
|
|
|
20
|
-
If you like this project and find it useful, please consider giving it a star on GitHub at https://github.com/Luligu/matterbridge-example-dynamic-platform and sponsoring it.
|
|
22
|
+
If you like this project and find it useful, please consider giving it a star on GitHub at <https://github.com/Luligu/matterbridge-example-dynamic-platform> and sponsoring it.
|
|
21
23
|
|
|
22
24
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
23
25
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="120">
|
|
24
26
|
</a>
|
|
25
27
|
|
|
28
|
+
## [2.0.0] - 2025-10-24
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- [package]: Bumped platform to v. 2.0.0.
|
|
33
|
+
- [package]: Updated dependencies.
|
|
34
|
+
- [package]: Bumped package to automator version 2.0.9
|
|
35
|
+
- [jest]: Updated jestHelpers to v. 1.0.9.
|
|
36
|
+
|
|
37
|
+
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
38
|
+
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
39
|
+
</a>
|
|
40
|
+
|
|
26
41
|
## [1.4.0] - 2025-10-15
|
|
27
42
|
|
|
28
43
|
### Added
|
|
29
44
|
|
|
30
45
|
- [jest]: Added jest helper module v. 1.0.6.
|
|
31
46
|
- [platform]: Added a thermostat with auto mode and occupancy and outdoorTemperature.
|
|
32
|
-
- [platform]: Added animation to Heat pump. Thanks Ludovic BOUÉ (https://github.com/Luligu/matterbridge-example-dynamic-platform/pull/35).
|
|
33
|
-
- [platform]: Added Toggle thermostatRunningState heat and cool. Thanks Ludovic BOUÉ (https://github.com/Luligu/matterbridge-example-dynamic-platform/pull/36).
|
|
47
|
+
- [platform]: Added animation to Heat pump. Thanks Ludovic BOUÉ (<https://github.com/Luligu/matterbridge-example-dynamic-platform/pull/35>).
|
|
48
|
+
- [platform]: Added Toggle thermostatRunningState heat and cool. Thanks Ludovic BOUÉ (<https://github.com/Luligu/matterbridge-example-dynamic-platform/pull/36>).
|
|
34
49
|
|
|
35
50
|
### Changed
|
|
36
51
|
|
|
37
52
|
- [package]: Require matterbridge 3.3.0.
|
|
38
53
|
- [index]: Updated to new signature PlatformMatterbridge.
|
|
39
54
|
- [platform]: Updated to new signature PlatformMatterbridge.
|
|
40
|
-
- [platform]: Added whiteList and blackList.
|
|
41
|
-
- [platform]: Typed TestPlatformConfig.
|
|
42
55
|
- [package]: Updated dependencies.
|
|
43
56
|
- [package]: Bumped package to automator version 2.0.7
|
|
44
|
-
- [workflows]: Ignore any .md
|
|
57
|
+
- [workflows]: Ignore any .md in build.yaml.
|
|
58
|
+
- [workflows]: Ignore any .md in codeql.yaml.
|
|
59
|
+
- [workflows]: Ignore any .md in codecov.yaml.
|
|
60
|
+
- [template]: Updated bug_report.md.
|
|
61
|
+
- [jest]: Updated jestHelpers to v. 1.0.6.
|
|
45
62
|
|
|
46
63
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
47
64
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
@@ -52,7 +69,7 @@ If you like this project and find it useful, please consider giving it a star on
|
|
|
52
69
|
### Added
|
|
53
70
|
|
|
54
71
|
- [jest]: Added jest helper module v. 1.0.5.
|
|
55
|
-
- [rvc]: Added DustBinFull to the Rvc animation (https://github.com/Luligu/matterbridge-example-dynamic-platform/pull/31).
|
|
72
|
+
- [rvc]: Added DustBinFull to the Rvc animation (<https://github.com/Luligu/matterbridge-example-dynamic-platform/pull/31>).
|
|
56
73
|
|
|
57
74
|
### Changed
|
|
58
75
|
|
|
@@ -69,7 +86,7 @@ If you like this project and find it useful, please consider giving it a star on
|
|
|
69
86
|
### Changed
|
|
70
87
|
|
|
71
88
|
- [package]: Updated dependencies.
|
|
72
|
-
- [platform]: Removed attributes setting when is managed by the Matterbridge servers. This add support for **Apple Home Adaptive Lighting**. See https://github.com/Luligu/matterbridge/discussions/390
|
|
89
|
+
- [platform]: Removed attributes setting when is managed by the Matterbridge servers. This add support for **Apple Home Adaptive Lighting**. See <https://github.com/Luligu/matterbridge/discussions/390>.
|
|
73
90
|
|
|
74
91
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
75
92
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
@@ -333,7 +350,7 @@ If you like this project and find it useful, please consider giving it a star on
|
|
|
333
350
|
|
|
334
351
|
### Added
|
|
335
352
|
|
|
336
|
-
- [platform]: Added Robot Vacuum Cleaner device (supported by SmartThings, Alexa, Home Assistant and partially by Apple Home). Read carefully the readme please and also https://github.com/Luligu/matterbridge/discussions/264
|
|
353
|
+
- [platform]: Added Robot Vacuum Cleaner device (supported by SmartThings, Alexa, Home Assistant and partially by Apple Home). Read carefully the readme please and also <https://github.com/Luligu/matterbridge/discussions/264>.
|
|
337
354
|
- [platform]: Added OnOff Mounted Switch device (supported by SmartThings, Alexa, Home Assistant).
|
|
338
355
|
- [platform]: Added Dimmer Mounted Switch device (supported by SmartThings, Alexa, Home Assistant).
|
|
339
356
|
- [platform]: Added Laundry Washer device (supported by SmartThings, Alexa and Home Assistant).
|
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD033 -->
|
|
2
|
+
|
|
1
3
|
# <img src="matterbridge.svg" alt="Matterbridge Logo" width="64px" height="64px"> Matterbridge dynamic platform example plugin
|
|
2
4
|
|
|
3
5
|
[](https://www.npmjs.com/package/matterbridge-example-dynamic-platform)
|
|
@@ -61,7 +63,7 @@ It exposes 58 virtual devices:
|
|
|
61
63
|
- an airQuality device with all concentration measurements clusters (supported by Apple Home with the concentration measurements from version 18.5)
|
|
62
64
|
- a momentary switch composed by three switches with Single Double Long (tagged with One Two Three and Top Middle Bottom) and three switches with Single only.
|
|
63
65
|
- a latching switch
|
|
64
|
-
- a Robot Vacuum Cleaner device (supported by SmartThings, Alexa, Home Assistant and partially by Apple Home). Read also https://github.com/Luligu/matterbridge/discussions/264
|
|
66
|
+
- a Robot Vacuum Cleaner device (supported by SmartThings, Alexa, Home Assistant and partially by Apple Home). Read also <https://github.com/Luligu/matterbridge/discussions/264>.
|
|
65
67
|
- a onOff Mounted Switch device (supported by SmartThings, Alexa, Home Assistant)
|
|
66
68
|
- a dimmer Mounted Switch device (supported by SmartThings, Alexa, Home Assistant)
|
|
67
69
|
- a laundry Washer device (supported by SmartThings, Alexa and Home Assistant)
|
|
@@ -83,7 +85,7 @@ All these devices continuously change state and position. The plugin also shows
|
|
|
83
85
|
|
|
84
86
|
If you want to write your plugin, the easiest way to start create a new plugin is to clone the [Matterbridge Plugin Template](https://github.com/Luligu/matterbridge-plugin-template) which has **Dev Container support for instant development environment** and all tools and extensions (like Node.js, npm, TypeScript, ESLint, Prettier, Jest and Vitest) already loaded and configured.
|
|
85
87
|
|
|
86
|
-
If you like this project and find it useful, please consider giving it a star on GitHub at https://github.com/Luligu/matterbridge-example-dynamic-platform and sponsoring it.
|
|
88
|
+
If you like this project and find it useful, please consider giving it a star on GitHub at <https://github.com/Luligu/matterbridge-example-dynamic-platform> and sponsoring it.
|
|
87
89
|
|
|
88
90
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
89
91
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="120">
|
|
@@ -19,6 +19,9 @@ function matterToLux(value) {
|
|
|
19
19
|
const lux = Math.pow(10, v / 10000);
|
|
20
20
|
return Math.round(lux < 0 ? 0 : lux);
|
|
21
21
|
}
|
|
22
|
+
export default function initializePlugin(matterbridge, log, config) {
|
|
23
|
+
return new ExampleMatterbridgeDynamicPlatform(matterbridge, log, config);
|
|
24
|
+
}
|
|
22
25
|
export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatform {
|
|
23
26
|
config;
|
|
24
27
|
door;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge-example-dynamic-platform",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge-example-dynamic-platform",
|
|
9
|
-
"version": "
|
|
9
|
+
"version": "2.0.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"node-ansi-logger": "3.1.1",
|
|
13
13
|
"node-persist-manager": "2.0.0"
|
|
14
14
|
},
|
|
15
15
|
"engines": {
|
|
16
|
-
"node": ">=
|
|
16
|
+
"node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
|
|
17
17
|
},
|
|
18
18
|
"funding": {
|
|
19
19
|
"type": "buymeacoffee",
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge-example-dynamic-platform",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Matterbridge dynamic plugin",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"homepage": "https://www.npmjs.com/package/matterbridge-example-dynamic-platform",
|
|
8
8
|
"type": "module",
|
|
9
|
-
"main": "dist/
|
|
9
|
+
"main": "dist/module.js",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git+https://github.com/Luligu/matterbridge-example-dynamic-platform.git"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"virtual devices"
|
|
32
32
|
],
|
|
33
33
|
"engines": {
|
|
34
|
-
"node": ">=
|
|
34
|
+
"node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"node-ansi-logger": "3.1.1",
|
package/dist/index.js
DELETED
package/dist/jestHelpers.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import { rmSync } from 'node:fs';
|
|
2
|
-
import { inspect } from 'node:util';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { jest } from '@jest/globals';
|
|
5
|
-
import { DeviceTypeId, Endpoint, Environment, MdnsService, ServerNode, ServerNodeStore, VendorId, LogFormat as MatterLogFormat, LogLevel as MatterLogLevel, Lifecycle, } from 'matterbridge/matter';
|
|
6
|
-
import { RootEndpoint, AggregatorEndpoint } from 'matterbridge/matter/endpoints';
|
|
7
|
-
import { AnsiLogger } from 'matterbridge/logger';
|
|
8
|
-
export let loggerLogSpy;
|
|
9
|
-
export let consoleLogSpy;
|
|
10
|
-
export let consoleDebugSpy;
|
|
11
|
-
export let consoleInfoSpy;
|
|
12
|
-
export let consoleWarnSpy;
|
|
13
|
-
export let consoleErrorSpy;
|
|
14
|
-
export function setupTest(name, debug = false) {
|
|
15
|
-
expect(name).toBeDefined();
|
|
16
|
-
expect(typeof name).toBe('string');
|
|
17
|
-
expect(name.length).toBeGreaterThanOrEqual(4);
|
|
18
|
-
rmSync(path.join('jest', name), { recursive: true, force: true });
|
|
19
|
-
if (debug) {
|
|
20
|
-
loggerLogSpy = jest.spyOn(AnsiLogger.prototype, 'log');
|
|
21
|
-
consoleLogSpy = jest.spyOn(console, 'log');
|
|
22
|
-
consoleDebugSpy = jest.spyOn(console, 'debug');
|
|
23
|
-
consoleInfoSpy = jest.spyOn(console, 'info');
|
|
24
|
-
consoleWarnSpy = jest.spyOn(console, 'warn');
|
|
25
|
-
consoleErrorSpy = jest.spyOn(console, 'error');
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
loggerLogSpy = jest.spyOn(AnsiLogger.prototype, 'log').mockImplementation(() => { });
|
|
29
|
-
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
30
|
-
consoleDebugSpy = jest.spyOn(console, 'debug').mockImplementation(() => { });
|
|
31
|
-
consoleInfoSpy = jest.spyOn(console, 'info').mockImplementation(() => { });
|
|
32
|
-
consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => { });
|
|
33
|
-
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export function setDebug(debug) {
|
|
37
|
-
if (debug) {
|
|
38
|
-
loggerLogSpy.mockRestore();
|
|
39
|
-
consoleLogSpy.mockRestore();
|
|
40
|
-
consoleDebugSpy.mockRestore();
|
|
41
|
-
consoleInfoSpy.mockRestore();
|
|
42
|
-
consoleWarnSpy.mockRestore();
|
|
43
|
-
consoleErrorSpy.mockRestore();
|
|
44
|
-
loggerLogSpy = jest.spyOn(AnsiLogger.prototype, 'log');
|
|
45
|
-
consoleLogSpy = jest.spyOn(console, 'log');
|
|
46
|
-
consoleDebugSpy = jest.spyOn(console, 'debug');
|
|
47
|
-
consoleInfoSpy = jest.spyOn(console, 'info');
|
|
48
|
-
consoleWarnSpy = jest.spyOn(console, 'warn');
|
|
49
|
-
consoleErrorSpy = jest.spyOn(console, 'error');
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
loggerLogSpy = jest.spyOn(AnsiLogger.prototype, 'log').mockImplementation(() => { });
|
|
53
|
-
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
54
|
-
consoleDebugSpy = jest.spyOn(console, 'debug').mockImplementation(() => { });
|
|
55
|
-
consoleInfoSpy = jest.spyOn(console, 'info').mockImplementation(() => { });
|
|
56
|
-
consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => { });
|
|
57
|
-
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
export function createTestEnvironment(homeDir) {
|
|
61
|
-
expect(homeDir).toBeDefined();
|
|
62
|
-
expect(typeof homeDir).toBe('string');
|
|
63
|
-
expect(homeDir.length).toBeGreaterThanOrEqual(4);
|
|
64
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
65
|
-
const environment = Environment.default;
|
|
66
|
-
environment.vars.set('log.level', MatterLogLevel.DEBUG);
|
|
67
|
-
environment.vars.set('log.format', MatterLogFormat.ANSI);
|
|
68
|
-
environment.vars.set('path.root', homeDir);
|
|
69
|
-
environment.vars.set('runtime.signals', false);
|
|
70
|
-
environment.vars.set('runtime.exitcode', false);
|
|
71
|
-
return environment;
|
|
72
|
-
}
|
|
73
|
-
export async function flushAsync(ticks = 3, microTurns = 10, pause = 100) {
|
|
74
|
-
for (let i = 0; i < ticks; i++)
|
|
75
|
-
await new Promise((resolve) => setImmediate(resolve));
|
|
76
|
-
for (let i = 0; i < microTurns; i++)
|
|
77
|
-
await Promise.resolve();
|
|
78
|
-
if (pause)
|
|
79
|
-
await new Promise((resolve) => setTimeout(resolve, pause));
|
|
80
|
-
}
|
|
81
|
-
export async function flushAllEndpointNumberPersistence(targetServer, rounds = 2) {
|
|
82
|
-
const nodeStore = targetServer.env.get(ServerNodeStore);
|
|
83
|
-
for (let i = 0; i < rounds; i++) {
|
|
84
|
-
await new Promise((resolve) => setImmediate(resolve));
|
|
85
|
-
await nodeStore.endpointStores.close();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function collectAllEndpoints(root) {
|
|
89
|
-
const list = [];
|
|
90
|
-
const walk = (ep) => {
|
|
91
|
-
list.push(ep);
|
|
92
|
-
if (ep.parts) {
|
|
93
|
-
for (const child of ep.parts) {
|
|
94
|
-
walk(child);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
walk(root);
|
|
99
|
-
return list;
|
|
100
|
-
}
|
|
101
|
-
export async function assertAllEndpointNumbersPersisted(targetServer) {
|
|
102
|
-
const nodeStore = targetServer.env.get(ServerNodeStore);
|
|
103
|
-
await nodeStore.endpointStores.close();
|
|
104
|
-
const all = collectAllEndpoints(targetServer);
|
|
105
|
-
for (const ep of all) {
|
|
106
|
-
const store = nodeStore.storeForEndpoint(ep);
|
|
107
|
-
if (ep.maybeNumber === 0) {
|
|
108
|
-
expect(store.number ?? 0).toBe(0);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
expect(store.number).toBeGreaterThan(0);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return all.length;
|
|
115
|
-
}
|
|
116
|
-
export async function startServerNode(name, port) {
|
|
117
|
-
const server = await ServerNode.create({
|
|
118
|
-
id: name + 'ServerNode',
|
|
119
|
-
productDescription: {
|
|
120
|
-
name: name + 'ServerNode',
|
|
121
|
-
deviceType: DeviceTypeId(RootEndpoint.deviceType),
|
|
122
|
-
vendorId: VendorId(0xfff1),
|
|
123
|
-
productId: 0x8000,
|
|
124
|
-
},
|
|
125
|
-
basicInformation: {
|
|
126
|
-
vendorId: VendorId(0xfff1),
|
|
127
|
-
vendorName: 'Matterbridge',
|
|
128
|
-
productId: 0x8000,
|
|
129
|
-
productName: 'Matterbridge ' + name,
|
|
130
|
-
nodeLabel: name + 'ServerNode',
|
|
131
|
-
hardwareVersion: 1,
|
|
132
|
-
softwareVersion: 1,
|
|
133
|
-
reachable: true,
|
|
134
|
-
},
|
|
135
|
-
network: {
|
|
136
|
-
port,
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
expect(server).toBeDefined();
|
|
140
|
-
expect(server.lifecycle.isReady).toBeTruthy();
|
|
141
|
-
const aggregator = new Endpoint(AggregatorEndpoint, {
|
|
142
|
-
id: name + 'AggregatorNode',
|
|
143
|
-
});
|
|
144
|
-
expect(aggregator).toBeDefined();
|
|
145
|
-
await server.add(aggregator);
|
|
146
|
-
expect(server.parts.has(aggregator.id)).toBeTruthy();
|
|
147
|
-
expect(server.parts.has(aggregator)).toBeTruthy();
|
|
148
|
-
expect(aggregator.lifecycle.isReady).toBeTruthy();
|
|
149
|
-
expect(server.lifecycle.isOnline).toBeFalsy();
|
|
150
|
-
await new Promise((resolve) => {
|
|
151
|
-
server.lifecycle.online.on(async () => {
|
|
152
|
-
resolve();
|
|
153
|
-
});
|
|
154
|
-
server.start();
|
|
155
|
-
});
|
|
156
|
-
expect(server.lifecycle.isReady).toBeTruthy();
|
|
157
|
-
expect(server.lifecycle.isOnline).toBeTruthy();
|
|
158
|
-
expect(server.lifecycle.isCommissioned).toBeFalsy();
|
|
159
|
-
expect(server.lifecycle.isPartsReady).toBeTruthy();
|
|
160
|
-
expect(server.lifecycle.hasId).toBeTruthy();
|
|
161
|
-
expect(server.lifecycle.hasNumber).toBeTruthy();
|
|
162
|
-
expect(aggregator.lifecycle.isReady).toBeTruthy();
|
|
163
|
-
expect(aggregator.lifecycle.isInstalled).toBeTruthy();
|
|
164
|
-
expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
|
|
165
|
-
expect(aggregator.lifecycle.hasId).toBeTruthy();
|
|
166
|
-
expect(aggregator.lifecycle.hasNumber).toBeTruthy();
|
|
167
|
-
await flushAsync(undefined, undefined, 200);
|
|
168
|
-
return [server, aggregator];
|
|
169
|
-
}
|
|
170
|
-
export async function stopServerNode(server) {
|
|
171
|
-
await flushAllEndpointNumberPersistence(server);
|
|
172
|
-
await assertAllEndpointNumbersPersisted(server);
|
|
173
|
-
expect(server).toBeDefined();
|
|
174
|
-
expect(server.lifecycle.isReady).toBeTruthy();
|
|
175
|
-
expect(server.lifecycle.isOnline).toBeTruthy();
|
|
176
|
-
await server.close();
|
|
177
|
-
expect(server.lifecycle.isReady).toBeTruthy();
|
|
178
|
-
expect(server.lifecycle.isOnline).toBeFalsy();
|
|
179
|
-
await server.env.get(MdnsService)[Symbol.asyncDispose]();
|
|
180
|
-
await flushAsync(undefined, undefined, 200);
|
|
181
|
-
}
|
|
182
|
-
export async function addDevice(owner, device, pause = 10) {
|
|
183
|
-
expect(owner).toBeDefined();
|
|
184
|
-
expect(device).toBeDefined();
|
|
185
|
-
expect(owner.lifecycle.isReady).toBeTruthy();
|
|
186
|
-
expect(owner.construction.status).toBe(Lifecycle.Status.Active);
|
|
187
|
-
expect(owner.lifecycle.isPartsReady).toBeTruthy();
|
|
188
|
-
try {
|
|
189
|
-
await owner.add(device);
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
const errorMessage = error instanceof Error ? error.message : error;
|
|
193
|
-
const errorInspect = inspect(error, { depth: 10 });
|
|
194
|
-
console.error(`Error adding device ${device.maybeId}.${device.maybeNumber}: ${errorMessage}\nstack: ${errorInspect}`);
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
expect(owner.parts.has(device)).toBeTruthy();
|
|
198
|
-
expect(owner.lifecycle.isPartsReady).toBeTruthy();
|
|
199
|
-
expect(device.lifecycle.isReady).toBeTruthy();
|
|
200
|
-
expect(device.lifecycle.isInstalled).toBeTruthy();
|
|
201
|
-
expect(device.lifecycle.hasId).toBeTruthy();
|
|
202
|
-
expect(device.lifecycle.hasNumber).toBeTruthy();
|
|
203
|
-
expect(device.construction.status).toBe(Lifecycle.Status.Active);
|
|
204
|
-
await flushAsync(1, 1, pause);
|
|
205
|
-
return true;
|
|
206
|
-
}
|
|
207
|
-
export async function deleteDevice(owner, device, pause = 10) {
|
|
208
|
-
expect(owner).toBeDefined();
|
|
209
|
-
expect(device).toBeDefined();
|
|
210
|
-
expect(owner.lifecycle.isReady).toBeTruthy();
|
|
211
|
-
expect(owner.construction.status).toBe(Lifecycle.Status.Active);
|
|
212
|
-
expect(owner.lifecycle.isPartsReady).toBeTruthy();
|
|
213
|
-
try {
|
|
214
|
-
await device.delete();
|
|
215
|
-
}
|
|
216
|
-
catch (error) {
|
|
217
|
-
const errorMessage = error instanceof Error ? error.message : error;
|
|
218
|
-
const errorInspect = inspect(error, { depth: 10 });
|
|
219
|
-
console.error(`Error deleting device ${device.maybeId}.${device.maybeNumber}: ${errorMessage}\nstack: ${errorInspect}`);
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
expect(owner.parts.has(device)).toBeFalsy();
|
|
223
|
-
expect(owner.lifecycle.isPartsReady).toBeTruthy();
|
|
224
|
-
expect(device.lifecycle.isReady).toBeFalsy();
|
|
225
|
-
expect(device.lifecycle.isInstalled).toBeFalsy();
|
|
226
|
-
expect(device.lifecycle.hasId).toBeTruthy();
|
|
227
|
-
expect(device.lifecycle.hasNumber).toBeTruthy();
|
|
228
|
-
expect(device.construction.status).toBe(Lifecycle.Status.Destroyed);
|
|
229
|
-
await flushAsync(1, 1, pause);
|
|
230
|
-
return true;
|
|
231
|
-
}
|