matterbridge-roborock-vacuum-plugin 1.0.8-rc05 → 1.0.8-rc07

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 (67) hide show
  1. package/README.md +9 -2
  2. package/README_CLEANMODE.md +29 -0
  3. package/dist/behaviorFactory.js +11 -15
  4. package/dist/behaviors/roborock.vacuum/default/default.js +108 -57
  5. package/dist/behaviors/roborock.vacuum/default/initalData.js +77 -10
  6. package/dist/behaviors/roborock.vacuum/default/runtimes.js +18 -30
  7. package/dist/behaviors/roborock.vacuum/smart/initalData.js +18 -0
  8. package/dist/behaviors/roborock.vacuum/smart/runtimes.js +11 -0
  9. package/dist/behaviors/roborock.vacuum/smart/smart.js +119 -0
  10. package/dist/initialData/getOperationalStates.js +2 -15
  11. package/dist/initialData/getSupportedCleanModes.js +8 -8
  12. package/dist/initialData/getSupportedRunModes.js +5 -18
  13. package/dist/model/DockingStationStatus.js +3 -0
  14. package/dist/platform.js +8 -2
  15. package/dist/platformRunner.js +71 -29
  16. package/dist/roborockCommunication/Zmodel/deviceStatus.js +2 -2
  17. package/dist/roborockCommunication/broadcast/client/MQTTClient.js +1 -2
  18. package/dist/roborockCommunication/broadcast/messageProcessor.js +36 -0
  19. package/dist/roborockService.js +11 -1
  20. package/dist/rvc.js +9 -5
  21. package/dist/share/runtimeHelper.js +11 -44
  22. package/eslint.config.js +1 -1
  23. package/matterbridge-roborock-vacuum-plugin.config.json +4 -2
  24. package/matterbridge-roborock-vacuum-plugin.schema.json +11 -1
  25. package/package.json +2 -1
  26. package/src/behaviorFactory.ts +14 -18
  27. package/src/behaviors/roborock.vacuum/default/default.ts +123 -60
  28. package/src/behaviors/roborock.vacuum/default/initalData.ts +83 -10
  29. package/src/behaviors/roborock.vacuum/default/runtimes.ts +19 -22
  30. package/src/behaviors/roborock.vacuum/smart/initalData.ts +20 -0
  31. package/src/behaviors/roborock.vacuum/smart/runtimes.ts +14 -0
  32. package/src/behaviors/roborock.vacuum/smart/smart.ts +159 -0
  33. package/src/initialData/getOperationalStates.ts +2 -15
  34. package/src/initialData/getSupportedCleanModes.ts +11 -8
  35. package/src/initialData/getSupportedRunModes.ts +5 -18
  36. package/src/model/DockingStationStatus.ts +5 -1
  37. package/src/model/ExperimentalFeatureSetting.ts +2 -0
  38. package/src/platform.ts +18 -2
  39. package/src/platformRunner.ts +87 -33
  40. package/src/roborockCommunication/Zmodel/deviceStatus.ts +4 -4
  41. package/src/roborockCommunication/broadcast/client/MQTTClient.ts +2 -2
  42. package/src/roborockCommunication/broadcast/messageProcessor.ts +41 -1
  43. package/src/roborockService.ts +12 -1
  44. package/src/rvc.ts +22 -5
  45. package/src/share/runtimeHelper.ts +12 -46
  46. package/src/tests/behaviors/roborock.vacuum/{S7_MAXV/a27.test.ts → default/default.test.ts} +26 -26
  47. package/src/tests/behaviors/roborock.vacuum/smart/runtimes.test.ts +64 -0
  48. package/src/tests/behaviors/roborock.vacuum/{QREVO_EDGE_5V1/a187.test.ts → smart/smart.test.ts} +51 -38
  49. package/dist/behaviors/roborock.vacuum/QREVO_EDGE_5V1/a187.js +0 -142
  50. package/dist/behaviors/roborock.vacuum/QREVO_EDGE_5V1/initalData.js +0 -81
  51. package/dist/behaviors/roborock.vacuum/QREVO_EDGE_5V1/runtimes.js +0 -39
  52. package/dist/behaviors/roborock.vacuum/S7_MAXV/a27.js +0 -133
  53. package/dist/behaviors/roborock.vacuum/S7_MAXV/initalData.js +0 -76
  54. package/dist/behaviors/roborock.vacuum/S7_MAXV/runtimes.js +0 -33
  55. package/dist/behaviors/roborock.vacuum/S8_PRO_ULTRA/a51.js +0 -132
  56. package/dist/behaviors/roborock.vacuum/S8_PRO_ULTRA/initalData.js +0 -76
  57. package/dist/behaviors/roborock.vacuum/S8_PRO_ULTRA/runtimes.js +0 -33
  58. package/src/behaviors/roborock.vacuum/QREVO_EDGE_5V1/a187.ts +0 -181
  59. package/src/behaviors/roborock.vacuum/QREVO_EDGE_5V1/initalData.ts +0 -85
  60. package/src/behaviors/roborock.vacuum/QREVO_EDGE_5V1/runtimes.ts +0 -29
  61. package/src/behaviors/roborock.vacuum/S7_MAXV/a27.ts +0 -172
  62. package/src/behaviors/roborock.vacuum/S7_MAXV/initalData.ts +0 -79
  63. package/src/behaviors/roborock.vacuum/S7_MAXV/runtimes.ts +0 -26
  64. package/src/behaviors/roborock.vacuum/S8_PRO_ULTRA/a51.ts +0 -171
  65. package/src/behaviors/roborock.vacuum/S8_PRO_ULTRA/initalData.ts +0 -79
  66. package/src/behaviors/roborock.vacuum/S8_PRO_ULTRA/runtimes.ts +0 -26
  67. package/src/tests/behaviors/roborock.vacuum/QREVO_EDGE_5V1/runtimes.test.ts +0 -83
