feat: Expose device serial number and origin (#7)

This commit is contained in:
Pascal Bourque
2025-06-07 10:58:41 -04:00
committed by GitHub
parent 2e2e64d2d0
commit 374dae1885
5 changed files with 245 additions and 145 deletions

335
package-lock.json generated
View File

@@ -11,8 +11,8 @@
"dependencies": {
"commander": "14.0.0",
"dotenv": "16.5.0",
"mqtt2ha": "4.0.0",
"mysa-js-sdk": "1.1.2",
"mqtt2ha": "4.1.0",
"mysa-js-sdk": "1.2.0",
"pino": "9.7.0",
"pino-pretty": "13.0.0"
},
@@ -167,45 +167,45 @@
}
},
"node_modules/@aws-sdk/client-cognito-identity": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.823.0.tgz",
"integrity": "sha512-zCTr4gemGm2bvbeOvXFa0g1SPyra+WlZvGQ7Vc/snFwOlZ/OLAH1OugYD357k9pMqh1DyElFbHlj2rY5I8JeUA==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.825.0.tgz",
"integrity": "sha512-FYXwkFmOYMiUYbLuzEl9by4Ks+bidXiHQwRXaDijuzkjM3B/Dd8noIxlvQCdxd6Ji7ofXcXTfNpVqN0U0JF9ag==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
"@aws-sdk/core": "3.823.0",
"@aws-sdk/credential-provider-node": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/credential-provider-node": "3.825.0",
"@aws-sdk/middleware-host-header": "3.821.0",
"@aws-sdk/middleware-logger": "3.821.0",
"@aws-sdk/middleware-recursion-detection": "3.821.0",
"@aws-sdk/middleware-user-agent": "3.823.0",
"@aws-sdk/middleware-user-agent": "3.825.0",
"@aws-sdk/region-config-resolver": "3.821.0",
"@aws-sdk/types": "3.821.0",
"@aws-sdk/util-endpoints": "3.821.0",
"@aws-sdk/util-user-agent-browser": "3.821.0",
"@aws-sdk/util-user-agent-node": "3.823.0",
"@aws-sdk/util-user-agent-node": "3.825.0",
"@smithy/config-resolver": "^4.1.4",
"@smithy/core": "^3.5.1",
"@smithy/core": "^3.5.2",
"@smithy/fetch-http-handler": "^5.0.4",
"@smithy/hash-node": "^4.0.4",
"@smithy/invalid-dependency": "^4.0.4",
"@smithy/middleware-content-length": "^4.0.4",
"@smithy/middleware-endpoint": "^4.1.9",
"@smithy/middleware-retry": "^4.1.10",
"@smithy/middleware-endpoint": "^4.1.10",
"@smithy/middleware-retry": "^4.1.11",
"@smithy/middleware-serde": "^4.0.8",
"@smithy/middleware-stack": "^4.0.4",
"@smithy/node-config-provider": "^4.1.3",
"@smithy/node-http-handler": "^4.0.6",
"@smithy/protocol-http": "^5.1.2",
"@smithy/smithy-client": "^4.4.1",
"@smithy/smithy-client": "^4.4.2",
"@smithy/types": "^4.3.1",
"@smithy/url-parser": "^4.0.4",
"@smithy/util-base64": "^4.0.0",
"@smithy/util-body-length-browser": "^4.0.0",
"@smithy/util-body-length-node": "^4.0.0",
"@smithy/util-defaults-mode-browser": "^4.0.17",
"@smithy/util-defaults-mode-node": "^4.0.17",
"@smithy/util-defaults-mode-browser": "^4.0.18",
"@smithy/util-defaults-mode-node": "^4.0.18",
"@smithy/util-endpoints": "^3.0.6",
"@smithy/util-middleware": "^4.0.4",
"@smithy/util-retry": "^4.0.5",
@@ -216,45 +216,97 @@
"node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/client-sso": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.823.0.tgz",
"integrity": "sha512-dBWdsbyGw8rPfdCsZySNtTOGQK4EZ8lxB/CneSQWRBPHgQ+Ys88NXxImO8xfWO7Itt1eh8O7UDTZ9+smcvw2pw==",
"node_modules/@aws-sdk/client-iot": {
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-iot/-/client-iot-3.825.0.tgz",
"integrity": "sha512-q2CcipEBhmLIaIr1NXL7ijYgQ5I4dKCMoeu/XdJNkPYE5ceONI+I+76CPlvqgFdG+/T2IrOsfpAGD8rtLTETzw==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
"@aws-sdk/core": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/credential-provider-node": "3.825.0",
"@aws-sdk/middleware-host-header": "3.821.0",
"@aws-sdk/middleware-logger": "3.821.0",
"@aws-sdk/middleware-recursion-detection": "3.821.0",
"@aws-sdk/middleware-user-agent": "3.823.0",
"@aws-sdk/middleware-user-agent": "3.825.0",
"@aws-sdk/region-config-resolver": "3.821.0",
"@aws-sdk/types": "3.821.0",
"@aws-sdk/util-endpoints": "3.821.0",
"@aws-sdk/util-user-agent-browser": "3.821.0",
"@aws-sdk/util-user-agent-node": "3.823.0",
"@aws-sdk/util-user-agent-node": "3.825.0",
"@smithy/config-resolver": "^4.1.4",
"@smithy/core": "^3.5.1",
"@smithy/core": "^3.5.2",
"@smithy/fetch-http-handler": "^5.0.4",
"@smithy/hash-node": "^4.0.4",
"@smithy/invalid-dependency": "^4.0.4",
"@smithy/middleware-content-length": "^4.0.4",
"@smithy/middleware-endpoint": "^4.1.9",
"@smithy/middleware-retry": "^4.1.10",
"@smithy/middleware-endpoint": "^4.1.10",
"@smithy/middleware-retry": "^4.1.11",
"@smithy/middleware-serde": "^4.0.8",
"@smithy/middleware-stack": "^4.0.4",
"@smithy/node-config-provider": "^4.1.3",
"@smithy/node-http-handler": "^4.0.6",
"@smithy/protocol-http": "^5.1.2",
"@smithy/smithy-client": "^4.4.1",
"@smithy/smithy-client": "^4.4.2",
"@smithy/types": "^4.3.1",
"@smithy/url-parser": "^4.0.4",
"@smithy/util-base64": "^4.0.0",
"@smithy/util-body-length-browser": "^4.0.0",
"@smithy/util-body-length-node": "^4.0.0",
"@smithy/util-defaults-mode-browser": "^4.0.17",
"@smithy/util-defaults-mode-node": "^4.0.17",
"@smithy/util-defaults-mode-browser": "^4.0.18",
"@smithy/util-defaults-mode-node": "^4.0.18",
"@smithy/util-endpoints": "^3.0.6",
"@smithy/util-middleware": "^4.0.4",
"@smithy/util-retry": "^4.0.5",
"@smithy/util-utf8": "^4.0.0",
"@types/uuid": "^9.0.1",
"tslib": "^2.6.2",
"uuid": "^9.0.1"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/client-sso": {
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.825.0.tgz",
"integrity": "sha512-U0J2RQUsxiin+uEYR8atMByojuvhtWvvEVSD2MhSUUnCa7BSu/H+4SbREBvnGDJ2nezrYh59bkSQBlp9c3Z9gg==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/middleware-host-header": "3.821.0",
"@aws-sdk/middleware-logger": "3.821.0",
"@aws-sdk/middleware-recursion-detection": "3.821.0",
"@aws-sdk/middleware-user-agent": "3.825.0",
"@aws-sdk/region-config-resolver": "3.821.0",
"@aws-sdk/types": "3.821.0",
"@aws-sdk/util-endpoints": "3.821.0",
"@aws-sdk/util-user-agent-browser": "3.821.0",
"@aws-sdk/util-user-agent-node": "3.825.0",
"@smithy/config-resolver": "^4.1.4",
"@smithy/core": "^3.5.2",
"@smithy/fetch-http-handler": "^5.0.4",
"@smithy/hash-node": "^4.0.4",
"@smithy/invalid-dependency": "^4.0.4",
"@smithy/middleware-content-length": "^4.0.4",
"@smithy/middleware-endpoint": "^4.1.10",
"@smithy/middleware-retry": "^4.1.11",
"@smithy/middleware-serde": "^4.0.8",
"@smithy/middleware-stack": "^4.0.4",
"@smithy/node-config-provider": "^4.1.3",
"@smithy/node-http-handler": "^4.0.6",
"@smithy/protocol-http": "^5.1.2",
"@smithy/smithy-client": "^4.4.2",
"@smithy/types": "^4.3.1",
"@smithy/url-parser": "^4.0.4",
"@smithy/util-base64": "^4.0.0",
"@smithy/util-body-length-browser": "^4.0.0",
"@smithy/util-body-length-node": "^4.0.0",
"@smithy/util-defaults-mode-browser": "^4.0.18",
"@smithy/util-defaults-mode-node": "^4.0.18",
"@smithy/util-endpoints": "^3.0.6",
"@smithy/util-middleware": "^4.0.4",
"@smithy/util-retry": "^4.0.5",
@@ -266,19 +318,19 @@
}
},
"node_modules/@aws-sdk/core": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.823.0.tgz",
"integrity": "sha512-1Cf4w8J7wYexz0KU3zpaikHvldGXQEjFldHOhm0SBGRy7qfYNXecfJAamccF7RdgLxKGgkv5Pl9zX/Z/DcW9zg==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.825.0.tgz",
"integrity": "sha512-UsdK6l62skh6mqY/La4xvehNj5sUl/eZ2N+8mNTHZKW4U+tiRESdrw1t/Z3r/NUAu7Tbmp+DHbUu+5K1BBY6YQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "3.821.0",
"@aws-sdk/xml-builder": "3.821.0",
"@smithy/core": "^3.5.1",
"@smithy/core": "^3.5.2",
"@smithy/node-config-provider": "^4.1.3",
"@smithy/property-provider": "^4.0.4",
"@smithy/protocol-http": "^5.1.2",
"@smithy/signature-v4": "^5.1.2",
"@smithy/smithy-client": "^4.4.1",
"@smithy/smithy-client": "^4.4.2",
"@smithy/types": "^4.3.1",
"@smithy/util-base64": "^4.0.0",
"@smithy/util-body-length-browser": "^4.0.0",
@@ -292,12 +344,12 @@
}
},
"node_modules/@aws-sdk/credential-provider-cognito-identity": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.823.0.tgz",
"integrity": "sha512-mpP6slEenKRjRpTnGMUBbZLdAJa8GszgnQ6Vep+7Z8YwLNeGWsTFRZkavGMnGsQ5K5KdqxYgdHe0SZ9j8oIoWw==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.825.0.tgz",
"integrity": "sha512-TDqaakIsUeYbShBCt5F8wgjLOkq5d16JwhCgHCuM/kbwxeLmQkJWDNlui1Z32MLCIWRBilsFCr+aNG6tlj9siQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/client-cognito-identity": "3.823.0",
"@aws-sdk/client-cognito-identity": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/property-provider": "^4.0.4",
"@smithy/types": "^4.3.1",
@@ -308,12 +360,12 @@
}
},
"node_modules/@aws-sdk/credential-provider-env": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.823.0.tgz",
"integrity": "sha512-AIrLLwumObge+U1klN4j5ToIozI+gE9NosENRyHe0GIIZgTLOG/8jxrMFVYFeNHs7RUtjDTxxewislhFyGxJ/w==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.825.0.tgz",
"integrity": "sha512-Ptkbhj4K1un+GIz5fmTLVCFtWv9rcbaCLgdZszudo/ZqLP0QzAoACADGYFFkPGYr2o51COKkgKPhHWl7FNEq6A==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/property-provider": "^4.0.4",
"@smithy/types": "^4.3.1",
@@ -324,18 +376,18 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.823.0.tgz",
"integrity": "sha512-u4DXvB/J/o2bcvP1JP6n3ch7V3/NngmiJFPsM0hKUyRlLuWM37HEDEdjPRs3/uL/soTxrEhWKTA9//YVkvzI0w==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.825.0.tgz",
"integrity": "sha512-r0V0rlNCjnFLfYfUqP6TlwAo+YgWxIkrgUb/K6mV2XCBElbFZlc9oPzMOJCmHF/+D6S60FLlMC9AnFopnEZ3/A==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/fetch-http-handler": "^5.0.4",
"@smithy/node-http-handler": "^4.0.6",
"@smithy/property-provider": "^4.0.4",
"@smithy/protocol-http": "^5.1.2",
"@smithy/smithy-client": "^4.4.1",
"@smithy/smithy-client": "^4.4.2",
"@smithy/types": "^4.3.1",
"@smithy/util-stream": "^4.2.2",
"tslib": "^2.6.2"
@@ -345,18 +397,18 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.823.0.tgz",
"integrity": "sha512-C0o63qviK5yFvjH9zKWAnCUBkssJoQ1A1XAHe0IAQkurzoNBSmu9oVemqwnKKHA4H6QrmusaEERfL00yohIkJA==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.825.0.tgz",
"integrity": "sha512-HDYopAiIGTLLhybI8jEuKGWdVUnKkkotwXHwvu8ttL5qgs13A6a/iWiREe71fmYH2fGT2URJE9+xeHa2oxohyQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "3.823.0",
"@aws-sdk/credential-provider-env": "3.823.0",
"@aws-sdk/credential-provider-http": "3.823.0",
"@aws-sdk/credential-provider-process": "3.823.0",
"@aws-sdk/credential-provider-sso": "3.823.0",
"@aws-sdk/credential-provider-web-identity": "3.823.0",
"@aws-sdk/nested-clients": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/credential-provider-env": "3.825.0",
"@aws-sdk/credential-provider-http": "3.825.0",
"@aws-sdk/credential-provider-process": "3.825.0",
"@aws-sdk/credential-provider-sso": "3.825.0",
"@aws-sdk/credential-provider-web-identity": "3.825.0",
"@aws-sdk/nested-clients": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/credential-provider-imds": "^4.0.6",
"@smithy/property-provider": "^4.0.4",
@@ -369,17 +421,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-node": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.823.0.tgz",
"integrity": "sha512-nfSxXVuZ+2GJDpVFlflNfh55Yb4BtDsXLGNssXF5YU6UgSPsi8j2YkaE92Jv2s7dlUK07l0vRpLyPuXMaGeiRQ==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.825.0.tgz",
"integrity": "sha512-qWMrrUgWFQN7nkMdQYzWF/Z/fhUctCjwTQQD/qNSs42qt3sxmC00SZcqwPn9N8S9R/hLmu5z6fefVF4o20nGng==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/credential-provider-env": "3.823.0",
"@aws-sdk/credential-provider-http": "3.823.0",
"@aws-sdk/credential-provider-ini": "3.823.0",
"@aws-sdk/credential-provider-process": "3.823.0",
"@aws-sdk/credential-provider-sso": "3.823.0",
"@aws-sdk/credential-provider-web-identity": "3.823.0",
"@aws-sdk/credential-provider-env": "3.825.0",
"@aws-sdk/credential-provider-http": "3.825.0",
"@aws-sdk/credential-provider-ini": "3.825.0",
"@aws-sdk/credential-provider-process": "3.825.0",
"@aws-sdk/credential-provider-sso": "3.825.0",
"@aws-sdk/credential-provider-web-identity": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/credential-provider-imds": "^4.0.6",
"@smithy/property-provider": "^4.0.4",
@@ -392,12 +444,12 @@
}
},
"node_modules/@aws-sdk/credential-provider-process": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.823.0.tgz",
"integrity": "sha512-U/A10/7zu2FbMFFVpIw95y0TZf+oYyrhZTBn9eL8zgWcrYRqxrxdqtPj/zMrfIfyIvQUhuJSENN4dx4tfpCMWQ==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.825.0.tgz",
"integrity": "sha512-QQoOBQAXuBfD6BCg61Hl5EkdrLyFSQCNRHVLjAO5WYQGyiPb9iTZPqo9sPwyOnCMpZE1k2EOwQ+FsnZh0xSa3Q==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/property-provider": "^4.0.4",
"@smithy/shared-ini-file-loader": "^4.0.4",
@@ -409,14 +461,14 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.823.0.tgz",
"integrity": "sha512-ff8IM80Wqz1V7VVMaMUqO2iR417jggfGWLPl8j2l7uCgwpEyop1ZZl5CFVYEwSupRBtwp+VlW1gTCk7ke56MUw==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.825.0.tgz",
"integrity": "sha512-ppwsN8tuwwJKvNnllkrhIx7AQv4r5uiNf5FTIkyeJ+3p67wgJeJye+0SP64IEkdmG7YxCaU2YkdSvyHud+D5og==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/client-sso": "3.823.0",
"@aws-sdk/core": "3.823.0",
"@aws-sdk/token-providers": "3.823.0",
"@aws-sdk/client-sso": "3.825.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/token-providers": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/property-provider": "^4.0.4",
"@smithy/shared-ini-file-loader": "^4.0.4",
@@ -428,13 +480,13 @@
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.823.0.tgz",
"integrity": "sha512-lzoZdJMQq9w7i4lXVka30cVBe/dZoUDZST8Xz/soEd73gg7RTKgG+0szL4xFWgdBDgcJDWLfZfJzlbyIVyAyOA==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.825.0.tgz",
"integrity": "sha512-cyL5xHqtvBUpflkmdQSkvjD/t+Dl/ZSXvPnc9KF79xDpuraZ5tFP1l0B6rIEu7dUzUh8XG+7m2CZ6TEs6QU33Q==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "3.823.0",
"@aws-sdk/nested-clients": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/nested-clients": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/property-provider": "^4.0.4",
"@smithy/types": "^4.3.1",
@@ -445,25 +497,25 @@
}
},
"node_modules/@aws-sdk/credential-providers": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.823.0.tgz",
"integrity": "sha512-S2iWP7+/lmaGJnGMoAipRlwRqOvd+5aWEJwdCSUCipR7cH+u/biRSbynBGrYvxjqqhyIagxjYn5gGYCX+x1v4g==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.825.0.tgz",
"integrity": "sha512-V4AaXB3oH+1lQS9lMp6+Iu3TPETdqVCktiqop3CknrjlYmtISt/vwcQ6GLWQskm1lsfewlfIsERwu5FDbHokEQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/client-cognito-identity": "3.823.0",
"@aws-sdk/core": "3.823.0",
"@aws-sdk/credential-provider-cognito-identity": "3.823.0",
"@aws-sdk/credential-provider-env": "3.823.0",
"@aws-sdk/credential-provider-http": "3.823.0",
"@aws-sdk/credential-provider-ini": "3.823.0",
"@aws-sdk/credential-provider-node": "3.823.0",
"@aws-sdk/credential-provider-process": "3.823.0",
"@aws-sdk/credential-provider-sso": "3.823.0",
"@aws-sdk/credential-provider-web-identity": "3.823.0",
"@aws-sdk/nested-clients": "3.823.0",
"@aws-sdk/client-cognito-identity": "3.825.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/credential-provider-cognito-identity": "3.825.0",
"@aws-sdk/credential-provider-env": "3.825.0",
"@aws-sdk/credential-provider-http": "3.825.0",
"@aws-sdk/credential-provider-ini": "3.825.0",
"@aws-sdk/credential-provider-node": "3.825.0",
"@aws-sdk/credential-provider-process": "3.825.0",
"@aws-sdk/credential-provider-sso": "3.825.0",
"@aws-sdk/credential-provider-web-identity": "3.825.0",
"@aws-sdk/nested-clients": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/config-resolver": "^4.1.4",
"@smithy/core": "^3.5.1",
"@smithy/core": "^3.5.2",
"@smithy/credential-provider-imds": "^4.0.6",
"@smithy/node-config-provider": "^4.1.3",
"@smithy/property-provider": "^4.0.4",
@@ -519,15 +571,15 @@
}
},
"node_modules/@aws-sdk/middleware-user-agent": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.823.0.tgz",
"integrity": "sha512-TKRQK09ld1LrIPExC9rIDpqnMsWcv+eq8ABKFHVo8mDLTSuWx/IiQ4eCh9T5zDuEZcLY4nNYCSzXKqw6XKcMCA==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.825.0.tgz",
"integrity": "sha512-3ZZOPU3GE5cqKl6VFDwiL8KIvlrrQJ4rgYkeiF+m5kA0eXV2xFOwoLgm3AmPB+6kfo9HQ0N74KKJV0teS5nO6Q==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@aws-sdk/util-endpoints": "3.821.0",
"@smithy/core": "^3.5.1",
"@smithy/core": "^3.5.2",
"@smithy/protocol-http": "^5.1.2",
"@smithy/types": "^4.3.1",
"tslib": "^2.6.2"
@@ -537,44 +589,44 @@
}
},
"node_modules/@aws-sdk/nested-clients": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.823.0.tgz",
"integrity": "sha512-/BcyOBubrJnd2gxlbbmNJR1w0Z3OVN/UE8Yz20e+ou+Mijjv7EbtVwmWvio1e3ZjphwdA8tVfPYZKwXmrvHKmQ==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.825.0.tgz",
"integrity": "sha512-OuV2pypFAv52Lty8eXWVWyyOywVmMAsgH6Gq3SA06pHEtcE+ghVIW9ByegecyfMRUpedAiovARKNy0pfGX05Pg==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
"@aws-sdk/core": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/middleware-host-header": "3.821.0",
"@aws-sdk/middleware-logger": "3.821.0",
"@aws-sdk/middleware-recursion-detection": "3.821.0",
"@aws-sdk/middleware-user-agent": "3.823.0",
"@aws-sdk/middleware-user-agent": "3.825.0",
"@aws-sdk/region-config-resolver": "3.821.0",
"@aws-sdk/types": "3.821.0",
"@aws-sdk/util-endpoints": "3.821.0",
"@aws-sdk/util-user-agent-browser": "3.821.0",
"@aws-sdk/util-user-agent-node": "3.823.0",
"@aws-sdk/util-user-agent-node": "3.825.0",
"@smithy/config-resolver": "^4.1.4",
"@smithy/core": "^3.5.1",
"@smithy/core": "^3.5.2",
"@smithy/fetch-http-handler": "^5.0.4",
"@smithy/hash-node": "^4.0.4",
"@smithy/invalid-dependency": "^4.0.4",
"@smithy/middleware-content-length": "^4.0.4",
"@smithy/middleware-endpoint": "^4.1.9",
"@smithy/middleware-retry": "^4.1.10",
"@smithy/middleware-endpoint": "^4.1.10",
"@smithy/middleware-retry": "^4.1.11",
"@smithy/middleware-serde": "^4.0.8",
"@smithy/middleware-stack": "^4.0.4",
"@smithy/node-config-provider": "^4.1.3",
"@smithy/node-http-handler": "^4.0.6",
"@smithy/protocol-http": "^5.1.2",
"@smithy/smithy-client": "^4.4.1",
"@smithy/smithy-client": "^4.4.2",
"@smithy/types": "^4.3.1",
"@smithy/url-parser": "^4.0.4",
"@smithy/util-base64": "^4.0.0",
"@smithy/util-body-length-browser": "^4.0.0",
"@smithy/util-body-length-node": "^4.0.0",
"@smithy/util-defaults-mode-browser": "^4.0.17",
"@smithy/util-defaults-mode-node": "^4.0.17",
"@smithy/util-defaults-mode-browser": "^4.0.18",
"@smithy/util-defaults-mode-node": "^4.0.18",
"@smithy/util-endpoints": "^3.0.6",
"@smithy/util-middleware": "^4.0.4",
"@smithy/util-retry": "^4.0.5",
@@ -603,13 +655,13 @@
}
},
"node_modules/@aws-sdk/token-providers": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.823.0.tgz",
"integrity": "sha512-vz6onCb/+g4y+owxGGPMEMdN789dTfBOgz/c9pFv0f01840w9Rrt46l+gjQlnXnx+0KG6wNeBIVhFdbCfV3HyQ==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.825.0.tgz",
"integrity": "sha512-a3HbF6h1Gq2vA+mGlxFe3op65wNK6dBRmp3GFwsPVQ+OFTbZJi86FCljMfBrv+BGYUkp503/IPC49wuRHOdcZA==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "3.823.0",
"@aws-sdk/nested-clients": "3.823.0",
"@aws-sdk/core": "3.825.0",
"@aws-sdk/nested-clients": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/property-provider": "^4.0.4",
"@smithy/shared-ini-file-loader": "^4.0.4",
@@ -673,12 +725,12 @@
}
},
"node_modules/@aws-sdk/util-user-agent-node": {
"version": "3.823.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.823.0.tgz",
"integrity": "sha512-WvNeRz7HV3JLBVGTXW4Qr5QvvWY0vtggH5jW/NqHFH+ZEliVQaUIJ/HNLMpMoCSiu/DlpQAyAjRZXAptJ0oqbw==",
"version": "3.825.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.825.0.tgz",
"integrity": "sha512-RfB0w9YJSsFGsbrzOQ1VE2O4NwR6gxelUvmz8PzuerPCg4iD4JW7hSCmnoAEi51Xnq0bNeCsnhzXJzIlPe04jA==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/middleware-user-agent": "3.823.0",
"@aws-sdk/middleware-user-agent": "3.825.0",
"@aws-sdk/types": "3.821.0",
"@smithy/node-config-provider": "^4.1.3",
"@smithy/types": "^4.3.1",
@@ -744,9 +796,9 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz",
"integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==",
"version": "7.27.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
"integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -2901,9 +2953,9 @@
"license": "MIT"
},
"node_modules/@types/readable-stream": {
"version": "4.0.19",
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.19.tgz",
"integrity": "sha512-6Tgd3lMocKwOul/kwAAgSebkhdMCLhRvcJ6CKHA6wdql2qNIwK6hw3Y4PZQxn9HcJogoC/1ZOmkFM7OZKH/VrA==",
"version": "4.0.21",
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.21.tgz",
"integrity": "sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
@@ -2916,6 +2968,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/uuid": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
"license": "MIT"
},
"node_modules/@types/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
@@ -7372,9 +7430,9 @@
}
},
"node_modules/mqtt": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.13.0.tgz",
"integrity": "sha512-pR+z+ChxFl3n8AKLQbTONVOOg/jl4KiKQRBAi78tjd6PksOWvl1nl9L8ZHOZ3MiavZfrUOjok2ddwc1VymGWRg==",
"version": "5.13.1",
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.13.1.tgz",
"integrity": "sha512-g+4G+ma0UeL3Pgu1y1si2NHb4VLIEUCtF789WrG99lLG0XZyoab2EJoy58YgGSg/1yFdthDBH0+4llsZZD/vug==",
"license": "MIT",
"dependencies": {
"commist": "^3.2.0",
@@ -7413,12 +7471,12 @@
}
},
"node_modules/mqtt2ha": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mqtt2ha/-/mqtt2ha-4.0.0.tgz",
"integrity": "sha512-QFGYWj8CubFPrA6+fbI3UAGHFsYVNZtueGjkWz9O7k4N28Om1xohei6GrtuQ4OMyfMVBhrG8l+5XBZLu7upYdw==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/mqtt2ha/-/mqtt2ha-4.1.0.tgz",
"integrity": "sha512-smxXEI9Tw0ZJZFC2AXAAAikTudxbuJYuw5/UDOt9LB/NrCWr4T6YQIVK7paO401BPBJFoZdjmlWqYu6p7/bdHA==",
"license": "MIT",
"dependencies": {
"mqtt": "5.13.0"
"mqtt": "5.13.1"
},
"engines": {
"node": ">=22.4.0"
@@ -7431,12 +7489,13 @@
"license": "MIT"
},
"node_modules/mysa-js-sdk": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/mysa-js-sdk/-/mysa-js-sdk-1.1.2.tgz",
"integrity": "sha512-JUbWDM5p8a2SIeYx1wBDzochRsySRToavUwqW7duCLza6EpqW4r/N5yEmTBYhQgiUYy9BLOowgJvGMnjVzeRGA==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mysa-js-sdk/-/mysa-js-sdk-1.2.0.tgz",
"integrity": "sha512-f84x1gL/yqjDqEY3FcocqxTM3/AqiGq+IySlCmnxqd1EQhbB+hyiUPe/DLEN7oQcKbPUgeqE90ZJu9q5CGlBFA==",
"license": "MIT",
"dependencies": {
"@aws-sdk/credential-providers": "3.823.0",
"@aws-sdk/client-iot": "3.825.0",
"@aws-sdk/credential-providers": "3.825.0",
"amazon-cognito-identity-js": "6.3.15",
"aws-iot-device-sdk-v2": "1.21.5",
"dayjs": "1.11.13",

View File

@@ -48,8 +48,8 @@
"dependencies": {
"commander": "14.0.0",
"dotenv": "16.5.0",
"mqtt2ha": "4.0.0",
"mysa-js-sdk": "1.1.2",
"mqtt2ha": "4.1.0",
"mysa-js-sdk": "1.2.0",
"pino": "9.7.0",
"pino-pretty": "13.0.0"
},

View File

@@ -64,8 +64,24 @@ async function main() {
await client.login(options.mysaUsername, options.mysaPassword);
}
rootLogger.debug('Fetching devices and firmwares...');
const [devices, firmwares] = await Promise.all([client.getDevices(), client.getDeviceFirmwares()]);
rootLogger.debug('Fetching serial numbers...');
const serialNumbers = new Map<string, string>();
for (const [deviceId] of Object.entries(devices.DevicesObj)) {
try {
const serial = await client.getDeviceSerialNumber(deviceId);
if (serial) {
serialNumbers.set(deviceId, serial);
}
} catch (error) {
rootLogger.error(`Failed to retrieve serial number for device ${deviceId}`, error);
}
}
rootLogger.debug('Initializing MQTT entities...');
const mqttSettings: MqttSettings = {
host: options.mqttHost,
port: options.mqttPort,
@@ -82,7 +98,8 @@ async function main() {
device,
mqttSettings,
new PinoLogger(rootLogger.child({ module: 'thermostat', deviceId: device.Id })),
firmwares.Firmware[device.Id]
firmwares.Firmware[device.Id],
serialNumbers.get(device.Id)
)
);

View File

@@ -64,6 +64,8 @@ function parseRequiredInt(value: string) {
return parsedValue;
}
export const version = getPackageVersion();
const extraHelpText = `
Copyright (c) 2025 Pascal Bourque
Licensed under the MIT License
@@ -72,7 +74,7 @@ Source code and documentation available at: https://github.com/bourquep/mysa2mqt
`;
export const options = new Command('mysa2mqtt')
.version(getPackageVersion())
.version(version)
.description('Expose Mysa smart thermostats to home automation platforms via MQTT.')
.addHelpText('afterAll', extraHelpText)
.addOption(

View File

@@ -21,12 +21,22 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import { Climate, ClimateAction, DeviceConfiguration, Logger, MqttSettings, Sensor } from 'mqtt2ha';
import {
Climate,
ClimateAction,
DeviceConfiguration,
Logger,
MqttSettings,
OriginConfiguration,
Sensor
} from 'mqtt2ha';
import { DeviceBase, FirmwareDevice, MysaApiClient, MysaDeviceMode, StateChange, Status } from 'mysa-js-sdk';
import { version } from './options';
export class Thermostat {
private isStarted = false;
private readonly mqttDevice: DeviceConfiguration;
private readonly mqttOrigin: OriginConfiguration;
private readonly mqttClimate: Climate;
private readonly mqttTemperature: Sensor;
private readonly mqttHumidity: Sensor;
@@ -40,14 +50,22 @@ export class Thermostat {
public readonly mysaDevice: DeviceBase,
private readonly mqttSettings: MqttSettings,
private readonly logger: Logger,
public readonly mysaDeviceFirmware?: FirmwareDevice
public readonly mysaDeviceFirmware?: FirmwareDevice,
public readonly mysaDeviceSerialNumber?: string
) {
this.mqttDevice = {
identifiers: mysaDevice.Id,
name: mysaDevice.Name,
manufacturer: 'Mysa',
model: mysaDevice.Model,
sw_version: mysaDeviceFirmware?.InstalledVersion
sw_version: mysaDeviceFirmware?.InstalledVersion,
serial_number: mysaDeviceSerialNumber
};
this.mqttOrigin = {
name: 'mysa2mqtt',
sw_version: version,
support_url: 'https://github.com/bourquep/mysa2mqtt'
};
this.mqttClimate = new Climate(
@@ -57,6 +75,7 @@ export class Thermostat {
component: {
component: 'climate',
device: this.mqttDevice,
origin: this.mqttOrigin,
unique_id: `mysa_${mysaDevice.Id}_climate`,
name: 'Thermostat',
min_temp: mysaDevice.MinSetpoint,
@@ -112,6 +131,7 @@ export class Thermostat {
component: {
component: 'sensor',
device: this.mqttDevice,
origin: this.mqttOrigin,
unique_id: `mysa_${mysaDevice.Id}_temperature`,
name: 'Current temperature',
device_class: 'temperature',
@@ -128,6 +148,7 @@ export class Thermostat {
component: {
component: 'sensor',
device: this.mqttDevice,
origin: this.mqttOrigin,
unique_id: `mysa_${mysaDevice.Id}_humidity`,
name: 'Current humidity',
device_class: 'humidity',
@@ -144,6 +165,7 @@ export class Thermostat {
component: {
component: 'sensor',
device: this.mqttDevice,
origin: this.mqttOrigin,
unique_id: `mysa_${mysaDevice.Id}_power`,
name: 'Current power',
device_class: 'power',