matterbridge 3.0.2-dev-20250513-ae61aa7 → 3.0.2-dev-20250514-827b4f2

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 CHANGED
@@ -12,17 +12,21 @@ If you like this project and find it useful, please consider giving it a star on
12
12
 
13
13
  ### Added
14
14
 
15
- - [virtual] Added virtual devices Restart Matterbridge and Update Matterbridge.
15
+ - [virtual] Added virtual devices Restart Matterbridge and Update Matterbridge and full Jest tests.
16
+ - [virtual] Added virtual devices Reboot Matterbridge for Shelly board and full Jest tests.
17
+ - [shelly] Refactor shelly api and added full Jest test.
16
18
 
17
19
  ### Changed
18
20
 
19
21
  - [package]: Updated dependencies.
20
22
  - [utils]: Refactor utils functions.
21
23
  - [utils]: Updated Jest tests on utils functions.
22
- - [devices]: Added RoboticVacuumCleaner class to create the Robotic Vacuum Cleaner device type.
24
+ - [devices]: Added RoboticVacuumCleaner class to create the Robotic Vacuum Cleaner device type in one line of code.
23
25
 
24
26
  ### Fixed
25
27
 
28
+ - [frontend]: Fixed refresh of start/stop sharing.
29
+
26
30
  <a href="https://www.buymeacoffee.com/luligugithub">
27
31
  <img src="bmc-button.svg" alt="Buy me a coffee" width="80">
28
32
  </a>