package/README.md CHANGED
@@ -40,7 +40,7 @@
40
40
  - **Matterbridge must be run in child bridge mode** for proper operation.
41
41
  - **Use one Matterbridge instance per Roborock vacuum.**
42
42
  If you have more than one vacuum, please run separate instances.
43
- Please put the **duid** of device you want to use into **whiteList** section in the plugin configuration popup.
43
+ Please put the <**Vacuum name**>-<**duid**> of device you want to use into **whiteList** section in the plugin configuration popup.
44
44
 
45
45
 
46
46
  More details available here: [Discussion #264](https://github.com/Luligu/matterbridge/discussions/264)
@@ -74,7 +74,14 @@ To get the **DUID** for your devices, you have two options:
74
74
 
75
75
  ---
76
76
 
77
- **➡️ [See Supported & Tested Roborock Devices](./README_SUPPORTED.md)**
77
+
78
+ ### ➡️ [See Supported & Tested Roborock Devices](./README_SUPPORTED.md)
79
+
80
+
81
+ 📋 **Apple Home ↔️ Roborock Clean Mode Mapping:**
82
+ For a detailed table of how Apple Home clean modes map to Roborock settings, see 👉 [Apple Home ↔️ Roborock Clean Mode Mapping](./README_CLEANMODE.md)
83
+
84
+ ---
78
85
 
79
86
  ### 📦 Prerequisites
80
87
 
@@ -0,0 +1,29 @@
1
+ # Apple Home RVC Clean Mode Mapping to Roborock Clean Setting
2
+
3
+ This table shows the mapping between **Apple Home RVC Clean Modes** and the corresponding **Roborock Clean Settings** as defined in `smart.ts` and `default.ts`.
4
+
5
+ | Apple Home RVC Clean Mode (Key) | Apple Home Mode Name | Roborock Clean Mode | suctionPower (enum value) | waterFlow (enum value) | distance_off | mopRoute (enum value) |
6
+ |:-------------------------------:|:-----------------------------|:--------------------|:--------------------------|:----------------------|:------------:|:---------------------:|
7
+ | 4 *(smart only)* | Mop & Vacuum: Automatic | Smart Plan | 0 | 0 | 0 | Smart (306) |
8
+ | 5 | Mop & Vacuum: Day (Automatic)| Vac & Mop | Balanced (102) | Medium (202) | 0 | Standard (300) |
9
+ | 6 | Mop & Vacuum: Quick | Vac & Mop | Balanced (102) | Medium (202) | 0 | Fast (304) |
10
+ | 7 | Mop & Vacuum: Max | Vac & Mop | Max (104) | Medium (202) | 0 | Standard (300) |
11
+ | 8 | Mop & Vacuum: Min | Vac & Mop | Balanced (102) | Low (201) | 0 | Standard (300) |
12
+ | 9 | Mop & Vacuum: Quiet | Vac & Mop | Quiet (101) | Medium (202) | 0 | Standard (300) |
13
+ | 10 | Mop & Vacuum: LowEnergy | Custom | Custom (106) | Custom (204) | 0 | Custom (302) |
14
+ | 31 | Mop: Default | Mop | Off (105) | Medium (202) | 0 | Standard (300) |
15
+ | 32 | Mop: Max | Mop | Off (105) | High (203) | 0 | Standard (300) |
16
+ | 33 | Mop: Min | Mop | Off (105) | Low (201) | 0 | Standard (300) |
17
+ | 34 | Mop: Quick | Mop | Off (105) | Medium (202) | 0 | Fast (304) |
18
+ | 35 | Mop: DeepClean | Mop | Off (105) | Medium (202) | 0 | Deep (301) |
19
+ | 66 | Vacuum: Default | Vacuum | Balanced (102) | Off (200) | 0 | Standard (300) |
20
+ | 67 | Vacuum: Max | Vacuum | Max (104) | Off (200) | 0 | Standard (300) |
21
+ | 68 | Vacuum: Quiet | Vacuum | Quiet (101) | Off (200) | 0 | Standard (300) |
22
+ | 69 | Vacuum: Quick | Vacuum | Balanced (102) | Off (200) | 0 | Fast (304) |
23
+ | 99 | Mop & Vacuum: Vacation | | | | | |
24
+
25
+ **Notes:**
26
+ - The values in parentheses are enum values from `VacuumSuctionPowerSmart`/`VacuumSuctionPower`, `MopWaterFlowSmart`/`MopWaterFlow`, and `MopRouteSmart`/`MopRoute` in `smart.ts` and `default.ts`.
27
+ - Key 4 ("Smart Plan") is only available on some new vacuums.
28
+ - This mapping helps you understand how Apple Home clean modes correspond to Roborock's internal cleaning settings for both "smart" and "default" behaviors.
29
+ - Key 99 is a tricky mode to support go to charge in Apple Home Automation
@@ -1,26 +1,22 @@
1
1
  import { BehaviorDeviceGeneric } from './behaviors/BehaviorDeviceGeneric.js';
2
- import { setCommandHandlerA187 } from './behaviors/roborock.vacuum/QREVO_EDGE_5V1/a187.js';
3
2
  import { setDefaultCommandHandler } from './behaviors/roborock.vacuum/default/default.js';
4
3
  import { DeviceModel } from './roborockCommunication/Zmodel/deviceModel.js';
5
- import { setCommandHandlerA27 } from './behaviors/roborock.vacuum/S7_MAXV/a27.js';
6
- import { setCommandHandlerA51 } from './behaviors/roborock.vacuum/S8_PRO_ULTRA/a51.js';
7
- export function configurateBehavior(model, duid, roborockService, cleanModeSettings, logger) {
4
+ import { setCommandHandlerSmart } from './behaviors/roborock.vacuum/smart/smart.js';
5
+ export function configurateBehavior(model, duid, roborockService, cleanModeSettings, forceRunAtDefault, logger) {
6
+ if (forceRunAtDefault) {
7
+ const deviceHandler = new BehaviorDeviceGeneric(logger);
8
+ setDefaultCommandHandler(duid, deviceHandler, logger, roborockService, cleanModeSettings);
9
+ return deviceHandler;
10
+ }
8
11
  switch (model) {
9
12
  case DeviceModel.QREVO_EDGE_5V1: {
10
13
  const deviceHandler = new BehaviorDeviceGeneric(logger);
11
- setCommandHandlerA187(duid, deviceHandler, logger, roborockService, cleanModeSettings);
12
- return deviceHandler;
13
- }
14
- case DeviceModel.S7_MAXV: {
15
- const deviceHandler = new BehaviorDeviceGeneric(logger);
16
- setCommandHandlerA27(duid, deviceHandler, logger, roborockService, cleanModeSettings);
17
- return deviceHandler;
18
- }
19
- case DeviceModel.S8_PRO_ULTRA: {
20
- const deviceHandler = new BehaviorDeviceGeneric(logger);
21
- setCommandHandlerA51(duid, deviceHandler, logger, roborockService, cleanModeSettings);
14
+ setCommandHandlerSmart(duid, deviceHandler, logger, roborockService, cleanModeSettings);
22
15
  return deviceHandler;
23
16
  }
17
+ case DeviceModel.S7_MAXV:
18
+ case DeviceModel.S8_PRO_ULTRA:
19
+ case DeviceModel.S6_PURE:
24
20
  default: {
25
21
  const deviceHandler = new BehaviorDeviceGeneric(logger);
26
22
  setDefaultCommandHandler(duid, deviceHandler, logger, roborockService, cleanModeSettings);
@@ -19,6 +19,7 @@ export var MopWaterFlow;
19
19
  MopWaterFlow[MopWaterFlow["Medium"] = 202] = "Medium";
20
20
  MopWaterFlow[MopWaterFlow["High"] = 203] = "High";
21
21
  MopWaterFlow[MopWaterFlow["Custom"] = 204] = "Custom";
22
+ MopWaterFlow[MopWaterFlow["CustomizeWithDistanceOff"] = 207] = "CustomizeWithDistanceOff";
22
23
  })(MopWaterFlow || (MopWaterFlow = {}));
23
24
  export var MopRoute;
24
25
  (function (MopRoute) {
@@ -28,50 +29,98 @@ export var MopRoute;
28
29
  MopRoute[MopRoute["DeepPlus"] = 303] = "DeepPlus";
29
30
  MopRoute[MopRoute["Fast"] = 304] = "Fast";
30
31
  })(MopRoute || (MopRoute = {}));
31
- const RvcRunMode = {
32
+ export const RvcRunMode = {
32
33
  [1]: 'Idle',
33
34
  [2]: 'Cleaning',
34
35
  [3]: 'Mapping',
35
36
  };
36
- const RvcCleanMode = {
37
- [5]: 'Mop',
38
- [6]: 'Vacuum',
39
- [7]: 'Vac & Mop',
40
- [8]: 'Custom',
37
+ export const RvcCleanMode = {
38
+ [5]: 'Mop & Vacuum: Default',
39
+ [6]: 'Mop & Vacuum: Quick',
40
+ [7]: 'Mop & Vacuum: Max',
41
+ [8]: 'Mop & Vacuum: Min',
42
+ [9]: 'Mop & Vacuum: Quiet',
43
+ [10]: 'Mop & Vacuum: Custom',
44
+ [31]: 'Mop: Default',
45
+ [32]: 'Mop: Max',
46
+ [33]: 'Mop: Min',
47
+ [34]: 'Mop: Quick',
48
+ [35]: 'Mop: DeepClean',
49
+ [66]: 'Vacuum: Default',
50
+ [67]: 'Vacuum: Max',
51
+ [68]: 'Vacuum: Quiet',
52
+ [69]: 'Vacuum: Quick',
53
+ [99]: 'Go Vacation',
41
54
  };
42
- const CleanSetting = {
43
- [5]: { suctionPower: VacuumSuctionPower.Off, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Standard },
44
- [6]: { suctionPower: VacuumSuctionPower.Balanced, waterFlow: MopWaterFlow.Off, distance_off: 0, mopRoute: MopRoute.Standard },
45
- [7]: { suctionPower: VacuumSuctionPower.Balanced, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Standard },
46
- [8]: { suctionPower: VacuumSuctionPower.Custom, waterFlow: MopWaterFlow.Custom, distance_off: 0, mopRoute: MopRoute.Custom },
55
+ export const CleanSetting = {
56
+ [5]: { suctionPower: VacuumSuctionPower.Balanced, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Standard },
57
+ [6]: { suctionPower: VacuumSuctionPower.Balanced, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Fast },
58
+ [7]: { suctionPower: VacuumSuctionPower.Max, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Standard },
59
+ [8]: { suctionPower: VacuumSuctionPower.Balanced, waterFlow: MopWaterFlow.Low, distance_off: 0, mopRoute: MopRoute.Standard },
60
+ [9]: { suctionPower: VacuumSuctionPower.Quiet, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Standard },
61
+ [10]: { suctionPower: VacuumSuctionPower.Custom, waterFlow: MopWaterFlow.Custom, distance_off: 0, mopRoute: MopRoute.Custom },
62
+ [31]: { suctionPower: VacuumSuctionPower.Off, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Standard },
63
+ [32]: { suctionPower: VacuumSuctionPower.Off, waterFlow: MopWaterFlow.High, distance_off: 0, mopRoute: MopRoute.Standard },
64
+ [33]: { suctionPower: VacuumSuctionPower.Off, waterFlow: MopWaterFlow.Low, distance_off: 0, mopRoute: MopRoute.Standard },
65
+ [34]: { suctionPower: VacuumSuctionPower.Off, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Fast },
66
+ [35]: { suctionPower: VacuumSuctionPower.Off, waterFlow: MopWaterFlow.Medium, distance_off: 0, mopRoute: MopRoute.Deep },
67
+ [66]: { suctionPower: VacuumSuctionPower.Balanced, waterFlow: MopWaterFlow.Off, distance_off: 0, mopRoute: MopRoute.Standard },
68
+ [67]: { suctionPower: VacuumSuctionPower.Max, waterFlow: MopWaterFlow.Off, distance_off: 0, mopRoute: MopRoute.Standard },
69
+ [68]: { suctionPower: VacuumSuctionPower.Quiet, waterFlow: MopWaterFlow.Off, distance_off: 0, mopRoute: MopRoute.Standard },
70
+ [69]: { suctionPower: VacuumSuctionPower.Balanced, waterFlow: MopWaterFlow.Off, distance_off: 0, mopRoute: MopRoute.Fast },
47
71
  };
48
72
  export function setDefaultCommandHandler(duid, handler, logger, roborockService, cleanModeSettings) {
49
73
  handler.setCommandHandler('changeToMode', async (newMode) => {
50
74
  const activity = RvcRunMode[newMode] || RvcCleanMode[newMode];
51
75
  switch (activity) {
52
76
  case 'Cleaning': {
77
+ logger.notice('DefaultBehavior-ChangeRunMode to: ', activity);
53
78
  await roborockService.startClean(duid);
54
- return;
79
+ break;
55
80
  }
56
- case 'Mop':
57
- case 'Vacuum':
58
- case 'Vac & Mop': {
59
- const setting = cleanModeSettings ? getSettingFromCleanMode(activity, cleanModeSettings) : CleanSetting[newMode];
81
+ case 'Go Vacation': {
82
+ logger.notice('DefaultBehavior-GoHome');
83
+ await roborockService.stopAndGoHome(duid);
84
+ break;
85
+ }
86
+ case 'Mop & Vacuum: Custom': {
87
+ const setting = CleanSetting[newMode];
88
+ logger.notice(`DefaultBehavior-ChangeCleanMode to: ${activity}, setting: ${debugStringify(setting)}`);
89
+ await roborockService.changeCleanMode(duid, setting);
90
+ break;
91
+ }
92
+ case 'Mop & Vacuum: Default':
93
+ case 'Mop: Default':
94
+ case 'Vacuum: Default': {
95
+ const setting = cleanModeSettings ? (getSettingFromCleanMode(activity, cleanModeSettings) ?? CleanSetting[newMode]) : CleanSetting[newMode];
60
96
  logger.notice(`DefaultBehavior-ChangeCleanMode to: ${activity}, setting: ${debugStringify(setting ?? {})}`);
61
97
  if (setting) {
62
98
  await roborockService.changeCleanMode(duid, setting);
63
99
  }
64
- return;
100
+ break;
65
101
  }
66
- case 'Custom': {
102
+ case 'Mop & Vacuum: Quick':
103
+ case 'Mop & Vacuum: Max':
104
+ case 'Mop & Vacuum: Min':
105
+ case 'Mop & Vacuum: Quiet':
106
+ case 'Mop: Max':
107
+ case 'Mop: Min':
108
+ case 'Mop: Quick':
109
+ case 'Mop: DeepClean':
110
+ case 'Vacuum: Max':
111
+ case 'Vacuum: Min':
112
+ case 'Vacuum: Quiet':
113
+ case 'Vacuum: Quick': {
67
114
  const setting = CleanSetting[newMode];
68
- logger.notice(`DefaultBehavior-ChangeCleanMode to: ${activity}, setting: ${debugStringify(setting)}`);
69
- await roborockService.changeCleanMode(duid, setting);
70
- return;
115
+ logger.notice(`DefaultBehavior-ChangeCleanMode to: ${activity}, setting: ${debugStringify(setting ?? {})}`);
116
+ if (setting) {
117
+ await roborockService.changeCleanMode(duid, setting);
118
+ }
119
+ break;
71
120
  }
72
121
  default:
73
122
  logger.notice('DefaultBehavior-changeToMode-Unknown: ', newMode);
74
- return;
123
+ break;
75
124
  }
76
125
  });
77
126
  handler.setCommandHandler('selectAreas', async (newAreas) => {
@@ -94,39 +143,41 @@ export function setDefaultCommandHandler(duid, handler, logger, roborockService,
94
143
  logger.notice('DefaultBehavior-playSoundToLocate');
95
144
  await roborockService.playSoundToLocate(duid);
96
145
  });
97
- const getSettingFromCleanMode = (activity, cleanModeSettings) => {
98
- switch (activity) {
99
- case 'Mop': {
100
- const mopSetting = cleanModeSettings?.mopping;
101
- const waterFlow = MopWaterFlow[mopSetting?.waterFlowMode] ?? MopWaterFlow.Medium;
102
- return {
103
- suctionPower: VacuumSuctionPower.Off,
104
- waterFlow,
105
- distance_off: 0,
106
- mopRoute: MopRoute[mopSetting?.mopRouteMode] ?? MopRoute.Standard,
107
- };
108
- }
109
- case 'Vacuum': {
110
- const vacuumSetting = cleanModeSettings?.vacuuming;
111
- return {
112
- suctionPower: VacuumSuctionPower[vacuumSetting?.fanMode] ?? VacuumSuctionPower.Balanced,
113
- waterFlow: MopWaterFlow.Off,
114
- distance_off: 0,
115
- mopRoute: MopRoute[vacuumSetting?.mopRouteMode] ?? MopRoute.Standard,
116
- };
117
- }
118
- case 'Vac & Mop': {
119
- const vacmopSetting = cleanModeSettings?.vacmop;
120
- const waterFlow = MopWaterFlow[vacmopSetting?.waterFlowMode] ?? MopWaterFlow.Medium;
121
- return {
122
- suctionPower: VacuumSuctionPower[vacmopSetting?.fanMode] ?? VacuumSuctionPower.Balanced,
123
- waterFlow,
124
- distance_off: 0,
125
- mopRoute: MopRoute[vacmopSetting?.mopRouteMode] ?? MopRoute.Standard,
126
- };
127
- }
128
- default:
129
- return undefined;
130
- }
131
- };
132
146
  }
147
+ export const getSettingFromCleanMode = (activity, cleanModeSettings) => {
148
+ switch (activity) {
149
+ case 'Mop: Default': {
150
+ const mopSetting = cleanModeSettings?.mopping;
151
+ const waterFlow = MopWaterFlow[mopSetting?.waterFlowMode] ?? MopWaterFlow.Medium;
152
+ const distance_off = waterFlow == MopWaterFlow.CustomizeWithDistanceOff ? 210 - 5 * (mopSetting?.distanceOff ?? 25) : 0;
153
+ return {
154
+ suctionPower: VacuumSuctionPower.Off,
155
+ waterFlow,
156
+ distance_off,
157
+ mopRoute: MopRoute[mopSetting?.mopRouteMode] ?? MopRoute.Standard,
158
+ };
159
+ }
160
+ case 'Vacuum: Default': {
161
+ const vacuumSetting = cleanModeSettings?.vacuuming;
162
+ return {
163
+ suctionPower: VacuumSuctionPower[vacuumSetting?.fanMode] ?? VacuumSuctionPower.Balanced,
164
+ waterFlow: MopWaterFlow.Off,
165
+ distance_off: 0,
166
+ mopRoute: MopRoute[vacuumSetting?.mopRouteMode] ?? MopRoute.Standard,
167
+ };
168
+ }
169
+ case 'Mop & Vacuum: Default': {
170
+ const vacmopSetting = cleanModeSettings?.vacmop;
171
+ const waterFlow = MopWaterFlow[vacmopSetting?.waterFlowMode] ?? MopWaterFlow.Medium;
172
+ const distance_off = waterFlow == MopWaterFlow.CustomizeWithDistanceOff ? 210 - 5 * (vacmopSetting?.distanceOff ?? 25) : 0;
173
+ return {
174
+ suctionPower: VacuumSuctionPower[vacmopSetting?.fanMode] ?? VacuumSuctionPower.Balanced,
175
+ waterFlow,
176
+ distance_off,
177
+ mopRoute: MopRoute[vacmopSetting?.mopRouteMode] ?? MopRoute.Standard,
178
+ };
179
+ }
180
+ default:
181
+ return undefined;
182
+ }
183
+ };
@@ -1,4 +1,5 @@
1
1
  import { RvcCleanMode, RvcOperationalState, RvcRunMode } from 'matterbridge/matter/clusters';
2
+ import { RvcCleanMode as RvcCleanModeDisplayMap } from './default.js';
2
3
  export function getDefaultSupportedRunModes() {
3
4
  return [
4
5
  {
@@ -18,29 +19,95 @@ export function getDefaultSupportedRunModes() {
18
19
  },
19
20
  ];
20
21
  }
21
- export function getDefaultSupportedCleanModes() {
22
- return [
22
+ export function getDefaultSupportedCleanModes(enableExperimentalFeature) {
23
+ const result = [
23
24
  {
24
- label: 'Mop',
25
+ label: RvcCleanModeDisplayMap[5],
25
26
  mode: 5,
26
- modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Auto }],
27
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Auto }],
27
28
  },
28
29
  {
29
- label: 'Vacuum',
30
+ label: RvcCleanModeDisplayMap[6],
30
31
  mode: 6,
31
- modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Auto }],
32
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Quick }],
32
33
  },
33
34
  {
34
- label: 'Mop & Vacuum',
35
+ label: RvcCleanModeDisplayMap[7],
35
36
  mode: 7,
36
- modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.DeepClean }],
37
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Max }],
37
38
  },
38
39
  {
39
- label: 'Custom',
40
+ label: RvcCleanModeDisplayMap[8],
40
41
  mode: 8,
41
- modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Quick }],
42
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Min }],
43
+ },
44
+ {
45
+ label: RvcCleanModeDisplayMap[9],
46
+ mode: 9,
47
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Quiet }],
48
+ },
49
+ {
50
+ label: RvcCleanModeDisplayMap[10],
51
+ mode: 10,
52
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.LowEnergy }],
53
+ },
54
+ {
55
+ label: RvcCleanModeDisplayMap[31],
56
+ mode: 31,
57
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Auto }],
58
+ },
59
+ {
60
+ label: RvcCleanModeDisplayMap[32],
61
+ mode: 32,
62
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Max }],
63
+ },
64
+ {
65
+ label: RvcCleanModeDisplayMap[33],
66
+ mode: 33,
67
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Min }],
68
+ },
69
+ {
70
+ label: RvcCleanModeDisplayMap[34],
71
+ mode: 34,
72
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Quick }],
73
+ },
74
+ {
75
+ label: RvcCleanModeDisplayMap[35],
76
+ mode: 35,
77
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.DeepClean }],
78
+ },
79
+ {
80
+ label: RvcCleanModeDisplayMap[66],
81
+ mode: 66,
82
+ modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Auto }],
83
+ },
84
+ {
85
+ label: RvcCleanModeDisplayMap[67],
86
+ mode: 67,
87
+ modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Max }],
88
+ },
89
+ {
90
+ label: RvcCleanModeDisplayMap[68],
91
+ mode: 68,
92
+ modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Quiet }],
93
+ },
94
+ {
95
+ label: RvcCleanModeDisplayMap[69],
96
+ mode: 69,
97
+ modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Quick }],
42
98
  },
