@switchbot/homebridge-switchbot 5.0.0-beta.6 → 5.0.0-beta.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +45 -3
- package/config.schema.json +866 -13754
- package/dist/devices-hap/airpurifier.d.ts.map +1 -1
- package/dist/devices-hap/airpurifier.js +12 -6
- package/dist/devices-hap/airpurifier.js.map +1 -1
- package/dist/devices-hap/blindtilt.js +3 -3
- package/dist/devices-hap/bot.d.ts.map +1 -1
- package/dist/devices-hap/bot.js +16 -5
- package/dist/devices-hap/bot.js.map +1 -1
- package/dist/devices-hap/ceilinglight.d.ts.map +1 -1
- package/dist/devices-hap/ceilinglight.js +13 -7
- package/dist/devices-hap/ceilinglight.js.map +1 -1
- package/dist/devices-hap/colorbulb.d.ts.map +1 -1
- package/dist/devices-hap/colorbulb.js +49 -9
- package/dist/devices-hap/colorbulb.js.map +1 -1
- package/dist/devices-hap/contact.js +3 -3
- package/dist/devices-hap/curtain.js +2 -2
- package/dist/devices-hap/curtain.js.map +1 -1
- package/dist/devices-hap/device.d.ts +18 -8
- package/dist/devices-hap/device.d.ts.map +1 -1
- package/dist/devices-hap/device.js +141 -69
- package/dist/devices-hap/device.js.map +1 -1
- package/dist/devices-hap/fan.d.ts.map +1 -1
- package/dist/devices-hap/fan.js +12 -6
- package/dist/devices-hap/fan.js.map +1 -1
- package/dist/devices-hap/hub.d.ts.map +1 -1
- package/dist/devices-hap/hub.js +6 -5
- package/dist/devices-hap/hub.js.map +1 -1
- package/dist/devices-hap/humidifier.d.ts +5 -0
- package/dist/devices-hap/humidifier.d.ts.map +1 -1
- package/dist/devices-hap/humidifier.js +92 -4
- package/dist/devices-hap/humidifier.js.map +1 -1
- package/dist/devices-hap/iosensor.d.ts.map +1 -1
- package/dist/devices-hap/iosensor.js +36 -21
- package/dist/devices-hap/iosensor.js.map +1 -1
- package/dist/devices-hap/lightstrip.d.ts.map +1 -1
- package/dist/devices-hap/lightstrip.js +38 -8
- package/dist/devices-hap/lightstrip.js.map +1 -1
- package/dist/devices-hap/lock.d.ts.map +1 -1
- package/dist/devices-hap/lock.js +14 -6
- package/dist/devices-hap/lock.js.map +1 -1
- package/dist/devices-hap/meter.d.ts.map +1 -1
- package/dist/devices-hap/meter.js +6 -5
- package/dist/devices-hap/meter.js.map +1 -1
- package/dist/devices-hap/meterplus.d.ts.map +1 -1
- package/dist/devices-hap/meterplus.js +6 -5
- package/dist/devices-hap/meterplus.js.map +1 -1
- package/dist/devices-hap/meterpro.d.ts.map +1 -1
- package/dist/devices-hap/meterpro.js +7 -6
- package/dist/devices-hap/meterpro.js.map +1 -1
- package/dist/devices-hap/motion.js +3 -3
- package/dist/devices-hap/plug.d.ts.map +1 -1
- package/dist/devices-hap/plug.js +11 -6
- package/dist/devices-hap/plug.js.map +1 -1
- package/dist/devices-hap/relayswitch.js +3 -3
- package/dist/devices-hap/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/devices-hap/robotvacuumcleaner.js +13 -6
- package/dist/devices-hap/robotvacuumcleaner.js.map +1 -1
- package/dist/devices-hap/waterdetector.js +3 -3
- package/dist/devices-matter/BaseMatterAccessory.d.ts +27 -0
- package/dist/devices-matter/BaseMatterAccessory.d.ts.map +1 -1
- package/dist/devices-matter/BaseMatterAccessory.js +169 -5
- package/dist/devices-matter/BaseMatterAccessory.js.map +1 -1
- package/dist/devices-matter/ColorLightAccessory.d.ts.map +1 -1
- package/dist/devices-matter/ColorLightAccessory.js +12 -12
- package/dist/devices-matter/ColorLightAccessory.js.map +1 -1
- package/dist/devices-matter/ColorTemperatureLightAccessory.d.ts.map +1 -1
- package/dist/devices-matter/ColorTemperatureLightAccessory.js +5 -7
- package/dist/devices-matter/ColorTemperatureLightAccessory.js.map +1 -1
- package/dist/devices-matter/DimmableLightAccessory.js +9 -9
- package/dist/devices-matter/DimmableLightAccessory.js.map +1 -1
- package/dist/devices-matter/ExtendedColorLightAccessory.d.ts.map +1 -1
- package/dist/devices-matter/ExtendedColorLightAccessory.js +14 -15
- package/dist/devices-matter/ExtendedColorLightAccessory.js.map +1 -1
- package/dist/devices-matter/OnOffLightAccessory.d.ts.map +1 -1
- package/dist/devices-matter/OnOffLightAccessory.js +8 -16
- package/dist/devices-matter/OnOffLightAccessory.js.map +1 -1
- package/dist/devices-matter/OnOffOutletAccessory.d.ts +2 -0
- package/dist/devices-matter/OnOffOutletAccessory.d.ts.map +1 -1
- package/dist/devices-matter/OnOffOutletAccessory.js +10 -7
- package/dist/devices-matter/OnOffOutletAccessory.js.map +1 -1
- package/dist/devices-matter/OnOffSwitchAccessory.js +2 -2
- package/dist/devices-matter/OnOffSwitchAccessory.js.map +1 -1
- package/dist/devices-matter/RoboticVacuumAccessory.d.ts +29 -43
- package/dist/devices-matter/RoboticVacuumAccessory.d.ts.map +1 -1
- package/dist/devices-matter/RoboticVacuumAccessory.js +287 -262
- package/dist/devices-matter/RoboticVacuumAccessory.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +200 -18
- package/dist/homebridge-ui/server.js +0 -31
- package/dist/homebridge-ui/server.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +11 -10
- package/dist/irdevice/irdevice.d.ts.map +1 -1
- package/dist/irdevice/irdevice.js +76 -35
- package/dist/irdevice/irdevice.js.map +1 -1
- package/dist/platform-hap.d.ts +26 -15
- package/dist/platform-hap.d.ts.map +1 -1
- package/dist/platform-hap.js +333 -153
- package/dist/platform-hap.js.map +1 -1
- package/dist/platform-matter.d.ts +93 -6
- package/dist/platform-matter.d.ts.map +1 -1
- package/dist/platform-matter.js +1822 -224
- package/dist/platform-matter.js.map +1 -1
- package/dist/settings.d.ts +58 -7
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/test/apiRequestTracker.test.d.ts +2 -0
- package/dist/test/apiRequestTracker.test.d.ts.map +1 -0
- package/dist/test/apiRequestTracker.test.js +392 -0
- package/dist/test/apiRequestTracker.test.js.map +1 -0
- package/dist/test/hap/device-webhook-context.test.d.ts +2 -0
- package/dist/test/hap/device-webhook-context.test.d.ts.map +1 -0
- package/dist/test/hap/device-webhook-context.test.js +128 -0
- package/dist/test/hap/device-webhook-context.test.js.map +1 -0
- package/dist/test/hap/platform-hap.logging.test.d.ts +2 -0
- package/dist/test/hap/platform-hap.logging.test.d.ts.map +1 -0
- package/dist/test/hap/platform-hap.logging.test.js +33 -0
- package/dist/test/hap/platform-hap.logging.test.js.map +1 -0
- package/dist/test/hap/platform-hap.test.d.ts +2 -0
- package/dist/test/hap/platform-hap.test.d.ts.map +1 -0
- package/dist/test/hap/platform-hap.test.js +62 -0
- package/dist/test/hap/platform-hap.test.js.map +1 -0
- package/dist/test/helpers/platform-fixtures.d.ts +9 -0
- package/dist/test/helpers/platform-fixtures.d.ts.map +1 -0
- package/dist/test/helpers/platform-fixtures.js +30 -0
- package/dist/test/helpers/platform-fixtures.js.map +1 -0
- package/dist/test/homebridge-ui/server.test.d.ts +2 -0
- package/dist/test/homebridge-ui/server.test.d.ts.map +1 -0
- package/dist/test/homebridge-ui/server.test.js +445 -0
- package/dist/test/homebridge-ui/server.test.js.map +1 -0
- package/dist/{index.test.d.ts.map → test/index.test.d.ts.map} +1 -1
- package/dist/test/index.test.js +19 -0
- package/dist/test/index.test.js.map +1 -0
- package/dist/test/matter/devices-matter/baseMatterAccessory.test.d.ts +2 -0
- package/dist/test/matter/devices-matter/baseMatterAccessory.test.d.ts.map +1 -0
- package/dist/test/matter/devices-matter/baseMatterAccessory.test.js +71 -0
- package/dist/test/matter/devices-matter/baseMatterAccessory.test.js.map +1 -0
- package/dist/test/matter/devices-matter/roboticVacuumAccessory.test.d.ts +2 -0
- package/dist/test/matter/devices-matter/roboticVacuumAccessory.test.d.ts.map +1 -0
- package/dist/test/matter/devices-matter/roboticVacuumAccessory.test.js +366 -0
- package/dist/test/matter/devices-matter/roboticVacuumAccessory.test.js.map +1 -0
- package/dist/test/matter/platform-matter.additional.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.additional.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.additional.test.js +35 -0
- package/dist/test/matter/platform-matter.additional.test.js.map +1 -0
- package/dist/test/matter/platform-matter.bleparse.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.bleparse.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.bleparse.test.js +43 -0
- package/dist/test/matter/platform-matter.bleparse.test.js.map +1 -0
- package/dist/test/matter/platform-matter.cleanup.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.cleanup.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.cleanup.test.js +70 -0
- package/dist/test/matter/platform-matter.cleanup.test.js.map +1 -0
- package/dist/test/matter/platform-matter.keepstale.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.keepstale.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.keepstale.test.js +27 -0
- package/dist/test/matter/platform-matter.keepstale.test.js.map +1 -0
- package/dist/test/matter/platform-matter.logging.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.logging.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.logging.test.js +29 -0
- package/dist/test/matter/platform-matter.logging.test.js.map +1 -0
- package/dist/test/matter/platform-matter.mapping.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.mapping.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.mapping.test.js +43 -0
- package/dist/test/matter/platform-matter.mapping.test.js.map +1 -0
- package/dist/test/matter/platform-matter.openapi-mapping.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.openapi-mapping.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.openapi-mapping.test.js +84 -0
- package/dist/test/matter/platform-matter.openapi-mapping.test.js.map +1 -0
- package/dist/test/matter/platform-matter.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.test.js +117 -0
- package/dist/test/matter/platform-matter.test.js.map +1 -0
- package/dist/test/matter/platform-matter.unregister.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.unregister.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.unregister.test.js +30 -0
- package/dist/test/matter/platform-matter.unregister.test.js.map +1 -0
- package/dist/test/matter/platform-matter.webhook.test.d.ts +2 -0
- package/dist/test/matter/platform-matter.webhook.test.d.ts.map +1 -0
- package/dist/test/matter/platform-matter.webhook.test.js +46 -0
- package/dist/test/matter/platform-matter.webhook.test.js.map +1 -0
- package/dist/test/utils.test.d.ts +2 -0
- package/dist/test/utils.test.d.ts.map +1 -0
- package/dist/test/utils.test.js +95 -0
- package/dist/test/utils.test.js.map +1 -0
- package/dist/test/verifyconfig.test.d.ts.map +1 -0
- package/dist/{verifyconfig.test.js → test/verifyconfig.test.js} +2 -2
- package/dist/test/verifyconfig.test.js.map +1 -0
- package/dist/utils.d.ts +204 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +713 -33
- package/dist/utils.js.map +1 -1
- package/docs/assets/highlight.css +14 -0
- package/docs/assets/main.js +2 -2
- package/docs/index.html +31 -2
- package/docs/variables/default.html +1 -1
- package/package.json +15 -15
- package/src/devices-hap/airpurifier.ts +11 -6
- package/src/devices-hap/blindtilt.ts +3 -3
- package/src/devices-hap/bot.ts +15 -5
- package/src/devices-hap/ceilinglight.ts +12 -7
- package/src/devices-hap/colorbulb.ts +46 -10
- package/src/devices-hap/contact.ts +3 -3
- package/src/devices-hap/curtain.ts +2 -2
- package/src/devices-hap/device.ts +149 -70
- package/src/devices-hap/fan.ts +11 -6
- package/src/devices-hap/hub.ts +6 -5
- package/src/devices-hap/humidifier.ts +97 -4
- package/src/devices-hap/iosensor.ts +36 -21
- package/src/devices-hap/lightstrip.ts +35 -8
- package/src/devices-hap/lock.ts +13 -6
- package/src/devices-hap/meter.ts +6 -5
- package/src/devices-hap/meterplus.ts +6 -5
- package/src/devices-hap/meterpro.ts +7 -6
- package/src/devices-hap/motion.ts +3 -3
- package/src/devices-hap/plug.ts +10 -6
- package/src/devices-hap/relayswitch.ts +3 -3
- package/src/devices-hap/robotvacuumcleaner.ts +12 -6
- package/src/devices-hap/waterdetector.ts +3 -3
- package/src/devices-matter/BaseMatterAccessory.ts +176 -5
- package/src/devices-matter/ColorLightAccessory.ts +12 -12
- package/src/devices-matter/ColorTemperatureLightAccessory.ts +5 -7
- package/src/devices-matter/DimmableLightAccessory.ts +9 -9
- package/src/devices-matter/ExtendedColorLightAccessory.ts +14 -15
- package/src/devices-matter/OnOffLightAccessory.ts +8 -16
- package/src/devices-matter/OnOffOutletAccessory.ts +12 -7
- package/src/devices-matter/OnOffSwitchAccessory.ts +2 -2
- package/src/devices-matter/RoboticVacuumAccessory.ts +340 -313
- package/src/homebridge-ui/public/index.html +200 -18
- package/src/homebridge-ui/server.ts +0 -34
- package/src/index.ts +4 -7
- package/src/irdevice/irdevice.ts +74 -35
- package/src/platform-hap.ts +365 -169
- package/src/platform-matter.ts +1872 -229
- package/src/settings.ts +62 -3
- package/src/test/apiRequestTracker.test.ts +417 -0
- package/src/test/hap/device-webhook-context.test.ts +136 -0
- package/src/test/hap/platform-hap.logging.test.ts +36 -0
- package/src/test/hap/platform-hap.test.ts +70 -0
- package/src/test/helpers/platform-fixtures.ts +33 -0
- package/src/test/homebridge-ui/server.test.ts +486 -0
- package/src/test/index.test.ts +24 -0
- package/src/test/matter/devices-matter/baseMatterAccessory.test.ts +88 -0
- package/src/test/matter/devices-matter/roboticVacuumAccessory.test.ts +453 -0
- package/src/test/matter/platform-matter.additional.test.ts +44 -0
- package/src/test/matter/platform-matter.bleparse.test.ts +47 -0
- package/src/test/matter/platform-matter.cleanup.test.ts +86 -0
- package/src/test/matter/platform-matter.keepstale.test.ts +37 -0
- package/src/test/matter/platform-matter.logging.test.ts +33 -0
- package/src/test/matter/platform-matter.mapping.test.ts +57 -0
- package/src/test/matter/platform-matter.openapi-mapping.test.ts +109 -0
- package/src/test/matter/platform-matter.test.ts +144 -0
- package/src/test/matter/platform-matter.unregister.test.ts +39 -0
- package/src/test/matter/platform-matter.webhook.test.ts +54 -0
- package/src/test/utils.test.ts +96 -0
- package/src/{verifyconfig.test.ts → test/verifyconfig.test.ts} +12 -11
- package/src/utils.ts +777 -36
- package/dist/index.test.js +0 -14
- package/dist/index.test.js.map +0 -1
- package/dist/verifyconfig.test.d.ts.map +0 -1
- package/dist/verifyconfig.test.js.map +0 -1
- package/src/index.test.ts +0 -19
- /package/dist/{index.test.d.ts → test/index.test.d.ts} +0 -0
- /package/dist/{verifyconfig.test.d.ts → test/verifyconfig.test.d.ts} +0 -0
|
@@ -1,75 +1,93 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
2
|
import { BaseMatterAccessory } from './BaseMatterAccessory.js';
|
|
3
|
+
function detectModelFromContext(ctx) {
|
|
4
|
+
const t = ctx?.deviceType?.trim();
|
|
5
|
+
switch (t) {
|
|
6
|
+
case 'Robot Vacuum Cleaner S1':
|
|
7
|
+
return 'S1';
|
|
8
|
+
case 'Robot Vacuum Cleaner S1 Plus':
|
|
9
|
+
return 'S1 Plus';
|
|
10
|
+
case 'Robot Vacuum Cleaner S1 Pro':
|
|
11
|
+
return 'S1 Pro';
|
|
12
|
+
case 'Robot Vacuum Cleaner S1 Mini':
|
|
13
|
+
return 'S1 Mini';
|
|
14
|
+
case 'WoSweeper':
|
|
15
|
+
return 'WoSweeper';
|
|
16
|
+
case 'WoSweeperMini':
|
|
17
|
+
return 'WoSweeperMini';
|
|
18
|
+
case 'K10+':
|
|
19
|
+
return 'K10+';
|
|
20
|
+
case 'K10+ Pro':
|
|
21
|
+
return 'K10+ Pro';
|
|
22
|
+
case 'Robot Vacuum Cleaner K10+ Pro Combo':
|
|
23
|
+
case 'K10+ Pro Combo':
|
|
24
|
+
return 'K10+ Pro Combo';
|
|
25
|
+
case 'Robot Vacuum Cleaner S10':
|
|
26
|
+
return 'S10';
|
|
27
|
+
case 'Robot Vacuum Cleaner S20':
|
|
28
|
+
case 'S20':
|
|
29
|
+
return 'S20';
|
|
30
|
+
case 'Robot Vacuum Cleaner K11+':
|
|
31
|
+
case 'K11+':
|
|
32
|
+
return 'K11+';
|
|
33
|
+
case 'Robot Vacuum Cleaner K20 Plus Pro':
|
|
34
|
+
case 'K20+ Pro':
|
|
35
|
+
return 'K20+ Pro';
|
|
36
|
+
default:
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function capabilitiesFor(model) {
|
|
41
|
+
// Defaults: conservative basic vac
|
|
42
|
+
if (!model) {
|
|
43
|
+
return { pause: false, resume: false, cleanAction: 'vacuum-only', suctionKind: 'powLevel-0-3', waterLevel: false };
|
|
44
|
+
}
|
|
45
|
+
// Basic vacuum models (S1 family, WoSweeper family, K10 family without Combo)
|
|
46
|
+
if (model === 'S1' || model === 'S1 Plus' || model === 'S1 Pro' || model === 'S1 Mini'
|
|
47
|
+
|| model === 'WoSweeper' || model === 'WoSweeperMini'
|
|
48
|
+
|| model === 'K10+' || model === 'K10+ Pro') {
|
|
49
|
+
return { pause: false, resume: false, cleanAction: 'vacuum-only', suctionKind: 'powLevel-0-3', waterLevel: false };
|
|
50
|
+
}
|
|
51
|
+
// K10+ Pro Combo: vacuum or mop, fanLevel, no waterLevel
|
|
52
|
+
if (model === 'K10+ Pro Combo') {
|
|
53
|
+
return { pause: true, resume: false, cleanAction: 'vacuum-or-mop', suctionKind: 'fanLevel-1-4', waterLevel: false };
|
|
54
|
+
}
|
|
55
|
+
// S10/S20: vacuum or vacuum+mop combo, fanLevel, waterLevel, plus advanced commands
|
|
56
|
+
if (model === 'S10' || model === 'S20') {
|
|
57
|
+
return {
|
|
58
|
+
pause: true,
|
|
59
|
+
resume: false,
|
|
60
|
+
cleanAction: 'vacuum-or-vacmop',
|
|
61
|
+
suctionKind: 'fanLevel-1-4',
|
|
62
|
+
waterLevel: true,
|
|
63
|
+
advancedCommands: {
|
|
64
|
+
setVolume: true,
|
|
65
|
+
selfClean: true,
|
|
66
|
+
addWaterForHumi: true,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// K11+/K20+ Pro: vacuum or mop, fanLevel, waterLevel, volume control
|
|
71
|
+
return {
|
|
72
|
+
pause: true,
|
|
73
|
+
resume: false,
|
|
74
|
+
cleanAction: 'vacuum-or-mop',
|
|
75
|
+
suctionKind: 'fanLevel-1-4',
|
|
76
|
+
waterLevel: true,
|
|
77
|
+
advancedCommands: {
|
|
78
|
+
setVolume: true,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
3
82
|
export class RoboticVacuumAccessory extends BaseMatterAccessory {
|
|
4
|
-
|
|
83
|
+
// Track current high-level preferences that affect OpenAPI payloads
|
|
84
|
+
currentCleanAction = 'vacuum';
|
|
85
|
+
currentFanLevel = 2;
|
|
86
|
+
capabilities;
|
|
5
87
|
constructor(api, log, opts) {
|
|
6
88
|
const serialNumber = opts?.serialNumber ?? 'VACUUM-001';
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
status: 0,
|
|
10
|
-
order: 0,
|
|
11
|
-
description: 'Battery',
|
|
12
|
-
batPercentRemaining: 100,
|
|
13
|
-
batChargeLevel: 2,
|
|
14
|
-
batReplaceability: 1,
|
|
15
|
-
},
|
|
16
|
-
rvcRunMode: {
|
|
17
|
-
supportedModes: [
|
|
18
|
-
{ label: 'Idle', mode: 0, modeTags: [{ value: 16384 }] },
|
|
19
|
-
{ label: 'Cleaning', mode: 1, modeTags: [{ value: 16385 }] },
|
|
20
|
-
{ label: 'Mapping', mode: 2, modeTags: [{ value: 16386 }] },
|
|
21
|
-
],
|
|
22
|
-
currentMode: 0,
|
|
23
|
-
},
|
|
24
|
-
rvcCleanMode: {
|
|
25
|
-
supportedModes: [
|
|
26
|
-
{ label: 'Vacuum', mode: 0, modeTags: [{ value: 16385 }] },
|
|
27
|
-
{ label: 'Mop', mode: 1, modeTags: [{ value: 16386 }] },
|
|
28
|
-
{ label: 'Vacuum & Mop', mode: 2, modeTags: [{ value: 16385 }, { value: 16386 }] },
|
|
29
|
-
{ label: 'Deep Clean', mode: 3, modeTags: [{ value: 16384 }] },
|
|
30
|
-
{ label: 'Deep Vacuum', mode: 4, modeTags: [{ value: 16384 }, { value: 16385 }] },
|
|
31
|
-
{ label: 'Deep Mop', mode: 5, modeTags: [{ value: 16384 }, { value: 16386 }] },
|
|
32
|
-
{ label: 'Quick Clean', mode: 6, modeTags: [{ value: 1 }, { value: 16385 }] },
|
|
33
|
-
{ label: 'Max Clean', mode: 7, modeTags: [{ value: 7 }, { value: 16385 }] },
|
|
34
|
-
{ label: 'Min Clean', mode: 8, modeTags: [{ value: 6 }, { value: 16385 }] },
|
|
35
|
-
{ label: 'Quiet Vacuum', mode: 9, modeTags: [{ value: 2 }, { value: 16385 }] },
|
|
36
|
-
{ label: 'Quiet Mop', mode: 10, modeTags: [{ value: 2 }, { value: 16386 }] },
|
|
37
|
-
{ label: 'Night Mode', mode: 11, modeTags: [{ value: 8 }, { value: 16385 }] },
|
|
38
|
-
{ label: 'Eco Vacuum', mode: 12, modeTags: [{ value: 4 }, { value: 16385 }] },
|
|
39
|
-
{ label: 'Eco Mop', mode: 13, modeTags: [{ value: 4 }, { value: 16386 }] },
|
|
40
|
-
{ label: 'Auto', mode: 14, modeTags: [{ value: 0 }, { value: 16385 }] },
|
|
41
|
-
],
|
|
42
|
-
currentMode: 0,
|
|
43
|
-
},
|
|
44
|
-
rvcOperationalState: {
|
|
45
|
-
operationalStateList: [
|
|
46
|
-
{ operationalStateId: 0 },
|
|
47
|
-
{ operationalStateId: 1 },
|
|
48
|
-
{ operationalStateId: 2 },
|
|
49
|
-
{ operationalStateId: 3 },
|
|
50
|
-
{ operationalStateId: 64 },
|
|
51
|
-
{ operationalStateId: 65 },
|
|
52
|
-
{ operationalStateId: 66 },
|
|
53
|
-
],
|
|
54
|
-
operationalState: 66,
|
|
55
|
-
},
|
|
56
|
-
serviceArea: {
|
|
57
|
-
supportedMaps: [],
|
|
58
|
-
supportedAreas: [
|
|
59
|
-
{ areaId: 0, mapId: null, areaInfo: { locationInfo: { locationName: 'Living Room', floorNumber: 0, areaType: 7 }, landmarkInfo: null } },
|
|
60
|
-
{ areaId: 1, mapId: null, areaInfo: { locationInfo: { locationName: 'Kitchen', floorNumber: 0, areaType: 10 }, landmarkInfo: null } },
|
|
61
|
-
{ areaId: 2, mapId: null, areaInfo: { locationInfo: { locationName: 'Bedroom', floorNumber: 0, areaType: 2 }, landmarkInfo: null } },
|
|
62
|
-
{ areaId: 3, mapId: null, areaInfo: { locationInfo: { locationName: 'Bathroom', floorNumber: 0, areaType: 6 }, landmarkInfo: null } },
|
|
63
|
-
],
|
|
64
|
-
selectedAreas: [0, 1, 2, 3],
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
const handlers = opts?.handlers ?? {
|
|
68
|
-
rvcRunMode: { changeToMode: async (request) => this.handleChangeRunMode(request) },
|
|
69
|
-
rvcCleanMode: { changeToMode: async (request) => this.handleChangeCleanMode(request) },
|
|
70
|
-
rvcOperationalState: { pause: async () => this.handlePause(), stop: async () => this.handleStop(), start: async () => this.handleStart(), resume: async () => this.handleResume(), goHome: async () => this.handleGoHome() },
|
|
71
|
-
serviceArea: { selectAreas: async (request) => this.handleSelectAreas(request), skipArea: async (request) => this.handleSkipArea(request) },
|
|
72
|
-
};
|
|
89
|
+
const model = detectModelFromContext(opts?.context);
|
|
90
|
+
const capabilities = capabilitiesFor(model);
|
|
73
91
|
super(api, log, {
|
|
74
92
|
uuid: opts?.uuid ?? api.matter.uuid.generate(serialNumber),
|
|
75
93
|
displayName: opts?.displayName ?? 'Robot Vacuum',
|
|
@@ -79,188 +97,218 @@ export class RoboticVacuumAccessory extends BaseMatterAccessory {
|
|
|
79
97
|
model: opts?.model ?? 'HB-MATTER-VACUUM-ROBOTIC',
|
|
80
98
|
firmwareRevision: opts?.firmwareRevision ?? '2.0.0',
|
|
81
99
|
hardwareRevision: opts?.hardwareRevision ?? '1.0.0',
|
|
82
|
-
clusters
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
clusters: {
|
|
101
|
+
rvcRunMode: {
|
|
102
|
+
supportedModes: [
|
|
103
|
+
{ label: 'Idle', mode: 0, modeTags: [{ value: 16384 }] },
|
|
104
|
+
{ label: 'Cleaning', mode: 1, modeTags: [{ value: 16385 }] },
|
|
105
|
+
],
|
|
106
|
+
currentMode: 0,
|
|
107
|
+
},
|
|
108
|
+
rvcCleanMode: (() => {
|
|
109
|
+
if (capabilities.cleanAction === 'vacuum-only') {
|
|
110
|
+
return {
|
|
111
|
+
supportedModes: [
|
|
112
|
+
{ label: 'Quiet', mode: 0, modeTags: [{ value: 2 }] },
|
|
113
|
+
{ label: 'Standard', mode: 1, modeTags: [{ value: 16384 }] },
|
|
114
|
+
{ label: 'Strong', mode: 2, modeTags: [{ value: 7 }] },
|
|
115
|
+
{ label: 'MAX', mode: 3, modeTags: [{ value: 8 }] },
|
|
116
|
+
],
|
|
117
|
+
currentMode: 1,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
else if (capabilities.cleanAction === 'vacuum-or-mop') {
|
|
121
|
+
return {
|
|
122
|
+
supportedModes: [
|
|
123
|
+
{ label: 'Vacuum', mode: 0, modeTags: [{ value: 16385 }] },
|
|
124
|
+
{ label: 'Mop', mode: 1, modeTags: [{ value: 16386 }] },
|
|
125
|
+
],
|
|
126
|
+
currentMode: 0,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return {
|
|
131
|
+
supportedModes: [
|
|
132
|
+
{ label: 'Vacuum', mode: 0, modeTags: [{ value: 16385 }] },
|
|
133
|
+
{ label: 'Vacuum & Mop', mode: 1, modeTags: [{ value: 16385 }, { value: 16386 }] },
|
|
134
|
+
],
|
|
135
|
+
currentMode: 0,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
})(),
|
|
139
|
+
rvcOperationalState: {
|
|
140
|
+
operationalStateList: [
|
|
141
|
+
{ operationalStateId: 0 }, // Stopped
|
|
142
|
+
{ operationalStateId: 1 }, // Running
|
|
143
|
+
{ operationalStateId: 2 }, // Paused
|
|
144
|
+
{ operationalStateId: 64 }, // Seeking Charger
|
|
145
|
+
{ operationalStateId: 65 }, // Charging
|
|
146
|
+
{ operationalStateId: 66 }, // Docked
|
|
147
|
+
],
|
|
148
|
+
operationalState: 66,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
handlers: (() => {
|
|
152
|
+
const opHandlers = {
|
|
153
|
+
stop: async () => this.handleStop(),
|
|
154
|
+
start: async () => this.handleStart(),
|
|
155
|
+
goHome: async () => this.handleGoHome(),
|
|
156
|
+
};
|
|
157
|
+
if (capabilities.pause) {
|
|
158
|
+
opHandlers.pause = async () => this.handlePause();
|
|
159
|
+
}
|
|
160
|
+
if (capabilities.resume) {
|
|
161
|
+
opHandlers.resume = async () => this.handleResume();
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
rvcRunMode: { changeToMode: async (request) => this.handleChangeRunMode(request) },
|
|
165
|
+
rvcCleanMode: { changeToMode: async (request) => this.handleChangeCleanMode(request) },
|
|
166
|
+
rvcOperationalState: opHandlers,
|
|
167
|
+
};
|
|
168
|
+
})(),
|
|
169
|
+
context: { deviceId: opts?.deviceId, ...(opts?.context ?? {}), deviceType: opts?.context?.deviceType },
|
|
85
170
|
});
|
|
171
|
+
this.capabilities = capabilities;
|
|
86
172
|
this.logInfo('initialized and ready.');
|
|
87
173
|
}
|
|
88
174
|
async handleChangeRunMode(request) {
|
|
89
175
|
this.logInfo(`ChangeToMode (run) request received: ${JSON.stringify(request)}`);
|
|
90
176
|
const { newMode } = request;
|
|
91
|
-
const modeStr = ['Idle', 'Cleaning'
|
|
177
|
+
const modeStr = ['Idle', 'Cleaning'][newMode] || `Unknown (mode=${newMode})`;
|
|
92
178
|
this.logInfo(`changing run mode to: ${modeStr}`);
|
|
93
|
-
// TODO: await myVacuumAPI.setRunMode(newMode)
|
|
94
|
-
// Clear any existing timers
|
|
95
|
-
this.clearTimers();
|
|
96
179
|
if (newMode === 1) {
|
|
97
|
-
|
|
98
|
-
this.updateOperationalState(1); // Running
|
|
99
|
-
// Simulate cleaning completion after 15 seconds
|
|
100
|
-
const completionTimer = setTimeout(() => {
|
|
101
|
-
this.logInfo('cleaning completed, returning to dock.');
|
|
102
|
-
this.updateRunMode(0); // Set to Idle - cleaning session ending
|
|
103
|
-
this.returnToDock();
|
|
104
|
-
}, 15000);
|
|
105
|
-
this.activeTimers.push(completionTimer);
|
|
180
|
+
await this.handleStart();
|
|
106
181
|
}
|
|
107
182
|
else if (newMode === 0) {
|
|
108
|
-
|
|
109
|
-
this.returnToDock();
|
|
110
|
-
}
|
|
111
|
-
else if (newMode === 2) {
|
|
112
|
-
// Switching to Mapping mode - start mapping
|
|
113
|
-
this.updateOperationalState(1); // Running
|
|
114
|
-
// Simulate mapping completion after 20 seconds
|
|
115
|
-
const completionTimer = setTimeout(() => {
|
|
116
|
-
this.logInfo('mapping completed, returning to dock.');
|
|
117
|
-
this.returnToDock();
|
|
118
|
-
}, 20000);
|
|
119
|
-
this.activeTimers.push(completionTimer);
|
|
183
|
+
await this.handleGoHome();
|
|
120
184
|
}
|
|
121
185
|
}
|
|
122
186
|
async handleChangeCleanMode(request) {
|
|
123
187
|
this.logInfo(`ChangeToMode (clean) request received: ${JSON.stringify(request)}`);
|
|
124
188
|
const { newMode } = request;
|
|
125
|
-
|
|
126
|
-
'
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
'
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
'
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
189
|
+
if (this.capabilities.cleanAction === 'vacuum-only') {
|
|
190
|
+
const mapPow = ['Quiet', 'Standard', 'Strong', 'MAX'];
|
|
191
|
+
const label = mapPow[newMode] ?? `Unknown (${newMode})`;
|
|
192
|
+
this.logInfo(`changing suction level to: ${label}`);
|
|
193
|
+
if (this.capabilities.suctionKind === 'powLevel-0-3') {
|
|
194
|
+
try {
|
|
195
|
+
this.logInfo(`[OpenAPI] Sending PowLevel: ${newMode}`);
|
|
196
|
+
await this.sendOpenAPICommand('PowLevel', String(newMode));
|
|
197
|
+
this.logInfo(`[OpenAPI] PowLevel command sent: ${newMode}`);
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
this.logWarn(`OpenAPI PowLevel failed: ${String(e?.message ?? e)}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else if (this.capabilities.suctionKind === 'fanLevel-1-4') {
|
|
204
|
+
this.currentFanLevel = (Math.min(3, Math.max(0, Number(newMode))) + 1);
|
|
205
|
+
try {
|
|
206
|
+
this.logInfo(`[OpenAPI] Sending changeParam fanLevel: ${this.currentFanLevel}`);
|
|
207
|
+
await this.sendOpenAPICommand('changeParam', JSON.stringify({ fanLevel: this.currentFanLevel }));
|
|
208
|
+
this.logInfo(`[OpenAPI] changeParam command sent: fanLevel=${this.currentFanLevel}`);
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
this.logWarn(`OpenAPI changeParam(fanLevel) failed: ${String(e?.message ?? e)}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
this.updateCleanMode(newMode);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (this.capabilities.cleanAction === 'vacuum-or-mop') {
|
|
218
|
+
const label = newMode === 0 ? 'Vacuum' : 'Mop';
|
|
219
|
+
this.currentCleanAction = newMode === 0 ? 'vacuum' : 'mop';
|
|
220
|
+
this.logInfo(`changing clean action to: ${label}`);
|
|
221
|
+
this.logInfo(`[OpenAPI] (no command sent for cleanAction change, just updating state)`);
|
|
222
|
+
this.updateCleanMode(newMode);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const label = newMode === 0 ? 'Vacuum' : 'Vacuum & Mop';
|
|
226
|
+
this.currentCleanAction = newMode === 0 ? 'vacuum' : 'vacuum_mop';
|
|
227
|
+
this.logInfo(`changing clean action to: ${label}`);
|
|
228
|
+
this.logInfo(`[OpenAPI] (no command sent for cleanAction change, just updating state)`);
|
|
229
|
+
this.updateCleanMode(newMode);
|
|
145
230
|
}
|
|
146
231
|
async handlePause() {
|
|
147
232
|
this.logInfo('pausing.');
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
233
|
+
try {
|
|
234
|
+
this.logInfo(`[OpenAPI] Sending pause command`);
|
|
235
|
+
await this.sendOpenAPICommand('pause');
|
|
236
|
+
this.logInfo(`[OpenAPI] pause command sent`);
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
this.logWarn(`OpenAPI pause failed: ${String(e?.message ?? e)}`);
|
|
240
|
+
}
|
|
241
|
+
this.updateOperationalState(2);
|
|
151
242
|
}
|
|
152
243
|
async handleStop() {
|
|
153
244
|
this.logInfo('stopping.');
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
245
|
+
try {
|
|
246
|
+
if (this.capabilities.cleanAction === 'vacuum-only' && this.capabilities.suctionKind === 'powLevel-0-3') {
|
|
247
|
+
this.logInfo(`[OpenAPI] Sending stop command`);
|
|
248
|
+
await this.sendOpenAPICommand('stop');
|
|
249
|
+
this.logInfo(`[OpenAPI] stop command sent`);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
this.logInfo(`[OpenAPI] Sending pause command (for stop)`);
|
|
253
|
+
await this.sendOpenAPICommand('pause');
|
|
254
|
+
this.logInfo(`[OpenAPI] pause command sent (for stop)`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (e) {
|
|
258
|
+
this.logWarn(`OpenAPI stop/pause failed: ${String(e?.message ?? e)}`);
|
|
259
|
+
}
|
|
260
|
+
this.updateRunMode(0);
|
|
261
|
+
this.updateOperationalState(0);
|
|
158
262
|
}
|
|
159
263
|
async handleStart() {
|
|
160
|
-
this.logInfo('starting
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
264
|
+
this.logInfo('starting clean.');
|
|
265
|
+
try {
|
|
266
|
+
if (this.capabilities.cleanAction === 'vacuum-only' && this.capabilities.suctionKind === 'powLevel-0-3') {
|
|
267
|
+
this.logInfo(`[OpenAPI] Sending start command`);
|
|
268
|
+
await this.sendOpenAPICommand('start');
|
|
269
|
+
this.logInfo(`[OpenAPI] start command sent`);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
const action = this.currentCleanAction === 'vacuum_mop' ? 'sweep_mop' : this.currentCleanAction;
|
|
273
|
+
const param = { action, param: { fanLevel: this.currentFanLevel } };
|
|
274
|
+
if (this.capabilities.waterLevel) {
|
|
275
|
+
param.param.waterLevel = 1;
|
|
276
|
+
}
|
|
277
|
+
this.logInfo(`[OpenAPI] Sending startClean: ${JSON.stringify(param)}`);
|
|
278
|
+
await this.sendOpenAPICommand('startClean', JSON.stringify(param));
|
|
279
|
+
this.logInfo(`[OpenAPI] startClean command sent: ${JSON.stringify(param)}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch (e) {
|
|
283
|
+
this.logWarn(`OpenAPI start/startClean failed: ${String(e?.message ?? e)}`);
|
|
284
|
+
}
|
|
285
|
+
this.updateRunMode(1);
|
|
286
|
+
this.updateOperationalState(1);
|
|
173
287
|
}
|
|
174
288
|
async handleResume() {
|
|
175
|
-
this.logInfo('
|
|
176
|
-
|
|
177
|
-
// Clear any existing timers
|
|
178
|
-
this.clearTimers();
|
|
179
|
-
this.updateRunMode(1); // Set to Cleaning mode
|
|
180
|
-
this.updateOperationalState(1); // Running
|
|
181
|
-
// Simulate cleaning completion after 10 seconds (shorter since resuming)
|
|
182
|
-
const completionTimer = setTimeout(() => {
|
|
183
|
-
this.logInfo('cleaning completed, returning to dock.');
|
|
184
|
-
this.updateRunMode(0); // Set to Idle - cleaning session ending
|
|
185
|
-
this.returnToDock();
|
|
186
|
-
}, 10000);
|
|
187
|
-
this.activeTimers.push(completionTimer);
|
|
289
|
+
this.logInfo('resume requested.');
|
|
290
|
+
await this.handleStart();
|
|
188
291
|
}
|
|
189
292
|
async handleGoHome() {
|
|
190
|
-
this.logInfo('
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
this.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
async handleSelectAreas(request) {
|
|
203
|
-
this.logInfo(`SelectAreas request received: ${JSON.stringify(request)}`);
|
|
204
|
-
const { newAreas } = request;
|
|
205
|
-
const areaNames = newAreas.map((id) => ['Living Room', 'Kitchen', 'Bedroom', 'Bathroom'][id] || `Area ${id}`);
|
|
206
|
-
this.logInfo(`selecting areas: ${areaNames.join(', ')}`);
|
|
207
|
-
// TODO: await myVacuumAPI.selectAreas(newAreas)
|
|
208
|
-
}
|
|
209
|
-
async handleSkipArea(request) {
|
|
210
|
-
this.logInfo(`SkipArea request received: ${JSON.stringify(request)}`);
|
|
211
|
-
const { skippedArea } = request;
|
|
212
|
-
const areaName = ['Living Room', 'Kitchen', 'Bedroom', 'Bathroom'][skippedArea] || `Area ${skippedArea}`;
|
|
213
|
-
this.logInfo(`skipping area: ${areaName}`);
|
|
214
|
-
// TODO: await myVacuumAPI.skipArea(skippedArea)
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Helper method to clear all active timers
|
|
218
|
-
*/
|
|
219
|
-
clearTimers() {
|
|
220
|
-
this.activeTimers.forEach(timer => clearTimeout(timer));
|
|
221
|
-
this.activeTimers = [];
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Helper method to initiate return to dock sequence
|
|
225
|
-
* Can be called synchronously from other handlers
|
|
226
|
-
*/
|
|
227
|
-
returnToDock() {
|
|
228
|
-
this.logInfo('initiating return to dock sequence.');
|
|
229
|
-
// Defer ALL state updates to ensure handler completes first
|
|
230
|
-
setImmediate(() => {
|
|
231
|
-
// Start seeking charger directly (skip intermediate Stopped state)
|
|
232
|
-
this.updateOperationalState(64); // Seeking Charger
|
|
233
|
-
// After 5 seconds, start charging
|
|
234
|
-
const chargingTimer = setTimeout(() => {
|
|
235
|
-
this.logInfo('reached dock, now charging.');
|
|
236
|
-
this.updateOperationalState(65); // Charging
|
|
237
|
-
// After 3 more seconds, fully docked
|
|
238
|
-
const dockedTimer = setTimeout(() => {
|
|
239
|
-
this.logInfo('fully charged and docked.');
|
|
240
|
-
this.updateOperationalState(66); // Docked
|
|
241
|
-
}, 3000);
|
|
242
|
-
this.activeTimers.push(dockedTimer);
|
|
243
|
-
}, 5000);
|
|
244
|
-
this.activeTimers.push(chargingTimer);
|
|
245
|
-
});
|
|
293
|
+
this.logInfo('returning to dock.');
|
|
294
|
+
try {
|
|
295
|
+
this.logInfo(`[OpenAPI] Sending dock command`);
|
|
296
|
+
await this.sendOpenAPICommand('dock');
|
|
297
|
+
this.logInfo(`[OpenAPI] dock command sent`);
|
|
298
|
+
}
|
|
299
|
+
catch (e) {
|
|
300
|
+
this.logWarn(`OpenAPI dock failed: ${String(e?.message ?? e)}`);
|
|
301
|
+
}
|
|
302
|
+
this.updateRunMode(0);
|
|
303
|
+
this.updateOperationalState(64);
|
|
246
304
|
}
|
|
247
|
-
/**
|
|
248
|
-
* Update Methods - Use these to update the vacuum state from your API/device
|
|
249
|
-
*
|
|
250
|
-
* Since this is a platform accessory, state updates work immediately after registration.
|
|
251
|
-
*/
|
|
252
305
|
updateOperationalState(state) {
|
|
253
306
|
this.updateState('rvcOperationalState', { operationalState: state });
|
|
254
307
|
const states = [
|
|
255
308
|
'Stopped',
|
|
256
309
|
'Running',
|
|
257
310
|
'Paused',
|
|
258
|
-
|
|
259
|
-
null,
|
|
260
|
-
null,
|
|
261
|
-
null,
|
|
262
|
-
null,
|
|
263
|
-
...Array.from({ length: 56 }).fill(null),
|
|
311
|
+
...Array.from({ length: 61 }).fill(null),
|
|
264
312
|
'Seeking Charger',
|
|
265
313
|
'Charging',
|
|
266
314
|
'Docked',
|
|
@@ -269,66 +317,43 @@ export class RoboticVacuumAccessory extends BaseMatterAccessory {
|
|
|
269
317
|
}
|
|
270
318
|
updateRunMode(mode) {
|
|
271
319
|
this.updateState('rvcRunMode', { currentMode: mode });
|
|
272
|
-
const modes = ['Idle', 'Cleaning'
|
|
320
|
+
const modes = ['Idle', 'Cleaning'];
|
|
273
321
|
this.logInfo(`run mode updated to: ${modes[mode] || `Unknown (${mode})`}`);
|
|
274
322
|
}
|
|
275
323
|
updateCleanMode(mode) {
|
|
276
324
|
this.updateState('rvcCleanMode', { currentMode: mode });
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
'
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
'
|
|
283
|
-
'Deep Mop',
|
|
284
|
-
'Quick Clean',
|
|
285
|
-
'Max Clean',
|
|
286
|
-
'Min Clean',
|
|
287
|
-
'Quiet Vacuum',
|
|
288
|
-
'Quiet Mop',
|
|
289
|
-
'Night Mode',
|
|
290
|
-
'Eco Vacuum',
|
|
291
|
-
'Eco Mop',
|
|
292
|
-
'Auto',
|
|
293
|
-
];
|
|
294
|
-
this.logInfo(`clean mode updated to: ${modes[mode] || `Unknown (${mode})`}`);
|
|
295
|
-
}
|
|
296
|
-
updateSelectedAreas(areaIds) {
|
|
297
|
-
this.updateState('serviceArea', { selectedAreas: areaIds });
|
|
298
|
-
const areaNames = areaIds.map(id => ['Living Room', 'Kitchen', 'Bedroom', 'Bathroom'][id] || `Area ${id}`);
|
|
299
|
-
this.logInfo(`selected areas updated to: ${areaNames.join(', ') || 'All Areas'}`);
|
|
300
|
-
}
|
|
301
|
-
updateCurrentArea(areaId) {
|
|
302
|
-
this.updateState('serviceArea', { currentArea: areaId });
|
|
303
|
-
if (areaId !== null) {
|
|
304
|
-
const areaName = ['Living Room', 'Kitchen', 'Bedroom', 'Bathroom'][areaId] || `Area ${areaId}`;
|
|
305
|
-
this.logInfo(`current area updated to: ${areaName}`);
|
|
325
|
+
let label = `Unknown (${mode})`;
|
|
326
|
+
if (this.capabilities.cleanAction === 'vacuum-only') {
|
|
327
|
+
label = ['Quiet', 'Standard', 'Strong', 'MAX'][mode] || label;
|
|
328
|
+
}
|
|
329
|
+
else if (this.capabilities.cleanAction === 'vacuum-or-mop') {
|
|
330
|
+
label = ['Vacuum', 'Mop'][mode] || label;
|
|
306
331
|
}
|
|
307
332
|
else {
|
|
308
|
-
|
|
333
|
+
label = ['Vacuum', 'Vacuum & Mop'][mode] || label;
|
|
309
334
|
}
|
|
310
|
-
|
|
311
|
-
updateProgress(progress) {
|
|
312
|
-
this.updateState('serviceArea', { progress });
|
|
313
|
-
this.logInfo(`progress updated: ${progress.length} areas`);
|
|
335
|
+
this.logInfo(`clean mode updated to: ${label}`);
|
|
314
336
|
}
|
|
315
337
|
/**
|
|
316
|
-
* Update battery percentage
|
|
317
|
-
* @param percentage - Battery percentage (0-100)
|
|
338
|
+
* Update battery percentage (no PowerSource cluster for this device type)
|
|
318
339
|
*/
|
|
319
|
-
async updateBatteryPercentage(
|
|
320
|
-
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
340
|
+
async updateBatteryPercentage(percentageOrBatPercentRemaining) {
|
|
341
|
+
const isBatPercent = Number(percentageOrBatPercentRemaining) > 100;
|
|
342
|
+
const percentage = isBatPercent
|
|
343
|
+
? Math.max(0, Math.min(100, Math.round(Number(percentageOrBatPercentRemaining) / 2)))
|
|
344
|
+
: Math.max(0, Math.min(100, Math.round(Number(percentageOrBatPercentRemaining))));
|
|
345
|
+
let chargeLevel = 0; // Ok
|
|
324
346
|
if (percentage < 20) {
|
|
325
|
-
|
|
347
|
+
chargeLevel = 2; // Critical
|
|
326
348
|
}
|
|
327
349
|
else if (percentage < 40) {
|
|
328
|
-
|
|
350
|
+
chargeLevel = 1; // Warning
|
|
351
|
+
}
|
|
352
|
+
this.logInfo(`battery status: ${percentage}% (${chargeLevel === 0 ? 'Ok' : chargeLevel === 1 ? 'Warning' : 'Critical'})`);
|
|
353
|
+
if (this.context) {
|
|
354
|
+
this.context.batteryPercentage = percentage;
|
|
355
|
+
this.context.batteryChargeLevel = chargeLevel;
|
|
329
356
|
}
|
|
330
|
-
await this.updateState('powerSource', { batPercentRemaining, batChargeLevel });
|
|
331
|
-
this.logInfo(`battery updated to: ${percentage}% (${batChargeLevel === 0 ? 'Ok' : batChargeLevel === 1 ? 'Warning' : 'Critical'})`);
|
|
332
357
|
}
|
|
333
358
|
}
|
|
334
359
|
//# sourceMappingURL=RoboticVacuumAccessory.js.map
|