@homebridge-plugins/homebridge-matter 0.1.1-beta.3 → 0.1.1-beta.5
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
CHANGED
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ This plugin provides example implementations of Matter device types in Homebridg
|
|
|
68
68
|
|
|
69
69
|
- To use this plugin, you will need to already have:
|
|
70
70
|
- [Node](https://nodejs.org): latest version of `v20`, `v22` or `v24` - any other major version is not supported.
|
|
71
|
-
- [Homebridge](https://homebridge.io): `>=2.0.0-alpha.
|
|
71
|
+
- [Homebridge](https://homebridge.io): `>=2.0.0-alpha.57 <2.0.0-beta.0` - refer to link for more information and installation instructions.
|
|
72
72
|
|
|
73
73
|
### Help/About
|
|
74
74
|
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
* }
|
|
51
51
|
* ```
|
|
52
52
|
*/
|
|
53
|
+
import { MatterTypes } from 'homebridge';
|
|
53
54
|
/**
|
|
54
55
|
* Registers a Robotic Vacuum Cleaner accessory.
|
|
55
56
|
*
|
|
@@ -81,163 +82,470 @@ export function registerRoboticVacuumCleaner(context) {
|
|
|
81
82
|
model: 'RobotVacuum v1',
|
|
82
83
|
// Matter clusters define the functionality of this device
|
|
83
84
|
// RVC devices require these three clusters: rvcRunMode, rvcOperationalState, rvcCleanMode
|
|
85
|
+
// Optional clusters: serviceArea (Matter 1.4+)
|
|
84
86
|
clusters: {
|
|
87
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
85
88
|
// RVC Run Mode Cluster (0x0054) - Defines operational modes
|
|
89
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
86
90
|
rvcRunMode: {
|
|
87
|
-
// Supported run modes
|
|
88
|
-
//
|
|
91
|
+
// Supported run modes with enhanced mode tags for better controller compatibility
|
|
92
|
+
// Mode tags help controllers understand the purpose and behavior of each mode
|
|
89
93
|
supportedModes: [
|
|
90
|
-
{
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
{
|
|
95
|
+
label: 'Idle',
|
|
96
|
+
mode: 0,
|
|
97
|
+
modeTags: [
|
|
98
|
+
{ value: MatterTypes.RvcRunMode.ModeTag.Idle },
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
label: 'Quick-Cleaning',
|
|
103
|
+
mode: 1,
|
|
104
|
+
modeTags: [
|
|
105
|
+
{ value: MatterTypes.RvcRunMode.ModeTag.Cleaning },
|
|
106
|
+
{ value: MatterTypes.ModeBase.ModeTag.Quick },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
label: 'Auto-Cleaning',
|
|
111
|
+
mode: 2,
|
|
112
|
+
modeTags: [
|
|
113
|
+
{ value: MatterTypes.RvcRunMode.ModeTag.Cleaning },
|
|
114
|
+
{ value: MatterTypes.ModeBase.ModeTag.Auto },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
label: 'Mapping',
|
|
119
|
+
mode: 3,
|
|
120
|
+
modeTags: [
|
|
121
|
+
{ value: MatterTypes.RvcRunMode.ModeTag.Mapping },
|
|
122
|
+
],
|
|
123
|
+
},
|
|
93
124
|
],
|
|
94
125
|
// Current mode - initial state
|
|
95
126
|
currentMode: 0, // Start in Idle mode
|
|
96
127
|
},
|
|
128
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
97
129
|
// RVC Operational State Cluster (0x0061) - Tracks current activity
|
|
130
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
98
131
|
rvcOperationalState: {
|
|
99
|
-
// List of all possible operational states
|
|
100
|
-
//
|
|
132
|
+
// List of all possible operational states with descriptive labels
|
|
133
|
+
// Labels help with debugging and may be displayed in some controllers
|
|
134
|
+
// Must include at least an error state (ID 3) per Matter spec
|
|
101
135
|
operationalStateList: [
|
|
102
|
-
{
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
136
|
+
{
|
|
137
|
+
operationalStateId: MatterTypes.RvcOperationalState.OperationalState.Stopped,
|
|
138
|
+
operationalStateLabel: 'Stopped',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
operationalStateId: MatterTypes.RvcOperationalState.OperationalState.Running,
|
|
142
|
+
operationalStateLabel: 'Running',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
operationalStateId: MatterTypes.RvcOperationalState.OperationalState.Paused,
|
|
146
|
+
operationalStateLabel: 'Paused',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
operationalStateId: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
150
|
+
operationalStateLabel: 'Error',
|
|
151
|
+
}, // REQUIRED by Matter spec
|
|
152
|
+
{
|
|
153
|
+
operationalStateId: MatterTypes.RvcOperationalState.OperationalState.SeekingCharger,
|
|
154
|
+
operationalStateLabel: 'Seeking Charger',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
operationalStateId: MatterTypes.RvcOperationalState.OperationalState.Charging,
|
|
158
|
+
operationalStateLabel: 'Charging',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
operationalStateId: MatterTypes.RvcOperationalState.OperationalState.Docked,
|
|
162
|
+
operationalStateLabel: 'Docked',
|
|
163
|
+
},
|
|
109
164
|
],
|
|
110
165
|
// Current operational state (just the ID number, not an object)
|
|
111
|
-
operationalState:
|
|
166
|
+
operationalState: MatterTypes.RvcOperationalState.OperationalState.Docked, // Start in Docked state
|
|
112
167
|
// Error state - indicates if device has an error
|
|
113
168
|
operationalError: {
|
|
114
|
-
errorStateId:
|
|
169
|
+
errorStateId: MatterTypes.OperationalState.ErrorState.NoError, // No error
|
|
170
|
+
errorStateLabel: '', // Empty when no error
|
|
115
171
|
},
|
|
116
172
|
},
|
|
173
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
117
174
|
// RVC Clean Mode Cluster (0x0055) - Defines cleaning method
|
|
175
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
118
176
|
rvcCleanMode: {
|
|
119
|
-
// Supported clean modes
|
|
120
|
-
//
|
|
177
|
+
// Supported clean modes with appropriate tags
|
|
178
|
+
// You can add more modes like Quiet, Turbo, Deep Clean, etc.
|
|
121
179
|
supportedModes: [
|
|
122
|
-
{
|
|
123
|
-
|
|
124
|
-
|
|
180
|
+
{
|
|
181
|
+
label: 'Vacuum',
|
|
182
|
+
mode: 0,
|
|
183
|
+
modeTags: [
|
|
184
|
+
{ value: MatterTypes.RvcCleanMode.ModeTag.Vacuum },
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
label: 'Mop',
|
|
189
|
+
mode: 1,
|
|
190
|
+
modeTags: [
|
|
191
|
+
{ value: MatterTypes.RvcCleanMode.ModeTag.Mop },
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
label: 'Vacuum & Mop',
|
|
196
|
+
mode: 2,
|
|
197
|
+
modeTags: [
|
|
198
|
+
{ value: MatterTypes.RvcCleanMode.ModeTag.Vacuum },
|
|
199
|
+
{ value: MatterTypes.RvcCleanMode.ModeTag.Mop }, // Both tags for combined mode
|
|
200
|
+
],
|
|
201
|
+
},
|
|
125
202
|
],
|
|
126
203
|
// Current clean mode - initial state
|
|
127
204
|
currentMode: 0, // Start with Vacuum mode
|
|
128
205
|
},
|
|
206
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
207
|
+
// Service Area Cluster (Matter 1.4+) - Zone/Room-based cleaning
|
|
208
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
209
|
+
//
|
|
210
|
+
// The Service Area cluster enables room/zone-specific cleaning, which is a key
|
|
211
|
+
// feature introduced in Matter 1.4. This allows users to:
|
|
212
|
+
// - Select specific rooms to clean from their Home app (iOS 18.4+)
|
|
213
|
+
// - Track which room is currently being cleaned
|
|
214
|
+
// - Define multiple cleaning zones/maps
|
|
215
|
+
//
|
|
216
|
+
// IMPORTANT: This cluster is OPTIONAL but highly recommended for modern RVC devices.
|
|
217
|
+
// Controllers that don't support it will simply not show room selection options.
|
|
218
|
+
serviceArea: {
|
|
219
|
+
// Define the rooms/areas available for cleaning
|
|
220
|
+
// Each area has metadata like name, floor number, and area type tags
|
|
221
|
+
supportedAreas: [
|
|
222
|
+
{
|
|
223
|
+
areaId: 0, // Unique ID for this area
|
|
224
|
+
mapId: null, // null = default map; use numbers for multiple floor plans
|
|
225
|
+
areaInfo: {
|
|
226
|
+
locationInfo: {
|
|
227
|
+
locationName: 'Kitchen',
|
|
228
|
+
floorNumber: 0, // Ground floor
|
|
229
|
+
areaType: 7, // Kitchen area type tag
|
|
230
|
+
},
|
|
231
|
+
landmarkInfo: null, // Optional: nearby landmarks
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
areaId: 1,
|
|
236
|
+
mapId: null,
|
|
237
|
+
areaInfo: {
|
|
238
|
+
locationInfo: {
|
|
239
|
+
locationName: 'Living Room',
|
|
240
|
+
floorNumber: 0,
|
|
241
|
+
areaType: 3, // Living room area type tag
|
|
242
|
+
},
|
|
243
|
+
landmarkInfo: null,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
areaId: 2,
|
|
248
|
+
mapId: null,
|
|
249
|
+
areaInfo: {
|
|
250
|
+
locationInfo: {
|
|
251
|
+
locationName: 'Bedroom',
|
|
252
|
+
floorNumber: 0,
|
|
253
|
+
areaType: 2, // Bedroom area type tag
|
|
254
|
+
},
|
|
255
|
+
landmarkInfo: null,
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
areaId: 3,
|
|
260
|
+
mapId: null,
|
|
261
|
+
areaInfo: {
|
|
262
|
+
locationInfo: {
|
|
263
|
+
locationName: 'Bathroom',
|
|
264
|
+
floorNumber: 0,
|
|
265
|
+
areaType: 6, // Bathroom area type tag
|
|
266
|
+
},
|
|
267
|
+
landmarkInfo: null,
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
// Areas selected for the next/current cleaning session
|
|
272
|
+
// Empty array = clean all areas
|
|
273
|
+
selectedAreas: [],
|
|
274
|
+
// Current area being cleaned (null when not cleaning)
|
|
275
|
+
currentArea: null,
|
|
276
|
+
// Progress information (optional but useful)
|
|
277
|
+
progress: [],
|
|
278
|
+
},
|
|
129
279
|
},
|
|
130
280
|
// Handlers respond to commands from Home apps (Apple Home, Google Home, etc.)
|
|
131
281
|
// These are called when users interact with the device in their Home app
|
|
132
282
|
handlers: {
|
|
283
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
133
284
|
// RVC Operational State handlers - control device operation
|
|
285
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
134
286
|
rvcOperationalState: {
|
|
135
287
|
/**
|
|
136
288
|
* pause() - Called when user presses "pause" in Home app
|
|
137
289
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
290
|
+
* Best practices:
|
|
291
|
+
* 1. Validate current state (can't pause if docked/charging)
|
|
292
|
+
* 2. Send command to physical device
|
|
293
|
+
* 3. Wait for confirmation
|
|
294
|
+
* 4. Update Matter state
|
|
295
|
+
* 5. Handle errors appropriately
|
|
142
296
|
*/
|
|
143
297
|
pause: async () => {
|
|
144
298
|
log.info('[Robot Vacuum] ✓ Handler `pause` called - Pausing cleaning');
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
299
|
+
try {
|
|
300
|
+
// TODO: Add validation - can we pause in current state?
|
|
301
|
+
// const currentState = accessory.clusters.rvcOperationalState.operationalState
|
|
302
|
+
// if (currentState === MatterTypes.RvcOperationalState.OperationalState.Charging ||
|
|
303
|
+
// currentState === MatterTypes.RvcOperationalState.OperationalState.Docked) {
|
|
304
|
+
// throw new Error('Cannot pause while docked or charging')
|
|
305
|
+
// }
|
|
306
|
+
// TODO: Send pause command to your actual robot vacuum
|
|
307
|
+
// Example: await yourVacuumAPI.pause()
|
|
308
|
+
// Update Matter state to reflect the change
|
|
309
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', { operationalState: MatterTypes.RvcOperationalState.OperationalState.Paused });
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
log.error('[Robot Vacuum] Failed to pause:', error);
|
|
313
|
+
// Update to error state
|
|
314
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
315
|
+
operationalState: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
316
|
+
operationalError: {
|
|
317
|
+
errorStateId: 1, // Generic error
|
|
318
|
+
errorStateLabel: 'Failed to pause vacuum',
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
}
|
|
151
322
|
},
|
|
152
323
|
/**
|
|
153
324
|
* resume() - Called when user presses "resume" or "start" in Home app
|
|
154
325
|
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* - Wait for confirmation
|
|
158
|
-
* - Then update the Matter state
|
|
326
|
+
* This should resume a paused cleaning session or start a new one.
|
|
327
|
+
* Make sure to validate the current state before resuming.
|
|
159
328
|
*/
|
|
160
329
|
resume: async () => {
|
|
161
330
|
log.info('[Robot Vacuum] ✓ Handler `resume` called - Resuming cleaning');
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
331
|
+
try {
|
|
332
|
+
// TODO: Add validation
|
|
333
|
+
// const currentState = accessory.clusters.rvcOperationalState.operationalState
|
|
334
|
+
// if (currentState === MatterTypes.RvcOperationalState.OperationalState.SeekingCharger) {
|
|
335
|
+
// throw new Error('Cannot resume while seeking charger')
|
|
336
|
+
// }
|
|
337
|
+
// TODO: Send resume command to your actual robot vacuum
|
|
338
|
+
// Example: await yourVacuumAPI.resume()
|
|
339
|
+
// Update Matter state to Running
|
|
340
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', { operationalState: MatterTypes.RvcOperationalState.OperationalState.Running });
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
log.error('[Robot Vacuum] Failed to resume:', error);
|
|
344
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
345
|
+
operationalState: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
346
|
+
operationalError: {
|
|
347
|
+
errorStateId: 1,
|
|
348
|
+
errorStateLabel: 'Failed to resume vacuum',
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
}
|
|
166
352
|
},
|
|
167
353
|
/**
|
|
168
354
|
* goHome() - Called when user sends robot to charging dock
|
|
169
355
|
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* - Wait for confirmation
|
|
173
|
-
* - Then update the Matter state
|
|
356
|
+
* This command should interrupt any current activity and return
|
|
357
|
+
* the vacuum to its charging station.
|
|
174
358
|
*/
|
|
175
359
|
goHome: async () => {
|
|
176
360
|
log.info('[Robot Vacuum] ✓ Handler `goHome` called - Returning to dock');
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
361
|
+
try {
|
|
362
|
+
// TODO: Send return-to-dock command to your actual robot vacuum
|
|
363
|
+
// Example: await yourVacuumAPI.returnToDock()
|
|
364
|
+
// Clear current area when returning home
|
|
365
|
+
api.matter.updateAccessoryState(uuid, 'serviceArea', {
|
|
366
|
+
currentArea: null,
|
|
367
|
+
});
|
|
368
|
+
// Update Matter state to SeekingCharger
|
|
369
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', { operationalState: MatterTypes.RvcOperationalState.OperationalState.SeekingCharger });
|
|
370
|
+
// TIP: Set up monitoring to track docking progress:
|
|
371
|
+
// - When vacuum reaches dock: update to Charging state
|
|
372
|
+
// - When fully charged: update to Docked state
|
|
373
|
+
// Example:
|
|
374
|
+
// await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
375
|
+
// operationalState: MatterTypes.RvcOperationalState.OperationalState.Charging
|
|
376
|
+
// })
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
log.error('[Robot Vacuum] Failed to return home:', error);
|
|
380
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
381
|
+
operationalState: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
382
|
+
operationalError: {
|
|
383
|
+
errorStateId: 1,
|
|
384
|
+
errorStateLabel: 'Failed to return to dock',
|
|
385
|
+
},
|
|
386
|
+
});
|
|
387
|
+
}
|
|
183
388
|
},
|
|
184
389
|
},
|
|
390
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
185
391
|
// RVC Run Mode handlers - change operational modes
|
|
392
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
186
393
|
rvcRunMode: {
|
|
187
394
|
/**
|
|
188
395
|
* changeToMode() - Called when user changes the run mode
|
|
189
396
|
*
|
|
190
|
-
* Modes:
|
|
397
|
+
* Run Modes:
|
|
398
|
+
* 0 = Idle - Device is inactive
|
|
399
|
+
* 1 = Quick-Cleaning - Single cleaning cycle
|
|
400
|
+
* 2 = Auto-Cleaning - Continuous/scheduled cleaning
|
|
401
|
+
* 3 = Mapping - Map the environment
|
|
191
402
|
*
|
|
192
|
-
*
|
|
193
|
-
* -
|
|
194
|
-
* -
|
|
195
|
-
* -
|
|
403
|
+
* Implementation notes:
|
|
404
|
+
* - Changing to a cleaning mode should start the vacuum
|
|
405
|
+
* - Changing to Idle should stop current activity
|
|
406
|
+
* - Update operational state accordingly
|
|
196
407
|
*/
|
|
197
408
|
changeToMode: async (request) => {
|
|
198
|
-
const modes = ['Idle', 'Cleaning', 'Mapping'];
|
|
409
|
+
const modes = ['Idle', 'Quick-Cleaning', 'Auto-Cleaning', 'Mapping'];
|
|
199
410
|
const modeName = modes[request.newMode] || `Unknown (${request.newMode})`;
|
|
200
|
-
log.info(`[Robot Vacuum] ✓ Handler \`changeToMode\` called: ${request.newMode} (${modeName})`);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
411
|
+
log.info(`[Robot Vacuum] ✓ Handler \`changeToMode\` (run mode) called: ${request.newMode} (${modeName})`);
|
|
412
|
+
try {
|
|
413
|
+
// TODO: Send mode change command to your actual robot vacuum
|
|
414
|
+
// Example:
|
|
415
|
+
// if (request.newMode === 0) {
|
|
416
|
+
// await yourVacuumAPI.stop()
|
|
417
|
+
// } else if (request.newMode === 1 || request.newMode === 2) {
|
|
418
|
+
// await yourVacuumAPI.startCleaning()
|
|
419
|
+
// } else if (request.newMode === 3) {
|
|
420
|
+
// await yourVacuumAPI.startMapping()
|
|
421
|
+
// }
|
|
422
|
+
// Update Matter state
|
|
423
|
+
return api.matter.updateAccessoryState(uuid, 'rvcRunMode', { currentMode: request.newMode });
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
log.error('[Robot Vacuum] Failed to change run mode:', error);
|
|
427
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
428
|
+
operationalState: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
429
|
+
operationalError: {
|
|
430
|
+
errorStateId: 1,
|
|
431
|
+
errorStateLabel: `Failed to change to ${modeName} mode`,
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
}
|
|
212
435
|
},
|
|
213
436
|
},
|
|
437
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
214
438
|
// RVC Clean Mode handlers - change cleaning method
|
|
439
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
215
440
|
rvcCleanMode: {
|
|
216
441
|
/**
|
|
217
442
|
* changeToMode() - Called when user changes the clean mode
|
|
218
443
|
*
|
|
219
|
-
* Modes:
|
|
444
|
+
* Clean Modes:
|
|
445
|
+
* 0 = Vacuum - Dry vacuuming only
|
|
446
|
+
* 1 = Mop - Wet mopping only
|
|
447
|
+
* 2 = Vacuum & Mop - Combined vacuum and mop
|
|
220
448
|
*
|
|
221
|
-
*
|
|
222
|
-
* - Send clean mode change command to your actual robot vacuum
|
|
223
|
-
* - Wait for confirmation
|
|
224
|
-
* - Then update the Matter state
|
|
449
|
+
* You can add additional modes like Quiet, Turbo, Deep Clean, etc.
|
|
225
450
|
*/
|
|
226
451
|
changeToMode: async (request) => {
|
|
227
452
|
const modes = ['Vacuum', 'Mop', 'Vacuum & Mop'];
|
|
228
453
|
const modeName = modes[request.newMode] || `Unknown (${request.newMode})`;
|
|
229
454
|
log.info(`[Robot Vacuum] ✓ Handler \`changeToMode\` (clean mode) called: ${request.newMode} (${modeName})`);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
455
|
+
try {
|
|
456
|
+
// TODO: Send clean mode change to your actual robot vacuum
|
|
457
|
+
// Example:
|
|
458
|
+
// if (request.newMode === 0) {
|
|
459
|
+
// await yourVacuumAPI.setCleanMode('vacuum')
|
|
460
|
+
// } else if (request.newMode === 1) {
|
|
461
|
+
// await yourVacuumAPI.setCleanMode('mop')
|
|
462
|
+
// } else if (request.newMode === 2) {
|
|
463
|
+
// await yourVacuumAPI.setCleanMode('vacuum_and_mop')
|
|
464
|
+
// }
|
|
465
|
+
// Update Matter state
|
|
466
|
+
return api.matter.updateAccessoryState(uuid, 'rvcCleanMode', { currentMode: request.newMode });
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
log.error('[Robot Vacuum] Failed to change clean mode:', error);
|
|
470
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
471
|
+
operationalState: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
472
|
+
operationalError: {
|
|
473
|
+
errorStateId: 1,
|
|
474
|
+
errorStateLabel: `Failed to change to ${modeName} mode`,
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
481
|
+
// Service Area handlers (Matter 1.4+) - Zone/room selection
|
|
482
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
483
|
+
//
|
|
484
|
+
// These handlers manage which rooms/zones the vacuum should clean.
|
|
485
|
+
// Controllers like iOS 18.4+ will use these to allow room-specific cleaning.
|
|
486
|
+
serviceArea: {
|
|
487
|
+
/**
|
|
488
|
+
* selectAreas() - Called when user selects specific rooms to clean
|
|
489
|
+
*
|
|
490
|
+
* @param request - Request object
|
|
491
|
+
* @param request.areas - Array of area IDs to clean
|
|
492
|
+
*
|
|
493
|
+
* Example usage:
|
|
494
|
+
* - User selects "Kitchen" and "Living Room" in Home app
|
|
495
|
+
* - request.areas = [0, 1] (Kitchen=0, Living Room=1)
|
|
496
|
+
* - Empty array means "clean all areas"
|
|
497
|
+
*/
|
|
498
|
+
selectAreas: async (request) => {
|
|
499
|
+
const areaNames = ['Kitchen', 'Living Room', 'Bedroom', 'Bathroom'];
|
|
500
|
+
const selectedNames = request.areas.map(id => areaNames[id] || `Area ${id}`);
|
|
501
|
+
log.info(`[Robot Vacuum] ✓ Handler \`selectAreas\` called - Selected areas: ${selectedNames.join(', ') || 'All areas'}`);
|
|
502
|
+
try {
|
|
503
|
+
// TODO: Send area selection to your actual robot vacuum
|
|
504
|
+
// Example:
|
|
505
|
+
// if (request.areas.length > 0) {
|
|
506
|
+
// await yourVacuumAPI.setCleaningAreas(request.areas)
|
|
507
|
+
// } else {
|
|
508
|
+
// await yourVacuumAPI.setCleaningAreas('all')
|
|
509
|
+
// }
|
|
510
|
+
// Update Matter state
|
|
511
|
+
return api.matter.updateAccessoryState(uuid, 'serviceArea', { selectedAreas: request.areas });
|
|
512
|
+
}
|
|
513
|
+
catch (error) {
|
|
514
|
+
log.error('[Robot Vacuum] Failed to select areas:', error);
|
|
515
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
516
|
+
operationalState: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
517
|
+
operationalError: {
|
|
518
|
+
errorStateId: 1,
|
|
519
|
+
errorStateLabel: 'Failed to select cleaning areas',
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
/**
|
|
525
|
+
* skipCurrentArea() - Called when user wants to skip the current room
|
|
526
|
+
*
|
|
527
|
+
* This is useful if the vacuum gets stuck or if the user wants to
|
|
528
|
+
* skip a room during a multi-room cleaning session.
|
|
529
|
+
*/
|
|
530
|
+
skipCurrentArea: async () => {
|
|
531
|
+
log.info('[Robot Vacuum] ✓ Handler `skipCurrentArea` called - Skipping current room');
|
|
532
|
+
try {
|
|
533
|
+
// TODO: Send skip command to your actual robot vacuum
|
|
534
|
+
// Example: await yourVacuumAPI.skipCurrentArea()
|
|
535
|
+
// Move to next area (you'll need to track area progression)
|
|
536
|
+
// For this example, we just clear the current area
|
|
537
|
+
return api.matter.updateAccessoryState(uuid, 'serviceArea', { currentArea: null });
|
|
538
|
+
}
|
|
539
|
+
catch (error) {
|
|
540
|
+
log.error('[Robot Vacuum] Failed to skip area:', error);
|
|
541
|
+
return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
542
|
+
operationalState: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
543
|
+
operationalError: {
|
|
544
|
+
errorStateId: 1,
|
|
545
|
+
errorStateLabel: 'Failed to skip current area',
|
|
546
|
+
},
|
|
547
|
+
});
|
|
548
|
+
}
|
|
241
549
|
},
|
|
242
550
|
},
|
|
243
551
|
},
|
|
@@ -248,71 +556,362 @@ export function registerRoboticVacuumCleaner(context) {
|
|
|
248
556
|
log.info('[Robot Vacuum] Look for separate commissioning codes in the logs when Homebridge starts');
|
|
249
557
|
return accessories;
|
|
250
558
|
}
|
|
559
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
560
|
+
// DEVELOPER GUIDE: Implementing a Real Robot Vacuum Integration
|
|
561
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
562
|
+
//
|
|
563
|
+
// This example provides a comprehensive template for integrating a real robot
|
|
564
|
+
// vacuum cleaner with Matter through Homebridge. The implementation includes
|
|
565
|
+
// all standard RVC clusters plus the optional Service Area cluster (Matter 1.4+).
|
|
566
|
+
//
|
|
251
567
|
// ────────────────────────────────────────────────────────────────────────────
|
|
252
|
-
//
|
|
568
|
+
// 1. INITIAL SETUP & CONFIGURATION
|
|
253
569
|
// ────────────────────────────────────────────────────────────────────────────
|
|
254
570
|
//
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
//
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
// api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
268
|
-
// operationalState: convertToMatterState(newState)
|
|
269
|
-
// })
|
|
270
|
-
// })
|
|
271
|
-
// ```
|
|
272
|
-
//
|
|
273
|
-
// 3. COMMANDS TO VACUUM:
|
|
274
|
-
// In your handlers, send actual commands to the vacuum:
|
|
275
|
-
// ```typescript
|
|
276
|
-
// pause: async () => {
|
|
277
|
-
// try {
|
|
278
|
-
// await vacuumAPI.pause()
|
|
279
|
-
// log.info('Successfully paused vacuum')
|
|
280
|
-
// return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
281
|
-
// operationalState: 2 // Paused
|
|
282
|
-
// })
|
|
283
|
-
// } catch (error) {
|
|
284
|
-
// log.error('Failed to pause vacuum:', error)
|
|
285
|
-
// // Optionally set error state
|
|
286
|
-
// return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
287
|
-
// operationalState: 3, // Error
|
|
288
|
-
// operationalError: { errorStateId: 1 }
|
|
289
|
-
// })
|
|
290
|
-
// }
|
|
291
|
-
// }
|
|
292
|
-
// ```
|
|
293
|
-
//
|
|
294
|
-
// 4. ERROR HANDLING:
|
|
295
|
-
// - Always wrap API calls in try/catch
|
|
296
|
-
// - Update Matter state to reflect errors
|
|
297
|
-
// - Log detailed error information for debugging
|
|
298
|
-
//
|
|
299
|
-
// 5. BATTERY LEVEL (optional):
|
|
300
|
-
// Add a PowerSource cluster to report battery:
|
|
301
|
-
// ```typescript
|
|
302
|
-
// clusters: {
|
|
303
|
-
// powerSource: {
|
|
304
|
-
// status: 1, // BatCharging
|
|
305
|
-
// batChargeLevel: 80, // 0-100%
|
|
306
|
-
// }
|
|
307
|
-
// }
|
|
308
|
-
// ```
|
|
309
|
-
//
|
|
310
|
-
// 6. TESTING:
|
|
311
|
-
// - Test with Apple Home (requires external bridge - done automatically!)
|
|
312
|
-
// - Test with Google Home
|
|
313
|
-
// - Test with Alexa (if supported)
|
|
314
|
-
// - Test all operational states and modes
|
|
315
|
-
// - Test error conditions
|
|
571
|
+
// Store your vacuum API client in the platform class for easy access:
|
|
572
|
+
//
|
|
573
|
+
// ```typescript
|
|
574
|
+
// export class MatterPlatform {
|
|
575
|
+
// private vacuumClients: Map<string, VacuumAPI> = new Map()
|
|
576
|
+
//
|
|
577
|
+
// async configureMatterAccessory(accessory: any) {
|
|
578
|
+
// if (accessory.context?.vacuumDeviceId) {
|
|
579
|
+
// // Reconnect to vacuum using stored device ID
|
|
580
|
+
// const client = new VacuumAPI()
|
|
581
|
+
// await client.connect(accessory.context.vacuumDeviceId)
|
|
582
|
+
// this.vacuumClients.set(accessory.uuid, client)
|
|
316
583
|
//
|
|
584
|
+
// // Set up state monitoring
|
|
585
|
+
// this.monitorVacuumState(accessory.uuid, client)
|
|
586
|
+
// }
|
|
587
|
+
// }
|
|
588
|
+
// }
|
|
589
|
+
// ```
|
|
590
|
+
//
|
|
591
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
592
|
+
// 2. STATE UPDATES FROM PHYSICAL DEVICE (Device → Matter)
|
|
317
593
|
// ────────────────────────────────────────────────────────────────────────────
|
|
594
|
+
//
|
|
595
|
+
// When the vacuum state changes externally (button press, manufacturer app,
|
|
596
|
+
// schedule, etc.), you MUST update the Matter state to keep controllers in sync.
|
|
597
|
+
//
|
|
598
|
+
// Example: Event-based updates (recommended if available)
|
|
599
|
+
// ```typescript
|
|
600
|
+
// monitorVacuumState(uuid: string, vacuumAPI: VacuumAPI) {
|
|
601
|
+
// // Listen for state changes from the vacuum
|
|
602
|
+
// vacuumAPI.on('stateChanged', async (newState) => {
|
|
603
|
+
// // Update operational state
|
|
604
|
+
// await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
605
|
+
// operationalState: this.convertToMatterOperationalState(newState.status)
|
|
606
|
+
// })
|
|
607
|
+
//
|
|
608
|
+
// // Update run mode if changed
|
|
609
|
+
// if (newState.mode) {
|
|
610
|
+
// await api.matter.updateAccessoryState(uuid, 'rvcRunMode', {
|
|
611
|
+
// currentMode: this.convertToMatterRunMode(newState.mode)
|
|
612
|
+
// })
|
|
613
|
+
// }
|
|
614
|
+
//
|
|
615
|
+
// // Update current cleaning area if available
|
|
616
|
+
// if (newState.currentRoom) {
|
|
617
|
+
// await api.matter.updateAccessoryState(uuid, 'serviceArea', {
|
|
618
|
+
// currentArea: newState.currentRoom
|
|
619
|
+
// })
|
|
620
|
+
// }
|
|
621
|
+
//
|
|
622
|
+
// // Update battery level (if you have a powerSource cluster)
|
|
623
|
+
// if (newState.battery) {
|
|
624
|
+
// await api.matter.updateAccessoryState(uuid, 'powerSource', {
|
|
625
|
+
// batPercentRemaining: newState.battery * 2, // 0-200 scale
|
|
626
|
+
// batChargeLevel: newState.battery > 20 ? 2 : (newState.battery > 5 ? 1 : 0)
|
|
627
|
+
// })
|
|
628
|
+
// }
|
|
629
|
+
// })
|
|
630
|
+
//
|
|
631
|
+
// // Listen for errors
|
|
632
|
+
// vacuumAPI.on('error', async (error) => {
|
|
633
|
+
// await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
634
|
+
// operationalState: 3, // Error state
|
|
635
|
+
// operationalError: {
|
|
636
|
+
// errorStateId: this.mapErrorToMatter(error.code),
|
|
637
|
+
// errorStateLabel: error.message
|
|
638
|
+
// }
|
|
639
|
+
// })
|
|
640
|
+
// })
|
|
641
|
+
// }
|
|
642
|
+
//
|
|
643
|
+
// // Helper functions to convert vacuum states to Matter states
|
|
644
|
+
// convertToMatterOperationalState(status: string): number {
|
|
645
|
+
// const stateMap = {
|
|
646
|
+
// 'idle': MatterTypes.RvcOperationalState.OperationalState.Stopped,
|
|
647
|
+
// 'cleaning': MatterTypes.RvcOperationalState.OperationalState.Running,
|
|
648
|
+
// 'paused': MatterTypes.RvcOperationalState.OperationalState.Paused,
|
|
649
|
+
// 'error': MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
650
|
+
// 'returning': MatterTypes.RvcOperationalState.OperationalState.SeekingCharger,
|
|
651
|
+
// 'charging': MatterTypes.RvcOperationalState.OperationalState.Charging,
|
|
652
|
+
// 'docked': MatterTypes.RvcOperationalState.OperationalState.Docked
|
|
653
|
+
// }
|
|
654
|
+
// return stateMap[status] ?? MatterTypes.RvcOperationalState.OperationalState.Stopped
|
|
655
|
+
// }
|
|
656
|
+
// ```
|
|
657
|
+
//
|
|
658
|
+
// Example: Polling-based updates (if events not available)
|
|
659
|
+
// ```typescript
|
|
660
|
+
// startPolling(uuid: string, vacuumAPI: VacuumAPI) {
|
|
661
|
+
// setInterval(async () => {
|
|
662
|
+
// try {
|
|
663
|
+
// const state = await vacuumAPI.getState()
|
|
664
|
+
//
|
|
665
|
+
// // Only update if state changed (to avoid unnecessary updates)
|
|
666
|
+
// const currentState = api.matter.getAccessoryState(uuid, 'rvcOperationalState')
|
|
667
|
+
// if (currentState.operationalState !== state.operationalState) {
|
|
668
|
+
// await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
669
|
+
// operationalState: this.convertToMatterOperationalState(state.status)
|
|
670
|
+
// })
|
|
671
|
+
// }
|
|
672
|
+
// } catch (error) {
|
|
673
|
+
// log.error('Error polling vacuum state:', error)
|
|
674
|
+
// }
|
|
675
|
+
// }, 5000) // Poll every 5 seconds
|
|
676
|
+
// }
|
|
677
|
+
// ```
|
|
678
|
+
//
|
|
679
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
680
|
+
// 3. COMMAND HANDLING (Matter → Device)
|
|
681
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
682
|
+
//
|
|
683
|
+
// Commands come from Home apps via handlers. Send these to your physical device.
|
|
684
|
+
//
|
|
685
|
+
// Example: Operational state commands
|
|
686
|
+
// ```typescript
|
|
687
|
+
// handlers: {
|
|
688
|
+
// rvcOperationalState: {
|
|
689
|
+
// pause: async () => {
|
|
690
|
+
// try {
|
|
691
|
+
// await vacuumAPI.pause()
|
|
692
|
+
// log.info('Successfully paused vacuum')
|
|
693
|
+
//
|
|
694
|
+
// return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
695
|
+
// operationalState: MatterTypes.RvcOperationalState.OperationalState.Paused
|
|
696
|
+
// })
|
|
697
|
+
// } catch (error) {
|
|
698
|
+
// log.error('Failed to pause vacuum:', error)
|
|
699
|
+
// return api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
700
|
+
// operationalState: MatterTypes.RvcOperationalState.OperationalState.Error,
|
|
701
|
+
// operationalError: {
|
|
702
|
+
// errorStateId: 1,
|
|
703
|
+
// errorStateLabel: 'Failed to pause'
|
|
704
|
+
// }
|
|
705
|
+
// })
|
|
706
|
+
// }
|
|
707
|
+
// }
|
|
708
|
+
// }
|
|
709
|
+
// }
|
|
710
|
+
// ```
|
|
711
|
+
//
|
|
712
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
713
|
+
// 4. SERVICE AREA (ROOM) MANAGEMENT
|
|
714
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
715
|
+
//
|
|
716
|
+
// The Service Area cluster enables room-specific cleaning. Here's how to manage
|
|
717
|
+
// area progression during a cleaning session:
|
|
718
|
+
//
|
|
719
|
+
// Example: Track and update current area during cleaning
|
|
720
|
+
// ```typescript
|
|
721
|
+
// async startAreaBasedCleaning(uuid: string, selectedAreas: number[]) {
|
|
722
|
+
// const areas = selectedAreas.length > 0 ? selectedAreas : [0, 1, 2, 3] // All areas
|
|
723
|
+
//
|
|
724
|
+
// for (const areaId of areas) {
|
|
725
|
+
// // Update current area before starting
|
|
726
|
+
// await api.matter.updateAccessoryState(uuid, 'serviceArea', {
|
|
727
|
+
// currentArea: areaId
|
|
728
|
+
// })
|
|
729
|
+
//
|
|
730
|
+
// log.info(`Starting cleaning in area ${areaId}`)
|
|
731
|
+
//
|
|
732
|
+
// // Send command to vacuum to clean this area
|
|
733
|
+
// await vacuumAPI.cleanArea(areaId)
|
|
734
|
+
//
|
|
735
|
+
// // Wait for completion (you might use events instead)
|
|
736
|
+
// await this.waitForAreaCompletion(uuid, areaId)
|
|
737
|
+
// }
|
|
738
|
+
//
|
|
739
|
+
// // All areas cleaned, clear current area
|
|
740
|
+
// await api.matter.updateAccessoryState(uuid, 'serviceArea', {
|
|
741
|
+
// currentArea: null
|
|
742
|
+
// })
|
|
743
|
+
//
|
|
744
|
+
// log.info('All areas cleaned')
|
|
745
|
+
// }
|
|
746
|
+
//
|
|
747
|
+
// // Update progress as vacuum cleans each area
|
|
748
|
+
// vacuumAPI.on('areaProgress', async (data) => {
|
|
749
|
+
// await api.matter.updateAccessoryState(uuid, 'serviceArea', {
|
|
750
|
+
// progress: [{
|
|
751
|
+
// areaId: data.areaId,
|
|
752
|
+
// status: data.percentComplete < 100 ? 1 : 2, // 1=In Progress, 2=Completed
|
|
753
|
+
// totalOperationalTime: data.timeElapsed
|
|
754
|
+
// }]
|
|
755
|
+
// })
|
|
756
|
+
// })
|
|
757
|
+
// ```
|
|
758
|
+
//
|
|
759
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
760
|
+
// 5. STATE MACHINE PATTERN
|
|
761
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
762
|
+
//
|
|
763
|
+
// Implement a state machine to handle complex cleaning workflows:
|
|
764
|
+
//
|
|
765
|
+
// ```typescript
|
|
766
|
+
// class VacuumStateMachine {
|
|
767
|
+
// private currentState: 'idle' | 'cleaning' | 'paused' | 'returning' | 'charging' = 'idle'
|
|
768
|
+
// private cleaningRounds = 0
|
|
769
|
+
// private selectedAreas: number[] = []
|
|
770
|
+
//
|
|
771
|
+
// async handleModeChange(newMode: number) {
|
|
772
|
+
// switch (newMode) {
|
|
773
|
+
// case 0: // Idle
|
|
774
|
+
// await this.transitionToIdle()
|
|
775
|
+
// break
|
|
776
|
+
// case 1: // Quick-Cleaning
|
|
777
|
+
// this.cleaningRounds = 1
|
|
778
|
+
// await this.startCleaning()
|
|
779
|
+
// break
|
|
780
|
+
// case 2: // Auto-Cleaning
|
|
781
|
+
// this.cleaningRounds = 3
|
|
782
|
+
// await this.startCleaning()
|
|
783
|
+
// break
|
|
784
|
+
// case 3: // Mapping
|
|
785
|
+
// await this.startMapping()
|
|
786
|
+
// break
|
|
787
|
+
// }
|
|
788
|
+
// }
|
|
789
|
+
//
|
|
790
|
+
// private async startCleaning() {
|
|
791
|
+
// this.currentState = 'cleaning'
|
|
792
|
+
// await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
793
|
+
// operationalState: MatterTypes.RvcOperationalState.OperationalState.Running
|
|
794
|
+
// })
|
|
795
|
+
//
|
|
796
|
+
// // Start cleaning selected areas or all areas
|
|
797
|
+
// await this.cleanAreas(this.selectedAreas)
|
|
798
|
+
//
|
|
799
|
+
// // When done, return to dock
|
|
800
|
+
// await this.returnToDock()
|
|
801
|
+
// }
|
|
802
|
+
//
|
|
803
|
+
// private async returnToDock() {
|
|
804
|
+
// this.currentState = 'returning'
|
|
805
|
+
// await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
|
|
806
|
+
// operationalState: MatterTypes.RvcOperationalState.OperationalState.SeekingCharger
|
|
807
|
+
// })
|
|
808
|
+
//
|
|
809
|
+
// await vacuumAPI.returnToDock()
|
|
810
|
+
//
|
|
811
|
+
// // Wait for docking (via event or polling)
|
|
812
|
+
// // Then update to Charging or Docked state
|
|
813
|
+
// }
|
|
814
|
+
// }
|
|
815
|
+
// ```
|
|
816
|
+
//
|
|
817
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
818
|
+
// 6. BATTERY LEVEL REPORTING
|
|
819
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
820
|
+
//
|
|
821
|
+
// Add battery status reporting using the PowerSource cluster:
|
|
822
|
+
//
|
|
823
|
+
// ```typescript
|
|
824
|
+
// clusters: {
|
|
825
|
+
// // ... RVC clusters ...
|
|
826
|
+
//
|
|
827
|
+
// powerSource: {
|
|
828
|
+
// status: 0, // 0=Active, 1=Standby, 2=Unavailable
|
|
829
|
+
// order: 0, // Primary power source
|
|
830
|
+
// description: 'Battery',
|
|
831
|
+
// batChargeLevel: 2, // 0=Critical, 1=Warning, 2=Ok
|
|
832
|
+
// batPercentRemaining: 100, // 0-200 (multiply battery % by 2)
|
|
833
|
+
// batVoltage: 14400, // Battery voltage in millivolts (optional)
|
|
834
|
+
// }
|
|
835
|
+
// }
|
|
836
|
+
//
|
|
837
|
+
// // Update battery status when it changes
|
|
838
|
+
// vacuumAPI.on('batteryChanged', async (batteryPercent) => {
|
|
839
|
+
// await api.matter.updateAccessoryState(uuid, 'powerSource', {
|
|
840
|
+
// batPercentRemaining: batteryPercent * 2, // Convert to 0-200 scale
|
|
841
|
+
// batChargeLevel: batteryPercent > 20 ? 2 : (batteryPercent > 5 ? 1 : 0),
|
|
842
|
+
// status: batteryPercent > 0 ? 0 : 2 // Active if has charge, unavailable if depleted
|
|
843
|
+
// })
|
|
844
|
+
// })
|
|
845
|
+
// ```
|
|
846
|
+
//
|
|
847
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
848
|
+
// 7. ERROR HANDLING & VALIDATION
|
|
849
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
850
|
+
//
|
|
851
|
+
// Always validate state transitions and handle errors gracefully:
|
|
852
|
+
//
|
|
853
|
+
// ```typescript
|
|
854
|
+
// // Validate state transitions
|
|
855
|
+
// function canPause(currentState: number): boolean {
|
|
856
|
+
// // Can't pause if docked, charging, or seeking charger
|
|
857
|
+
// return ![
|
|
858
|
+
// MatterTypes.RvcOperationalState.OperationalState.SeekingCharger,
|
|
859
|
+
// MatterTypes.RvcOperationalState.OperationalState.Charging,
|
|
860
|
+
// MatterTypes.RvcOperationalState.OperationalState.Docked
|
|
861
|
+
// ].includes(currentState)
|
|
862
|
+
// }
|
|
863
|
+
//
|
|
864
|
+
// // Map vacuum errors to Matter error codes
|
|
865
|
+
// function mapErrorToMatter(errorCode: string): number {
|
|
866
|
+
// const errorMap = {
|
|
867
|
+
// 'STUCK': 1,
|
|
868
|
+
// 'WHEEL_ISSUE': 2,
|
|
869
|
+
// 'BRUSH_ISSUE': 3,
|
|
870
|
+
// 'DUSTBIN_FULL': 4,
|
|
871
|
+
// 'BATTERY_LOW': 5,
|
|
872
|
+
// }
|
|
873
|
+
// return errorMap[errorCode] ?? 1 // Default to generic error
|
|
874
|
+
// }
|
|
875
|
+
// ```
|
|
876
|
+
//
|
|
877
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
878
|
+
// 8. TESTING CHECKLIST
|
|
879
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
880
|
+
//
|
|
881
|
+
// Before deploying, test the following scenarios:
|
|
882
|
+
//
|
|
883
|
+
// ✓ Basic Operations:
|
|
884
|
+
// - Start cleaning from Home app
|
|
885
|
+
// - Pause/resume cleaning
|
|
886
|
+
// - Return to dock command
|
|
887
|
+
// - Mode changes (Idle, Quick, Auto, Mapping)
|
|
888
|
+
// - Clean mode changes (Vacuum, Mop, Vacuum & Mop)
|
|
889
|
+
//
|
|
890
|
+
// ✓ Service Area (Room Selection):
|
|
891
|
+
// - Select single room to clean
|
|
892
|
+
// - Select multiple rooms
|
|
893
|
+
// - Clean all rooms (no selection)
|
|
894
|
+
// - Skip current room during cleaning
|
|
895
|
+
//
|
|
896
|
+
// ✓ State Synchronization:
|
|
897
|
+
// - Start vacuum from manufacturer app → verify Home app updates
|
|
898
|
+
// - Start vacuum from physical button → verify Home app updates
|
|
899
|
+
// - Schedule cleaning → verify Home app shows correct state
|
|
900
|
+
//
|
|
901
|
+
// ✓ Error Conditions:
|
|
902
|
+
// - Vacuum gets stuck → verify error state in Home app
|
|
903
|
+
// - Battery depleted → verify battery reporting
|
|
904
|
+
// - Connection loss → verify proper error handling
|
|
905
|
+
//
|
|
906
|
+
// ✓ Platform Compatibility:
|
|
907
|
+
// - Test with Apple Home (iOS 18.4+ for room selection)
|
|
908
|
+
// - Test with Google Home
|
|
909
|
+
// - Test with other Matter controllers (if applicable)
|
|
910
|
+
//
|
|
911
|
+
// ✓ Performance:
|
|
912
|
+
// - Verify state updates are timely (< 2 seconds)
|
|
913
|
+
// - Check that polling doesn't overwhelm the vacuum API
|
|
914
|
+
// - Monitor Homebridge logs for errors
|
|
915
|
+
//
|
|
916
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
318
917
|
//# sourceMappingURL=robotic-vacuum-cleaner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"robotic-vacuum-cleaner.js","sourceRoot":"","sources":["../../../src/devices/section-12-robotic/robotic-vacuum-cleaner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"robotic-vacuum-cleaner.js","sourceRoot":"","sources":["../../../src/devices/section-12-robotic/robotic-vacuum-cleaner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"displayName": "Homebridge Matter",
|
|
4
4
|
"alias": "Matter",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "0.1.1-beta.
|
|
6
|
+
"version": "0.1.1-beta.5",
|
|
7
7
|
"description": "Homebridge plugin to showcase examples of Matter devices in Homebridge.",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "bwp91",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"main": "dist/index.js",
|
|
50
50
|
"engines": {
|
|
51
51
|
"node": "^20.18.0 || ^22.10.0 || ^24.0.0",
|
|
52
|
-
"homebridge": ">=2.0.0-alpha.
|
|
52
|
+
"homebridge": ">=2.0.0-alpha.57 <2.0.0-beta.0"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "rimraf ./dist && tsc && npm run plugin-ui",
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@antfu/eslint-config": "^6.0.0",
|
|
67
|
-
"@types/node": "^24.
|
|
68
|
-
"homebridge": "2.0.0-alpha.
|
|
67
|
+
"@types/node": "^24.9.0",
|
|
68
|
+
"homebridge": "2.0.0-alpha.57",
|
|
69
69
|
"rimraf": "^6.0.1",
|
|
70
70
|
"ts-node": "^10.9.2",
|
|
71
71
|
"typescript": "^5.9.3"
|