matterbridge-roborock-vacuum-plugin 1.1.0-rc11 → 1.1.0-rc12

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.
@@ -4,7 +4,12 @@ export function getSupportedAreas(rooms, roomMap, log) {
4
4
  log?.debug('getSupportedAreas', debugStringify(rooms));
5
5
  log?.debug('getSupportedAreas', roomMap ? debugStringify(roomMap) : 'undefined');
6
6
  if (!rooms || rooms.length === 0 || !roomMap?.rooms || roomMap.rooms.length == 0) {
7
- log?.error('No rooms found');
7
+ if (!rooms || rooms.length === 0) {
8
+ log?.error('No rooms found');
9
+ }
10
+ if (!roomMap || !roomMap.rooms || roomMap.rooms.length == 0) {
11
+ log?.error('No room map found');
12
+ }
8
13
  return [
9
14
  {
10
15
  areaId: 1,
package/dist/platform.js CHANGED
@@ -26,8 +26,8 @@ export class RoborockMatterbridgePlatform extends MatterbridgeDynamicPlatform {
26
26
  rrHomeId;
27
27
  constructor(matterbridge, log, config) {
28
28
  super(matterbridge, log, config);
29
- if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.1.5')) {
30
- throw new Error(`This plugin requires Matterbridge version >= "3.1.5". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
29
+ if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.1.6')) {
30
+ throw new Error(`This plugin requires Matterbridge version >= "3.1.6". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
31
31
  }
32
32
  this.log.info('Initializing platform:', this.config.name);
33
33
  if (config.whiteList === undefined)
@@ -157,6 +157,7 @@ export class RoborockMatterbridgePlatform extends MatterbridgeDynamicPlatform {
157
157
  return false;
158
158
  }
159
159
  if (vacuum.rooms === undefined || vacuum.rooms.length === 0) {
160
+ this.log.error(`Fetching map information for device: ${vacuum.name} (${vacuum.duid}) to get rooms`);
160
161
  const map_info = await this.roborockService.getMapInformation(vacuum.duid);
161
162
  const rooms = map_info?.maps?.[0]?.rooms ?? [];
162
163
  vacuum.rooms = rooms;
@@ -35,9 +35,19 @@ export class PlatformRunner {
35
35
  async getRoomMapFromDevice(device) {
36
36
  const platform = this.platform;
37
37
  const rooms = device?.rooms ?? [];
38
+ platform.log.error(`getRoomMapFromDevice: ${debugStringify(rooms)}`);
38
39
  if (device && platform.roborockService) {
39
40
  const roomData = await platform.roborockService.getRoomMappings(device.duid);
40
- return new RoomMap(roomData ?? [], rooms);
41
+ if (roomData !== undefined && roomData.length > 0) {
42
+ platform.log.error(`getRoomMapFromDevice - roomData: ${debugStringify(roomData ?? [])}`);
43
+ return new RoomMap(roomData ?? [], rooms);
44
+ }
45
+ const mapInfo = await platform.roborockService.getMapInformation(device.duid);
46
+ if (mapInfo && mapInfo.maps && mapInfo.maps.length > 0) {
47
+ platform.log.error(`getRoomMapFromDevice - mapInfo: ${debugStringify(mapInfo.maps)}`);
48
+ const roomDataMap = mapInfo.maps[0].rooms.map((r) => [r.id, parseInt(r.name)]);
49
+ return new RoomMap(roomDataMap, rooms);
50
+ }
41
51
  }
42
52
  return new RoomMap([], rooms);
43
53
  }
@@ -53,8 +63,18 @@ export class PlatformRunner {
53
63
  const rooms = robot.device.rooms ?? [];
54
64
  if (robot.roomInfo === undefined) {
55
65
  const roomData = await platform.roborockService.getRoomMappings(robot.device.duid);
56
- robot.roomInfo = new RoomMap(roomData ?? [], rooms);
57
- return robot.roomInfo;
66
+ if (roomData !== undefined && roomData.length > 0) {
67
+ robot.roomInfo = new RoomMap(roomData ?? [], rooms);
68
+ return robot.roomInfo;
69
+ }
70
+ }
71
+ if (robot.roomInfo === undefined) {
72
+ const mapInfo = await platform.roborockService.getMapInformation(robot.device.duid);
73
+ if (mapInfo && mapInfo.maps && mapInfo.maps.length > 0) {
74
+ platform.log.error(`getRoomMap - mapInfo: ${debugStringify(mapInfo.maps)}`);
75
+ const roomDataMap = mapInfo.maps[0].rooms.map((r) => [r.id, parseInt(r.name)]);
76
+ robot.roomInfo = new RoomMap(roomDataMap, rooms);
77
+ }
58
78
  }
59
79
  return robot.roomInfo;
60
80
  }
@@ -109,13 +129,20 @@ export class PlatformRunner {
109
129
  if (state) {
110
130
  robot.updateAttribute(RvcRunMode.Cluster.id, 'currentMode', getRunningMode(state), platform.log);
111
131
  }
112
- const currentRoom = data.cleaning_info?.segment_id ?? -1;
113
132
  const currentMappedAreas = this.platform.roborockService?.getSupportedAreas(duid);
133
+ const roomMap = await this.getRoomMap(duid);
134
+ const targetRoom = data.cleaning_info?.target_segment_id ?? -1;
135
+ const isTargetMappedArea = currentMappedAreas?.some((x) => x.areaId == targetRoom);
136
+ if (targetRoom !== -1 && isTargetMappedArea) {
137
+ this.platform.log.debug(`RoomMap: ${roomMap ? debugStringify(roomMap) : 'undefined'}`);
138
+ this.platform.log.debug(`TargetRoom: ${targetRoom}, room name: ${roomMap?.rooms.find((x) => x.id === targetRoom)?.displayName ?? 'unknown'}`);
139
+ robot.updateAttribute(ServiceArea.Cluster.id, 'currentArea', targetRoom, platform.log);
140
+ }
141
+ const currentRoom = data.cleaning_info?.segment_id ?? -1;
114
142
  const isMappedArea = currentMappedAreas?.some((x) => x.areaId == currentRoom);
115
143
  if (currentRoom !== -1 && isMappedArea) {
116
- const roomMap = await this.getRoomMap(duid);
117
144
  this.platform.log.debug(`RoomMap: ${roomMap ? debugStringify(roomMap) : 'undefined'}`);
118
- this.platform.log.debug('CurrentRoom:', currentRoom);
145
+ this.platform.log.debug(`CurrentRoom: ${currentRoom}, room name: ${roomMap?.rooms.find((x) => x.id === currentRoom)?.displayName ?? 'unknown'}`);
119
146
  robot.updateAttribute(ServiceArea.Cluster.id, 'currentArea', currentRoom, platform.log);
120
147
  }
121
148
  if (data.battery) {
@@ -9,8 +9,8 @@ export class MapInfo {
9
9
  rooms: map.rooms && map.rooms.length > 0
10
10
  ? map.rooms.map((room) => {
11
11
  return {
12
- id: room.iot_name_id,
13
- name: room.iot_name,
12
+ id: room.id,
13
+ name: room.iot_name_id,
14
14
  };
15
15
  })
16
16
  : [],
@@ -21,7 +21,9 @@ export class ConnectionStateListener {
21
21
  }
22
22
  if (this.client.retryCount > 10) {
23
23
  this.logger.error(`Device with DUID ${duid} has exceeded retry limit, not re-registering.`);
24
- this.changeToSecureConnection(duid);
24
+ if (this.changeToSecureConnection) {
25
+ this.changeToSecureConnection(duid);
26
+ }
25
27
  return;
26
28
  }
27
29
  this.client.retryCount++;
@@ -260,7 +260,6 @@ export default class RoborockService {
260
260
  model: homeData.products.find((p) => p.id === device.productId)?.model,
261
261
  category: homeData.products.find((p) => p.id === device.productId)?.category,
262
262
  batteryLevel: device.deviceStatus?.[Protocol.battery] ?? 100,
263
- schema: homeData.products.find((p) => p.id === device.productId)?.schema,
264
263
  },
265
264
  store: {
266
265
  username: username,
@@ -308,7 +307,6 @@ export default class RoborockService {
308
307
  model: homeData.products.find((p) => p.id === device.productId)?.model,
309
308
  category: homeData.products.find((p) => p.id === device.productId)?.category,
310
309
  batteryLevel: device.deviceStatus?.[Protocol.battery] ?? 100,
311
- schema: homeData.products.find((p) => p.id === device.productId)?.schema,
312
310
  },
313
311
  store: {
314
312
  userData: this.userdata,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "matterbridge-roborock-vacuum-plugin",
3
3
  "type": "DynamicPlatform",
4
- "version": "1.1.0-rc11",
4
+ "version": "1.1.0-rc12",
5
5
  "whiteList": [],
6
6
  "blackList": [],
7
7
  "useInterval": true,
@@ -37,4 +37,4 @@
37
37
  "debug": true,
38
38
  "unregisterOnShutdown": false,
39
39
  "enableExperimentalFeature": false
40
- }
40
+ }
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "title": "Matterbridge Roborock Vacuum Plugin",
3
- "description": "matterbridge-roborock-vacuum-plugin v. 1.1.0-rc11 by https://github.com/RinDevJunior",
3
+ "description": "matterbridge-roborock-vacuum-plugin v. 1.1.0-rc12 by https://github.com/RinDevJunior",
4
4
  "type": "object",
5
- "required": ["username", "password"],
5
+ "required": [
6
+ "username",
7
+ "password"
8
+ ],
6
9
  "properties": {
7
10
  "name": {
8
11
  "description": "Plugin name",
@@ -57,7 +60,9 @@
57
60
  "const": true
58
61
  }
59
62
  },
60
- "required": ["enableExperimentalFeature"]
63
+ "required": [
64
+ "enableExperimentalFeature"
65
+ ]
61
66
  },
62
67
  "then": {
63
68
  "properties": {
@@ -114,7 +119,9 @@
114
119
  "const": true
115
120
  }
116
121
  },
117
- "required": ["enableCleanModeMapping"]
122
+ "required": [
123
+ "enableCleanModeMapping"
124
+ ]
118
125
  },
119
126
  "then": {
120
127
  "properties": {
@@ -159,7 +166,9 @@
159
166
  "default": 25
160
167
  }
161
168
  },
162
- "required": ["distanceOff"]
169
+ "required": [
170
+ "distanceOff"
171
+ ]
163
172
  }
164
173
  }
165
174
  ]
@@ -196,7 +205,9 @@
196
205
  "default": 25
197
206
  }
198
207
  },
199
- "required": ["distanceOff"]
208
+ "required": [
209
+ "distanceOff"
210
+ ]
200
211
  }
201
212
  }
202
213
  ]
@@ -226,20 +237,36 @@
226
237
  "fanMode": {
227
238
  "type": "string",
228
239
  "description": "Suction power mode to use (e.g., 'Quiet', 'Balanced', 'Turbo', 'Max', 'MaxPlus').",
229
- "enum": ["Quiet", "Balanced", "Turbo", "Max", "MaxPlus"],
240
+ "enum": [
241
+ "Quiet",
242
+ "Balanced",
243
+ "Turbo",
244
+ "Max",
245
+ "MaxPlus"
246
+ ],
230
247
  "default": "Balanced"
231
248
  },
232
249
  "waterFlowMode": {
233
250
  "type": "string",
234
251
  "description": "Water flow mode to use (e.g., 'Low', 'Medium', 'High', 'CustomizeWithDistanceOff').",
235
- "enum": ["Low", "Medium", "High", "CustomizeWithDistanceOff"],
252
+ "enum": [
253
+ "Low",
254
+ "Medium",
255
+ "High",
256
+ "CustomizeWithDistanceOff"
257
+ ],
236
258
  "default": "Medium"
237
259
  },
238
260
  "mopRouteMode": {
239
261
  "type": "string",
240
262
  "description": "Mop route intensity to use (e.g., 'Standard', 'Deep', 'DeepPlus', 'Fast').",
241
- "enum": ["Standard", "Deep", "DeepPlus", "Fast"],
263
+ "enum": [
264
+ "Standard",
265
+ "Deep",
266
+ "DeepPlus",
267
+ "Fast"
268
+ ],
242
269
  "default": "Standard"
243
270
  }
244
271
  }