43
99
  ];
100
+ if (enableExperimentalFeature?.advancedFeature?.useVacationModeToSendVacuumToDock ?? false) {
101
+ return [
102
+ ...result,
103
+ {
104
+ label: RvcCleanModeDisplayMap[99],
105
+ mode: 99,
106
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Vacation }],
107
+ },
108
+ ];
109
+ }
110
+ return result;
44
111
  }
45
112
  export function getDefaultOperationalStates() {
46
113
  return [
@@ -1,33 +1,21 @@
1
- import { MopWaterFlow, VacuumSuctionPower } from './default.js';
2
- export function getCurrentCleanModeDefault(fan_power, water_box_mode) {
3
- if (!fan_power || !water_box_mode)
1
+ import { CleanSetting, MopRoute, MopWaterFlow, VacuumSuctionPower } from './default.js';
2
+ export function getCurrentCleanModeDefault(setting) {
3
+ if (!setting || typeof setting !== 'object') {
4
4
  return undefined;
5
- if (fan_power == VacuumSuctionPower.Custom || water_box_mode == MopWaterFlow.Custom)
6
- return 8;
7
- if (fan_power == VacuumSuctionPower.Off)
5
+ }
6
+ if (setting.suctionPower === VacuumSuctionPower.Custom || setting.waterFlow === MopWaterFlow.Custom || setting.mopRoute === MopRoute.Custom) {
7
+ return 10;
8
+ }
9
+ for (const [key, value] of Object.entries(CleanSetting)) {
10
+ if (value.suctionPower === setting.suctionPower && value.waterFlow === setting.waterFlow && value.mopRoute === setting.mopRoute) {
11
+ return Number(key);
12
+ }
13
+ }
14
+ if (setting.suctionPower == VacuumSuctionPower.Off)
15
+ return 31;
16
+ if (setting.waterFlow == MopWaterFlow.Off)
17
+ return 66;
18
+ if ((setting.suctionPower !== VacuumSuctionPower.Off && setting.waterFlow) !== MopWaterFlow.Off)
8
19
  return 5;
9
- if (water_box_mode == MopWaterFlow.Off)
10
- return 6;
11
- else
12
- return 7;
13
- }
14
- export function getCurrentCleanModeFromFanPowerDefault(fan_power) {
15
- if (!fan_power)
16
- return undefined;
17
- if (fan_power == VacuumSuctionPower.Custom)
18
- return 8;
19
- if (fan_power == VacuumSuctionPower.Off)
20
- return 5;
21
- else
22
- return undefined;
23
- }
24
- export function getCurrentCleanModeFromWaterBoxModeDefault(water_box_mode) {
25
- if (!water_box_mode)
26
- return undefined;
27
- if (water_box_mode == MopWaterFlow.Custom)
28
- return 8;
29
- if (water_box_mode == MopWaterFlow.Off)
30
- return 6;
31
- else
32
- return undefined;
20
+ return undefined;
33
21
  }
@@ -0,0 +1,18 @@
1
+ import { RvcCleanMode } from 'matterbridge/matter/clusters';
2
+ import { RvcCleanMode as RvcCleanModeDisplayMap } from './smart.js';
3
+ import { getDefaultSupportedCleanModes } from '../default/initalData.js';
4
+ export function getSupportedCleanModesSmart(enableExperimentalFeature) {
5
+ return [
6
+ {
7
+ label: RvcCleanModeDisplayMap[4],
8
+ mode: 4,
9
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Auto }],
10
+ },
11
+ {
12
+ label: RvcCleanModeDisplayMap[5],
13
+ mode: 5,
14
+ modeTags: [{ value: RvcCleanMode.ModeTag.Mop }, { value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Day }],
15
+ },
16
+ ...getDefaultSupportedCleanModes(enableExperimentalFeature).filter((x) => x.mode !== 4 && x.mode !== 5),
17
+ ];
18
+ }
@@ -0,0 +1,11 @@
1
+ import { getCurrentCleanModeDefault } from '../default/runtimes.js';
2
+ import { MopRouteSmart, MopWaterFlowSmart, VacuumSuctionPowerSmart } from './smart.js';
3
+ export function getCurrentCleanModeSmart(setting) {
4
+ if (!setting || typeof setting !== 'object') {
5
+ return undefined;
6
+ }
7
+ if (setting.suctionPower === VacuumSuctionPowerSmart.Smart || setting.waterFlow === MopWaterFlowSmart.Smart || setting.mopRoute === MopRouteSmart.Smart) {
8
+ return 4;
9
+ }
10
+ return getCurrentCleanModeDefault(setting);
11
+ }
@@ -0,0 +1,119 @@
1
+ import { debugStringify } from 'matterbridge/logger';
2
+ import { BehaviorRoborock } from '../../BehaviorDeviceGeneric.js';
3
+ import { RvcCleanMode as DefaultRvcCleanMode, CleanSetting as DefaultCleanSetting, getSettingFromCleanMode, RvcRunMode } from '../default/default.js';
4
+ export class BehaviorSmart extends BehaviorRoborock {
5
+ }
6
+ export var VacuumSuctionPowerSmart;
7
+ (function (VacuumSuctionPowerSmart) {
8
+ VacuumSuctionPowerSmart[VacuumSuctionPowerSmart["Quiet"] = 101] = "Quiet";
9
+ VacuumSuctionPowerSmart[VacuumSuctionPowerSmart["Balanced"] = 102] = "Balanced";
10
+ VacuumSuctionPowerSmart[VacuumSuctionPowerSmart["Turbo"] = 103] = "Turbo";
11
+ VacuumSuctionPowerSmart[VacuumSuctionPowerSmart["Max"] = 104] = "Max";
12
+ VacuumSuctionPowerSmart[VacuumSuctionPowerSmart["Off"] = 105] = "Off";
13
+ VacuumSuctionPowerSmart[VacuumSuctionPowerSmart["Custom"] = 106] = "Custom";
14
+ VacuumSuctionPowerSmart[VacuumSuctionPowerSmart["MaxPlus"] = 108] = "MaxPlus";
15
+ VacuumSuctionPowerSmart[VacuumSuctionPowerSmart["Smart"] = 110] = "Smart";
16
+ })(VacuumSuctionPowerSmart || (VacuumSuctionPowerSmart = {}));
17
+ export var MopWaterFlowSmart;
18
+ (function (MopWaterFlowSmart) {
19
+ MopWaterFlowSmart[MopWaterFlowSmart["Off"] = 200] = "Off";
20
+ MopWaterFlowSmart[MopWaterFlowSmart["Low"] = 201] = "Low";
21
+ MopWaterFlowSmart[MopWaterFlowSmart["Medium"] = 202] = "Medium";
22
+ MopWaterFlowSmart[MopWaterFlowSmart["High"] = 203] = "High";
23
+ MopWaterFlowSmart[MopWaterFlowSmart["Custom"] = 204] = "Custom";
24
+ MopWaterFlowSmart[MopWaterFlowSmart["CustomizeWithDistanceOff"] = 207] = "CustomizeWithDistanceOff";
25
+ MopWaterFlowSmart[MopWaterFlowSmart["Smart"] = 209] = "Smart";
26
+ })(MopWaterFlowSmart || (MopWaterFlowSmart = {}));
27
+ export var MopRouteSmart;
28
+ (function (MopRouteSmart) {
29
+ MopRouteSmart[MopRouteSmart["Standard"] = 300] = "Standard";
30
+ MopRouteSmart[MopRouteSmart["Deep"] = 301] = "Deep";
31
+ MopRouteSmart[MopRouteSmart["Custom"] = 302] = "Custom";
32
+ MopRouteSmart[MopRouteSmart["DeepPlus"] = 303] = "DeepPlus";
33
+ MopRouteSmart[MopRouteSmart["Fast"] = 304] = "Fast";
34
+ MopRouteSmart[MopRouteSmart["Smart"] = 306] = "Smart";
35
+ })(MopRouteSmart || (MopRouteSmart = {}));
36
+ export const RvcCleanMode = {
37
+ [4]: 'Smart Plan',
38
+ ...DefaultRvcCleanMode,
39
+ };
40
+ export const CleanSetting = {
41
+ [4]: { suctionPower: 0, waterFlow: 0, distance_off: 0, mopRoute: MopRouteSmart.Smart },
42
+ ...DefaultCleanSetting,
43
+ };
44
+ export function setCommandHandlerSmart(duid, handler, logger, roborockService, cleanModeSettings) {
45
+ handler.setCommandHandler('changeToMode', async (newMode) => {
46
+ const activity = RvcRunMode[newMode] || RvcCleanMode[newMode];
47
+ switch (activity) {
48
+ case 'Cleaning': {
49
+ logger.notice('BehaviorSmart-ChangeRunMode to: ', activity);
50
+ await roborockService.startClean(duid);
51
+ break;
52
+ }
53
+ case 'Go Vacation': {
54
+ logger.notice('BehaviorSmart-GoHome');
55
+ await roborockService.stopAndGoHome(duid);
56
+ break;
57
+ }
58
+ case 'Smart Plan':
59
+ case 'Mop & Vacuum: Custom': {
60
+ const setting = CleanSetting[newMode];
61
+ logger.notice(`BehaviorSmart-ChangeCleanMode to: ${activity}, setting: ${debugStringify(setting)}`);
62
+ await roborockService.changeCleanMode(duid, setting);
63
+ break;
64
+ }
65
+ case 'Mop & Vacuum: Default':
66
+ case 'Mop: Default':
67
+ case 'Vacuum: Default': {
68
+ const setting = cleanModeSettings ? (getSettingFromCleanMode(activity, cleanModeSettings) ?? CleanSetting[newMode]) : CleanSetting[newMode];
69
+ logger.notice(`BehaviorSmart-ChangeCleanMode to: ${activity}, setting: ${debugStringify(setting ?? {})}`);
70
+ if (setting) {
71
+ await roborockService.changeCleanMode(duid, setting);
72
+ }
73
+ break;
74
+ }
75
+ case 'Mop & Vacuum: Quick':
76
+ case 'Mop & Vacuum: Max':
77
+ case 'Mop & Vacuum: Min':
78
+ case 'Mop & Vacuum: Quiet':
79
+ case 'Mop: Max':
80
+ case 'Mop: Min':
81
+ case 'Mop: Quick':
82
+ case 'Mop: DeepClean':
83
+ case 'Vacuum: Max':
84
+ case 'Vacuum: Min':
85
+ case 'Vacuum: Quiet':
86
+ case 'Vacuum: Quick': {
87
+ const setting = CleanSetting[newMode];
88
+ logger.notice(`BehaviorSmart-ChangeCleanMode to: ${activity}, setting: ${debugStringify(setting ?? {})}`);
89
+ if (setting) {
90
+ await roborockService.changeCleanMode(duid, setting);
91
+ }
92
+ break;
93
+ }
94
+ default:
95
+ logger.notice('BehaviorSmart-changeToMode-Unknown: ', newMode);
96
+ break;
97
+ }
98
+ });
99
+ handler.setCommandHandler('selectAreas', async (newAreas) => {
100
+ logger.notice(`BehaviorSmart-selectAreas: ${newAreas}`);
101
+ roborockService.setSelectedAreas(duid, newAreas ?? []);
102
+ });
103
+ handler.setCommandHandler('pause', async () => {
104
+ logger.notice('BehaviorSmart-Pause');
105
+ await roborockService.pauseClean(duid);
106
+ });
107
+ handler.setCommandHandler('resume', async () => {
108
+ logger.notice('BehaviorSmart-Resume');
109
+ await roborockService.resumeClean(duid);
110
+ });
111
+ handler.setCommandHandler('goHome', async () => {
112
+ logger.notice('BehaviorSmart-GoHome');
113
+ await roborockService.stopAndGoHome(duid);
114
+ });
115
+ handler.setCommandHandler('playSoundToLocate', async () => {
116
+ logger.notice('BehaviorSmart-playSoundToLocate');
117
+ await roborockService.playSoundToLocate(duid);
118
+ });
119
+ }
@@ -1,21 +1,8 @@
1
1
  import { RvcOperationalState } from 'matterbridge/matter/clusters';
2
- import { getOperationalStatesA187 } from '../behaviors/roborock.vacuum/QREVO_EDGE_5V1/initalData.js';
3
2
  import { getDefaultOperationalStates } from '../behaviors/roborock.vacuum/default/initalData.js';
4
- import { DeviceModel } from '../roborockCommunication/Zmodel/deviceModel.js';
5
3
  import { VacuumErrorCode } from '../roborockCommunication/Zenum/vacuumAndDockErrorCode.js';
6
- import { getOperationalStatesA27 } from '../behaviors/roborock.vacuum/S7_MAXV/initalData.js';
7
- import { getOperationalStatesA51 } from '../behaviors/roborock.vacuum/S8_PRO_ULTRA/initalData.js';
8
- export function getOperationalStates(model) {
9
- switch (model) {
10
- case DeviceModel.QREVO_EDGE_5V1:
11
- return getOperationalStatesA187();
12
- case DeviceModel.S7_MAXV:
13
- return getOperationalStatesA27();
14
- case DeviceModel.S8_MAXV_ULTRA:
15
- return getOperationalStatesA51();
16
- default:
17
- return getDefaultOperationalStates();
18
- }
4
+ export function getOperationalStates() {
5
+ return getDefaultOperationalStates();
19
6
  }
20
7
  export function getOperationalErrorState(errorCode) {
21
8
  switch (errorCode) {