matterbridge 2.1.4-dev.3 → 2.1.5-dev.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/CHANGELOG.md CHANGED
@@ -25,13 +25,29 @@ You need to update all plugins you use and Matterbridge in the same moment.
25
25
 
26
26
  I suggest to first update all plugins without restarting and then to update Matterbridge so when it restarts, all versions will be the latest.
27
27
 
28
+ If you use docker, all plugins are already installed in the image so you just need to pull the new image.
29
+
28
30
  Compatibility list:
29
31
  matterbridge-shelly v. 1.1.5
30
32
  matterbridge-zigbee2mqtt v. 2.4.4
31
33
  matterbridge-somfy-tahoma v. 1.2.3
32
34
  matterbridge-hass v. 0.0.8
33
35
 
34
- ## [2.1.4] - 2025-02-06
36
+ ## [2.1.5] - 2025-02-08
37
+
38
+ ### Added
39
+
40
+ ### Changed
41
+
42
+ - [matterbridge]: Calls getNpmPackageVersion() instead of npm to get latest version.
43
+
44
+ ### Fixed
45
+
46
+ <a href="https://www.buymeacoffee.com/luligugithub">
47
+ <img src="./yellow-button.png" alt="Buy me a coffee" width="120">
48
+ </a>
49
+
50
+ ## [2.1.4] - 2025-02-07
35
51
 
36
52
  ### Added
37
53
 
@@ -42,6 +58,7 @@ matterbridge-hass v. 0.0.8
42
58
  ### Changed
43
59
 
44
60
  - [package]: Update matter.js to 0.12.3.
61
+ - [matter.js]: Since matter.js storage cannot properly encode non latin names, they are encoded before passing them to matter.js.
45
62
 
46
63
  <a href="https://www.buymeacoffee.com/luligugithub">
47
64
  <img src="./yellow-button.png" alt="Buy me a coffee" width="120">
package/README-DOCKER.md CHANGED
@@ -48,11 +48,13 @@ The container must have full access to the host network (needed for mdns).
48
48
 
49
49
  ```
50
50
  sudo docker run --name matterbridge \
51
- -v ${HOME}/Matterbridge:/root/Matterbridge \
52
- -v ${HOME}/.matterbridge:/root/.matterbridge \
51
+ -v /home/<USER>/Matterbridge:/root/Matterbridge \
52
+ -v /home/<USER>/.matterbridge:/root/.matterbridge \
53
53
  --network host --restart always -d luligu/matterbridge:latest
54
54
  ```
55
55
 
56
+ Replace USER with your user name (i.e. ubuntu or pi).
57
+
56
58
  You may need to adapt the script to your setup.
57
59
 
58
60
  ### Run with docker compose
@@ -63,14 +65,16 @@ The docker-compose.yml file is available in the docker directory of the package
63
65
  services:
64
66
  matterbridge:
65
67
  container_name: matterbridge
66
- image: luligu/matterbridge:latest # Matterbridge image with the latest tag
67
- network_mode: host # Ensures the Matter mdns works
68
- restart: always # Ensures the container always restarts automatically
68
+ image: luligu/matterbridge:latest # Matterbridge image with the tag latest
69
+ network_mode: host # Ensures the Matter mdns works
70
+ restart: always # Ensures the container always restarts automatically
69
71
  volumes:
70
- - "${HOME}/Matterbridge:/root/Matterbridge" # Mounts the Matterbridge plugin directory
71
- - "${HOME}/.matterbridge:/root/.matterbridge" # Mounts the Matterbridge storage directory
72
+ - "/home/<USER>/Matterbridge:/root/Matterbridge" # Mounts the Matterbridge plugin directory
73
+ - "/home/<USER>/.matterbridge:/root/.matterbridge" # Mounts the Matterbridge storage directory
72
74
  ```
73
75
 
76
+ Replace USER with your user name (i.e. ubuntu or pi).
77
+
74
78
  copy it in the home directory or edit the existing one to add the matterbridge service.
75
79
 
76
80
  Then start docker compose with:
@@ -7,7 +7,7 @@ import path from 'path';
7
7
  import { randomBytes } from 'crypto';
8
8
  import { NodeStorageManager } from './storage/export.js';
9
9
  import { AnsiLogger, UNDERLINE, UNDERLINEOFF, YELLOW, db, debugStringify, BRIGHT, RESET, er, nf, rs, wr, RED, GREEN, zb, CYAN, nt } from './logger/export.js';
10
- import { logInterfaces, copyDirectory, getParameter, getIntParameter, hasParameter } from './utils/utils.js';
10
+ import { logInterfaces, copyDirectory, getParameter, getIntParameter, hasParameter, getNpmPackageVersion } from './utils/utils.js';
11
11
  import { PluginManager } from './pluginManager.js';
12
12
  import { DeviceManager } from './deviceManager.js';
13
13
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
@@ -518,6 +518,10 @@ export class Matterbridge extends EventEmitter {
518
518
  if (getIntParameter('frontend') !== 0 || getIntParameter('frontend') === undefined)
519
519
  await this.frontend.start(getIntParameter('frontend'));
520
520
  this.frontend.logLevel = this.log.logLevel;
521
+ this.getMatterbridgeLatestVersion();
522
+ for (const plugin of this.plugins) {
523
+ this.getPluginLatestVersion(plugin);
524
+ }
521
525
  this.checkUpdateInterval = setInterval(() => {
522
526
  this.getMatterbridgeLatestVersion();
523
527
  for (const plugin of this.plugins) {
@@ -787,11 +791,10 @@ export class Matterbridge extends EventEmitter {
787
791
  });
788
792
  }
789
793
  async getMatterbridgeLatestVersion() {
790
- this.getLatestVersion('matterbridge')
791
- .then(async (matterbridgeLatestVersion) => {
792
- this.matterbridgeLatestVersion = matterbridgeLatestVersion;
793
- this.matterbridgeInformation.matterbridgeLatestVersion = this.matterbridgeLatestVersion;
794
- this.log.debug(`Matterbridge Latest Version: ${this.matterbridgeLatestVersion}`);
794
+ getNpmPackageVersion('matterbridge')
795
+ .then(async (version) => {
796
+ this.matterbridgeLatestVersion = version;
797
+ this.matterbridgeInformation.matterbridgeLatestVersion = version;
795
798
  await this.nodeContext?.set('matterbridgeLatestVersion', this.matterbridgeLatestVersion);
796
799
  if (this.matterbridgeVersion !== this.matterbridgeLatestVersion) {
797
800
  this.log.notice(`Matterbridge is out of date. Current version: ${this.matterbridgeVersion}. Latest version: ${this.matterbridgeLatestVersion}.`);
@@ -799,19 +802,20 @@ export class Matterbridge extends EventEmitter {
799
802
  else {
800
803
  this.log.debug(`Matterbridge is up to date. Current version: ${this.matterbridgeVersion}. Latest version: ${this.matterbridgeLatestVersion}.`);
801
804
  }
805
+ this.frontend.wssSendRefreshRequired();
802
806
  })
803
807
  .catch((error) => {
804
808
  this.log.error(`Error getting Matterbridge latest version: ${error.message}`);
805
809
  });
806
810
  }
807
811
  async getPluginLatestVersion(plugin) {
808
- this.getLatestVersion(plugin.name)
809
- .then(async (latestVersion) => {
810
- plugin.latestVersion = latestVersion;
811
- if (plugin.version !== latestVersion)
812
- this.log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest version: ${latestVersion}.`);
812
+ getNpmPackageVersion(plugin.name)
813
+ .then((version) => {
814
+ plugin.latestVersion = version;
815
+ if (plugin.version !== plugin.latestVersion)
816
+ this.log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
813
817
  else
814
- this.log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest version: ${latestVersion}.`);
818
+ this.log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
815
819
  })
816
820
  .catch((error) => {
817
821
  this.log.error(`Error getting ${plg}${plugin.name}${er} latest version: ${error.message}`);
@@ -64,7 +64,7 @@ export class MatterbridgePlatform {
64
64
  return;
65
65
  }
66
66
  if (device.deviceName && checkNotLatinCharacters(device.deviceName)) {
67
- this.log.debug(`Device with name ${CYAN}${device.deviceName}${db} has non latin characters. Please keep the name as short as possible.`);
67
+ this.log.debug(`Device with name ${CYAN}${device.deviceName}${db} has non latin characters.`);
68
68
  }
69
69
  await this.matterbridge.addBridgedEndpoint(this.name, device);
70
70
  if (device.uniqueId)
@@ -1,8 +1,8 @@
1
1
  import os from 'os';
2
- import { createWriteStream, statSync } from 'fs';
3
2
  import path from 'path';
4
- import * as dns from 'dns';
3
+ import { createWriteStream, statSync } from 'fs';
5
4
  import { promises as fs } from 'fs';
5
+ import * as dns from 'dns';
6
6
  import { AnsiLogger, idn, rs } from 'node-ansi-logger';
7
7
  const log = new AnsiLogger({ logName: 'MatterbridgeUtils', logTimestampFormat: 4, logLevel: "info" });
8
8
  export function deepEqual(a, b, excludeProperties = []) {
@@ -351,7 +351,7 @@ export async function copyDirectory(srcDir, destDir) {
351
351
  }
352
352
  export async function resolveHostname(hostname, family = 4) {
353
353
  try {
354
- const addresses = await dns.promises.lookup(hostname.toLowerCase() + '.local', { family });
354
+ const addresses = await dns.promises.lookup(hostname.toLowerCase(), { family });
355
355
  return addresses.address;
356
356
  }
357
357
  catch (error) {
@@ -383,3 +383,47 @@ export function getIntParameter(name) {
383
383
  return undefined;
384
384
  return intValue;
385
385
  }
386
+ export async function getNpmPackageVersion(packageName, tag = 'latest', timeout = 5000) {
387
+ const https = await import('https');
388
+ return new Promise((resolve, reject) => {
389
+ const url = `https://registry.npmjs.org/${packageName}`;
390
+ const controller = new AbortController();
391
+ const timeoutId = setTimeout(() => {
392
+ controller.abort();
393
+ reject(new Error(`Request timed out after ${timeout / 1000} seconds`));
394
+ }, timeout);
395
+ const req = https.get(url, { signal: controller.signal }, (res) => {
396
+ let data = '';
397
+ if (res.statusCode !== 200) {
398
+ clearTimeout(timeoutId);
399
+ res.resume();
400
+ req.destroy();
401
+ reject(new Error(`Failed to fetch data. Status code: ${res.statusCode}`));
402
+ return;
403
+ }
404
+ res.on('data', (chunk) => {
405
+ data += chunk;
406
+ });
407
+ res.on('end', () => {
408
+ clearTimeout(timeoutId);
409
+ try {
410
+ const jsonData = JSON.parse(data);
411
+ const version = jsonData['dist-tags']?.[tag];
412
+ if (version) {
413
+ resolve(version);
414
+ }
415
+ else {
416
+ reject(new Error(`Tag "${tag}" not found for package "${packageName}"`));
417
+ }
418
+ }
419
+ catch (error) {
420
+ reject(new Error(`Failed to parse response JSON: ${error instanceof Error ? error.message : error}`));
421
+ }
422
+ });
423
+ });
424
+ req.on('error', (error) => {
425
+ clearTimeout(timeoutId);
426
+ reject(new Error(`Request failed: ${error instanceof Error ? error.message : error}`));
427
+ });
428
+ });
429
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "2.1.4-dev.3",
3
+ "version": "2.1.5-dev.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "2.1.4-dev.3",
9
+ "version": "2.1.5-dev.1",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.12.3",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "2.1.4-dev.3",
3
+ "version": "2.1.5-dev.1",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",