245
- }
272
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge-roborock-vacuum-plugin",
3
- "version": "1.1.0-rc11",
3
+ "version": "1.1.0-rc12",
4
4
  "description": "Matterbridge Roborock Vacuum Plugin",
5
5
  "author": "https://github.com/RinDevJunior",
6
6
  "license": "MIT",
@@ -9,7 +9,14 @@ export function getSupportedAreas(rooms: Room[], roomMap: RoomMap | undefined, l
9
9
  log?.debug('getSupportedAreas', roomMap ? debugStringify(roomMap) : 'undefined');
10
10
 
11
11
  if (!rooms || rooms.length === 0 || !roomMap?.rooms || roomMap.rooms.length == 0) {
12
- log?.error('No rooms found');
12
+ if (!rooms || rooms.length === 0) {
13
+ log?.error('No rooms found');
14
+ }
15
+
16
+ if (!roomMap || !roomMap.rooms || roomMap.rooms.length == 0) {
17
+ log?.error('No room map found');
18
+ }
19
+
13
20
  return [
14
21
  {
15
22
  areaId: 1,
package/src/platform.ts CHANGED
@@ -32,9 +32,9 @@ export class RoborockMatterbridgePlatform extends MatterbridgeDynamicPlatform {
32
32
  super(matterbridge, log, config);
33
33
 
34
34
  // Verify that Matterbridge is the correct version
35
- if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.1.5')) {
35
+ if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.1.6')) {
36
36
  throw new Error(
37
- `This plugin requires Matterbridge version >= "3.1.5". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`,
37
+ `This plugin requires Matterbridge version >= "3.1.6". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`,
38
38
  );
39
39
  }
40
40
  this.log.info('Initializing platform:', this.config.name);
@@ -224,6 +224,7 @@ export class RoborockMatterbridgePlatform extends MatterbridgeDynamicPlatform {
224
224
  }
225
225
 
226
226
  if (vacuum.rooms === undefined || vacuum.rooms.length === 0) {
227
+ this.log.error(`Fetching map information for device: ${vacuum.name} (${vacuum.duid}) to get rooms`);
227
228
  const map_info = await this.roborockService.getMapInformation(vacuum.duid);
228
229
  const rooms = map_info?.maps?.[0]?.rooms ?? [];
229
230
  vacuum.rooms = rooms;
@@ -44,11 +44,23 @@ export class PlatformRunner {
44
44
  public async getRoomMapFromDevice(device: Device): Promise<RoomMap> {
45
45
  const platform = this.platform;
46
46
  const rooms = device?.rooms ?? [];
47
-
47
+ platform.log.error(`getRoomMapFromDevice: ${debugStringify(rooms)}`);
48
48
  if (device && platform.roborockService) {
49
49
  const roomData = await platform.roborockService.getRoomMappings(device.duid);
50
- return new RoomMap(roomData ?? [], rooms);
50
+ if (roomData !== undefined && roomData.length > 0) {
51
+ platform.log.error(`getRoomMapFromDevice - roomData: ${debugStringify(roomData ?? [])}`);
52
+ return new RoomMap(roomData ?? [], rooms);
53
+ }
54
+
55
+ const mapInfo = await platform.roborockService.getMapInformation(device.duid);
56
+ if (mapInfo && mapInfo.maps && mapInfo.maps.length > 0) {
57
+ platform.log.error(`getRoomMapFromDevice - mapInfo: ${debugStringify(mapInfo.maps)}`);
58
+
59
+ const roomDataMap = mapInfo.maps[0].rooms.map((r) => [r.id, parseInt(r.name)] as [number, number]);
60
+ return new RoomMap(roomDataMap, rooms);
61
+ }
51
62
  }
63
+
52
64
  return new RoomMap([], rooms);
53
65
  }
54
66
 
@@ -67,8 +79,20 @@ export class PlatformRunner {
67
79
  // if (platform.robot?.device === undefined || platform.roborockService === undefined) return undefined;
68
80
  if (robot.roomInfo === undefined) {
69
81
  const roomData = await platform.roborockService.getRoomMappings(robot.device.duid);
70
- robot.roomInfo = new RoomMap(roomData ?? [], rooms);
71
- return robot.roomInfo;
82
+ if (roomData !== undefined && roomData.length > 0) {
83
+ robot.roomInfo = new RoomMap(roomData ?? [], rooms);
84
+ return robot.roomInfo;
85
+ }
86
+ }
87
+
88
+ if (robot.roomInfo === undefined) {
89
+ const mapInfo = await platform.roborockService.getMapInformation(robot.device.duid);
90
+ if (mapInfo && mapInfo.maps && mapInfo.maps.length > 0) {
91
+ platform.log.error(`getRoomMap - mapInfo: ${debugStringify(mapInfo.maps)}`);
92
+
93
+ const roomDataMap = mapInfo.maps[0].rooms.map((r) => [r.id, parseInt(r.name)] as [number, number]);
94
+ robot.roomInfo = new RoomMap(roomDataMap, rooms);
95
+ }
72
96
  }
73
97
 
74
98
  return robot.roomInfo;
@@ -144,14 +168,22 @@ export class PlatformRunner {
144
168
  robot.updateAttribute(RvcRunMode.Cluster.id, 'currentMode', getRunningMode(state), platform.log);
145
169
  }
146
170
 
147
- const currentRoom = data.cleaning_info?.segment_id ?? -1;
148
171
  const currentMappedAreas = this.platform.roborockService?.getSupportedAreas(duid);
149
- const isMappedArea = currentMappedAreas?.some((x) => x.areaId == currentRoom);
172
+ const roomMap = await this.getRoomMap(duid);
173
+ const targetRoom = data.cleaning_info?.target_segment_id ?? -1;
174
+ const isTargetMappedArea = currentMappedAreas?.some((x) => x.areaId == targetRoom);
150
175
 
176
+ if (targetRoom !== -1 && isTargetMappedArea) {
177
+ this.platform.log.debug(`RoomMap: ${roomMap ? debugStringify(roomMap) : 'undefined'}`);
178
+ this.platform.log.debug(`TargetRoom: ${targetRoom}, room name: ${roomMap?.rooms.find((x) => x.id === targetRoom)?.displayName ?? 'unknown'}`);
179
+ robot.updateAttribute(ServiceArea.Cluster.id, 'currentArea', targetRoom, platform.log);
180
+ }
181
+
182
+ const currentRoom = data.cleaning_info?.segment_id ?? -1;
183
+ const isMappedArea = currentMappedAreas?.some((x) => x.areaId == currentRoom);
151
184
  if (currentRoom !== -1 && isMappedArea) {
152
- const roomMap = await this.getRoomMap(duid);
153
185
  this.platform.log.debug(`RoomMap: ${roomMap ? debugStringify(roomMap) : 'undefined'}`);
154
- this.platform.log.debug('CurrentRoom:', currentRoom);
186
+ this.platform.log.debug(`CurrentRoom: ${currentRoom}, room name: ${roomMap?.rooms.find((x) => x.id === currentRoom)?.displayName ?? 'unknown'}`);
155
187
  robot.updateAttribute(ServiceArea.Cluster.id, 'currentArea', currentRoom, platform.log);
156
188
  }
157
189
 
@@ -36,7 +36,6 @@ export interface Device {
36
36
  model: string;
37
37
  category: string;
38
38
  batteryLevel: number;
39
- // schema: DeviceSchema[];
40
39
  };
41
40
 
42
41
  scenes: Scene[];
@@ -15,9 +15,9 @@ export class MapInfo {
15
15
  map.rooms && map.rooms.length > 0
16
16
  ? map.rooms.map((room: RoomInformation) => {
17
17
  return {
18
- id: room.iot_name_id,
19
- name: room.iot_name,
20
- } as unknown as Room;
18
+ id: room.id,
19
+ name: room.iot_name_id,
20
+ } as Room;
21
21
  })
22
22
  : [],
23
23
  });
@@ -29,7 +29,9 @@ export class ConnectionStateListener implements AbstractConnectionListener {
29
29
 
30
30
  if (this.client.retryCount > 10) {
31
31
  this.logger.error(`Device with DUID ${duid} has exceeded retry limit, not re-registering.`);
32
- this.changeToSecureConnection(duid);
32
+ if (this.changeToSecureConnection) {
33
+ this.changeToSecureConnection(duid);
34
+ }
33
35
  return;
34
36
  }
35
37
 
@@ -340,7 +340,6 @@ export default class RoborockService {
340
340
  model: homeData.products.find((p) => p.id === device.productId)?.model,
341
341
  category: homeData.products.find((p) => p.id === device.productId)?.category,
342
342
  batteryLevel: device.deviceStatus?.[Protocol.battery] ?? 100,
343
- schema: homeData.products.find((p) => p.id === device.productId)?.schema,
344
343
  },
345
344
 
346
345
  store: {
@@ -394,7 +393,6 @@ export default class RoborockService {
394
393
  model: homeData.products.find((p) => p.id === device.productId)?.model,
395
394
  category: homeData.products.find((p) => p.id === device.productId)?.category,
396
395
  batteryLevel: device.deviceStatus?.[Protocol.battery] ?? 100,
397
- schema: homeData.products.find((p) => p.id === device.productId)?.schema,
398
396
  },
399
397
 
400
398
  store: {
@@ -427,7 +425,6 @@ export default class RoborockService {
427
425
  this.logger.warn('messageClient not initialized. Waititing for next execution');
428
426
  return Promise.resolve(undefined);
429
427
  }
430
-
431
428
  return this.messageClient.get(duid, new RequestMessage({ method: 'get_room_mapping', secure: this.isRequestSecure(duid) }));
432
429
  }
433
430
 
@@ -1,3 +1,5 @@
1
+ import { UserData } from './ext/roborockCommunication/index.js';
2
+
1
3
  export function getAccountStore(): Map<string, UserData> {
2
4
  const accountStore = new Map<string, UserData>();
3
5