@@ -0,0 +1,67 @@
1
+ import { OnOff } from '@matter/main/clusters/on-off';
2
+ import { Endpoint } from '@matter/node';
3
+ import { BridgedDeviceBasicInformationServer } from '@matter/node/behaviors/bridged-device-basic-information';
4
+ import { OnOffBaseServer } from '@matter/node/behaviors/on-off';
5
+ import { OnOffPlugInUnitDevice } from '@matter/node/devices/on-off-plug-in-unit';
6
+ import { hasParameter } from './utils/commandLine.js';
7
+ export async function addVirtualDevice(aggregatorEndpoint, name, callback) {
8
+ const device = new Endpoint(OnOffPlugInUnitDevice.with(BridgedDeviceBasicInformationServer), {
9
+ id: name.replaceAll(' ', ''),
10
+ bridgedDeviceBasicInformation: { nodeLabel: name },
11
+ onOff: { onOff: false, startUpOnOff: OnOff.StartUpOnOff.Off },
12
+ });
13
+ device.events.onOff.onOff$Changed.on(async (value) => {
14
+ if (value) {
15
+ await device.setStateOf(OnOffBaseServer, { onOff: false });
16
+ callback();
17
+ }
18
+ });
19
+ await aggregatorEndpoint.add(device);
20
+ await device.setStateOf(OnOffBaseServer, { onOff: false });
21
+ return device;
22
+ }
23
+ export async function addVirtualDevices(matterbridge, aggregatorEndpoint) {
24
+ if (!hasParameter('novirtual') && matterbridge.bridgeMode === 'bridge' && aggregatorEndpoint) {
25
+ matterbridge.log.notice(`Creating virtual devices for Matterbridge server node...`);
26
+ await addVirtualDevice(aggregatorEndpoint, 'Restart Matterbridge', async () => {
27
+ if (matterbridge.restartMode === '')
28
+ await matterbridge.restartProcess();
29
+ else
30
+ await matterbridge.shutdownProcess();
31
+ });
32
+ await addVirtualDevice(aggregatorEndpoint, 'Update Matterbridge', async () => {
33
+ if (hasParameter('shelly')) {
34
+ const { getShelly } = await import('./shelly.js');
35
+ getShelly('/api/updates/sys/perform', 10 * 1000)
36
+ .then(() => {
37
+ matterbridge.log.notice('Shelly system updated successfully');
38
+ })
39
+ .catch((error) => {
40
+ matterbridge.log.error(`Error updating shelly system: ${error}`);
41
+ });
42
+ getShelly('/api/updates/main/perform', 10 * 1000)
43
+ .then(() => {
44
+ matterbridge.log.notice('Shelly software updated successfully');
45
+ })
46
+ .catch((error) => {
47
+ matterbridge.log.error(`Error updating shelly software: ${error}`);
48
+ });
49
+ }
50
+ else {
51
+ await matterbridge.updateProcess();
52
+ }
53
+ });
54
+ if (hasParameter('shelly')) {
55
+ await addVirtualDevice(aggregatorEndpoint, 'Reboot Matterbridge', async () => {
56
+ const { postShelly } = await import('./shelly.js');
57
+ postShelly('/api/system/reboot', {}, 60 * 1000)
58
+ .then(() => {
59
+ matterbridge.log.notice('Rebooting shelly board...');
60
+ })
61
+ .catch((error) => {
62
+ matterbridge.log.error(`Error rebooting shelly board: ${error}`);
63
+ });
64
+ });
65
+ }
66
+ }
67
+ }
@@ -7,21 +7,18 @@ import { AnsiLogger, UNDERLINE, UNDERLINEOFF, YELLOW, db, debugStringify, BRIGHT
7
7
  import { NodeStorageManager } from './storage/export.js';
8
8
  import { getParameter, getIntParameter, hasParameter, copyDirectory, withTimeout, waiter, isValidString, parseVersionString, isValidNumber } from './utils/export.js';
9
9
  import { logInterfaces, getGlobalNodeModules } from './utils/network.js';
10
+ import { dev, plg, typ } from './matterbridgeTypes.js';
10
11
  import { PluginManager } from './pluginManager.js';
11
12
  import { DeviceManager } from './deviceManager.js';
12
13
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
13
14
  import { bridge } from './matterbridgeDeviceTypes.js';
14
15
  import { Frontend } from './frontend.js';
15
- import { DeviceTypeId, Endpoint as EndpointNode, Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, VendorId, StorageService, Environment, ServerNode, UINT32_MAX, UINT16_MAX, Endpoint, } from '@matter/main';
16
+ import { addVirtualDevices } from './helpers.js';
17
+ import { DeviceTypeId, Endpoint, Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, VendorId, StorageService, Environment, ServerNode, UINT32_MAX, UINT16_MAX, } from '@matter/main';
16
18
  import { DeviceCommissioner, FabricAction, MdnsService, PaseClient } from '@matter/main/protocol';
17
- import { OnOffPlugInUnitDevice } from '@matter/main/devices/on-off-plug-in-unit';
18
19
  import { AggregatorEndpoint } from '@matter/main/endpoints';
19
20
  import { BasicInformationServer } from '@matter/main/behaviors/basic-information';
20
- import { OnOffBaseServer } from '@matter/main/behaviors/on-off';
21
21
  import { BridgedDeviceBasicInformationServer } from '@matter/main/behaviors/bridged-device-basic-information';
22
- const plg = '\u001B[38;5;33m';
23
- const dev = '\u001B[38;5;79m';
24
- const typ = '\u001B[38;5;207m';
25
22
  export class Matterbridge extends EventEmitter {
26
23
  systemInformation = {
27
24
  interfaceName: '',
@@ -1244,6 +1241,7 @@ export class Matterbridge extends EventEmitter {
1244
1241
  this.serverNode = await this.createServerNode(this.matterbridgeContext, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
1245
1242
  this.aggregatorNode = await this.createAggregatorNode(this.matterbridgeContext);
1246
1243
  await this.serverNode.add(this.aggregatorNode);
1244
+ await addVirtualDevices(this, this.aggregatorNode);
1247
1245
  await this.startPlugins();
1248
1246
  this.log.debug('Starting start matter interval in bridge mode');
1249
1247
  let failCount = 0;
@@ -1521,30 +1519,6 @@ export class Matterbridge extends EventEmitter {
1521
1519
  serverNode.lifecycle.decommissioned.on(() => this.log.notice(`Server node for ${storeId} was fully decommissioned successfully!`));
1522
1520
  serverNode.lifecycle.online.on(async () => {
1523
1521
  this.log.notice(`Server node for ${storeId} is online`);
1524
- if (!hasParameter('novirtual') && this.bridgeMode === 'bridge') {
1525
- this.log.notice(`Creating virtual devices for server node ${storeId}`);
1526
- const virtualRestart = new Endpoint(OnOffPlugInUnitDevice.with(BridgedDeviceBasicInformationServer), { id: 'Restart Matterbridge', bridgedDeviceBasicInformation: { nodeLabel: 'Restart' } });
1527
- virtualRestart.events.onOff.onOff$Changed.on(async (value) => {
1528
- if (value) {
1529
- await virtualRestart.setStateOf(OnOffBaseServer, { onOff: false });
1530
- if (this.restartMode === '')
1531
- this.restartProcess();
1532
- else
1533
- this.shutdownProcess();
1534
- }
1535
- });
1536
- await this.aggregatorNode?.add(virtualRestart);
1537
- await virtualRestart.setStateOf(OnOffBaseServer, { onOff: false });
1538
- const virtualUpdate = new Endpoint(OnOffPlugInUnitDevice.with(BridgedDeviceBasicInformationServer), { id: 'Update Matterbridge', bridgedDeviceBasicInformation: { nodeLabel: 'Update' } });
1539
- virtualUpdate.events.onOff.onOff$Changed.on(async (value) => {
1540
- if (value) {
1541
- await virtualUpdate.setStateOf(OnOffBaseServer, { onOff: false });
1542
- this.updateProcess();
1543
- }
1544
- });
1545
- await this.aggregatorNode?.add(virtualUpdate);
1546
- await virtualUpdate.setStateOf(OnOffBaseServer, { onOff: false });
1547
- }
1548
1522
  if (!serverNode.lifecycle.isCommissioned) {
1549
1523
  this.log.notice(`Server node for ${storeId} is not commissioned. Pair to commission ...`);
1550
1524
  const { qrPairingCode, manualPairingCode } = serverNode.state.commissioning.pairingCodes;
@@ -1719,7 +1693,7 @@ export class Matterbridge extends EventEmitter {
1719
1693
  }
1720
1694
  async createAggregatorNode(storageContext) {
1721
1695
  this.log.notice(`Creating ${await storageContext.get('storeId')} aggregator `);
1722
- const aggregatorNode = new EndpointNode(AggregatorEndpoint, { id: `${await storageContext.get('storeId')}` });
1696
+ const aggregatorNode = new Endpoint(AggregatorEndpoint, { id: `${await storageContext.get('storeId')}` });
1723
1697
  return aggregatorNode;
1724
1698
  }
1725
1699
  async addBridgedEndpoint(pluginName, device) {
@@ -227,17 +227,18 @@ export function getBehavior(endpoint, cluster) {
227
227
  export async function invokeBehaviorCommand(endpoint, cluster, command, params) {
228
228
  const behaviorId = getBehavior(endpoint, cluster)?.id;
229
229
  if (!behaviorId) {
230
- endpoint.log.error(`invokeBehaviorCommand error: command ${hk}${command}${er} not found on endpoint ${or}${endpoint.maybeId}${er}:${or}${endpoint.maybeNumber}${er}`);
231
- return;
230
+ endpoint.log?.error(`invokeBehaviorCommand error: command ${hk}${command}${er} not found on endpoint ${or}${endpoint.maybeId}${er}:${or}${endpoint.maybeNumber}${er}`);
231
+ return false;
232
232
  }
233
233
  await endpoint.act((agent) => {
234
234
  const behavior = agent[behaviorId];
235
235
  if (!(command in behavior) || typeof behavior[command] !== 'function') {
236
- endpoint.log.error(`invokeBehaviorCommand error: command ${hk}${command}${er} not found on agent for endpoint ${or}${endpoint.maybeId}${er}:${or}${endpoint.maybeNumber}${er}`);
237
- return;
236
+ endpoint.log?.error(`invokeBehaviorCommand error: command ${hk}${command}${er} not found on agent for endpoint ${or}${endpoint.maybeId}${er}:${or}${endpoint.maybeNumber}${er}`);
237
+ return false;
238
238
  }
239
239
  behavior[command](params);
240
240
  });
241
+ return true;
241
242
  }
242
243
  export function addRequiredClusterServers(endpoint) {
243
244
  const requiredServerList = [];
package/dist/shelly.js CHANGED
@@ -1,80 +1,82 @@
1
1
  import { WS_ID_SHELLY_MAIN_UPDATE, WS_ID_SHELLY_SYS_UPDATE } from './frontend.js';
2
2
  import { debugStringify } from './logger/export.js';
3
+ let verifyIntervalSecs = 15;
4
+ let verifyTimeoutSecs = 600;
5
+ export function setVerifyIntervalSecs(seconds) {
6
+ verifyIntervalSecs = seconds;
7
+ }
8
+ export function setVerifyTimeoutSecs(seconds) {
9
+ verifyTimeoutSecs = seconds;
10
+ }
3
11
  export async function getShellySysUpdate(matterbridge) {
4
- getShelly('/api/updates/sys/check', 60 * 1000)
5
- .then(async (data) => {
6
- if (data.length > 0) {
7
- matterbridge.matterbridgeInformation.shellySysUpdate = true;
8
- matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_SYS_UPDATE, 'shelly-sys-update', { available: true });
9
- for (const update of data) {
10
- if (update.name)
11
- matterbridge.log.notice(`Shelly system update available: ${update.name}`);
12
- if (update.name)
13
- matterbridge.frontend.wssSendSnackbarMessage(`Shelly system update available: ${update.name}`, 10);
14
- }
12
+ try {
13
+ const updates = (await getShelly('/api/updates/sys/check'));
14
+ if (updates.length === 0)
15
+ return;
16
+ matterbridge.matterbridgeInformation.shellySysUpdate = true;
17
+ matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_SYS_UPDATE, 'shelly-sys-update', { available: true });
18
+ for (const { name } of updates) {
19
+ if (!name)
20
+ continue;
21
+ matterbridge.log.notice(`Shelly system update available: ${name}`);
22
+ matterbridge.frontend.wssSendSnackbarMessage(`Shelly system update available: ${name}`, 10);
15
23
  }
16
- })
17
- .catch((error) => {
18
- matterbridge.log.warn(`Error getting Shelly system updates: ${error instanceof Error ? error.message : error}`);
19
- });
24
+ }
25
+ catch (err) {
26
+ matterbridge.log.error(`Error getting Shelly system updates: ${err instanceof Error ? err.message : String(err)}`);
27
+ }
20
28
  }
21
29
  export async function triggerShellySysUpdate(matterbridge) {
22
- getShelly('/api/updates/sys/perform', 10 * 1000)
23
- .then(async () => {
24
- matterbridge.log.debug(`Triggered Shelly system updates`);
25
- })
26
- .catch((error) => {
27
- matterbridge.log.debug(`****Error triggering Shelly system updates: ${error instanceof Error ? error.message : error}`);
28
- })
29
- .finally(() => {
30
+ try {
31
+ await getShelly('/api/updates/sys/perform');
32
+ matterbridge.log.notice('Installing Shelly system update...');
30
33
  matterbridge.matterbridgeInformation.shellySysUpdate = false;
31
- matterbridge.log.notice(`Installing Shelly system update...`);
32
34
  matterbridge.frontend.wssSendSnackbarMessage('Installing Shelly system update...', 15);
33
35
  matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_SYS_UPDATE, 'shelly-sys-update', { available: false });
34
- verifyShellyUpdate(matterbridge, '/api/updates/sys/status', 'Shelly system update');
35
- });
36
+ await verifyShellyUpdate(matterbridge, '/api/updates/sys/status', 'Shelly system update');
37
+ }
38
+ catch (err) {
39
+ matterbridge.log.error(`Error triggering Shelly system update: ${err instanceof Error ? err.message : String(err)}`);
40
+ }
36
41
  }
37
42
  export async function getShellyMainUpdate(matterbridge) {
38
- getShelly('/api/updates/main/check', 60 * 1000)
39
- .then(async (data) => {
40
- if (data.length > 0) {
41
- matterbridge.matterbridgeInformation.shellyMainUpdate = true;
42
- matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_MAIN_UPDATE, 'shelly-main-update', { available: true });
43
- for (const update of data) {
44
- if (update.name)
45
- matterbridge.log.notice(`Shelly software update available: ${update.name}`);
46
- if (update.name)
47
- matterbridge.frontend.wssSendSnackbarMessage(`Shelly software update available: ${update.name}`, 10);
48
- }
43
+ try {
44
+ const updates = (await getShelly('/api/updates/main/check'));
45
+ if (updates.length === 0)
46
+ return;
47
+ matterbridge.matterbridgeInformation.shellyMainUpdate = true;
48
+ matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_MAIN_UPDATE, 'shelly-main-update', { available: true });
49
+ for (const { name } of updates) {
50
+ if (!name)
51
+ continue;
52
+ matterbridge.log.notice(`Shelly software update available: ${name}`);
53
+ matterbridge.frontend.wssSendSnackbarMessage(`Shelly software update available: ${name}`, 10);
49
54
  }
50
- })
51
- .catch((error) => {
52
- matterbridge.log.warn(`Error getting Shelly main updates: ${error instanceof Error ? error.message : error}`);
53
- });
55
+ }
56
+ catch (err) {
57
+ matterbridge.log.error(`Error getting Shelly main updates: ${err instanceof Error ? err.message : String(err)}`);
58
+ }
54
59
  }
55
60
  export async function triggerShellyMainUpdate(matterbridge) {
56
- getShelly('/api/updates/main/perform', 10 * 1000)
57
- .then(async () => {
58
- matterbridge.log.debug(`Triggered Shelly main updates`);
59
- })
60
- .catch((error) => {
61
- matterbridge.log.debug(`****Error triggering Shelly main updates: ${error instanceof Error ? error.message : error}`);
62
- })
63
- .finally(() => {
61
+ try {
62
+ await getShelly('/api/updates/main/perform');
63
+ matterbridge.log.notice('Installing Shelly software update...');
64
64
  matterbridge.matterbridgeInformation.shellyMainUpdate = false;
65
- matterbridge.log.notice(`Installing Shelly software update...`);
66
65
  matterbridge.frontend.wssSendSnackbarMessage('Installing Shelly software update...', 15);
67
66
  matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_MAIN_UPDATE, 'shelly-main-update', { available: false });
68
- verifyShellyUpdate(matterbridge, '/api/updates/main/status', 'Shelly software update');
69
- });
67
+ await verifyShellyUpdate(matterbridge, '/api/updates/main/status', 'Shelly software update');
68
+ }
69
+ catch (err) {
70
+ matterbridge.log.error(`Error triggering Shelly main update: ${err instanceof Error ? err.message : String(err)}`);
71
+ }
70
72
  }
71
73
  async function verifyShellyUpdate(matterbridge, api, name) {
72
74
  return new Promise((resolve) => {
73
75
  const timeout = setTimeout(() => {
74
- matterbridge.log.warn(`${name} check timed out`);
76
+ matterbridge.log.error(`${name} check timed out`);
75
77
  clearInterval(interval);
76
78
  resolve();
77
- }, 600 * 1000);
79
+ }, verifyTimeoutSecs * 1000);
78
80
  const interval = setInterval(() => {
79
81
  getShelly(api, 10 * 1000)
80
82
  .then(async (data) => {
@@ -91,12 +93,12 @@ async function verifyShellyUpdate(matterbridge, api, name) {
91
93
  }
92
94
  })
93
95
  .catch((error) => {
94
- matterbridge.log.warn(`Error getting status of ${name}: ${error instanceof Error ? error.message : error}`);
96
+ matterbridge.log.error(`Error getting status of ${name}: ${error instanceof Error ? error.message : String(error)}`);
95
97
  clearInterval(interval);
96
98
  clearTimeout(timeout);
97
99
  resolve();
98
100
  });
99
- }, 15 * 1000);
101
+ }, verifyIntervalSecs * 1000);
100
102
  });
101
103
  }
102
104
  export async function triggerShellyChangeIp(matterbridge, config) {
@@ -109,88 +111,75 @@ export async function triggerShellyChangeIp(matterbridge, config) {
109
111
  data['dns'] = config.dns;
110
112
  }
111
113
  matterbridge.log.debug(`Triggering Shelly network configuration change: ${debugStringify(config)}`);
112
- postShelly(api, data, 60 * 1000)
113
- .then(async () => {
114
+ try {
115
+ await postShelly(api, data);
114
116
  matterbridge.log.debug(`Triggered Shelly network configuration change: ${debugStringify(config)}`);
115
117
  matterbridge.log.notice(`Changed Shelly network configuration`);
116
118
  matterbridge.frontend.wssSendSnackbarMessage('Changed Shelly network configuration');
117
- })
118
- .catch((error) => {
119
- matterbridge.log.debug(`****Error triggering Shelly network configuration change: ${error instanceof Error ? error.message : error}`);
120
- matterbridge.log.error(`Error changing Shelly network configuration: ${error instanceof Error ? error.message : error}`);
119
+ }
120
+ catch (error) {
121
+ matterbridge.log.debug(`****Error triggering Shelly network configuration change ${debugStringify(config)}: ${error instanceof Error ? error.message : String(error)}`);
122
+ matterbridge.log.error(`Error changing Shelly network configuration: ${error instanceof Error ? error.message : String(error)}`);
121
123
  matterbridge.frontend.wssSendSnackbarMessage('Error changing Shelly network configuration', 10, 'error');
122
- })
123
- .finally(() => {
124
- });
124
+ }
125
125
  }
126
126
  export async function triggerShellyReboot(matterbridge) {
127
127
  matterbridge.log.debug(`Triggering Shelly system reboot`);
128
- postShelly('/api/system/reboot', {}, 60 * 1000)
129
- .then(async () => {
128
+ try {
129
+ await postShelly('/api/system/reboot', {});
130
130
  matterbridge.log.debug(`Triggered Shelly system reboot`);
131
131
  matterbridge.log.notice(`Rebooting Shelly board...`);
132
132
  matterbridge.frontend.wssSendSnackbarMessage('Rebooting Shelly board...');
133
- })
134
- .catch((error) => {
135
- matterbridge.log.debug(`****Error triggering Shelly system reboot: ${error instanceof Error ? error.message : error}`);
136
- matterbridge.log.error(`Error rebooting Shelly board: ${error instanceof Error ? error.message : error}`);
133
+ }
134
+ catch (error) {
135
+ matterbridge.log.debug(`****Error triggering Shelly system reboot: ${error instanceof Error ? error.message : String(error)}`);
136
+ matterbridge.log.error(`Error rebooting Shelly board: ${error instanceof Error ? error.message : String(error)}`);
137
137
  matterbridge.frontend.wssSendSnackbarMessage('Error rebooting Shelly board', 10, 'error');
138
- })
139
- .finally(() => {
140
- });
138
+ }
141
139
  }
142
140
  export async function triggerShellySoftReset(matterbridge) {
143
141
  matterbridge.log.debug(`Triggering Shelly soft reset`);
144
- getShelly('/api/reset/soft', 60 * 1000)
145
- .then(async () => {
142
+ try {
143
+ await getShelly('/api/reset/soft');
146
144
  matterbridge.log.debug(`Triggered Shelly soft reset`);
147
145
  matterbridge.log.notice(`Resetting the network parameters on Shelly board...`);
148
146
  matterbridge.frontend.wssSendSnackbarMessage('Resetting the network parameters on Shelly board...');
149
- })
150
- .catch((error) => {
151
- matterbridge.log.debug(`****Error triggering Shelly soft reset: ${error instanceof Error ? error.message : error}`);
152
- matterbridge.log.error(`Error resetting the network parameters on Shelly board: ${error instanceof Error ? error.message : error}`);
147
+ }
148
+ catch (error) {
149
+ matterbridge.log.debug(`****Error triggering Shelly soft reset: ${error instanceof Error ? error.message : String(error)}`);
150
+ matterbridge.log.error(`Error resetting the network parameters on Shelly board: ${error instanceof Error ? error.message : String(error)}`);
153
151
  matterbridge.frontend.wssSendSnackbarMessage('Error resetting the network parameters on Shelly board', 10, 'error');
154
- })
155
- .finally(() => {
156
- });
152
+ }
157
153
  }
158
154
  export async function triggerShellyHardReset(matterbridge) {
159
155
  matterbridge.log.debug(`Triggering Shelly hard reset`);
160
- getShelly('/api/reset/hard', 60 * 1000)
161
- .then(async () => {
156
+ try {
157
+ await getShelly('/api/reset/hard');
162
158
  matterbridge.log.debug(`Triggered Shelly hard reset`);
163
159
  matterbridge.log.notice(`Factory resetting Shelly board...`);
164
160
  matterbridge.frontend.wssSendSnackbarMessage('Factory resetting Shelly board...');
165
- })
166
- .catch((error) => {
167
- matterbridge.log.debug(`****Error triggering Shelly hard reset: ${error instanceof Error ? error.message : error}`);
168
- matterbridge.log.error(`Error while factory resetting the Shelly board: ${error instanceof Error ? error.message : error}`);
161
+ }
162
+ catch (error) {
163
+ matterbridge.log.debug(`****Error triggering Shelly hard reset: ${error instanceof Error ? error.message : String(error)}`);
164
+ matterbridge.log.error(`Error while factory resetting the Shelly board: ${error instanceof Error ? error.message : String(error)}`);
169
165
  matterbridge.frontend.wssSendSnackbarMessage('Error while factory resetting the Shelly board', 10, 'error');
170
- })
171
- .finally(() => {
172
- });
166
+ }
173
167
  }
174
168
  export async function createShellySystemLog(matterbridge) {
175
169
  const { promises: fs } = await import('node:fs');
176
170
  const path = await import('node:path');
177
171
  matterbridge.log.debug(`Downloading Shelly system log...`);
178
- getShelly('/api/logs/system', 60 * 1000)
179
- .then(async (data) => {
180
- fs.writeFile(path.join(matterbridge.matterbridgeDirectory, 'shelly.log'), data)
181
- .then(() => {
182
- matterbridge.log.notice(`Shelly system log ready for download`);
183
- matterbridge.frontend.wssSendSnackbarMessage('Shelly system log ready for download');
184
- })
185
- .catch((error) => {
186
- matterbridge.log.warn(`Error writing Shelly system log to file: ${error instanceof Error ? error.message : error}`);
187
- });
188
- })
189
- .catch((error) => {
190
- matterbridge.log.warn(`Error getting Shelly system log: ${error instanceof Error ? error.message : error}`);
191
- });
172
+ try {
173
+ const data = await getShelly('/api/logs/system');
174
+ await fs.writeFile(path.join(matterbridge.matterbridgeDirectory, 'shelly.log'), data);
175
+ matterbridge.log.notice(`Shelly system log ready for download`);
176
+ matterbridge.frontend.wssSendSnackbarMessage('Shelly system log ready for download');
177
+ }
178
+ catch (error) {
179
+ matterbridge.log.error(`Error getting Shelly system log: ${error instanceof Error ? error.message : error}`);
180
+ }
192
181
  }
193
- async function getShelly(api, timeout = 60000) {
182
+ export async function getShelly(api, timeout = 60000) {
194
183
  const http = await import('node:http');
195
184
  return new Promise((resolve, reject) => {
196
185
  const url = `http://127.0.0.1:8101${api}`;
@@ -233,7 +222,7 @@ async function getShelly(api, timeout = 60000) {
233
222
  });
234
223
  });
235
224
  }
236
- async function postShelly(api, data, timeout = 60000) {
225
+ export async function postShelly(api, data, timeout = 60000) {
237
226
  const http = await import('node:http');
238
227
  return new Promise((resolve, reject) => {
239
228
  const url = `http://127.0.0.1:8101${api}`;
package/dist/update.js CHANGED
@@ -1,22 +1,28 @@
1
+ import { db, nt, wr } from 'node-ansi-logger';
1
2
  import { plg } from './matterbridgeTypes.js';
2
- import { db, nt, wr } from './logger/export.js';
3
3
  export async function checkUpdates(matterbridge) {
4
4
  const { hasParameter } = await import('./utils/commandLine.js');
5
- getMatterbridgeLatestVersion(matterbridge);
6
- getMatterbridgeDevVersion(matterbridge);
5
+ const latestVersion = getMatterbridgeLatestVersion(matterbridge);
6
+ const devVersion = getMatterbridgeDevVersion(matterbridge);
7
+ const pluginsVersions = [];
8
+ const shellyUpdates = [];
7
9
  for (const plugin of matterbridge.plugins) {
8
- getPluginLatestVersion(matterbridge, plugin);
10
+ const pluginVersion = getPluginLatestVersion(matterbridge, plugin);
11
+ pluginsVersions.push(pluginVersion);
9
12
  }
10
13
  if (hasParameter('shelly')) {
11
14
  const { getShellySysUpdate, getShellyMainUpdate } = await import('./shelly.js');
12
- getShellySysUpdate(matterbridge);
13
- getShellyMainUpdate(matterbridge);
15
+ const systemUpdate = getShellySysUpdate(matterbridge);
16
+ shellyUpdates.push(systemUpdate);
17
+ const mainUpdate = getShellyMainUpdate(matterbridge);
18
+ shellyUpdates.push(mainUpdate);
14
19
  }
20
+ await Promise.all([latestVersion, devVersion, ...pluginsVersions, ...shellyUpdates]);
15
21
  }
16
- async function getMatterbridgeLatestVersion(matterbridge) {
22
+ export async function getMatterbridgeLatestVersion(matterbridge) {
17
23
  const { getNpmPackageVersion } = await import('./utils/network.js');
18
- getNpmPackageVersion('matterbridge')
19
- .then(async (version) => {
24
+ try {
25
+ const version = await getNpmPackageVersion('matterbridge');
20
26
  matterbridge.matterbridgeLatestVersion = version;
21
27
  matterbridge.matterbridgeInformation.matterbridgeLatestVersion = version;
22
28
  await matterbridge.nodeContext?.set('matterbridgeLatestVersion', matterbridge.matterbridgeLatestVersion);
@@ -28,15 +34,16 @@ async function getMatterbridgeLatestVersion(matterbridge) {
28
34
  else {
29
35
  matterbridge.log.debug(`Matterbridge is up to date. Current version: ${matterbridge.matterbridgeVersion}. Latest version: ${matterbridge.matterbridgeLatestVersion}.`);
30
36
  }
31
- })
32
- .catch((error) => {
33
- matterbridge.log.warn(`Error getting Matterbridge latest version: ${error.message}`);
34
- });
37
+ return version;
38
+ }
39
+ catch (error) {
40
+ matterbridge.log.warn(`Error getting Matterbridge latest version: ${error instanceof Error ? error.message : error}`);
41
+ }
35
42
  }
36
- async function getMatterbridgeDevVersion(matterbridge) {
43
+ export async function getMatterbridgeDevVersion(matterbridge) {
37
44
  const { getNpmPackageVersion } = await import('./utils/network.js');
38
- getNpmPackageVersion('matterbridge', 'dev')
39
- .then(async (version) => {
45
+ try {
46
+ const version = await getNpmPackageVersion('matterbridge', 'dev');
40
47
  matterbridge.matterbridgeDevVersion = version;
41
48
  matterbridge.matterbridgeInformation.matterbridgeDevVersion = version;
42
49
  await matterbridge.nodeContext?.set('matterbridgeDevVersion', version);
@@ -45,15 +52,19 @@ async function getMatterbridgeDevVersion(matterbridge) {
45
52
  matterbridge.frontend.wssSendRefreshRequired('matterbridgeDevVersion');
46
53
  matterbridge.frontend.wssSendUpdateRequired();
47
54
  }
48
- })
49
- .catch((error) => {
50
- matterbridge.log.warn(`Error getting Matterbridge latest dev version: ${error.message}`);
51
- });
55
+ else {
56
+ matterbridge.log.debug(`Matterbridge@dev is up to date. Current version: ${matterbridge.matterbridgeVersion}. Latest dev version: ${matterbridge.matterbridgeDevVersion}.`);
57
+ }
58
+ return version;
59
+ }
60
+ catch (error) {
61
+ matterbridge.log.warn(`Error getting Matterbridge latest dev version: ${error instanceof Error ? error.message : error}`);
62
+ }
52
63
  }
53
- async function getPluginLatestVersion(matterbridge, plugin) {
64
+ export async function getPluginLatestVersion(matterbridge, plugin) {
54
65
  const { getNpmPackageVersion } = await import('./utils/network.js');
55
- getNpmPackageVersion(plugin.name)
56
- .then((version) => {
66
+ try {
67
+ const version = await getNpmPackageVersion(plugin.name);
57
68
  plugin.latestVersion = version;
58
69
  if (plugin.version !== plugin.latestVersion) {
59
70
  matterbridge.log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
@@ -62,8 +73,9 @@ async function getPluginLatestVersion(matterbridge, plugin) {
62
73
  else {
63
74
  matterbridge.log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
64
75
  }
65
- })
66
- .catch((error) => {
67
- matterbridge.log.warn(`Error getting ${plg}${plugin.name}${wr} latest version: ${error.message}`);
68
- });
76
+ return version;
77
+ }
78
+ catch (error) {
79
+ matterbridge.log.warn(`Error getting plugin ${plg}${plugin.name}${wr} latest version: ${error instanceof Error ? error.message : error}`);
80
+ }
69
81
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.944b63c3.css",
4
- "main.js": "./static/js/main.15906009.js",
4
+ "main.js": "./static/js/main.f6e0f736.js",
5
5
  "static/js/453.d855a71b.chunk.js": "./static/js/453.d855a71b.chunk.js",
6
6
  "static/media/roboto-latin-700-normal.woff2": "./static/media/roboto-latin-700-normal.c4d6cab43bec89049809.woff2",
7
7
  "static/media/roboto-latin-500-normal.woff2": "./static/media/roboto-latin-500-normal.599f66a60bdf974e578e.woff2",
@@ -77,11 +77,11 @@
77
77
  "static/media/roboto-greek-ext-300-normal.woff": "./static/media/roboto-greek-ext-300-normal.60729cafbded24073dfb.woff",
78
78
  "index.html": "./index.html",
79
79
  "main.944b63c3.css.map": "./static/css/main.944b63c3.css.map",
80
- "main.15906009.js.map": "./static/js/main.15906009.js.map",
80
+ "main.f6e0f736.js.map": "./static/js/main.f6e0f736.js.map",
81
81
  "453.d855a71b.chunk.js.map": "./static/js/453.d855a71b.chunk.js.map"
82
82
  },
83
83
  "entrypoints": [
84
84
  "static/css/main.944b63c3.css",
85
- "static/js/main.15906009.js"
85
+ "static/js/main.f6e0f736.js"
86
86
  ]
87
87
  }
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.15906009.js"></script><link href="./static/css/main.944b63c3.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.f6e0f736.js"></script><link href="./static/css/main.944b63c3.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>