matterbridge-roborock-vacuum-plugin-regions 1.1.1-jb.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/.github/workflows/build.yml +56 -0
  2. package/.github/workflows/coverage.yml +59 -0
  3. package/.github/workflows/publish.yml +37 -0
  4. package/.tarignore +5 -0
  5. package/CHANGELOG.md +62 -0
  6. package/LICENSE +202 -0
  7. package/README.md +135 -0
  8. package/README_CLEANMODE.md +29 -0
  9. package/README_DEV.md +75 -0
  10. package/README_REPORT_ISSUE.md +34 -0
  11. package/README_SUPPORTED.md +67 -0
  12. package/dist/behaviorFactory.js +26 -0
  13. package/dist/behaviors/BehaviorDeviceGeneric.js +22 -0
  14. package/dist/behaviors/roborock.vacuum/default/default.js +183 -0
  15. package/dist/behaviors/roborock.vacuum/default/initalData.js +143 -0
  16. package/dist/behaviors/roborock.vacuum/default/runtimes.js +21 -0
  17. package/dist/behaviors/roborock.vacuum/smart/initalData.js +18 -0
  18. package/dist/behaviors/roborock.vacuum/smart/runtimes.js +11 -0
  19. package/dist/behaviors/roborock.vacuum/smart/smart.js +119 -0
  20. package/dist/clientManager.js +17 -0
  21. package/dist/helper.js +76 -0
  22. package/dist/index.js +4 -0
  23. package/dist/initialData/getBatteryStatus.js +24 -0
  24. package/dist/initialData/getOperationalStates.js +82 -0
  25. package/dist/initialData/getSupportedAreas.js +120 -0
  26. package/dist/initialData/getSupportedCleanModes.js +17 -0
  27. package/dist/initialData/getSupportedRunModes.js +11 -0
  28. package/dist/initialData/getSupportedScenes.js +26 -0
  29. package/dist/initialData/index.js +6 -0
  30. package/dist/model/CloudMessageModel.js +1 -0
  31. package/dist/model/DockingStationStatus.js +26 -0
  32. package/dist/model/ExperimentalFeatureSetting.js +30 -0
  33. package/dist/model/RoomMap.js +19 -0
  34. package/dist/model/roomIndexMap.js +21 -0
  35. package/dist/notifyMessageTypes.js +9 -0
  36. package/dist/platform.js +312 -0
  37. package/dist/platformRunner.js +90 -0
  38. package/dist/roborockCommunication/RESTAPI/roborockAuthenticateApi.js +213 -0
  39. package/dist/roborockCommunication/RESTAPI/roborockIoTApi.js +95 -0
  40. package/dist/roborockCommunication/Zenum/additionalPropCode.js +4 -0
  41. package/dist/roborockCommunication/Zenum/authenticateResponseCode.js +7 -0
  42. package/dist/roborockCommunication/Zenum/dockType.js +4 -0
  43. package/dist/roborockCommunication/Zenum/operationStatusCode.js +44 -0
  44. package/dist/roborockCommunication/Zenum/vacuumAndDockErrorCode.js +68 -0
  45. package/dist/roborockCommunication/Zmodel/apiResponse.js +1 -0
  46. package/dist/roborockCommunication/Zmodel/authenticateFlowState.js +1 -0
  47. package/dist/roborockCommunication/Zmodel/authenticateResponse.js +1 -0
  48. package/dist/roborockCommunication/Zmodel/baseURL.js +1 -0
  49. package/dist/roborockCommunication/Zmodel/batteryMessage.js +1 -0
  50. package/dist/roborockCommunication/Zmodel/device.js +1 -0
  51. package/dist/roborockCommunication/Zmodel/deviceModel.js +28 -0
  52. package/dist/roborockCommunication/Zmodel/deviceSchema.js +1 -0
  53. package/dist/roborockCommunication/Zmodel/deviceStatus.js +22 -0
  54. package/dist/roborockCommunication/Zmodel/dockInfo.js +6 -0
  55. package/dist/roborockCommunication/Zmodel/home.js +1 -0
  56. package/dist/roborockCommunication/Zmodel/homeInfo.js +1 -0
  57. package/dist/roborockCommunication/Zmodel/map.js +1 -0
  58. package/dist/roborockCommunication/Zmodel/mapInfo.js +29 -0
  59. package/dist/roborockCommunication/Zmodel/messageResult.js +7 -0
  60. package/dist/roborockCommunication/Zmodel/multipleMap.js +1 -0
  61. package/dist/roborockCommunication/Zmodel/networkInfo.js +1 -0
  62. package/dist/roborockCommunication/Zmodel/product.js +1 -0
  63. package/dist/roborockCommunication/Zmodel/room.js +1 -0
  64. package/dist/roborockCommunication/Zmodel/roomInfo.js +22 -0
  65. package/dist/roborockCommunication/Zmodel/scene.js +16 -0
  66. package/dist/roborockCommunication/Zmodel/userData.js +1 -0
  67. package/dist/roborockCommunication/Zmodel/vacuumError.js +27 -0
  68. package/dist/roborockCommunication/broadcast/abstractClient.js +55 -0
  69. package/dist/roborockCommunication/broadcast/client/LocalNetworkClient.js +174 -0
  70. package/dist/roborockCommunication/broadcast/client/LocalNetworkUDPClient.js +129 -0
  71. package/dist/roborockCommunication/broadcast/client/MQTTClient.js +139 -0
  72. package/dist/roborockCommunication/broadcast/client.js +1 -0
  73. package/dist/roborockCommunication/broadcast/clientRouter.js +82 -0
  74. package/dist/roborockCommunication/broadcast/listener/abstractConnectionListener.js +1 -0
  75. package/dist/roborockCommunication/broadcast/listener/abstractMessageHandler.js +1 -0
  76. package/dist/roborockCommunication/broadcast/listener/abstractMessageListener.js +1 -0
  77. package/dist/roborockCommunication/broadcast/listener/implementation/chainedConnectionListener.js +26 -0
  78. package/dist/roborockCommunication/broadcast/listener/implementation/chainedMessageListener.js +11 -0
  79. package/dist/roborockCommunication/broadcast/listener/implementation/connectionStateListener.js +43 -0
  80. package/dist/roborockCommunication/broadcast/listener/implementation/generalSyncMessageListener.js +28 -0
  81. package/dist/roborockCommunication/broadcast/listener/implementation/simpleMessageListener.js +27 -0
  82. package/dist/roborockCommunication/broadcast/listener/implementation/syncMessageListener.js +33 -0
  83. package/dist/roborockCommunication/broadcast/listener/index.js +1 -0
  84. package/dist/roborockCommunication/broadcast/messageProcessor.js +148 -0
  85. package/dist/roborockCommunication/broadcast/model/contentMessage.js +1 -0
  86. package/dist/roborockCommunication/broadcast/model/dps.js +1 -0
  87. package/dist/roborockCommunication/broadcast/model/headerMessage.js +1 -0
  88. package/dist/roborockCommunication/broadcast/model/messageContext.js +37 -0
  89. package/dist/roborockCommunication/broadcast/model/protocol.js +28 -0
  90. package/dist/roborockCommunication/broadcast/model/requestMessage.js +38 -0
  91. package/dist/roborockCommunication/broadcast/model/responseMessage.js +14 -0
  92. package/dist/roborockCommunication/helper/chunkBuffer.js +17 -0
  93. package/dist/roborockCommunication/helper/cryptoHelper.js +23 -0
  94. package/dist/roborockCommunication/helper/messageDeserializer.js +98 -0
  95. package/dist/roborockCommunication/helper/messageSerializer.js +84 -0
  96. package/dist/roborockCommunication/helper/nameDecoder.js +66 -0
  97. package/dist/roborockCommunication/helper/sequence.js +16 -0
  98. package/dist/roborockCommunication/index.js +13 -0
  99. package/dist/roborockService.js +494 -0
  100. package/dist/runtimes/handleCloudMessage.js +110 -0
  101. package/dist/runtimes/handleHomeDataMessage.js +57 -0
  102. package/dist/runtimes/handleLocalMessage.js +169 -0
  103. package/dist/rvc.js +51 -0
  104. package/dist/settings.js +1 -0
  105. package/dist/share/function.js +93 -0
  106. package/dist/share/runtimeHelper.js +17 -0
  107. package/dist/tests/testData/mockData.js +359 -0
  108. package/eslint.config.js +80 -0
  109. package/jest.config.js +22 -0
  110. package/jest.setup.js +2 -0
  111. package/logo.png +0 -0
  112. package/matterbridge-roborock-vacuum-plugin.config.json +46 -0
  113. package/matterbridge-roborock-vacuum-plugin.schema.json +293 -0
  114. package/misc/status.md +119 -0
  115. package/package.json +111 -0
  116. package/prettier.config.js +49 -0
  117. package/screenshot/IMG_1.PNG +0 -0
  118. package/screenshot/IMG_2.PNG +0 -0
  119. package/screenshot/IMG_3.PNG +0 -0
  120. package/screenshot/IMG_4.PNG +0 -0
  121. package/screenshot/IMG_5.PNG +0 -0
  122. package/screenshot/IMG_6.PNG +0 -0
  123. package/screenshot/IMG_7.PNG +0 -0
  124. package/src/behaviorFactory.ts +41 -0
  125. package/src/behaviors/BehaviorDeviceGeneric.ts +31 -0
  126. package/src/behaviors/roborock.vacuum/default/default.ts +238 -0
  127. package/src/behaviors/roborock.vacuum/default/initalData.ts +152 -0
  128. package/src/behaviors/roborock.vacuum/default/runtimes.ts +23 -0
  129. package/src/behaviors/roborock.vacuum/smart/initalData.ts +20 -0
  130. package/src/behaviors/roborock.vacuum/smart/runtimes.ts +15 -0
  131. package/src/behaviors/roborock.vacuum/smart/smart.ts +159 -0
  132. package/src/clientManager.ts +23 -0
  133. package/src/helper.ts +97 -0
  134. package/src/index.ts +16 -0
  135. package/src/initialData/getBatteryStatus.ts +26 -0
  136. package/src/initialData/getOperationalStates.ts +94 -0
  137. package/src/initialData/getSupportedAreas.ts +162 -0
  138. package/src/initialData/getSupportedCleanModes.ts +22 -0
  139. package/src/initialData/getSupportedRunModes.ts +14 -0
  140. package/src/initialData/getSupportedScenes.ts +32 -0
  141. package/src/initialData/index.ts +6 -0
  142. package/src/model/CloudMessageModel.ts +11 -0
  143. package/src/model/DockingStationStatus.ts +41 -0
  144. package/src/model/ExperimentalFeatureSetting.ts +77 -0
  145. package/src/model/RoomMap.ts +38 -0
  146. package/src/model/roomIndexMap.ts +26 -0
  147. package/src/notifyMessageTypes.ts +8 -0
  148. package/src/platform.ts +424 -0
  149. package/src/platformRunner.ts +103 -0
  150. package/src/roborockCommunication/RESTAPI/roborockAuthenticateApi.ts +302 -0
  151. package/src/roborockCommunication/RESTAPI/roborockIoTApi.ts +107 -0
  152. package/src/roborockCommunication/Zenum/additionalPropCode.ts +3 -0
  153. package/src/roborockCommunication/Zenum/authenticateResponseCode.ts +6 -0
  154. package/src/roborockCommunication/Zenum/dockType.ts +3 -0
  155. package/src/roborockCommunication/Zenum/operationStatusCode.ts +43 -0
  156. package/src/roborockCommunication/Zenum/vacuumAndDockErrorCode.ts +68 -0
  157. package/src/roborockCommunication/Zmodel/apiResponse.ts +3 -0
  158. package/src/roborockCommunication/Zmodel/authenticateFlowState.ts +6 -0
  159. package/src/roborockCommunication/Zmodel/authenticateResponse.ts +5 -0
  160. package/src/roborockCommunication/Zmodel/baseURL.ts +5 -0
  161. package/src/roborockCommunication/Zmodel/batteryMessage.ts +16 -0
  162. package/src/roborockCommunication/Zmodel/device.ts +50 -0
  163. package/src/roborockCommunication/Zmodel/deviceModel.ts +27 -0
  164. package/src/roborockCommunication/Zmodel/deviceSchema.ts +8 -0
  165. package/src/roborockCommunication/Zmodel/deviceStatus.ts +30 -0
  166. package/src/roborockCommunication/Zmodel/dockInfo.ts +9 -0
  167. package/src/roborockCommunication/Zmodel/home.ts +13 -0
  168. package/src/roborockCommunication/Zmodel/homeInfo.ts +5 -0
  169. package/src/roborockCommunication/Zmodel/map.ts +20 -0
  170. package/src/roborockCommunication/Zmodel/mapInfo.ts +54 -0
  171. package/src/roborockCommunication/Zmodel/messageResult.ts +75 -0
  172. package/src/roborockCommunication/Zmodel/multipleMap.ts +8 -0
  173. package/src/roborockCommunication/Zmodel/networkInfo.ts +7 -0
  174. package/src/roborockCommunication/Zmodel/product.ts +9 -0
  175. package/src/roborockCommunication/Zmodel/room.ts +4 -0
  176. package/src/roborockCommunication/Zmodel/roomInfo.ts +30 -0
  177. package/src/roborockCommunication/Zmodel/scene.ts +44 -0
  178. package/src/roborockCommunication/Zmodel/userData.ts +26 -0
  179. package/src/roborockCommunication/Zmodel/vacuumError.ts +35 -0
  180. package/src/roborockCommunication/broadcast/abstractClient.ts +80 -0
  181. package/src/roborockCommunication/broadcast/client/LocalNetworkClient.ts +218 -0
  182. package/src/roborockCommunication/broadcast/client/LocalNetworkUDPClient.ts +157 -0
  183. package/src/roborockCommunication/broadcast/client/MQTTClient.ts +174 -0
  184. package/src/roborockCommunication/broadcast/client.ts +19 -0
  185. package/src/roborockCommunication/broadcast/clientRouter.ts +104 -0
  186. package/src/roborockCommunication/broadcast/listener/abstractConnectionListener.ts +6 -0
  187. package/src/roborockCommunication/broadcast/listener/abstractMessageHandler.ts +11 -0
  188. package/src/roborockCommunication/broadcast/listener/abstractMessageListener.ts +5 -0
  189. package/src/roborockCommunication/broadcast/listener/implementation/chainedConnectionListener.ts +33 -0
  190. package/src/roborockCommunication/broadcast/listener/implementation/chainedMessageListener.ts +16 -0
  191. package/src/roborockCommunication/broadcast/listener/implementation/connectionStateListener.ts +57 -0
  192. package/src/roborockCommunication/broadcast/listener/implementation/generalSyncMessageListener.ts +38 -0
  193. package/src/roborockCommunication/broadcast/listener/implementation/simpleMessageListener.ts +37 -0
  194. package/src/roborockCommunication/broadcast/listener/implementation/syncMessageListener.ts +50 -0
  195. package/src/roborockCommunication/broadcast/listener/index.ts +3 -0
  196. package/src/roborockCommunication/broadcast/messageProcessor.ts +184 -0
  197. package/src/roborockCommunication/broadcast/model/contentMessage.ts +5 -0
  198. package/src/roborockCommunication/broadcast/model/dps.ts +19 -0
  199. package/src/roborockCommunication/broadcast/model/headerMessage.ts +7 -0
  200. package/src/roborockCommunication/broadcast/model/messageContext.ts +53 -0
  201. package/src/roborockCommunication/broadcast/model/protocol.ts +28 -0
  202. package/src/roborockCommunication/broadcast/model/requestMessage.ts +51 -0
  203. package/src/roborockCommunication/broadcast/model/responseMessage.ts +19 -0
  204. package/src/roborockCommunication/helper/chunkBuffer.ts +18 -0
  205. package/src/roborockCommunication/helper/cryptoHelper.ts +30 -0
  206. package/src/roborockCommunication/helper/messageDeserializer.ts +119 -0
  207. package/src/roborockCommunication/helper/messageSerializer.ts +101 -0
  208. package/src/roborockCommunication/helper/nameDecoder.ts +78 -0
  209. package/src/roborockCommunication/helper/sequence.ts +18 -0
  210. package/src/roborockCommunication/index.ts +25 -0
  211. package/src/roborockService.ts +657 -0
  212. package/src/runtimes/handleCloudMessage.ts +134 -0
  213. package/src/runtimes/handleHomeDataMessage.ts +67 -0
  214. package/src/runtimes/handleLocalMessage.ts +209 -0
  215. package/src/rvc.ts +97 -0
  216. package/src/settings.ts +1 -0
  217. package/src/share/function.ts +103 -0
  218. package/src/share/runtimeHelper.ts +23 -0
  219. package/src/tests/behaviors/roborock.vacuum/default/default.test.ts +134 -0
  220. package/src/tests/behaviors/roborock.vacuum/smart/runtimes.test.ts +64 -0
  221. package/src/tests/behaviors/roborock.vacuum/smart/smart.test.ts +215 -0
  222. package/src/tests/helper.test.ts +162 -0
  223. package/src/tests/initialData/getSupportedAreas.test.ts +181 -0
  224. package/src/tests/model/DockingStationStatus.test.ts +39 -0
  225. package/src/tests/platformRunner.test.ts +188 -0
  226. package/src/tests/platformRunner2.test.ts +228 -0
  227. package/src/tests/platformRunner3.test.ts +46 -0
  228. package/src/tests/roborockCommunication/RESTAPI/roborockAuthenticateApi.test.ts +144 -0
  229. package/src/tests/roborockCommunication/RESTAPI/roborockIoTApi.test.ts +106 -0
  230. package/src/tests/roborockCommunication/broadcast/client/LocalNetworkClient.test.ts +189 -0
  231. package/src/tests/roborockCommunication/broadcast/client/MQTTClient.test.ts +208 -0
  232. package/src/tests/roborockCommunication/broadcast/clientRouter.test.ts +168 -0
  233. package/src/tests/roborockCommunication/broadcast/listener/implementation/chainedConnectionListener.test.ts +59 -0
  234. package/src/tests/roborockCommunication/broadcast/listener/implementation/chainedMessageListener.test.ts +46 -0
  235. package/src/tests/roborockCommunication/broadcast/listener/implementation/simpleMessageListener.test.ts +71 -0
  236. package/src/tests/roborockCommunication/broadcast/listener/implementation/syncMessageListener.test.ts +86 -0
  237. package/src/tests/roborockCommunication/broadcast/messageProcessor.test.ts +126 -0
  238. package/src/tests/roborockService.setSelectedAreas.test.ts +61 -0
  239. package/src/tests/roborockService.test.ts +517 -0
  240. package/src/tests/roborockService2.test.ts +69 -0
  241. package/src/tests/roborockService3.test.ts +133 -0
  242. package/src/tests/roborockService4.test.ts +76 -0
  243. package/src/tests/roborockService5.test.ts +79 -0
  244. package/src/tests/runtimes/handleCloudMessage.test.ts +200 -0
  245. package/src/tests/runtimes/handleHomeDataMessage.test.ts +54 -0
  246. package/src/tests/runtimes/handleLocalMessage.test.ts +227 -0
  247. package/src/tests/testData/mockData.ts +370 -0
  248. package/src/tests/testData/mockHomeData-a187.json +286 -0
  249. package/tsconfig.jest.json +21 -0
  250. package/tsconfig.json +37 -0
  251. package/tsconfig.production.json +19 -0
  252. package/tslint.json +9 -0
  253. package/web-for-testing/README.md +47 -0
  254. package/web-for-testing/nodemon.json +7 -0
  255. package/web-for-testing/package-lock.json +6600 -0
  256. package/web-for-testing/package.json +36 -0
  257. package/web-for-testing/src/app.ts +194 -0
  258. package/web-for-testing/tsconfig-ext.json +19 -0
  259. package/web-for-testing/tsconfig.json +23 -0
  260. package/web-for-testing/views/index.ejs +172 -0
  261. package/web-for-testing/watch.mjs +93 -0
