[matter] Upgrades to matter.js v0.14.0, adds matter error codes and translations (#18786)
Signed-off-by: Dan Cunningham <dan@digitaldan.com>pull/18623/merge
parent
9f73acaf39
commit
c9eaa00145
|
@ -2,6 +2,8 @@
|
|||
|
||||
The Matter Binding for openHAB allows seamless integration with Matter-compatible devices.
|
||||
|
||||
It currently supports version 1.4.1 of the Matter specification and earlier.
|
||||
|
||||
## Supported functionality
|
||||
|
||||
This binding supports two different types of Matter functionality which operate independently of each other.
|
||||
|
@ -17,7 +19,7 @@ For more information on the Matter specification, see the [Matter Ecosystem Over
|
|||
|
||||
## Matter.JS Runtime
|
||||
|
||||
This binding uses the excellent [matter.js](https://github.com/project-chip/matter.js) implementation of the the Matter 1.4 protocol.
|
||||
This binding uses the excellent [matter.js](https://github.com/project-chip/matter.js) implementation of the the Matter 1.4.1 protocol.
|
||||
|
||||
As such, this binding requires NodesJS 18+ and will attempt to download and cache an appropriate version when started if a version is not already installed on the system.
|
||||
Alpine Linux users (typically docker) and those on older Linux distributions will need to install this manually as the official NodeJS versions are not compatible.
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
"name": "code-gen",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@matter/main": "v0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/main": "v0.14.0",
|
||||
"handlebars": "^4.7.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-organize-imports": "^4.1.0",
|
||||
"ts-loader": "^9.4.4",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.2.2"
|
||||
|
@ -122,85 +124,85 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@matter/general": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/general/-/general-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-0rkdLhn/ETSW5w/MQqJQnYRPtOwFx2VKRHAiu5w1lHS7TIVtJ4emPLq2HMSiQ2HMAEDz9eYzfIO4OueEhCbW4A==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/general/-/general-0.14.0.tgz",
|
||||
"integrity": "sha512-lTaJgeWRlwr+4JZr0RcuwSMqbZMa/uPpDWG5P2RC7N/QvmL3fPoRjfdWYjCKXZkGfeG2XXIezQGCkp0z2BWLLQ==",
|
||||
"dependencies": {
|
||||
"@noble/curves": "^1.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/main": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/main/-/main-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-tu/XAD3wK0kzI9PfXHUK5T0z4Y2vNUMZhbxNe7kSB4kHHjWCHitv1NMG0/uEIWRkSrm4/e82WCdJUrWxLgtm0g==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/main/-/main-0.14.0.tgz",
|
||||
"integrity": "sha512-fBXQtBm5+ySWg7yA4FyiCl/olbirWeBSt8ExXCBoMX2blByiYgKdj7HiHWUK0ksgNGXwh8qX62jS3+VFEdWNBQ==",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/node": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/protocol": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0",
|
||||
"@matter/node": "0.14.0",
|
||||
"@matter/protocol": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@matter/nodejs": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/nodejs": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/model": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/model/-/model-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-NvXbecY1WUjXVuXSzZX78uP50rixPNKM8mKP6JRzUpO8sKys1JwZIiJl3kGKPdTuvwot2hwpFJURtnReDam/MA==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/model/-/model-0.14.0.tgz",
|
||||
"integrity": "sha512-m4j+AY4lJCi9VE5bikUMwRIVuNWfjFIjhjD6VonTuYWVvqMGttWRQ3jTZV9qszkgur9YvOW2REmCJKvzB/KPqw==",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/node": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/node/-/node-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-dJt1HoFeomJKfBwcEkK2iAETLJfUVebYzCZ9Ie2qJ37uNc7DfhRomy/Dvj+deHS2Icfalm/COrkMiJQf2G3SvA==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/node/-/node-0.14.0.tgz",
|
||||
"integrity": "sha512-QlK8Dg4YRD3db+CNZGnp0KVC1PsIbBwMzIAGh4TiO4ln68ltjRiOjNwYxb62F9YTSQhTuEQNxxiSfhK2nkYe2A==",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/protocol": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0",
|
||||
"@matter/protocol": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/nodejs": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/nodejs/-/nodejs-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-TTI7HfubBUQEZjcQAmcikoEerTfEt5iCy7ctSwzvt+M0PMToLyj3UrOgDEezezYw+hPzTBmitLWyb/VBnSpk0g==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/nodejs/-/nodejs-0.14.0.tgz",
|
||||
"integrity": "sha512-/XkBV5yX8ZH2SOkR4DDLoBivSONpEKk88QNf7AcTCf2wDadvM+hETsQ0Kli6U8pInpKTG/vghec+0bQ50nvO/A==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/node": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/protocol": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/node": "0.14.0",
|
||||
"@matter/protocol": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/protocol": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/protocol/-/protocol-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-y3PNdjtuiA1mAHnfpA3U30y29zQsxW3BOB3anYmGnpKTLTQia6hpmtp3FGHMBMi8rMNW5+PgQT9Gx2f/G+WwFg==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/protocol/-/protocol-0.14.0.tgz",
|
||||
"integrity": "sha512-lmnXEXiO9/dEKOL/0n4jTXnEhwDwZvkRIu9QU6miuETMjBoG0spUkV6+EPWbE1+j/vXr21m65NoIvUtDoS2SKw==",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/types": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/types/-/types-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-72AgxSd1PQ5jxILMqt3JJ0Eg+duBekM/Bbjy7RIsXAB6eKPwXvvGypC4jjHn/FrAFbS7s0UVIvezT+xvxQM1gg==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/types/-/types-0.14.0.tgz",
|
||||
"integrity": "sha512-xOm/Mbs2Uqota4jJwAjl8kzsz8l1wIA216FslzSpS4TmzCskQNI8j7JIROlGkJbdMeZvBhFLirYnwilLYfQ6zw==",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/curves": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz",
|
||||
"integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==",
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.2.tgz",
|
||||
"integrity": "sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.8.0"
|
||||
},
|
||||
|
@ -1099,6 +1101,37 @@
|
|||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
|
||||
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-plugin-organize-imports": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz",
|
||||
"integrity": "sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"prettier": ">=2.0",
|
||||
"typescript": ">=2.9",
|
||||
"vue-tsc": "^2.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vue-tsc": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"prettier-plugin-organize-imports": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@matter/main": "v0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/main": "v0.14.0",
|
||||
"handlebars": "^4.7.8"
|
||||
},
|
||||
"files": [
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
"name": "matter-server",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@matter/main": "v0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/node": "v0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@project-chip/matter.js": "v0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/main": "v0.14.0",
|
||||
"@matter/node": "v0.14.0",
|
||||
"@project-chip/matter.js": "v0.14.0",
|
||||
"uuid": "^9.0.1",
|
||||
"ws": "^8.18.0",
|
||||
"yargs": "^17.7.2"
|
||||
|
@ -424,85 +424,93 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@matter/general": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/general/-/general-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-0rkdLhn/ETSW5w/MQqJQnYRPtOwFx2VKRHAiu5w1lHS7TIVtJ4emPLq2HMSiQ2HMAEDz9eYzfIO4OueEhCbW4A==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/general/-/general-0.14.0.tgz",
|
||||
"integrity": "sha512-lTaJgeWRlwr+4JZr0RcuwSMqbZMa/uPpDWG5P2RC7N/QvmL3fPoRjfdWYjCKXZkGfeG2XXIezQGCkp0z2BWLLQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@noble/curves": "^1.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/main": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/main/-/main-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-tu/XAD3wK0kzI9PfXHUK5T0z4Y2vNUMZhbxNe7kSB4kHHjWCHitv1NMG0/uEIWRkSrm4/e82WCdJUrWxLgtm0g==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/main/-/main-0.14.0.tgz",
|
||||
"integrity": "sha512-fBXQtBm5+ySWg7yA4FyiCl/olbirWeBSt8ExXCBoMX2blByiYgKdj7HiHWUK0ksgNGXwh8qX62jS3+VFEdWNBQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/node": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/protocol": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0",
|
||||
"@matter/node": "0.14.0",
|
||||
"@matter/protocol": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@matter/nodejs": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/nodejs": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/model": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/model/-/model-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-NvXbecY1WUjXVuXSzZX78uP50rixPNKM8mKP6JRzUpO8sKys1JwZIiJl3kGKPdTuvwot2hwpFJURtnReDam/MA==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/model/-/model-0.14.0.tgz",
|
||||
"integrity": "sha512-m4j+AY4lJCi9VE5bikUMwRIVuNWfjFIjhjD6VonTuYWVvqMGttWRQ3jTZV9qszkgur9YvOW2REmCJKvzB/KPqw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/node": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/node/-/node-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-dJt1HoFeomJKfBwcEkK2iAETLJfUVebYzCZ9Ie2qJ37uNc7DfhRomy/Dvj+deHS2Icfalm/COrkMiJQf2G3SvA==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/node/-/node-0.14.0.tgz",
|
||||
"integrity": "sha512-QlK8Dg4YRD3db+CNZGnp0KVC1PsIbBwMzIAGh4TiO4ln68ltjRiOjNwYxb62F9YTSQhTuEQNxxiSfhK2nkYe2A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/protocol": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0",
|
||||
"@matter/protocol": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/nodejs": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/nodejs/-/nodejs-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-TTI7HfubBUQEZjcQAmcikoEerTfEt5iCy7ctSwzvt+M0PMToLyj3UrOgDEezezYw+hPzTBmitLWyb/VBnSpk0g==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/nodejs/-/nodejs-0.14.0.tgz",
|
||||
"integrity": "sha512-/XkBV5yX8ZH2SOkR4DDLoBivSONpEKk88QNf7AcTCf2wDadvM+hETsQ0Kli6U8pInpKTG/vghec+0bQ50nvO/A==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/node": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/protocol": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/node": "0.14.0",
|
||||
"@matter/protocol": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/protocol": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/protocol/-/protocol-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-y3PNdjtuiA1mAHnfpA3U30y29zQsxW3BOB3anYmGnpKTLTQia6hpmtp3FGHMBMi8rMNW5+PgQT9Gx2f/G+WwFg==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/protocol/-/protocol-0.14.0.tgz",
|
||||
"integrity": "sha512-lmnXEXiO9/dEKOL/0n4jTXnEhwDwZvkRIu9QU6miuETMjBoG0spUkV6+EPWbE1+j/vXr21m65NoIvUtDoS2SKw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@matter/types": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@matter/types/-/types-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-72AgxSd1PQ5jxILMqt3JJ0Eg+duBekM/Bbjy7RIsXAB6eKPwXvvGypC4jjHn/FrAFbS7s0UVIvezT+xvxQM1gg==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@matter/types/-/types-0.14.0.tgz",
|
||||
"integrity": "sha512-xOm/Mbs2Uqota4jJwAjl8kzsz8l1wIA216FslzSpS4TmzCskQNI8j7JIROlGkJbdMeZvBhFLirYnwilLYfQ6zw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/curves": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz",
|
||||
"integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==",
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.2.tgz",
|
||||
"integrity": "sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.8.0"
|
||||
},
|
||||
|
@ -517,6 +525,7 @@
|
|||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
|
@ -563,15 +572,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@project-chip/matter.js": {
|
||||
"version": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"resolved": "https://registry.npmjs.org/@project-chip/matter.js/-/matter.js-0.14.0-alpha.0-20250531-7ed2d6da8.tgz",
|
||||
"integrity": "sha512-CewVH1Ug1eSZBetCICpDs0HJbhi8uAKLMgdiMmkFrf2FwcQb9whdCwQ1FmB0cHThZCNsHLicStqv1S5poS9QkQ==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@project-chip/matter.js/-/matter.js-0.14.0.tgz",
|
||||
"integrity": "sha512-w2aTSC3YbCbASBv/5YJvo9wIevRcfuuSP9mQwPnJVMlNiK8ocReVhS0L2xLqIrZVbA3SILATRnD6g7skT/G5wg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@matter/general": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/model": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/node": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/protocol": "0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/types": "0.14.0-alpha.0-20250531-7ed2d6da8"
|
||||
"@matter/general": "0.14.0",
|
||||
"@matter/model": "0.14.0",
|
||||
"@matter/node": "0.14.0",
|
||||
"@matter/protocol": "0.14.0",
|
||||
"@matter/types": "0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
"webpack-cli": "^5.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@matter/main": "v0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/node": "v0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@project-chip/matter.js": "v0.14.0-alpha.0-20250531-7ed2d6da8",
|
||||
"@matter/main": "v0.14.0",
|
||||
"@matter/node": "v0.14.0",
|
||||
"@project-chip/matter.js": "v0.14.0",
|
||||
"uuid": "^9.0.1",
|
||||
"ws": "^8.18.0",
|
||||
"yargs": "^17.7.2"
|
||||
|
|
|
@ -44,21 +44,20 @@ export abstract class Controller {
|
|||
try {
|
||||
const result = this.executeCommand(namespace, functionName, args || []);
|
||||
if (result instanceof Promise) {
|
||||
result
|
||||
.then(asyncResult => {
|
||||
const asyncResult = await result;
|
||||
this.ws.sendResponse(MessageType.ResultSuccess, id, asyncResult);
|
||||
})
|
||||
.catch(error => {
|
||||
printError(logger, error, functionName);
|
||||
this.ws.sendResponse(MessageType.ResultError, id, undefined, error.message);
|
||||
});
|
||||
} else {
|
||||
this.ws.sendResponse(MessageType.ResultSuccess, id, result);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
printError(logger, error, functionName);
|
||||
this.ws.sendResponse(MessageType.ResultError, id, undefined, error.message);
|
||||
let errorId: string | undefined;
|
||||
// instances of a MatterError has an id property
|
||||
if ("id" in error) {
|
||||
errorId = (error as any).id;
|
||||
}
|
||||
this.ws.sendResponse(MessageType.ResultError, id, undefined, error.message, errorId);
|
||||
} else {
|
||||
logger.error(`Unexpected error executing function ${functionName}: ${error}`);
|
||||
this.ws.sendResponse(MessageType.ResultError, id, undefined, String(error));
|
||||
|
|
|
@ -31,7 +31,6 @@ export interface Message {
|
|||
}
|
||||
|
||||
export enum MessageType {
|
||||
Result = "result",
|
||||
ResultError = "resultError",
|
||||
ResultSuccess = "resultSuccess",
|
||||
}
|
||||
|
|
|
@ -6,8 +6,10 @@ import { hideBin } from "yargs/helpers";
|
|||
import { BridgeController } from "./bridge/BridgeController";
|
||||
import { ClientController } from "./client/ClientController";
|
||||
import { Controller } from "./Controller";
|
||||
import { Message, MessageType, Request } from "./MessageTypes";
|
||||
import { Message, Request } from "./MessageTypes";
|
||||
import { printError } from "./util/error";
|
||||
import { toJSON } from "./util/Json";
|
||||
|
||||
const argv: any = yargs(hideBin(process.argv)).argv;
|
||||
|
||||
const logger = Logger.get("matter");
|
||||
|
@ -72,7 +74,7 @@ const shutdownHandler = async (signal: string) => {
|
|||
|
||||
export interface WebSocketSession extends WebSocket {
|
||||
controller?: Controller;
|
||||
sendResponse(type: string, id: string, result?: any, error?: string): void;
|
||||
sendResponse(type: string, id: string, result?: any, error?: string, errorId?: string): void;
|
||||
sendEvent(type: string, data?: any): void;
|
||||
}
|
||||
|
||||
|
@ -80,7 +82,7 @@ const socketPort = argv.port ? parseInt(argv.port) : 8888;
|
|||
const wss: Server = new WebSocket.Server({ port: socketPort, host: argv.host });
|
||||
|
||||
wss.on("connection", (ws: WebSocketSession, req: IncomingMessage) => {
|
||||
ws.sendResponse = (type: string, id: string, result?: any, error?: string) => {
|
||||
ws.sendResponse = (type: string, id: string, result?: any, error?: string, errorId?: string) => {
|
||||
const message: Message = {
|
||||
type: "response",
|
||||
message: {
|
||||
|
@ -88,10 +90,11 @@ wss.on("connection", (ws: WebSocketSession, req: IncomingMessage) => {
|
|||
id,
|
||||
result,
|
||||
error,
|
||||
errorId,
|
||||
},
|
||||
};
|
||||
logger.debug(`Sending response: ${Logger.toJSON(message)}`);
|
||||
ws.send(Logger.toJSON(message));
|
||||
logger.debug(`Sending response: ${toJSON(message)}`);
|
||||
ws.send(toJSON(message));
|
||||
};
|
||||
|
||||
ws.sendEvent = (type: string, data?: any) => {
|
||||
|
@ -102,8 +105,8 @@ wss.on("connection", (ws: WebSocketSession, req: IncomingMessage) => {
|
|||
data,
|
||||
},
|
||||
};
|
||||
logger.debug(`Sending event: ${Logger.toJSON(message)}`);
|
||||
ws.send(Logger.toJSON(message));
|
||||
logger.debug(`Sending event: ${toJSON(message)}`);
|
||||
ws.send(toJSON(message));
|
||||
};
|
||||
|
||||
ws.on("open", () => {
|
||||
|
@ -111,17 +114,9 @@ wss.on("connection", (ws: WebSocketSession, req: IncomingMessage) => {
|
|||
});
|
||||
|
||||
ws.on("message", (message: string) => {
|
||||
try {
|
||||
const request: Request = JSON.parse(message);
|
||||
if (ws.controller) {
|
||||
void ws.controller.handleRequest(request).catch((error: Error) => {
|
||||
ws.sendResponse(MessageType.ResultError, "", undefined, error.message);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
ws.sendResponse(MessageType.ResultError, "", undefined, error.message);
|
||||
}
|
||||
void ws.controller.handleRequest(request);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Logger } from "@matter/general";
|
||||
import { WebSocketSession } from "../app";
|
||||
import { Controller } from "../Controller";
|
||||
import { toJSON } from "../util/Json";
|
||||
import { ControllerNode } from "./ControllerNode";
|
||||
import { Clusters } from "./namespaces/Clusters";
|
||||
import { Nodes } from "./namespaces/Nodes";
|
||||
|
@ -53,7 +54,7 @@ export class ClientController extends Controller {
|
|||
}
|
||||
|
||||
executeCommand(namespace: string, functionName: string, args: any[]): any | Promise<any> {
|
||||
logger.debug(`Executing function ${namespace}.${functionName}(${Logger.toJSON(args)})`);
|
||||
logger.debug(`Executing function ${namespace}.${functionName}(${toJSON(args)})`);
|
||||
|
||||
const controllerAny: any = this;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Logger } from "@matter/general";
|
|||
import { ClusterId, ValidationError } from "@matter/main/types";
|
||||
import { ClusterModel, MatterModel } from "@matter/model";
|
||||
import { SupportedAttributeClient } from "@matter/protocol";
|
||||
import { convertJsonDataWithModel } from "../../util/Json";
|
||||
import { convertJsonDataWithModel, toJSON } from "../../util/Json";
|
||||
import { capitalize } from "../../util/String";
|
||||
import { ControllerNode } from "../ControllerNode";
|
||||
|
||||
|
@ -28,7 +28,7 @@ export class Clusters {
|
|||
* @throws Error if the cluster or command is not found on the device.
|
||||
*/
|
||||
async command(nodeId: number, endpointId: number, clusterName: string, commandName: string, args: any) {
|
||||
logger.debug(`command ${nodeId} ${endpointId} ${clusterName} ${commandName} ${Logger.toJSON(args)}`);
|
||||
logger.debug(`command ${nodeId} ${endpointId} ${clusterName} ${commandName} ${toJSON(args)}`);
|
||||
const device = this.controllerNode.getNode(nodeId).getDeviceById(endpointId);
|
||||
if (device == undefined) {
|
||||
throw new Error(`Endpoint ${endpointId} not found`);
|
||||
|
@ -114,15 +114,15 @@ export class Clusters {
|
|||
parsedValue = convertJsonDataWithModel(attribute, parsedValue);
|
||||
await attributeClient.set(parsedValue);
|
||||
console.log(
|
||||
`Attribute ${attributeName} ${nodeId}/${endpointId}/${clusterName}/${attributeName} set to ${Logger.toJSON(value)}`,
|
||||
`Attribute ${attributeName} ${nodeId}/${endpointId}/${clusterName}/${attributeName} set to ${toJSON(value)}`,
|
||||
);
|
||||
} catch (error) {
|
||||
if (error instanceof ValidationError) {
|
||||
throw new Error(
|
||||
`Could not validate data for attribute ${attributeName} to ${Logger.toJSON(parsedValue)}: ${error}${error.fieldName !== undefined ? ` in field ${error.fieldName}` : ""}`,
|
||||
`Could not validate data for attribute ${attributeName} to ${toJSON(parsedValue)}: ${error}${error.fieldName !== undefined ? ` in field ${error.fieldName}` : ""}`,
|
||||
);
|
||||
} else {
|
||||
throw new Error(`Could not set attribute ${attributeName} to ${Logger.toJSON(parsedValue)}: ${error}`);
|
||||
throw new Error(`Could not set attribute ${attributeName} to ${toJSON(parsedValue)}: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ export function printError(logger: Logger, error: Error, functionName: string) {
|
|||
if ("name" in error) {
|
||||
logger.error(`Error name: ${(error as any).name}`);
|
||||
}
|
||||
if ("id" in error) {
|
||||
logger.error(`Error id: ${(error as any).id}`);
|
||||
}
|
||||
|
||||
// Fallback: log the entire error object in case there are other useful details
|
||||
logger.error(`Full error object: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`);
|
||||
|
|
|
@ -17,6 +17,8 @@ import java.util.concurrent.ExecutionException;
|
|||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.matter.internal.MatterBindingConstants;
|
||||
import org.openhab.binding.matter.internal.client.MatterErrorCode;
|
||||
import org.openhab.binding.matter.internal.client.MatterRequestException;
|
||||
import org.openhab.binding.matter.internal.handler.ControllerHandler;
|
||||
import org.openhab.binding.matter.internal.util.TranslationService;
|
||||
import org.openhab.core.automation.annotation.ActionInput;
|
||||
|
@ -72,9 +74,21 @@ public class MatterControllerActions implements ThingActions {
|
|||
try {
|
||||
handler.startScan(code).get();
|
||||
return translationService.getTranslation(MatterBindingConstants.THING_ACTION_RESULT_DEVICE_ADDED);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
return handler.getTranslation(MatterBindingConstants.THING_ACTION_RESULT_PAIRING_FAILED)
|
||||
+ e.getLocalizedMessage();
|
||||
} catch (InterruptedException e) {
|
||||
return handler.getTranslation(MatterBindingConstants.THING_ACTION_RESULT_PAIRING_FAILED,
|
||||
e.getLocalizedMessage());
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof MatterRequestException matterRequestException) {
|
||||
MatterErrorCode errorCode = matterRequestException.getErrorCode();
|
||||
if (errorCode != null) {
|
||||
return handler.getTranslation(errorCode.getTranslationKey());
|
||||
} else {
|
||||
return handler.getTranslation(MatterBindingConstants.THING_ACTION_RESULT_PAIRING_FAILED,
|
||||
matterRequestException.getErrorMessage());
|
||||
}
|
||||
}
|
||||
return handler.getTranslation(MatterBindingConstants.THING_ACTION_RESULT_PAIRING_FAILED,
|
||||
e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
return translationService.getTranslation(MatterBindingConstants.THING_ACTION_RESULT_NO_HANDLER);
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2025 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
|
||||
package org.openhab.binding.matter.internal.client;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Error codes and translation keys for Matter errors events.
|
||||
*
|
||||
* @author Dan Cunningham - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum MatterErrorCode {
|
||||
COMMISSIONING("commissioning", "matterjs.error.commissioning"),
|
||||
MAXIMUM_COMMISSIONED_FABRICS_REACHED("maximum-commissioned-fabrics-reached",
|
||||
"matterjs.error.maximum-commissioned-fabrics-reached"),
|
||||
COMMISSIONING_TIMEOUT("commissioning-timeout", "matterjs.error.commissioning-timeout"),
|
||||
DEVICE_ALREADY_COMMISSIONED_TO_THIS_FABRIC("device-already-commissioned-to-this-fabric",
|
||||
"matterjs.error.device-already-commissioned-to-this-fabric"),
|
||||
FABRIC_LABEL_CONFLICT("fabric-label-conflict", "matterjs.error.fabric-label-conflict"),
|
||||
WIFI_OR_THREAD_NETWORK_CREDENTIALS_NOT_CONFIGURED("wifi-or-thread-network-credentials-not-configured",
|
||||
"matterjs.error.wifi-or-thread-network-credentials-not-configured"),
|
||||
WIFI_NETWORK_SETUP_FAILED("wifi-network-setup-failed", "matterjs.error.wifi-network-setup-failed"),
|
||||
THREAD_NETWORK_SETUP_FAILED("thread-network-setup-failed", "matterjs.error.thread-network-setup-failed"),
|
||||
NODE_ID_CONFLICT("node-id-conflict", "matterjs.error.node-id-conflict"),
|
||||
COMMISSIONABLE_DEVICE_DISCOVERY_FAILED("commissionable-device-discovery-failed",
|
||||
"matterjs.error.commissionable-device-discovery-failed"),
|
||||
OPERATIVE_CONNECTION_FAILED("operative-connection-failed", "matterjs.error.operative-connection-failed");
|
||||
|
||||
private final String errorId;
|
||||
private final String translationKey;
|
||||
|
||||
MatterErrorCode(String errorId, String translationKey) {
|
||||
this.errorId = errorId;
|
||||
this.translationKey = translationKey;
|
||||
}
|
||||
|
||||
public String getErrorId() {
|
||||
return errorId;
|
||||
}
|
||||
|
||||
public String getTranslationKey() {
|
||||
return translationKey;
|
||||
}
|
||||
|
||||
public static @Nullable MatterErrorCode fromErrorId(String errorId) {
|
||||
for (MatterErrorCode error : values()) {
|
||||
if (error.errorId.equals(errorId)) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2025 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.matter.internal.client;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Exception thrown when a request to the Matter server fails.
|
||||
*
|
||||
* @author Dan Cunningham - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MatterRequestException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String errorMessage;
|
||||
private final @Nullable MatterErrorCode errorCode;
|
||||
|
||||
public MatterRequestException(String message, @Nullable MatterErrorCode errorCode) {
|
||||
super(message);
|
||||
this.errorMessage = message;
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public @Nullable MatterErrorCode getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
|
@ -58,6 +58,7 @@ import org.openhab.binding.matter.internal.client.dto.ws.NodeStateMessage;
|
|||
import org.openhab.binding.matter.internal.client.dto.ws.Path;
|
||||
import org.openhab.binding.matter.internal.client.dto.ws.Request;
|
||||
import org.openhab.binding.matter.internal.client.dto.ws.Response;
|
||||
import org.openhab.binding.matter.internal.client.dto.ws.ResponseType;
|
||||
import org.openhab.binding.matter.internal.client.dto.ws.TriggerEvent;
|
||||
import org.openhab.core.common.ThreadPoolManager;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -261,8 +262,9 @@ public class MatterWebsocketClient implements WebSocketListener, MatterWebsocket
|
|||
return;
|
||||
}
|
||||
logger.debug("result type: {} ", response.type);
|
||||
if (!"resultSuccess".equals(response.type)) {
|
||||
future.completeExceptionally(new Exception(response.error));
|
||||
if (response.type != ResponseType.RESULT_SUCCESS) {
|
||||
future.completeExceptionally(
|
||||
new MatterRequestException(response.error, MatterErrorCode.fromErrorId(response.errorId)));
|
||||
} else {
|
||||
future.complete(response.result);
|
||||
}
|
||||
|
|
|
@ -20,8 +20,9 @@ import com.google.gson.JsonElement;
|
|||
* @author Dan Cunningham - Initial contribution
|
||||
*/
|
||||
public class Response {
|
||||
public String type;
|
||||
public ResponseType type;
|
||||
public String id;
|
||||
public JsonElement result;
|
||||
public String error;
|
||||
public String errorId;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2025 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.matter.internal.client.dto.ws;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Websocket message response types.
|
||||
*
|
||||
* @author Dan Cunningham - Initial contribution
|
||||
*/
|
||||
public enum ResponseType {
|
||||
|
||||
@SerializedName("resultError")
|
||||
RESULT_ERROR("resultError"),
|
||||
|
||||
@SerializedName("resultSuccess")
|
||||
RESULT_SUCCESS("resultSuccess");
|
||||
|
||||
private final String value;
|
||||
|
||||
ResponseType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* Get all nodes that are commissioned / paired to this controller
|
||||
*
|
||||
* @return a future that returns a list of node IDs
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<List<BigInteger>> getCommissionedNodeIds() {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "listNodes", new Object[0]);
|
||||
|
@ -69,6 +70,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param nodeId the node ID to initialize
|
||||
* @param connectionTimeoutMilliseconds the timeout in milliseconds to wait for the node to connect
|
||||
* @return a future that completes when the node is initialized
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<Void> initializeNode(BigInteger nodeId, Integer connectionTimeoutMilliseconds) {
|
||||
// add 1 second delay to the message timeout to allow the function to complete
|
||||
|
@ -85,6 +87,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
*
|
||||
* @param nodeId the node ID to request data for
|
||||
* @return a future that completes when the data is requested
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<Void> requestAllNodeData(BigInteger nodeId) {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "requestAllData", new Object[] { nodeId });
|
||||
|
@ -99,6 +102,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param nodeId the node ID to request data for
|
||||
* @param endpointId the endpoint ID to request data for
|
||||
* @return a future that completes when the data is requested
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<Void> requestEndpointData(BigInteger nodeId, Integer endpointId) {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "requestEndpointData",
|
||||
|
@ -113,6 +117,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
*
|
||||
* @param code the pairing code to pair with
|
||||
* @return a future that completes when the node is paired (or fails)
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<BigInteger> pairNode(String code) {
|
||||
String[] parts = code.trim().split(" ");
|
||||
|
@ -134,6 +139,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
*
|
||||
* @param nodeId the node ID to remove
|
||||
* @return a future that completes when the node is removed
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<Void> removeNode(BigInteger nodeId) {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "removeNode", new Object[] { nodeId });
|
||||
|
@ -147,6 +153,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
*
|
||||
* @param nodeId the node ID to reconnect
|
||||
* @return a future that completes when the node is reconnected
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<Void> reconnectNode(BigInteger nodeId) {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "reconnectNode", new Object[] { nodeId });
|
||||
|
@ -161,6 +168,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param nodeId the node ID to get the pairing codes for
|
||||
* @return a future that completes when the pairing codes are retrieved
|
||||
* @throws JsonParseException when completing the future if the pairing codes cannot be deserialized
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<PairingCodes> enhancedCommissioningWindow(BigInteger nodeId) {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "enhancedCommissioningWindow",
|
||||
|
@ -179,6 +187,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
*
|
||||
* @param nodeId the node ID to disconnect
|
||||
* @return a future that completes when the node is disconnected
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<Void> disconnectNode(BigInteger nodeId) {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "disconnectNode", new Object[] { nodeId });
|
||||
|
@ -193,6 +202,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param nodeId the node ID to get the fabrics for
|
||||
* @return a future that completes when the fabrics are retrieved or an exception is thrown
|
||||
* @throws JsonParseException when completing the future if the fabrics cannot be deserialized
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<List<OperationalCredentialsCluster.FabricDescriptorStruct>> getFabrics(BigInteger nodeId) {
|
||||
Object[] clusterArgs = { String.valueOf(nodeId) };
|
||||
|
@ -214,6 +224,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param nodeId the node ID to remove the fabric from
|
||||
* @param index the index of the fabric to remove
|
||||
* @return a future that completes when the fabric is removed
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<Void> removeFabric(BigInteger nodeId, Integer index) {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "removeFabric", new Object[] { nodeId, index });
|
||||
|
@ -230,6 +241,8 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param clusterName the cluster name to send the command to
|
||||
* @param command the command to send
|
||||
* @return a future that completes when the command is sent
|
||||
* @throws MatterRequestException if the request fails
|
||||
* @throws JsonParseException when completing the future if the command cannot be deserialized
|
||||
*/
|
||||
public CompletableFuture<JsonElement> clusterCommand(BigInteger nodeId, Integer endpointId, String clusterName,
|
||||
ClusterCommand command) {
|
||||
|
@ -247,6 +260,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param attributeName the attribute name to write
|
||||
* @param value the value to write
|
||||
* @return a future that completes when the attribute is written
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<Void> clusterWriteAttribute(BigInteger nodeId, Integer endpointId, String clusterName,
|
||||
String attributeName, String value) {
|
||||
|
@ -266,6 +280,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param clusterId the cluster ID to read the cluster from
|
||||
* @return a future that completes when the cluster is read
|
||||
* @throws JsonParseException when completing the future if the cluster cannot be deserialized
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public <T extends BaseCluster> CompletableFuture<T> readCluster(Class<T> type, BigInteger nodeId,
|
||||
Integer endpointId, Integer clusterId) {
|
||||
|
@ -289,6 +304,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
* @param clusterName the cluster name to read the attribute from
|
||||
* @param attributeName the attribute name to read
|
||||
* @return a future that completes when the attribute is read
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<String> clusterReadAttribute(BigInteger nodeId, Integer endpointId, String clusterName,
|
||||
String attributeName) {
|
||||
|
@ -304,6 +320,7 @@ public class MatterControllerClient extends MatterWebsocketClient {
|
|||
*
|
||||
* @return a future that completes when the session information is retrieved
|
||||
* @throws JsonParseException when completing the future if the session information cannot be deserialized
|
||||
* @throws MatterRequestException if the request fails
|
||||
*/
|
||||
public CompletableFuture<ActiveSessionInformation[]> getSessionInformation() {
|
||||
CompletableFuture<JsonElement> future = sendMessage("nodes", "sessionInformation", new Object[0]);
|
||||
|
|
|
@ -270,8 +270,8 @@ public class ControllerHandler extends BaseBridgeHandler implements MatterClient
|
|||
linkedNodes.keySet().forEach(nodeId -> updateNode(nodeId));
|
||||
}
|
||||
|
||||
public String getTranslation(String key) {
|
||||
return translationService.getTranslation(key);
|
||||
public String getTranslation(String key, Object... args) {
|
||||
return translationService.getTranslation(key, args);
|
||||
}
|
||||
|
||||
public MatterControllerClient getClient() {
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
*/
|
||||
package org.openhab.binding.matter.internal.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TranslationProvider;
|
||||
|
@ -51,10 +53,10 @@ public class TranslationService {
|
|||
* @param key the key to get the translation for (with or without the @text/ prefix)
|
||||
* @return the translation
|
||||
*/
|
||||
public String getTranslation(String key) {
|
||||
public String getTranslation(String key, Object... args) {
|
||||
String lookupKey = key.replace("@text/", "");
|
||||
String result = translationProvider.getText(bundle, lookupKey, lookupKey, localeProvider.getLocale());
|
||||
return result == null ? lookupKey : result;
|
||||
String result = translationProvider.getText(bundle, lookupKey, lookupKey, localeProvider.getLocale(), args);
|
||||
return result == null ? lookupKey + " " + Arrays.toString(args) : result;
|
||||
}
|
||||
|
||||
public LocaleProvider getLocaleProvider() {
|
||||
|
|
|
@ -324,3 +324,17 @@ thing-action.result.pairing-failed = Failed to pair device: {0}
|
|||
|
||||
thing-status.detail.controller.waitingForData = Waiting for data
|
||||
thing-status.detail.endpoint.thingNotReachable = Bridge reports device as not reachable
|
||||
|
||||
# matterjs error messages
|
||||
|
||||
matterjs.error.commissioning = General commissioning error
|
||||
matterjs.error.maximum-commissioned-fabrics-reached = Maximum number of commissioned fabrics reached on device, please remove a fabric from another controller or reset the device
|
||||
matterjs.error.commissioning-timeout = The commissioning process could not be finished within the maximum allowed time frame
|
||||
matterjs.error.device-already-commissioned-to-this-fabric = The device is already commissioned to this fabric, either remove this fabric using another controller or reset the device
|
||||
matterjs.error.fabric-label-conflict = The device is already commissioned to another fabric with the same label, please remove the fabric using another controller or reset the device
|
||||
matterjs.error.wifi-or-thread-network-credentials-not-configured = Wi-Fi or Thread network credentials not configured
|
||||
matterjs.error.wifi-network-setup-failed = Wi-Fi network setup failed
|
||||
matterjs.error.thread-network-setup-failed = Thread network setup failed
|
||||
matterjs.error.node-id-conflict = Node ID conflict, reset the device and try again
|
||||
matterjs.error.commissionable-device-discovery-failed = The device could not be discovered using the provided code
|
||||
matterjs.error.operative-connection-failed = The reconnection process for the device failed, please reset the device and try again
|
||||
|
|
Loading…
Reference in New Issue