homebridge-aeg-robot-matter 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -0
  3. package/config.schema.json +88 -0
  4. package/dist/aeg-account.d.ts +21 -0
  5. package/dist/aeg-account.d.ts.map +1 -0
  6. package/dist/aeg-account.js +68 -0
  7. package/dist/aeg-account.js.map +1 -0
  8. package/dist/aeg-appliance-log-rx9.d.ts +15 -0
  9. package/dist/aeg-appliance-log-rx9.d.ts.map +1 -0
  10. package/dist/aeg-appliance-log-rx9.js +165 -0
  11. package/dist/aeg-appliance-log-rx9.js.map +1 -0
  12. package/dist/aeg-appliance-matter-rx9.d.ts +35 -0
  13. package/dist/aeg-appliance-matter-rx9.d.ts.map +1 -0
  14. package/dist/aeg-appliance-matter-rx9.js +163 -0
  15. package/dist/aeg-appliance-matter-rx9.js.map +1 -0
  16. package/dist/aeg-appliance-rx9-ctrl-activity.d.ts +21 -0
  17. package/dist/aeg-appliance-rx9-ctrl-activity.d.ts.map +1 -0
  18. package/dist/aeg-appliance-rx9-ctrl-activity.js +187 -0
  19. package/dist/aeg-appliance-rx9-ctrl-activity.js.map +1 -0
  20. package/dist/aeg-appliance-rx9-ctrl.d.ts +28 -0
  21. package/dist/aeg-appliance-rx9-ctrl.d.ts.map +1 -0
  22. package/dist/aeg-appliance-rx9-ctrl.js +212 -0
  23. package/dist/aeg-appliance-rx9-ctrl.js.map +1 -0
  24. package/dist/aeg-appliance-rx9.d.ts +87 -0
  25. package/dist/aeg-appliance-rx9.d.ts.map +1 -0
  26. package/dist/aeg-appliance-rx9.js +367 -0
  27. package/dist/aeg-appliance-rx9.js.map +1 -0
  28. package/dist/aeg-map-coordinate.d.ts +22 -0
  29. package/dist/aeg-map-coordinate.d.ts.map +1 -0
  30. package/dist/aeg-map-coordinate.js +95 -0
  31. package/dist/aeg-map-coordinate.js.map +1 -0
  32. package/dist/aeg-map-text.d.ts +37 -0
  33. package/dist/aeg-map-text.d.ts.map +1 -0
  34. package/dist/aeg-map-text.js +187 -0
  35. package/dist/aeg-map-text.js.map +1 -0
  36. package/dist/aeg-map.d.ts +21 -0
  37. package/dist/aeg-map.d.ts.map +1 -0
  38. package/dist/aeg-map.js +166 -0
  39. package/dist/aeg-map.js.map +1 -0
  40. package/dist/aegapi-auth-types.d.ts +19 -0
  41. package/dist/aegapi-auth-types.d.ts.map +1 -0
  42. package/dist/aegapi-auth-types.js +4 -0
  43. package/dist/aegapi-auth-types.js.map +1 -0
  44. package/dist/aegapi-error.d.ts +27 -0
  45. package/dist/aegapi-error.d.ts.map +1 -0
  46. package/dist/aegapi-error.js +82 -0
  47. package/dist/aegapi-error.js.map +1 -0
  48. package/dist/aegapi-rx9-types.d.ts +395 -0
  49. package/dist/aegapi-rx9-types.d.ts.map +1 -0
  50. package/dist/aegapi-rx9-types.js +82 -0
  51. package/dist/aegapi-rx9-types.js.map +1 -0
  52. package/dist/aegapi-rx9.d.ts +15 -0
  53. package/dist/aegapi-rx9.d.ts.map +1 -0
  54. package/dist/aegapi-rx9.js +39 -0
  55. package/dist/aegapi-rx9.js.map +1 -0
  56. package/dist/aegapi-types.d.ts +91 -0
  57. package/dist/aegapi-types.d.ts.map +1 -0
  58. package/dist/aegapi-types.js +4 -0
  59. package/dist/aegapi-types.js.map +1 -0
  60. package/dist/aegapi-ua-auth.d.ts +26 -0
  61. package/dist/aegapi-ua-auth.d.ts.map +1 -0
  62. package/dist/aegapi-ua-auth.js +220 -0
  63. package/dist/aegapi-ua-auth.js.map +1 -0
  64. package/dist/aegapi-ua.d.ts +66 -0
  65. package/dist/aegapi-ua.d.ts.map +1 -0
  66. package/dist/aegapi-ua.js +265 -0
  67. package/dist/aegapi-ua.js.map +1 -0
  68. package/dist/aegapi.d.ts +19 -0
  69. package/dist/aegapi.d.ts.map +1 -0
  70. package/dist/aegapi.js +51 -0
  71. package/dist/aegapi.js.map +1 -0
  72. package/dist/config-types.d.ts +21 -0
  73. package/dist/config-types.d.ts.map +1 -0
  74. package/dist/config-types.js +2 -0
  75. package/dist/config-types.js.map +1 -0
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +6 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/log-error.d.ts +3 -0
  81. package/dist/log-error.d.ts.map +1 -0
  82. package/dist/log-error.js +40 -0
  83. package/dist/log-error.js.map +1 -0
  84. package/dist/logger-options.d.ts +12 -0
  85. package/dist/logger-options.d.ts.map +1 -0
  86. package/dist/logger-options.js +36 -0
  87. package/dist/logger-options.js.map +1 -0
  88. package/dist/logger.d.ts +26 -0
  89. package/dist/logger.d.ts.map +1 -0
  90. package/dist/logger.js +66 -0
  91. package/dist/logger.js.map +1 -0
  92. package/dist/periodic-op.d.ts +28 -0
  93. package/dist/periodic-op.d.ts.map +1 -0
  94. package/dist/periodic-op.js +110 -0
  95. package/dist/periodic-op.js.map +1 -0
  96. package/dist/platform.d.ts +34 -0
  97. package/dist/platform.d.ts.map +1 -0
  98. package/dist/platform.js +176 -0
  99. package/dist/platform.js.map +1 -0
  100. package/dist/settings.d.ts +11 -0
  101. package/dist/settings.d.ts.map +1 -0
  102. package/dist/settings.js +37 -0
  103. package/dist/settings.js.map +1 -0
  104. package/dist/ti/aegapi-auth-types-ti.d.ts +11 -0
  105. package/dist/ti/aegapi-auth-types-ti.d.ts.map +1 -0
  106. package/dist/ti/aegapi-auth-types-ti.js +31 -0
  107. package/dist/ti/aegapi-auth-types-ti.js.map +1 -0
  108. package/dist/ti/aegapi-auth-types.d.ts +22 -0
  109. package/dist/ti/aegapi-auth-types.d.ts.map +1 -0
  110. package/dist/ti/aegapi-auth-types.js +11 -0
  111. package/dist/ti/aegapi-auth-types.js.map +1 -0
  112. package/dist/ti/aegapi-rx9-types-ti.d.ts +66 -0
  113. package/dist/ti/aegapi-rx9-types-ti.d.ts.map +1 -0
  114. package/dist/ti/aegapi-rx9-types-ti.js +456 -0
  115. package/dist/ti/aegapi-rx9-types-ti.js.map +1 -0
  116. package/dist/ti/aegapi-rx9-types.d.ts +187 -0
  117. package/dist/ti/aegapi-rx9-types.d.ts.map +1 -0
  118. package/dist/ti/aegapi-rx9-types.js +12 -0
  119. package/dist/ti/aegapi-rx9-types.js.map +1 -0
  120. package/dist/ti/aegapi-types-ti.d.ts +33 -0
  121. package/dist/ti/aegapi-types-ti.d.ts.map +1 -0
  122. package/dist/ti/aegapi-types-ti.js +125 -0
  123. package/dist/ti/aegapi-types-ti.js.map +1 -0
  124. package/dist/ti/aegapi-types.d.ts +88 -0
  125. package/dist/ti/aegapi-types.d.ts.map +1 -0
  126. package/dist/ti/aegapi-types.js +11 -0
  127. package/dist/ti/aegapi-types.js.map +1 -0
  128. package/dist/utils.d.ts +15 -0
  129. package/dist/utils.d.ts.map +1 -0
  130. package/dist/utils.js +120 -0
  131. package/dist/utils.js.map +1 -0
  132. package/package.json +69 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Niklas31
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # homebridge-aeg-robot-matter
2
+
3
+ Homebridge plugin for AEG RX9 / Electrolux Pure i9 robot vacuums.
4
+
5
+ This is an early Homebridge port of `matterbridge-aeg-robot-niklas`. The first working target is a HomeKit switch:
6
+
7
+ - switch on: start cleaning
8
+ - switch off: configurable `dock`, `pause`, or `stop`
9
+ - state follows whether the robot is actively cleaning
10
+
11
+ Matter RVC support is planned. For now, `exposeMode: "auto"` exposes the HomeKit switch even when Matter is enabled, so the plugin remains usable while the Matter accessory implementation is added.
12
+
13
+ ## Configuration
14
+
15
+ ```json
16
+ {
17
+ "platform": "AEGRobotMatter",
18
+ "name": "AEG Robot",
19
+ "apiKey": "YOUR_ELECTROLUX_API_KEY",
20
+ "accessToken": "",
21
+ "refreshToken": "",
22
+ "exposeMode": "auto",
23
+ "switchOffAction": "dock",
24
+ "pollIntervalSeconds": 30
25
+ }
26
+ ```
27
+
28
+ ## Options
29
+
30
+ | Option | Default | Description |
31
+ | --- | --- | --- |
32
+ | `apiKey` | required | Electrolux Group API key. |
33
+ | `accessToken` | `""` | Initial access token, if not using `accessTokenURL`. |
34
+ | `refreshToken` | `""` | Initial refresh token, if not using `accessTokenURL`. |
35
+ | `accessTokenURL` | unset | Optional URL returning token JSON for refresh/bootstrap. |
36
+ | `exposeMode` | `"auto"` | `auto`, `switch`, `matter-rvc`, or `both`. Matter RVC is not implemented yet. |
37
+ | `switchOffAction` | `"dock"` | Action when the HomeKit switch is turned off: `dock`, `pause`, or `stop`. |
38
+ | `pollIntervalSeconds` | `30` | Poll interval for Electrolux state. |
39
+ | `whiteList` | `[]` | Optional robot serial numbers to include. |
40
+ | `blackList` | `[]` | Optional robot serial numbers to exclude. |
41
+
42
+ ## Development
43
+
44
+ ```bash
45
+ npm install
46
+ npm run build
47
+ ```
@@ -0,0 +1,88 @@
1
+ {
2
+ "pluginAlias": "AEGRobotMatter",
3
+ "pluginType": "platform",
4
+ "singular": true,
5
+ "schema": {
6
+ "type": "object",
7
+ "properties": {
8
+ "name": {
9
+ "title": "Name",
10
+ "type": "string",
11
+ "default": "AEG Robot"
12
+ },
13
+ "apiKey": {
14
+ "title": "Electrolux API Key",
15
+ "type": "string",
16
+ "required": true
17
+ },
18
+ "accessToken": {
19
+ "title": "Access Token",
20
+ "type": "string",
21
+ "default": ""
22
+ },
23
+ "refreshToken": {
24
+ "title": "Refresh Token",
25
+ "type": "string",
26
+ "default": ""
27
+ },
28
+ "accessTokenURL": {
29
+ "title": "Access Token URL",
30
+ "type": "string"
31
+ },
32
+ "exposeMode": {
33
+ "title": "Expose Mode",
34
+ "type": "string",
35
+ "default": "auto",
36
+ "oneOf": [
37
+ { "title": "Auto", "enum": ["auto"] },
38
+ { "title": "HomeKit Switch", "enum": ["switch"] },
39
+ { "title": "Matter RVC", "enum": ["matter-rvc"] },
40
+ { "title": "Both", "enum": ["both"] }
41
+ ]
42
+ },
43
+ "switchOffAction": {
44
+ "title": "Switch Off Action",
45
+ "type": "string",
46
+ "default": "dock",
47
+ "oneOf": [
48
+ { "title": "Pause", "enum": ["pause"] },
49
+ { "title": "Stop", "enum": ["stop"] },
50
+ { "title": "Dock", "enum": ["dock"] }
51
+ ]
52
+ },
53
+ "pollIntervalSeconds": {
54
+ "title": "Polling Interval",
55
+ "type": "integer",
56
+ "default": 30,
57
+ "minimum": 10
58
+ },
59
+ "whiteList": {
60
+ "title": "Serial Number Allow List",
61
+ "type": "array",
62
+ "items": { "type": "string" },
63
+ "default": []
64
+ },
65
+ "blackList": {
66
+ "title": "Serial Number Block List",
67
+ "type": "array",
68
+ "items": { "type": "string" },
69
+ "default": []
70
+ },
71
+ "logMapStyle": {
72
+ "title": "Map Logging",
73
+ "type": "string",
74
+ "default": "Off",
75
+ "oneOf": [
76
+ { "title": "Off", "enum": ["Off"] },
77
+ { "title": "Homebridge", "enum": ["Homebridge"] },
78
+ { "title": "Monospaced", "enum": ["Monospaced"] }
79
+ ]
80
+ },
81
+ "debug": {
82
+ "title": "Debug Logging",
83
+ "type": "boolean",
84
+ "default": false
85
+ }
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,21 @@
1
+ import { AnsiLogger } from './logger.js';
2
+ import { AEGAPI } from './aegapi.js';
3
+ import { Config } from './config-types.js';
4
+ import { Appliance } from './aegapi-types.js';
5
+ import { AEGApplianceRX9 } from './aeg-appliance-rx9.js';
6
+ import NodePersist from 'node-persist';
7
+ export interface AEGPendingRX9 extends Appliance {
8
+ log: AnsiLogger;
9
+ appliancePromise: Promise<AEGApplianceRX9>;
10
+ }
11
+ export declare class AEGAccount {
12
+ readonly log: AnsiLogger;
13
+ readonly config: Config;
14
+ readonly persist: NodePersist.LocalStorage;
15
+ readonly api: AEGAPI;
16
+ constructor(log: AnsiLogger, config: Config, persist: NodePersist.LocalStorage);
17
+ getAllRX9(): Promise<AEGPendingRX9[]>;
18
+ createRX9(appliance: Appliance): AEGPendingRX9;
19
+ checkPollingInterval(robots: number): void;
20
+ }
21
+ //# sourceMappingURL=aeg-account.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aeg-account.d.ts","sourceRoot":"","sources":["../src/aeg-account.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,WAAW,MAAM,cAAc,CAAC;AAGvC,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC5C,GAAG,EAAiB,UAAU,CAAC;IAC/B,gBAAgB,EAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CAChD;AAMD,qBAAa,UAAU;IAOf,QAAQ,CAAC,GAAG,EAAQ,UAAU;IAC9B,QAAQ,CAAC,MAAM,EAAK,MAAM;IAC1B,QAAQ,CAAC,OAAO,EAAI,WAAW,CAAC,YAAY;IANhD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBAIR,GAAG,EAAQ,UAAU,EACrB,MAAM,EAAK,MAAM,EACjB,OAAO,EAAI,WAAW,CAAC,YAAY;IAO1C,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAoB3C,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,aAAa;IAQ9C,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAiB7C"}
@@ -0,0 +1,68 @@
1
+ // Matterbridge plugin for AEG RX9 / Electrolux Pure i9 robot vacuum
2
+ // Copyright © 2025 Alexander Thoukydides
3
+ import { AEGAPI } from './aegapi.js';
4
+ import { formatList, formatSeconds, plural } from './utils.js';
5
+ import { AEGAPIRX9 } from './aegapi-rx9.js';
6
+ import { API_DAILY_LIMIT, API_DAILY_POLL_LIMIT, PLUGIN_NAME } from './settings.js';
7
+ import { PrefixLogger } from './logger.js';
8
+ import { AEGApplianceRX9 } from './aeg-appliance-rx9.js';
9
+ ;
10
+ // Number of seconds in a day
11
+ const SECONDS_PER_DAY = 24 * 60 * 60;
12
+ // An AEG user account manager
13
+ export class AEGAccount {
14
+ log;
15
+ config;
16
+ persist;
17
+ // Electrolux Group API
18
+ api;
19
+ // Create a new AEG user account manager
20
+ constructor(log, config, persist) {
21
+ this.log = log;
22
+ this.config = config;
23
+ this.persist = persist;
24
+ // Create a new API instance
25
+ this.api = new AEGAPI(log, config, persist);
26
+ }
27
+ // Return a list of AEG RX9.1 and RX9.2 robot vacuum cleaners in the account
28
+ async getAllRX9() {
29
+ // Read the list of appliances and identify compatible robots
30
+ const appliances = await this.api.getAppliances();
31
+ const robots = appliances.filter(appliance => AEGAPIRX9.isRX9(appliance));
32
+ const incompatible = appliances.filter(appliance => !AEGAPIRX9.isRX9(appliance));
33
+ // Log details of any incompatible appliances
34
+ if (incompatible.length) {
35
+ this.log.info(`Ignoring ${plural(incompatible.length, 'incompatible appliance')}: `
36
+ + formatList(incompatible.map(a => `${a.applianceName} (${a.applianceType})`)));
37
+ }
38
+ // Ensure that the polling interval is under the daily API limit
39
+ this.checkPollingInterval(robots.length);
40
+ // Create a manager for each robot
41
+ return robots.map(appliance => this.createRX9(appliance));
42
+ }
43
+ // Create a manager for a single robot
44
+ createRX9(appliance) {
45
+ const api = this.api.rx9API(appliance.applianceId);
46
+ const log = new PrefixLogger(this.log, appliance.applianceName);
47
+ const appliancePromise = AEGApplianceRX9.create(log, this.config, api, appliance);
48
+ return { ...appliance, log, appliancePromise };
49
+ }
50
+ // Ensure that the polling interval is under the daily API limit
51
+ checkPollingInterval(robots) {
52
+ // Check whether the daily rate limit will be exceeded
53
+ const { pollIntervalSeconds } = this.config;
54
+ const dailyCalls = (seconds) => Math.ceil(robots * SECONDS_PER_DAY / seconds);
55
+ if (dailyCalls(pollIntervalSeconds) < API_DAILY_LIMIT)
56
+ return;
57
+ // Pick a more suitable polling interval
58
+ const newPollIntervalSeconds = Math.ceil(robots * SECONDS_PER_DAY / API_DAILY_POLL_LIMIT);
59
+ this.config.pollIntervalSeconds = newPollIntervalSeconds;
60
+ // Log details of the increased poll interval
61
+ this.log.warn(`Increasing polling interval from ${formatSeconds(pollIntervalSeconds)} to ${formatSeconds(newPollIntervalSeconds)} `
62
+ + `due to Electrolux Group API rate limit of ${API_DAILY_LIMIT} calls/day`);
63
+ this.log.warn(`With ${plural(robots, 'robot vacuum cleaner')} this reduces the polling rate from `
64
+ + `${dailyCalls(pollIntervalSeconds)} to ${dailyCalls(newPollIntervalSeconds)} calls/day`);
65
+ this.log.warn(`Increase pollIntervalSeconds in the Homebridge ${PLUGIN_NAME} config`);
66
+ }
67
+ }
68
+ //# sourceMappingURL=aeg-account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aeg-account.js","sourceRoot":"","sources":["../src/aeg-account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { AnsiLogger } from './logger.js';
2
+ import { AEGApplianceRX9 } from './aeg-appliance-rx9.js';
3
+ export declare class AEGApplianceRX9Log {
4
+ readonly appliance: AEGApplianceRX9;
5
+ readonly log: AnsiLogger;
6
+ private readonly loggedHealthErrors;
7
+ private lastMapLogTimestamp;
8
+ constructor(appliance: AEGApplianceRX9);
9
+ logStatic(): void;
10
+ logStatus(): void;
11
+ logHealth(err?: unknown): void;
12
+ logMessages(): void;
13
+ logMaps(): void;
14
+ }
15
+ //# sourceMappingURL=aeg-appliance-log-rx9.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aeg-appliance-log-rx9.d.ts","sourceRoot":"","sources":["../src/aeg-appliance-log-rx9.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAY,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA8DzD,qBAAa,kBAAkB;IAUf,QAAQ,CAAC,SAAS,EAAE,eAAe;IAP/C,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IAGzB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,OAAO,CAAC,mBAAmB,CAAK;gBAGX,SAAS,EAAE,eAAe;IAY/C,SAAS,IAAI,IAAI;IAcjB,SAAS,IAAI,IAAI;IA8BjB,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI;IAc9B,WAAW,IAAI,IAAI;IAYnB,OAAO,IAAI,IAAI;CAsBlB"}
@@ -0,0 +1,165 @@
1
+ // Matterbridge plugin for AEG RX9 / Electrolux Pure i9 robot vacuum
2
+ // Copyright © 2025 Alexander Thoukydides
3
+ import { LogLevel } from './logger.js';
4
+ import { formatList, formatMilliseconds, MS, plural } from './utils.js';
5
+ import { RX9BatteryStatus, RX9Dustbin, RX92PowerMode, RX9RobotStatus } from './aegapi-rx9-types.js';
6
+ import { RR, RT, RV } from './logger-options.js';
7
+ import { aegRobotMap, MAP_CONFIG_MATTERBRIDGE, MAP_CONFIG_MONOSPACED } from './aeg-map.js';
8
+ // Descriptions of the robot activity
9
+ const activityNames = {
10
+ [RX9RobotStatus.Cleaning]: 'CLEANING',
11
+ [RX9RobotStatus.PausedCleaning]: 'PAUSED during cleaning',
12
+ [RX9RobotStatus.SpotCleaning]: 'SPOT CLEANING',
13
+ [RX9RobotStatus.PausedSpotCleaning]: 'PAUSED during spot cleaning',
14
+ [RX9RobotStatus.Return]: 'returning HOME',
15
+ [RX9RobotStatus.PausedReturn]: 'PAUSED during return home',
16
+ [RX9RobotStatus.ReturnForPitstop]: 'returning HOME; it will resume cleaning when charged',
17
+ [RX9RobotStatus.PausedReturnForPitstop]: 'PAUSED during return home; it will resume cleaning when charged',
18
+ [RX9RobotStatus.Charging]: 'CHARGING',
19
+ [RX9RobotStatus.Sleeping]: 'SLEEPING (either charged on dock or idle off dock)',
20
+ [RX9RobotStatus.Error]: 'in an ERROR state',
21
+ [RX9RobotStatus.Pitstop]: 'CHARGING; it will resume cleaning when charged',
22
+ [RX9RobotStatus.ManualSteering]: 'being STEERED MANUALLY',
23
+ [RX9RobotStatus.FirmwareUpgrade]: 'performing a FIRMWARE UPGRADE'
24
+ };
25
+ // Descriptions of the robot battery levels
26
+ const batteryNames = {
27
+ [RX9BatteryStatus.Dead]: 'DEAD',
28
+ [RX9BatteryStatus.CriticalLow]: 'CRITICALLY LOW',
29
+ [RX9BatteryStatus.Low]: 'LOW',
30
+ [RX9BatteryStatus.Medium]: 'MEDIUM',
31
+ [RX9BatteryStatus.High]: 'HIGH',
32
+ [RX9BatteryStatus.FullyCharged]: 'FULLY CHARGED'
33
+ };
34
+ // Descriptions of dustbin states
35
+ const dustbinNames = {
36
+ [RX9Dustbin.Unknown]: { value: 'UNKNOWN' },
37
+ [RX9Dustbin.Present]: { value: 'PRESENT', extra: 'not full' },
38
+ [RX9Dustbin.Missing]: { value: 'MISSING' },
39
+ [RX9Dustbin.Full]: { value: 'FULL', extra: 'requires emptying' }
40
+ };
41
+ // Descriptions of power modes
42
+ const powerModeNames = {
43
+ [RX92PowerMode.Quiet]: { value: 'QUIET', extra: 'lower energy consumption and quieter' },
44
+ [RX92PowerMode.Smart]: { value: 'SMART', extra: 'cleans quietly on hard surfaces, uses full power on carpets' },
45
+ [RX92PowerMode.Power]: { value: 'POWER', extra: 'optimal cleaning performance, higher energy consumption' }
46
+ };
47
+ const MAP_LOG_MIN_INTERVAL = 30 * MS;
48
+ const MAP_LOG_LINE_LIMIT = 120;
49
+ // Logging of information about a robot
50
+ export class AEGApplianceRX9Log {
51
+ appliance;
52
+ // Logger
53
+ log;
54
+ // Reported error messages
55
+ loggedHealthErrors = new Set();
56
+ lastMapLogTimestamp = 0;
57
+ // Construct a robot logger
58
+ constructor(appliance) {
59
+ this.appliance = appliance;
60
+ // Use the appliance's logger
61
+ this.log = appliance.log;
62
+ // Start logging information about the robot
63
+ this.logStatic();
64
+ this.logStatus();
65
+ this.logMessages();
66
+ this.logMaps();
67
+ }
68
+ // Log static information about the robot once at startup
69
+ logStatic() {
70
+ const { applianceType, brand, capabilities, colour, model, variant } = this.appliance;
71
+ const redacted = !this.appliance.config.debugFeatures.includes('Log Appliance IDs');
72
+ this.log.info(`${RT}My name is "${RV}${this.appliance.applianceName}${RT}"${RR}`);
73
+ this.log.info(`${RV}${brand} ${applianceType}${RT} (${RV}${model}${RT}/${RV}${variant}${RT}) ${RV}${colour}${RR}`);
74
+ if (!redacted)
75
+ this.log.info(`${RT}Product ID ${RV}${this.appliance.applianceId}${RR}`);
76
+ this.log.info(`${RT}Product number code ${RV}${this.appliance.pnc}${RR}`);
77
+ if (!redacted)
78
+ this.log.info(`${RT}Serial number ${RV}${this.appliance.serialNumber}${RR}`);
79
+ this.log.info(`${RT}Hardware platform ${RV}${this.appliance.platform}${RR}`);
80
+ const capabilityValues = [...capabilities].sort().map(c => `${RV}${c}${RT}`);
81
+ this.log.info(`${RT}Supports ${plural(capabilities.length, 'capability')}: ${formatList(capabilityValues)}${RR}`);
82
+ }
83
+ // Log initial values and changes for other status
84
+ logStatus() {
85
+ this.appliance.on('firmwareVersion', (firmwareVersion) => {
86
+ this.log.info(`${RT}Firmware version ${RV}${firmwareVersion}${RT} installed${RR}`);
87
+ }).on('batteryStatus', (batteryStatus) => {
88
+ this.log.info(`${RT}Battery level is ${RV}${batteryNames[batteryStatus]}${RR}`);
89
+ }).on('robotStatus', (robotStatus) => {
90
+ this.log.info(`${RT}Robot is ${RV}${activityNames[robotStatus]}${RR}`);
91
+ }).on('fauxStatus', (fauxStatus) => {
92
+ if (fauxStatus === this.appliance.state.robotStatus)
93
+ return;
94
+ this.log.info(`${RT}Predicting robot will be ${RV}${activityNames[fauxStatus]}${RR}`);
95
+ }).on('dustbinStatus', (dustbinStatus) => {
96
+ const { value, extra } = dustbinNames[dustbinStatus];
97
+ this.log.info(`${RT}Dust collection bin is ${RV}${value}${extra ? `${RT} and ${extra}` : ''}${RR}`);
98
+ }).on('powerMode', (powerMode) => {
99
+ if (powerMode === undefined)
100
+ return;
101
+ const { value, extra } = powerModeNames[powerMode];
102
+ this.log.info(`${RT}Power mode is set to ${RV}${value}${RT} (${extra})${RR}`);
103
+ }).on('ecoMode', (ecoMode) => {
104
+ if (ecoMode === undefined)
105
+ return;
106
+ this.log.info(`${RT}ECO mode is ${RV}${ecoMode ? 'enabled' : 'disabled'}${RR}`);
107
+ }).on('enabled', (enabled) => {
108
+ this.log.log(enabled ? LogLevel.INFO : LogLevel.WARN, `${RT}Robot is ${RV}${enabled ? 'enabled' : 'disabled'}${RR}`);
109
+ }).on('connected', (connected) => {
110
+ this.log.log(connected ? LogLevel.INFO : LogLevel.WARN, `${RT}Robot ${RV}${connected ? 'is' : 'is NOT'}${RT} connected to the cloud servers${RR}`);
111
+ }).on('apiError', (err) => { this.logHealth(err); });
112
+ }
113
+ // Log changes to cloud server health
114
+ logHealth(err) {
115
+ if (err) {
116
+ const message = err instanceof Error ? err.message : JSON.stringify(err);
117
+ if (!this.loggedHealthErrors.has(message)) {
118
+ this.loggedHealthErrors.add(message);
119
+ this.log.error(`Lost connection to cloud servers: ${message}`);
120
+ }
121
+ }
122
+ else {
123
+ this.loggedHealthErrors.clear();
124
+ this.log.info(`${RT}Successfully connected to cloud servers${RR}`);
125
+ }
126
+ }
127
+ // Log messages from the robot
128
+ logMessages() {
129
+ this.appliance.on('message', (message) => {
130
+ const age = `${formatMilliseconds(Date.now() - message.timestamp * MS)} ago`;
131
+ const bits = [`type=${message.type}`];
132
+ if (message.userErrorId)
133
+ bits.push(`user-error=${message.userErrorId}`);
134
+ if (message.internalErrorId)
135
+ bits.push(`internal-error=${message.internalErrorId}`);
136
+ this.log.warn(`Message: ${message.text} (${age})`);
137
+ this.log.debug(`Message: ${formatList(bits)}`);
138
+ });
139
+ }
140
+ // Log map data from the robot
141
+ logMaps() {
142
+ this.appliance.on('map', (mapData, mapDataExtra) => {
143
+ const { logMapStyle } = this.appliance.config;
144
+ if (logMapStyle === 'Off')
145
+ return;
146
+ const now = Date.now();
147
+ if (now - this.lastMapLogTimestamp < MAP_LOG_MIN_INTERVAL)
148
+ return;
149
+ this.lastMapLogTimestamp = now;
150
+ const mapStyle = logMapStyle === 'Matterbridge'
151
+ ? MAP_CONFIG_MATTERBRIDGE : MAP_CONFIG_MONOSPACED;
152
+ const mapText = aegRobotMap(mapStyle, mapData, mapDataExtra);
153
+ const fullMapLogging = this.appliance.config.debugFeatures.includes('Log Endpoint Debug');
154
+ const maxLines = fullMapLogging ? mapText.length : MAP_LOG_LINE_LIMIT;
155
+ mapText.slice(0, maxLines).forEach(line => {
156
+ this.log.info(line);
157
+ });
158
+ if (mapText.length > maxLines) {
159
+ this.log.info(`${RT}[Map output truncated: ${maxLines}/${mapText.length} lines.`);
160
+ this.log.info(`${RT}Enable 'Log Endpoint Debug' for full map logs.]${RR}`);
161
+ }
162
+ });
163
+ }
164
+ }
165
+ //# sourceMappingURL=aeg-appliance-log-rx9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aeg-appliance-log-rx9.js","sourceRoot":"","sources":["../src/aeg-appliance-log-rx9.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { AEGApplianceRX9 } from './aeg-appliance-rx9.js';
2
+ import { AEGRobotPlatform } from './platform.js';
3
+ /**
4
+ * AEGMatterRobot handles the Matter Robotic Vacuum Cleaner (RVC) implementation.
5
+ * It maps the robot's state and commands to Matter clusters.
6
+ */
7
+ export declare class AEGMatterRobot {
8
+ private readonly platform;
9
+ private readonly appliance;
10
+ private readonly matter;
11
+ private readonly uuid;
12
+ constructor(platform: AEGRobotPlatform, appliance: AEGApplianceRX9);
13
+ /**
14
+ * Register the robot as a Matter accessory.
15
+ */
16
+ private register;
17
+ /**
18
+ * Update the Matter accessory state when the robot state changes.
19
+ */
20
+ private updateState;
21
+ /**
22
+ * Map the robot status to Matter OperationalStateId.
23
+ * IDLE: 0x00, STOPPED: 0x01, RUNNING: 0x02, PAUSED: 0x03, ERROR: 0x04, SEEKING_CHARGER: 0x05, CHARGING: 0x06
24
+ */
25
+ private mapOperationalState;
26
+ /**
27
+ * Map the current run mode.
28
+ */
29
+ private mapRunMode;
30
+ /**
31
+ * Determine if the robot is currently in a cleaning or moving state.
32
+ */
33
+ private isCleaning;
34
+ }
35
+ //# sourceMappingURL=aeg-appliance-matter-rx9.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aeg-appliance-matter-rx9.d.ts","sourceRoot":"","sources":["../src/aeg-appliance-matter-rx9.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIjD;;;GAGG;AACH,qBAAa,cAAc;IAKnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiD;IACxE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAGT,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,eAAe;IAU/C;;OAEG;YACW,QAAQ;IAyEtB;;OAEG;YACW,WAAW;IAoBzB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAyB3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,OAAO,CAAC,UAAU;CASrB"}