package/src/helper.ts ADDED
@@ -0,0 +1,97 @@
1
+ import { debugStringify } from 'matterbridge/logger';
2
+ import { RoomMap } from './model/RoomMap.js';
3
+ import { RoborockMatterbridgePlatform } from './platform.js';
4
+ import { Device } from './roborockCommunication/index.js';
5
+ import { CloudMessageResult } from './roborockCommunication/Zmodel/messageResult.js';
6
+ import { MapRoom } from './roborockCommunication/Zmodel/mapInfo.js';
7
+
8
+ export function getVacuumProperty(device: Device, property: string): number | undefined {
9
+ if (device) {
10
+ const schemas = device.schema;
11
+ const schema = schemas.find((sch) => sch.code == property);
12
+
13
+ if (schema && device.deviceStatus && device.deviceStatus[schema.id] != undefined) {
14
+ return Number(device.deviceStatus[schema.id]);
15
+ }
16
+
17
+ if (device.deviceStatus && device.deviceStatus[property] != undefined) {
18
+ return Number(device.deviceStatus[property]);
19
+ }
20
+ }
21
+
22
+ return undefined;
23
+ }
24
+
25
+ export function isSupportedDevice(model: string): boolean {
26
+ return model.startsWith('roborock.vacuum.');
27
+ }
28
+
29
+ export function isStatusUpdate(result: unknown): boolean {
30
+ return (
31
+ Array.isArray(result) &&
32
+ result.length > 0 &&
33
+ typeof result[0] === 'object' &&
34
+ result[0] !== null &&
35
+ 'msg_ver' in result[0] &&
36
+ (result[0] as CloudMessageResult).msg_ver !== undefined &&
37
+ (result[0] as CloudMessageResult).msg_ver !== null
38
+ );
39
+ }
40
+
41
+ export async function getRoomMap(duid: string, platform: RoborockMatterbridgePlatform): Promise<RoomMap | undefined> {
42
+ const robot = platform.robots.get(duid);
43
+ const enableMultipleMap = (platform.enableExperimentalFeature?.enableExperimentalFeature && platform.enableExperimentalFeature?.advancedFeature.enableMultipleMap) ?? false;
44
+ if (robot === undefined) {
45
+ platform.log.error(`Error6: Robot with DUID ${duid} not found`);
46
+ return undefined;
47
+ }
48
+
49
+ if (platform.roborockService === undefined) return undefined;
50
+
51
+ const rooms = robot.device.rooms ?? [];
52
+
53
+ if (robot.roomInfo === undefined) {
54
+ const mapInfo = await platform.roborockService.getMapInformation(robot.device.duid);
55
+ if (mapInfo && mapInfo.allRooms && mapInfo.allRooms.length > 0) {
56
+ platform.log.info(`getRoomMap - mapInfo: ${debugStringify(mapInfo.allRooms)}`);
57
+ robot.roomInfo = new RoomMap(mapInfo.allRooms, rooms, mapInfo.maps, enableMultipleMap);
58
+ }
59
+ }
60
+
61
+ if (robot.roomInfo === undefined) {
62
+ const roomData = await platform.roborockService.getRoomMappings(robot.device.duid);
63
+ if (roomData !== undefined && roomData.length > 0) {
64
+ const roomDataMap: MapRoom[] = roomData.map((r) => ({ id: r[0], iot_name_id: String(r[1]), globalId: r[1], tag: r[2], mapId: 0, displayName: undefined }));
65
+ robot.roomInfo = new RoomMap(roomDataMap, rooms, [], enableMultipleMap);
66
+ return robot.roomInfo;
67
+ }
68
+ }
69
+
70
+ return robot.roomInfo;
71
+ }
72
+
73
+ export async function getRoomMapFromDevice(device: Device, platform: RoborockMatterbridgePlatform): Promise<RoomMap> {
74
+ const rooms = device?.rooms ?? [];
75
+ const enableMultipleMap = (platform.enableExperimentalFeature?.enableExperimentalFeature && platform.enableExperimentalFeature?.advancedFeature.enableMultipleMap) ?? false;
76
+ if (device && platform.roborockService) {
77
+ const mapInfo = await platform.roborockService.getMapInformation(device.duid);
78
+ platform.log.debug(`getRoomMapFromDevice - mapInfo: ${mapInfo ? debugStringify(mapInfo) : 'undefined'}`);
79
+ platform.log.debug(`getRoomMapFromDevice - rooms: ${debugStringify(rooms)}`);
80
+
81
+ if (mapInfo && mapInfo.allRooms && mapInfo.allRooms.length > 0) {
82
+ const roomDataMap = mapInfo.allRooms; // .map((r) => [r.id, parseInt(r.iot_name_id), r.tag, r.mapId] as [number, number, number, number]);
83
+ const roomMap = new RoomMap(roomDataMap, rooms, mapInfo.maps, enableMultipleMap);
84
+ return roomMap;
85
+ }
86
+
87
+ const roomData = await platform.roborockService.getRoomMappings(device.duid);
88
+ if (roomData !== undefined && roomData.length > 0) {
89
+ platform.log.notice(`getRoomMapFromDevice - roomData: ${debugStringify(roomData ?? [])}`);
90
+ const roomDataMap: MapRoom[] = roomData.map((r) => ({ id: r[0], iot_name_id: String(r[1]), globalId: r[1], tag: r[2], mapId: 0, displayName: undefined }));
91
+ const roomMap = new RoomMap(roomDataMap ?? [], rooms, [], enableMultipleMap);
92
+ return roomMap;
93
+ }
94
+ }
95
+
96
+ return new RoomMap([], rooms, [], enableMultipleMap);
97
+ }
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { Matterbridge, PlatformConfig } from 'matterbridge';
2
+ import { AnsiLogger } from 'matterbridge/logger';
3
+ import { RoborockMatterbridgePlatform } from './platform.js';
4
+
5
+ /**
6
+ * This is the standard interface for Matterbridge plugins.
7
+ * Each plugin should export a default function that follows this signature.
8
+ *
9
+ * @param {Matterbridge} matterbridge - The Matterbridge instance.
10
+ * @param {AnsiLogger} log - The logger instance.
11
+ * @param {PlatformConfig} config - The platform configuration.
12
+ * @returns {RoborockMatterbridgePlatform} The initialized platform.
13
+ */
14
+ export default function initializePlugin(matterbridge: Matterbridge, log: AnsiLogger, config: PlatformConfig): RoborockMatterbridgePlatform {
15
+ return new RoborockMatterbridgePlatform(matterbridge, log, config);
16
+ }
@@ -0,0 +1,26 @@
1
+ import { PowerSource } from 'matterbridge/matter/clusters';
2
+ import { OperationStatusCode } from '../roborockCommunication/Zenum/operationStatusCode.js';
3
+
4
+ export function getBatteryStatus(batteryLevel?: number): PowerSource.BatChargeLevel {
5
+ if (batteryLevel === undefined) return PowerSource.BatChargeLevel.Ok;
6
+
7
+ if (batteryLevel >= 70) {
8
+ return PowerSource.BatChargeLevel.Ok;
9
+ } else if (batteryLevel >= 40) {
10
+ return PowerSource.BatChargeLevel.Warning;
11
+ } else {
12
+ return PowerSource.BatChargeLevel.Critical;
13
+ }
14
+ }
15
+
16
+ export function getBatteryState(deviceState: number, batRemaining: number): PowerSource.BatChargeState {
17
+ if (deviceState == OperationStatusCode.Charging) {
18
+ return batRemaining < 100 ? PowerSource.BatChargeState.IsCharging : PowerSource.BatChargeState.IsAtFullCharge;
19
+ }
20
+
21
+ if (deviceState == OperationStatusCode.ChargingError) {
22
+ return PowerSource.BatChargeState.IsNotCharging;
23
+ }
24
+
25
+ return PowerSource.BatChargeState.IsAtFullCharge;
26
+ }
@@ -0,0 +1,94 @@
1
+ import { RvcOperationalState } from 'matterbridge/matter/clusters';
2
+ import { getDefaultOperationalStates } from '../behaviors/roborock.vacuum/default/initalData.js';
3
+ import { VacuumErrorCode } from '../roborockCommunication/Zenum/vacuumAndDockErrorCode.js';
4
+ import { DockingStationStatus, DockingStationStatusType, hasDockingStationError } from '../model/DockingStationStatus.js';
5
+
6
+ export function getOperationalStates(): RvcOperationalState.OperationalStateStruct[] {
7
+ return getDefaultOperationalStates();
8
+ }
9
+
10
+ export function getOperationalErrorState(errorCode: VacuumErrorCode): RvcOperationalState.OperationalState | undefined {
11
+ switch (errorCode) {
12
+ case VacuumErrorCode.None:
13
+ return undefined;
14
+ default: {
15
+ return RvcOperationalState.OperationalState.Error;
16
+ }
17
+ }
18
+ }
19
+
20
+ export function getErrorFromErrorCode(errorCode: VacuumErrorCode): RvcOperationalState.ErrorStateStruct | undefined {
21
+ const operationalState = getOperationalErrorState(errorCode);
22
+ if (operationalState) {
23
+ return {
24
+ errorStateId: RvcOperationalState.ErrorState.NoError,
25
+ errorStateLabel: `${RvcOperationalState.ErrorState.NoError}`,
26
+ errorStateDetails: `Error code: ${errorCode}`,
27
+ };
28
+ }
29
+ return undefined;
30
+ }
31
+
32
+ export function getErrorFromDSS(status: DockingStationStatus): RvcOperationalState.ErrorStateStruct | undefined {
33
+ if (!status) {
34
+ return {
35
+ errorStateId: RvcOperationalState.ErrorState.NoError,
36
+ errorStateLabel: 'No Docking Station Status',
37
+ errorStateDetails: 'Docking station status is not available.',
38
+ };
39
+ }
40
+
41
+ const hasError = hasDockingStationError(status);
42
+
43
+ if (hasError) {
44
+ if (status.cleanFluidStatus === DockingStationStatusType.Error) {
45
+ return {
46
+ errorStateId: RvcOperationalState.ErrorState.MopCleaningPadMissing,
47
+ errorStateLabel: 'Clean Fluid Error',
48
+ errorStateDetails: 'The clean fluid is not available or has an issue.',
49
+ };
50
+ }
51
+
52
+ if (status.waterBoxFilterStatus === DockingStationStatusType.Error) {
53
+ return {
54
+ errorStateId: RvcOperationalState.ErrorState.WaterTankEmpty,
55
+ errorStateLabel: 'Water Box Filter Error',
56
+ errorStateDetails: 'The water box filter is not available or has an issue.',
57
+ };
58
+ }
59
+
60
+ if (status.dustBagStatus === DockingStationStatusType.Error) {
61
+ return {
62
+ errorStateId: RvcOperationalState.ErrorState.DustBinMissing,
63
+ errorStateLabel: 'Dust Bag Error',
64
+ errorStateDetails: 'The dust bag is not available or has an issue.',
65
+ };
66
+ }
67
+
68
+ if (status.dirtyWaterBoxStatus === DockingStationStatusType.Error) {
69
+ return {
70
+ errorStateId: RvcOperationalState.ErrorState.WaterTankEmpty, // TODO: Check if this is correct
71
+ errorStateLabel: 'Dirty Water Box Error',
72
+ errorStateDetails: 'The dirty water box is not available or has an issue.',
73
+ };
74
+ }
75
+
76
+ if (status.clearWaterBoxStatus === DockingStationStatusType.Error) {
77
+ return {
78
+ errorStateId: RvcOperationalState.ErrorState.WaterTankEmpty,
79
+ errorStateLabel: 'Clear Water Box Error',
80
+ errorStateDetails: 'The clear water box is not available or has an issue.',
81
+ };
82
+ }
83
+
84
+ if (status.isUpdownWaterReady === DockingStationStatusType.Error) {
85
+ return {
86
+ errorStateId: RvcOperationalState.ErrorState.WaterTankMissing,
87
+ errorStateLabel: 'Updown Water Ready Error',
88
+ errorStateDetails: 'The updown water tank is not ready or has an issue.',
89
+ };
90
+ }
91
+ }
92
+
93
+ return undefined;
94
+ }
@@ -0,0 +1,162 @@
1
+ import { AnsiLogger, debugStringify } from 'matterbridge/logger';
2
+ import { ServiceArea } from 'matterbridge/matter/clusters';
3
+ import { RoomMap } from '../model/RoomMap.js';
4
+ import { Room } from '../roborockCommunication/Zmodel/room.js';
5
+ import { randomInt } from 'node:crypto';
6
+ import { RoomIndexMap } from '../model/roomIndexMap.js';
7
+
8
+ export interface SupportedAreasResult {
9
+ supportedAreas: ServiceArea.Area[];
10
+ supportedMaps: ServiceArea.Map[];
11
+ roomIndexMap: RoomIndexMap;
12
+ }
13
+
14
+ export function getSupportedAreas(vacuumRooms: Room[], roomMap: RoomMap | undefined, enableMultipleMap = false, log?: AnsiLogger): SupportedAreasResult {
15
+ log?.debug('getSupportedAreas-vacuum room', debugStringify(vacuumRooms));
16
+ log?.debug('getSupportedAreas-roomMap', roomMap ? debugStringify(roomMap) : 'undefined');
17
+
18
+ const noVacuumRooms = !vacuumRooms || vacuumRooms.length === 0;
19
+ const noRoomMap = !roomMap?.rooms || roomMap.rooms.length === 0;
20
+
21
+ if (noVacuumRooms || noRoomMap) {
22
+ if (noVacuumRooms) {
23
+ log?.error('No rooms found');
24
+ }
25
+ if (noRoomMap) {
26
+ log?.error('No room map found');
27
+ }
28
+
29
+ return {
30
+ supportedAreas: [
31
+ {
32
+ areaId: 1,
33
+ mapId: null,
34
+ areaInfo: {
35
+ locationInfo: {
36
+ locationName: 'Unknown',
37
+ floorNumber: null,
38
+ areaType: null,
39
+ },
40
+ landmarkInfo: null,
41
+ },
42
+ },
43
+ ],
44
+ supportedMaps: [],
45
+ roomIndexMap: new RoomIndexMap(new Map([[1, { roomId: 1, mapId: null }]])),
46
+ };
47
+ }
48
+ const { supportedAreas, indexMap } = processValidData(enableMultipleMap, vacuumRooms, roomMap);
49
+ const duplicated = findDuplicatedAreaIds(supportedAreas, log);
50
+
51
+ if (duplicated) {
52
+ return {
53
+ supportedAreas: [
54
+ {
55
+ areaId: 2,
56
+ mapId: null,
57
+ areaInfo: {
58
+ locationInfo: {
59
+ locationName: 'Unknown - Duplicated Areas Found',
60
+ floorNumber: null,
61
+ areaType: null,
62
+ },
63
+ landmarkInfo: null,
64
+ },
65
+ },
66
+ ],
67
+ supportedMaps: [],
68
+ roomIndexMap: new RoomIndexMap(new Map([[2, { roomId: 2, mapId: null }]])),
69
+ };
70
+ }
71
+
72
+ const supportedMaps = getSupportedMaps(enableMultipleMap, supportedAreas, roomMap);
73
+
74
+ log?.debug('getSupportedAreas - supportedAreas', debugStringify(supportedAreas));
75
+ log?.debug('getSupportedAreas - supportedMaps', debugStringify(supportedMaps));
76
+ const roomIndexMap = new RoomIndexMap(indexMap);
77
+ return {
78
+ supportedAreas,
79
+ supportedMaps,
80
+ roomIndexMap,
81
+ };
82
+ }
83
+
84
+ interface SupportedArea {
85
+ areaId: number;
86
+ mapId: number;
87
+ }
88
+
89
+ function findDuplicatedAreaIds(areas: ServiceArea.Area[], log?: AnsiLogger): boolean {
90
+ const seen = new Set<string>();
91
+ const duplicates: SupportedArea[] = [];
92
+
93
+ for (const area of areas) {
94
+ const key = `${area.areaId}=${area.mapId}`;
95
+ if (seen.has(key)) {
96
+ duplicates.push({ areaId: area.areaId, mapId: area.mapId ?? 0 });
97
+ } else {
98
+ seen.add(key);
99
+ }
100
+ }
101
+
102
+ if (duplicates.length > 0 && log) {
103
+ const duplicated = areas.filter(({ areaId, mapId }) => duplicates.some((y) => y.areaId === areaId && y.mapId === (mapId ?? 0)));
104
+ log.error(`Duplicated areaId(s) found: ${debugStringify(duplicated)}`);
105
+ }
106
+
107
+ return duplicates.length > 0;
108
+ }
109
+
110
+ export interface MapInfo {
111
+ roomId: number;
112
+ mapId: number | null;
113
+ }
114
+
115
+ interface ProcessedData {
116
+ supportedAreas: ServiceArea.Area[];
117
+ indexMap: Map<number, MapInfo>;
118
+ }
119
+
120
+ function processValidData(enableMultipleMap: boolean, vacuumRooms: Room[], roomMap?: RoomMap): ProcessedData {
121
+ const indexMap = new Map<number, MapInfo>();
122
+ const supportedAreas: ServiceArea.Area[] =
123
+ roomMap?.rooms !== undefined && roomMap.rooms.length > 0
124
+ ? roomMap.rooms.map((room, index) => {
125
+ const locationName = room.displayName ?? vacuumRooms.find((r) => r.id === room.globalId || r.id === room.id)?.name ?? `Unknown Room ${randomInt(1000, 9999)}`;
126
+
127
+ const areaId = enableMultipleMap ? index + 100 : room.id;
128
+ const mapId = enableMultipleMap ? (room.mapId ?? null) : null;
129
+
130
+ indexMap.set(areaId, { roomId: room.id, mapId: room.mapId ?? null });
131
+ return {
132
+ areaId: areaId,
133
+ mapId: mapId,
134
+ areaInfo: {
135
+ locationInfo: {
136
+ locationName: locationName,
137
+ floorNumber: room.mapId ?? null,
138
+ areaType: null,
139
+ },
140
+ landmarkInfo: null,
141
+ },
142
+ };
143
+ })
144
+ : [];
145
+ return {
146
+ supportedAreas,
147
+ indexMap,
148
+ };
149
+ }
150
+
151
+ function getSupportedMaps(enableMultipleMap: boolean, supportedAreas: ServiceArea.Area[], roomMap?: RoomMap): ServiceArea.Map[] {
152
+ if (enableMultipleMap) {
153
+ return (
154
+ roomMap?.mapInfo?.map((map) => ({
155
+ mapId: map.id,
156
+ name: map.name ?? `Map ${map.id}`,
157
+ })) ?? []
158
+ );
159
+ }
160
+
161
+ return [];
162
+ }
@@ -0,0 +1,22 @@
1
+ import { RvcCleanMode } from 'matterbridge/matter/clusters';
2
+ import { getSupportedCleanModesSmart } from '../behaviors/roborock.vacuum/smart/initalData.js';
3
+ import { getDefaultSupportedCleanModes } from '../behaviors/roborock.vacuum/default/initalData.js';
4
+ import { DeviceModel } from '../roborockCommunication/Zmodel/deviceModel.js';
5
+ import { ExperimentalFeatureSetting } from '../model/ExperimentalFeatureSetting.js';
6
+
7
+ export function getSupportedCleanModes(model: string, enableExperimentalFeature: ExperimentalFeatureSetting | undefined): RvcCleanMode.ModeOption[] {
8
+ if (enableExperimentalFeature?.advancedFeature?.forceRunAtDefault ?? false) {
9
+ return getDefaultSupportedCleanModes(enableExperimentalFeature);
10
+ }
11
+
12
+ switch (model) {
13
+ case DeviceModel.QREVO_EDGE_5V1:
14
+ return getSupportedCleanModesSmart(enableExperimentalFeature);
15
+
16
+ case DeviceModel.S7_MAXV:
17
+ case DeviceModel.S8_PRO_ULTRA:
18
+ case DeviceModel.S6_PURE:
19
+ default:
20
+ return getDefaultSupportedCleanModes(enableExperimentalFeature);
21
+ }
22
+ }
@@ -0,0 +1,14 @@
1
+ import { RvcRunMode } from 'matterbridge/matter/clusters';
2
+ import { getDefaultSupportedRunModes } from '../behaviors/roborock.vacuum/default/initalData.js';
3
+
4
+ export function getRunningMode(modeTag: RvcRunMode.ModeTag | undefined): number | null {
5
+ if (!modeTag) return null;
6
+
7
+ const supportedMode = getDefaultSupportedRunModes();
8
+ const runningMode = supportedMode.find((s) => s.modeTags.some((mt) => mt.value === modeTag));
9
+ return runningMode?.mode ?? null;
10
+ }
11
+
12
+ export function getSupportedRunModes(): RvcRunMode.ModeOption[] {
13
+ return getDefaultSupportedRunModes();
14
+ }
@@ -0,0 +1,32 @@
1
+ import { AnsiLogger, debugStringify } from 'matterbridge/logger';
2
+ import { ServiceArea } from 'matterbridge/matter/clusters';
3
+ import { Scene } from '../roborockCommunication/index.js';
4
+ import { randomInt } from 'node:crypto';
5
+
6
+ export function getSupportedScenes(scenes: Scene[], log?: AnsiLogger): ServiceArea.Area[] {
7
+ log?.debug('getSupportedScenes', debugStringify(scenes));
8
+
9
+ if (!scenes || scenes.length === 0) {
10
+ log?.error('No scenes found');
11
+ return [];
12
+ }
13
+
14
+ const supportedAreas: ServiceArea.Area[] = scenes
15
+ .filter((s) => s.enabled && s.id)
16
+ .map((scene) => {
17
+ return {
18
+ areaId: scene.id ?? 0 + randomInt(5000, 9000),
19
+ mapId: null,
20
+ areaInfo: {
21
+ locationInfo: {
22
+ locationName: `Scene: ${scene.name}`,
23
+ floorNumber: null,
24
+ areaType: null,
25
+ },
26
+ landmarkInfo: null,
27
+ },
28
+ };
29
+ });
30
+
31
+ return supportedAreas;
32
+ }
@@ -0,0 +1,6 @@
1
+ export { getSupportedRunModes } from './getSupportedRunModes.js';
2
+ export { getOperationalStates, getOperationalErrorState } from './getOperationalStates.js';
3
+ export { getSupportedCleanModes } from './getSupportedCleanModes.js';
4
+ export { getSupportedAreas } from './getSupportedAreas.js';
5
+ export { getBatteryStatus, getBatteryState } from './getBatteryStatus.js';
6
+ export { getSupportedScenes } from './getSupportedScenes.js';
@@ -0,0 +1,11 @@
1
+ import { CloudMessageResult } from '../roborockCommunication/Zmodel/messageResult.js';
2
+
3
+ interface CloudMessageDpsEntry {
4
+ id: number;
5
+ result: CloudMessageResult[];
6
+ }
7
+
8
+ export interface CloudMessageModel {
9
+ duid: string;
10
+ dps: Record<string, number | CloudMessageDpsEntry>;
11
+ }
@@ -0,0 +1,41 @@
1
+ export interface DockingStationStatus {
2
+ cleanFluidStatus: number;
3
+ waterBoxFilterStatus: number;
4
+ dustBagStatus: number;
5
+ dirtyWaterBoxStatus: number;
6
+ clearWaterBoxStatus: number;
7
+ isUpdownWaterReady: number;
8
+ }
9
+ // {"cleanFluidStatus":0,"waterBoxFilterStatus":0,"dustBagStatus":2,"dirtyWaterBoxStatus":2,"clearWaterBoxStatus":2,"isUpdownWaterReady":0}
10
+
11
+ export enum DockingStationStatusType {
12
+ Unknown = 0,
13
+ Error = 1,
14
+ OK = 2,
15
+ }
16
+
17
+ export function parseDockingStationStatus(dss: number): DockingStationStatus {
18
+ return {
19
+ cleanFluidStatus: (dss >> 10) & 0b11,
20
+ waterBoxFilterStatus: (dss >> 8) & 0b11,
21
+ dustBagStatus: (dss >> 6) & 0b11,
22
+ dirtyWaterBoxStatus: (dss >> 4) & 0b11,
23
+ clearWaterBoxStatus: (dss >> 2) & 0b11,
24
+ isUpdownWaterReady: dss & 0b11,
25
+ };
26
+ }
27
+
28
+ export function hasDockingStationError(status: DockingStationStatus | undefined): boolean {
29
+ if (!status) {
30
+ return false;
31
+ }
32
+
33
+ return (
34
+ status.cleanFluidStatus === DockingStationStatusType.Error ||
35
+ status.waterBoxFilterStatus === DockingStationStatusType.Error ||
36
+ status.dustBagStatus === DockingStationStatusType.Error ||
37
+ status.dirtyWaterBoxStatus === DockingStationStatusType.Error ||
38
+ status.clearWaterBoxStatus === DockingStationStatusType.Error
39
+ // || status.isUpdownWaterReady === DockingStationStatusType.Error
40
+ );
41
+ }
@@ -0,0 +1,77 @@
1
+ export interface AdvancedFeature {
2
+ showRoutinesAsRoom: boolean;
3
+ includeDockStationStatus: boolean;
4
+ forceRunAtDefault: boolean;
5
+ useVacationModeToSendVacuumToDock: boolean;
6
+ enableServerMode: boolean;
7
+ alwaysExecuteAuthentication: boolean;
8
+ enableMultipleMap: boolean;
9
+ }
10
+
11
+ export interface AuthenticationPayload {
12
+ authenticationMethod: 'VerificationCode' | 'Password';
13
+ verificationCode?: string;
14
+ password?: string;
15
+ }
16
+
17
+ export interface ExperimentalFeatureSetting {
18
+ enableExperimentalFeature: boolean;
19
+ advancedFeature: AdvancedFeature;
20
+ cleanModeSettings: CleanModeSettings;
21
+ }
22
+
23
+ interface VacuumingCleanModeSetting {
24
+ fanMode: 'Balanced' | string;
25
+ mopRouteMode: 'Standard' | string;
26
+ }
27
+
28
+ interface MoppingCleanModeSetting {
29
+ waterFlowMode: 'Medium' | string;
30
+ mopRouteMode: 'Standard' | string;
31
+ distanceOff?: number;
32
+ }
33
+
34
+ interface VacMopCleanModeSetting {
35
+ fanMode: 'Balanced' | string;
36
+ waterFlowMode: 'Medium' | string;
37
+ mopRouteMode: 'Standard' | string;
38
+ distanceOff?: number;
39
+ }
40
+
41
+ export interface CleanModeSettings {
42
+ enableCleanModeMapping: boolean;
43
+ vacuuming?: VacuumingCleanModeSetting;
44
+ mopping?: MoppingCleanModeSetting;
45
+ vacmop?: VacMopCleanModeSetting;
46
+ }
47
+
48
+ export function createDefaultExperimentalFeatureSetting(): ExperimentalFeatureSetting {
49
+ return {
50
+ enableExperimentalFeature: false,
51
+ advancedFeature: {
52
+ showRoutinesAsRoom: false,
53
+ includeDockStationStatus: false,
54
+ forceRunAtDefault: false,
55
+ useVacationModeToSendVacuumToDock: false,
56
+ enableServerMode: false,
57
+ alwaysExecuteAuthentication: false,
58
+ enableMultipleMap: false,
59
+ },
60
+ cleanModeSettings: {
61
+ enableCleanModeMapping: false,
62
+ vacuuming: {
63
+ fanMode: 'Balanced',
64
+ mopRouteMode: 'Standard',
65
+ },
66
+ mopping: {
67
+ waterFlowMode: 'Medium',
68
+ mopRouteMode: 'Standard',
69
+ },
70
+ vacmop: {
71
+ fanMode: 'Balanced',
72
+ waterFlowMode: 'Medium',
73
+ mopRouteMode: 'Standard',
74
+ },
75
+ },
76
+ };
77
+ }
@@ -0,0 +1,38 @@
1
+ import { MapRoom } from '../roborockCommunication/Zmodel/mapInfo.js';
2
+ import { Room } from '../roborockCommunication/Zmodel/room.js';
3
+
4
+ export interface RoomMapEntry {
5
+ id: number;
6
+ globalId: number | undefined;
7
+ displayName: string;
8
+ alternativeId: string;
9
+ mapId?: number;
10
+ }
11
+
12
+ export interface MapInfo {
13
+ id: number;
14
+ name: string | undefined;
15
+ }
16
+
17
+ export class RoomMap {
18
+ rooms: RoomMapEntry[];
19
+ mapInfo?: MapInfo[];
20
+
21
+ constructor(roomData: MapRoom[], rooms: Room[], mapInfo: MapInfo[], enableMultipleMap: boolean) {
22
+ const mapid = mapInfo[0]?.id ?? 0;
23
+ const roomDataTmp = enableMultipleMap ? roomData : roomData.filter((room) => room.mapId === undefined || room.mapId === mapid);
24
+
25
+ this.rooms = roomDataTmp.map(({ id, globalId, tag, mapId }) => {
26
+ const room = rooms.find((r) => Number(r.id) === Number(globalId) || Number(r.id) === Number(id));
27
+ return {
28
+ id,
29
+ globalId: globalId !== undefined ? Number(globalId) : undefined,
30
+ displayName: room?.name ?? `Room ${id}`,
31
+ alternativeId: `${id}${tag}`,
32
+ mapId,
33
+ };
34
+ });
35
+
36
+ this.mapInfo = mapInfo;
37
+ }
38
+ }
@@ -0,0 +1,26 @@
1
+ import { MapInfo } from '../initialData/getSupportedAreas.js';
2
+
3
+ export class RoomIndexMap {
4
+ public indexMap: Map<number, MapInfo>;
5
+ public roomMap: Map<string, number>;
6
+
7
+ constructor(roomMap: Map<number, MapInfo>) {
8
+ this.indexMap = roomMap;
9
+ this.roomMap = new Map();
10
+ for (const [areaId, r] of roomMap.entries()) {
11
+ this.roomMap.set(`${r.roomId}:${r.mapId}`, areaId);
12
+ }
13
+ }
14
+
15
+ public getAreaId(roomId: number, mapId: number): number | undefined {
16
+ const areaId = this.roomMap.get(`${roomId}:${mapId}`);
17
+ if (areaId === undefined) {
18
+ return undefined;
19
+ }
20
+ return areaId;
21
+ }
22
+
23
+ public getRoomId(areaId: number): number | undefined {
24
+ return this.indexMap.get(areaId)?.roomId;
25
+ }
26
+ }
@@ -0,0 +1,8 @@
1
+ export enum NotifyMessageTypes {
2
+ LocalMessage = 'LocalMessage',
3
+ CloudMessage = 'CloudMessage',
4
+ BatteryUpdate = 'BatteryUpdate',
5
+ ErrorOccurred = 'ErrorOccurred',
6
+ HomeData = 'HomeData',
7
+ DeviceStatus = 'DeviceStatus',
8
+ }