homebridge-roborock-vacuum 0.1.0

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 (45) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE +21 -0
  3. package/README.md +37 -0
  4. package/config.schema.json +31 -0
  5. package/dist/index.js +10 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/logger.js +39 -0
  8. package/dist/logger.js.map +1 -0
  9. package/dist/platform.js +167 -0
  10. package/dist/platform.js.map +1 -0
  11. package/dist/settings.js +8 -0
  12. package/dist/settings.js.map +1 -0
  13. package/dist/types.js +3 -0
  14. package/dist/types.js.map +1 -0
  15. package/dist/vacuum_accessory.js +152 -0
  16. package/dist/vacuum_accessory.js.map +1 -0
  17. package/package.json +66 -0
  18. package/roborockLib/data/UserData +4 -0
  19. package/roborockLib/data/clientID +4 -0
  20. package/roborockLib/i18n/de/translations.json +188 -0
  21. package/roborockLib/i18n/en/translations.json +208 -0
  22. package/roborockLib/i18n/es/translations.json +188 -0
  23. package/roborockLib/i18n/fr/translations.json +188 -0
  24. package/roborockLib/i18n/it/translations.json +188 -0
  25. package/roborockLib/i18n/nl/translations.json +188 -0
  26. package/roborockLib/i18n/pl/translations.json +188 -0
  27. package/roborockLib/i18n/pt/translations.json +188 -0
  28. package/roborockLib/i18n/ru/translations.json +188 -0
  29. package/roborockLib/i18n/uk/translations.json +188 -0
  30. package/roborockLib/i18n/zh-cn/translations.json +188 -0
  31. package/roborockLib/lib/RRMapParser.js +447 -0
  32. package/roborockLib/lib/deviceFeatures.js +995 -0
  33. package/roborockLib/lib/localConnector.js +249 -0
  34. package/roborockLib/lib/map/map.html +110 -0
  35. package/roborockLib/lib/map/zones.js +713 -0
  36. package/roborockLib/lib/mapCreator.js +692 -0
  37. package/roborockLib/lib/message.js +223 -0
  38. package/roborockLib/lib/messageQueueHandler.js +87 -0
  39. package/roborockLib/lib/roborockPackageHelper.js +116 -0
  40. package/roborockLib/lib/roborock_mqtt_connector.js +349 -0
  41. package/roborockLib/lib/sniffing/mitmproxy_roborock.py +300 -0
  42. package/roborockLib/lib/vacuum.js +636 -0
  43. package/roborockLib/roborockAPI.js +1365 -0
  44. package/roborockLib/test.js +31 -0
  45. package/roborockLib/userdata.json +24 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - First version.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018-2019 Nico Hartung
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # homebridge-roborock-vacuum
2
+
3
+ ![Roborock Vacuum in Home App](https://is1-ssl.mzstatic.com/image/thumb/Purple211/v4/40/21/71/40217177-c879-f670-bd01-c93acfabc31e/AppIcon-0-0-1x_U007emarketing-0-8-0-85-220.png/460x0w.webp)
4
+
5
+ A Homebridge plugin to integrate your Roborock vacuum cleaner with Apple HomeKit, allowing you to control it via the Home app and Siri.
6
+
7
+ ## Introduction
8
+
9
+ `homebridge-roborock-vacuum` brings your Roborock vacuum cleaner into Apple HomeKit. Using your Roborock app account credentials, this plugin automatically detects your vacuum, enabling you to control it directly from the Home app on your iPhone, iPad, or Mac, or with Siri voice commands.
10
+
11
+ This plugin is inspired by and adapted from the [ioBroker.roborock](https://github.com/copystring/ioBroker.roborock) project by copystring.
12
+
13
+ ## Features
14
+
15
+ - **Automatic Device Detection**: No need to manually find or enter your vacuum's device ID.
16
+ - **Start/Stop Cleaning**: Begin or end cleaning sessions.
17
+
18
+ ## Requirements
19
+
20
+ Before installing, ensure you have:
21
+
22
+ - A Roborock vacuum cleaner compatible with the Roborock app.
23
+ - A Roborock app account (email and password).
24
+ - [Homebridge](https://github.com/homebridge/homebridge) installed on a server (e.g., Raspberry Pi).
25
+ - Node.js and npm installed on your Homebridge server.
26
+
27
+ ## Installation
28
+
29
+ Follow these steps to install the plugin:
30
+
31
+ 1. **Install Homebridge** (if not already installed):
32
+ - Refer to the official [Homebridge installation guide](https://github.com/homebridge/homebridge#installation).
33
+
34
+ 2. **Install the Plugin**:
35
+ - Open a terminal and run:
36
+ ```bash
37
+ npm install -g homebridge-roborock-vacuum
@@ -0,0 +1,31 @@
1
+ {
2
+ "pluginAlias": "RoborockVacuumPlatform",
3
+ "pluginType": "platform",
4
+ "schema": {
5
+ "type": "object",
6
+ "properties": {
7
+ "email": {
8
+ "type": "string",
9
+ "format": "email",
10
+ "description": "Roborock account email"
11
+ },
12
+ "password": {
13
+ "type": "string",
14
+ "description": "Roborock account password"
15
+ },
16
+ "baseURL": {
17
+ "type": "string",
18
+ "default": "usiot.roborock.com",
19
+ "description": "Roborock API endpoint"
20
+ }
21
+ ,
22
+ "debugMode": {
23
+ "title": "Debug Mode",
24
+ "description": "When enabled, debug messages will be written to the log.",
25
+ "type": "boolean",
26
+ "default": false
27
+ }
28
+ },
29
+ "required": ["email", "password"]
30
+ }
31
+ }
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const platform_1 = __importDefault(require("./platform"));
6
+ const settings_1 = require("./settings");
7
+ module.exports = (api) => {
8
+ api.registerPlatform(settings_1.PLATFORM_NAME, platform_1.default);
9
+ };
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AACA,0DAA0C;AAC1C,yCAA2C;AAK3C,iBAAS,CAAC,GAAQ,EAAE,EAAE;IACpB,GAAG,CAAC,gBAAgB,CAAC,wBAAa,EAAE,kBAAgB,CAAC,CAAC;AACxD,CAAC,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Decorates the Homebridge logger to only log debug messages when debug mode is enabled.
5
+ */
6
+ class RoborockPlatformLogger {
7
+ constructor(logger, debugMode) {
8
+ this.logger = logger;
9
+ this.debugMode = debugMode;
10
+ }
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ debug(...messages) {
13
+ if (this.debugMode) {
14
+ for (let i = 0; i < messages.length; i++) {
15
+ this.logger.debug(messages[i]);
16
+ }
17
+ }
18
+ }
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ info(...messages) {
21
+ for (let i = 0; i < messages.length; i++) {
22
+ this.logger.info(messages[i]);
23
+ }
24
+ }
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ warn(...messages) {
27
+ for (let i = 0; i < messages.length; i++) {
28
+ this.logger.warn(messages[i]);
29
+ }
30
+ }
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ error(...messages) {
33
+ for (let i = 0; i < messages.length; i++) {
34
+ this.logger.error(messages[i]);
35
+ }
36
+ }
37
+ }
38
+ exports.default = RoborockPlatformLogger;
39
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;AAEA;;GAEG;AACH,MAAqB,sBAAsB;IACzC,YACmB,MAAc,EACd,SAAkB;QADlB,WAAM,GAAN,MAAM,CAAQ;QACd,cAAS,GAAT,SAAS,CAAS;IAClC,CAAC;IAEJ,8DAA8D;IAC9D,KAAK,CAAC,GAAG,QAAe;QACtB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,IAAI,CAAC,GAAG,QAAe;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,IAAI,CAAC,GAAG,QAAe;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;IAEA,8DAA8D;IAC9D,KAAK,CAAC,GAAG,QAAe;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;CACF;AAnCD,yCAmCC"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vacuum_accessory_1 = __importDefault(require("./vacuum_accessory"));
7
+ const logger_1 = __importDefault(require("./logger"));
8
+ const settings_1 = require("./settings");
9
+ const Roborock = require("../roborockLib/roborockAPI").Roborock;
10
+ /**
11
+ * Roborock App Platform Plugin for Homebridge
12
+ * Based on https://github.com/homebridge/homebridge-plugin-template
13
+ */
14
+ class RoborockPlatform {
15
+ /**
16
+ * This constructor is where you should parse the user config
17
+ * and discover/register accessories with Homebridge.
18
+ *
19
+ * @param logger Homebridge logger
20
+ * @param config Homebridge platform config
21
+ * @param api Homebridge API
22
+ */
23
+ constructor(homebridgeLogger, config, api) {
24
+ this.api = api;
25
+ this.Service = this.api.hap.Service;
26
+ this.Characteristic = this.api.hap.Characteristic;
27
+ // Used to track restored cached accessories
28
+ this.accessories = [];
29
+ this.vacuums = [];
30
+ this.platformConfig = config;
31
+ // Initialise logging utility
32
+ this.log = new logger_1.default(homebridgeLogger, this.platformConfig.debugMode);
33
+ // Create Roborock App communication module
34
+ const username = this.platformConfig.email;
35
+ const password = this.platformConfig.password;
36
+ const baseURL = this.platformConfig.baseURL;
37
+ const debugMode = this.platformConfig.debugMode;
38
+ this.roborockAPI = new Roborock({ username: username, password: password, debug: debugMode, baseURL: baseURL, log: this.log });
39
+ /**
40
+ * When this event is fired it means Homebridge has restored all cached accessories from disk.
41
+ * Dynamic Platform plugins should only register new accessories after this event was fired,
42
+ * in order to ensure they weren't added to homebridge already. This event can also be used
43
+ * to start discovery of new accessories.
44
+ */
45
+ this.api.on("didFinishLaunching" /* APIEvent.DID_FINISH_LAUNCHING */, () => {
46
+ this.log.debug('Finished launching and restored cached accessories.');
47
+ this.configurePlugin();
48
+ });
49
+ this.api.on("shutdown" /* APIEvent.SHUTDOWN */, () => {
50
+ this.log.debug('Shutting down...');
51
+ if (this.roborockAPI) {
52
+ this.roborockAPI.stopService();
53
+ }
54
+ });
55
+ }
56
+ async configurePlugin() {
57
+ await this.loginAndDiscoverDevices();
58
+ }
59
+ async loginAndDiscoverDevices() {
60
+ if (!this.platformConfig.email) {
61
+ this.log.error('Email is not configured - aborting plugin start. '
62
+ + 'Please set the field `email` in your config and restart Homebridge.');
63
+ return;
64
+ }
65
+ if (!this.platformConfig.password) {
66
+ this.log.error('Password is not configured - aborting plugin start. '
67
+ + 'Please set the field `password` in your config and restart Homebridge.');
68
+ return;
69
+ }
70
+ const self = this;
71
+ self.roborockAPI.setDeviceNotify(function (id, homeData) {
72
+ console.warn(`${id} notifyDeviceUpdater:${JSON.stringify(homeData)}`);
73
+ for (const vacuum of self.vacuums) {
74
+ vacuum.notifyDeviceUpdater(id, homeData);
75
+ }
76
+ });
77
+ self.roborockAPI.startService(function () {
78
+ console.warn("Service started");
79
+ //call the discoverDevices function
80
+ self.discoverDevices();
81
+ });
82
+ }
83
+ /**
84
+ * This function is invoked when Homebridge restores cached accessories from disk at startup.
85
+ * It should be used to set up event handlers for characteristics and update respective values.
86
+ */
87
+ configureAccessory(accessory) {
88
+ this.log.info(`Loading accessory '${accessory.displayName}' from cache.`);
89
+ /**
90
+ * We don't have to set up the handlers here,
91
+ * because our device discovery function takes care of that.
92
+ *
93
+ * But we need to add the restored accessory to the
94
+ * accessories cache so we can access it during that process.
95
+ */
96
+ this.accessories.push(accessory);
97
+ }
98
+ isSupportedDevice(deviceType) {
99
+ return true;
100
+ }
101
+ /**
102
+ * Fetches all of the user's devices from Roborock App and sets up handlers.
103
+ *
104
+ * Accessories must only be registered once. Previously created accessories
105
+ * must not be registered again to prevent "duplicate UUID" errors.
106
+ */
107
+ async discoverDevices() {
108
+ this.log.info('Discovering vacuum devices...');
109
+ try {
110
+ const self = this;
111
+ if (self.roborockAPI.isInited()) {
112
+ self.roborockAPI.getVacuumList().forEach(function (device) {
113
+ var duid = device.duid;
114
+ var name = device.name;
115
+ var battery = self.roborockAPI.getVacuumDeviceStatus(duid, "battery");
116
+ if (!self.isSupportedDevice(device.deviceType)) {
117
+ self.log.info(`Device '${name}' (${duid}) is not supported.`);
118
+ return;
119
+ }
120
+ const uuid = self.api.hap.uuid.generate(device.duid);
121
+ const existingAccessory = self.accessories.find(accessory => accessory.UUID === uuid);
122
+ if (existingAccessory !== undefined) {
123
+ self.log.info(`Restoring accessory '${existingAccessory.displayName}' ` + `(${uuid}) from cache.`);
124
+ // If you need to update the accessory.context then you should run
125
+ // `api.updatePlatformAccessories`. eg.:
126
+ existingAccessory.context = duid;
127
+ self.api.updatePlatformAccessories([existingAccessory]);
128
+ // Create the accessory handler for the restored accessory
129
+ self.createRoborockAccessory(existingAccessory);
130
+ }
131
+ self.log.info(`Adding accessory '${name}' (${uuid}).`);
132
+ // The accessory does not yet exist, so we need to create it
133
+ const accessory = new self.api.platformAccessory(name, uuid);
134
+ // Store a copy of the device object in the `accessory.context` property,
135
+ // which can be used to store any data about the accessory you may need.
136
+ accessory.context = duid;
137
+ // Create the accessory handler for the newly create accessory
138
+ // this is imported from `platformAccessory.ts`
139
+ self.createRoborockAccessory(accessory);
140
+ // Link the accessory to your platform
141
+ self.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
142
+ });
143
+ }
144
+ // At this point, we set up all devices from Roborock App, but we did not unregister
145
+ // cached devices that do not exist on the Roborock App account anymore.
146
+ for (const cachedAccessory of this.accessories) {
147
+ if (cachedAccessory.context) {
148
+ const vacuum = self.roborockAPI.getVacuumDeviceData(cachedAccessory.context);
149
+ if (vacuum === undefined) {
150
+ // This cached devices does not exist on the Roborock App account (anymore).
151
+ this.log.info(`Removing accessory '${cachedAccessory.displayName}' (${cachedAccessory.context}) ` + 'because it does not exist on the Roborock account anymore.');
152
+ this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [cachedAccessory]);
153
+ }
154
+ }
155
+ }
156
+ }
157
+ catch (error) {
158
+ this.log.error('An error occurred during device discovery. ' + 'Turn on debug mode for more information.');
159
+ this.log.debug(error);
160
+ }
161
+ }
162
+ createRoborockAccessory(accessory) {
163
+ this.vacuums.push(new vacuum_accessory_1.default(this, accessory));
164
+ }
165
+ }
166
+ exports.default = RoborockPlatform;
167
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PLATFORM_NAME = exports.PLUGIN_NAME = void 0;
4
+ // Name of the plugin (must match the `name` of the package.json).
5
+ exports.PLUGIN_NAME = 'homebridge-roborock-vacuum';
6
+ // The platform the plugin creates (see config.json).
7
+ exports.PLATFORM_NAME = 'RoborockVacuumPlatform';
8
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":";;;AAAA,kEAAkE;AACrD,QAAA,WAAW,GAAG,4BAA4B,CAAC;AAExD,qDAAqD;AACxC,QAAA,aAAa,GAAG,wBAAwB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * An instance of this class is created for each accessory the platform registers.
5
+ * Each accessory may expose multiple services of different service types.
6
+ */
7
+ class RoborockVacuumAccessory {
8
+ constructor(platform, accessory) {
9
+ var _a;
10
+ this.platform = platform;
11
+ this.accessory = accessory;
12
+ this.services = [];
13
+ const self = this;
14
+ // Accessory Information
15
+ // https://developers.homebridge.io/#/service/AccessoryInformation
16
+ (_a = this.accessory.getService(this.platform.Service.AccessoryInformation)) === null || _a === void 0 ? void 0 : _a.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Roborock').setCharacteristic(this.platform.Characteristic.Model, this.platform.roborockAPI.getProductAttribute(accessory.context, "model") || 'Unknown').setCharacteristic(this.platform.Characteristic.SerialNumber, this.platform.roborockAPI.getVacuumDeviceInfo(accessory.context, "sn") || 'Unknown').setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.platform.roborockAPI.getVacuumDeviceInfo(accessory.context, "fv") || 'Unknown');
17
+ this.services['Fan'] = this.accessory.getService(this.platform.Service.Fanv2)
18
+ || this.accessory.addService(this.platform.Service.Fanv2);
19
+ // This is what is displayed as the default name on the Home app
20
+ this.services['Fan'].setCharacteristic(this.platform.Characteristic.Name, this.platform.roborockAPI.getVacuumDeviceInfo(accessory.context, "name") || 'Roborock Vacuum');
21
+ this.services['Fan'].getCharacteristic(this.platform.Characteristic.Active)
22
+ .onSet(this.setActive.bind(this))
23
+ .onGet(this.getActive.bind(this));
24
+ this.services['Battery'] = this.accessory.getService(this.platform.Service.Battery)
25
+ || this.accessory.addService(this.platform.Service.Battery);
26
+ this.services['Battery'].setCharacteristic(this.platform.Characteristic.BatteryLevel, this.platform.roborockAPI.getVacuumDeviceStatus(accessory.context, "battery") || 0);
27
+ this.services['Battery'].setCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.roborockAPI.getVacuumDeviceStatus(accessory.context, "battery") < 20 ? 1 : 0);
28
+ this.services['Battery'].setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.roborockAPI.getVacuumDeviceStatus(accessory.context, "charge_status") || 0);
29
+ }
30
+ updateDeviceState() {
31
+ try {
32
+ this.services['Fan'].updateCharacteristic(this.platform.Characteristic.Active, this.platform.roborockAPI.isCleaning(this.platform.roborockAPI.getVacuumDeviceStatus(this.accessory.context, "state")) || 0);
33
+ this.services['Battery'].updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.platform.roborockAPI.getVacuumDeviceStatus(this.accessory.context, "battery") || 0);
34
+ this.services['Battery'].updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.platform.roborockAPI.getVacuumDeviceStatus(this.accessory.context, "battery") < 20 ? 1 : 0);
35
+ this.services['Battery'].updateCharacteristic(this.platform.Characteristic.ChargingState, this.platform.roborockAPI.getVacuumDeviceStatus(this.accessory.context, "charge_status") || 0);
36
+ this.platform.log.debug("Device state is " + this.state_code_to_state(this.platform.roborockAPI.getVacuumDeviceStatus(this.accessory.context, "state")));
37
+ }
38
+ catch (e) {
39
+ this.platform.log.error("Error updating device state: " + e);
40
+ }
41
+ }
42
+ notifyDeviceUpdater(id, data) {
43
+ try {
44
+ if (id == 'CloudMessage' || id == 'LocalMessage') {
45
+ this.platform.log.debug(`Updating accessory with ${id} data: ` + JSON.stringify(data));
46
+ if (data.length > 0) {
47
+ const messages = data[0];
48
+ if (messages.hasOwnProperty('state')) {
49
+ this.services['Fan'].updateCharacteristic(this.platform.Characteristic.Active, this.isCleaningState(messages.state) ? 1 : 0);
50
+ }
51
+ if (messages.hasOwnProperty('battery')) {
52
+ this.services['Battery'].updateCharacteristic(this.platform.Characteristic.BatteryLevel, messages.battery);
53
+ this.services['Battery'].updateCharacteristic(this.platform.Characteristic.StatusLowBattery, messages.battery < 20 ? 1 : 0);
54
+ this.services['Battery'].updateCharacteristic(this.platform.Characteristic.ChargingState, messages.charge_status);
55
+ }
56
+ }
57
+ if (data.hasOwnProperty('dps') && data.dps.hasOwnProperty('121')) {
58
+ this.platform.log.debug(`${this.platform.roborockAPI.getVacuumDeviceInfo(this.accessory.context, "name")} state update to: ${this.state_code_to_state(data.dps['121'])}`);
59
+ this.services['Fan'].updateCharacteristic(this.platform.Characteristic.Active, this.isCleaningState(data.dps['121']) ? 1 : 0);
60
+ }
61
+ if (data.hasOwnProperty('dps') && data.dps.hasOwnProperty('122')) {
62
+ this.platform.log.debug(`${this.platform.roborockAPI.getVacuumDeviceInfo(this.accessory.context, "name")} battery update to: ${data.dps['122']}`);
63
+ this.services['Battery'].updateCharacteristic(this.platform.Characteristic.BatteryLevel, data.dps['122']);
64
+ this.services['Battery'].updateCharacteristic(this.platform.Characteristic.StatusLowBattery, data.dps['122'] < 20 ? 1 : 0);
65
+ }
66
+ }
67
+ else if (id == 'HomeData') {
68
+ this.updateDeviceState();
69
+ }
70
+ }
71
+ catch (e) {
72
+ this.platform.log.error("Error notifying device updater: " + e);
73
+ }
74
+ }
75
+ async setActive(value) {
76
+ try {
77
+ this.platform.log.debug("Setting active to " + value);
78
+ if (value == 1) {
79
+ await this.platform.roborockAPI.app_start(this.accessory.context);
80
+ }
81
+ else {
82
+ const isCleaning = await this.isCleaning();
83
+ if (isCleaning) {
84
+ await this.platform.roborockAPI.app_stop(this.accessory.context);
85
+ }
86
+ else {
87
+ await this.platform.roborockAPI.app_charge(this.accessory.context);
88
+ }
89
+ }
90
+ this.services['Fan'].updateCharacteristic(this.platform.Characteristic.Active, value);
91
+ }
92
+ catch (e) {
93
+ this.platform.log.error("Error setting active: " + e);
94
+ }
95
+ }
96
+ async getActive() {
97
+ return await this.isCleaning() ? 1 : 0;
98
+ }
99
+ state_code_to_state(code) {
100
+ const RoborockStateCodes = {
101
+ 0: "Unknown",
102
+ 1: "Initiating",
103
+ 2: "Sleeping",
104
+ 3: "Idle",
105
+ 4: "Remote Control",
106
+ 5: "Cleaning",
107
+ 6: "Returning Dock",
108
+ 7: "Manual Mode",
109
+ 8: "Charging",
110
+ 9: "Charging Error",
111
+ 10: "Paused",
112
+ 11: "Spot Cleaning",
113
+ 12: "In Error",
114
+ 13: "Shutting Down",
115
+ 14: "Updating",
116
+ 15: "Docking",
117
+ 16: "Go To",
118
+ 17: "Zone Clean",
119
+ 18: "Room Clean",
120
+ 22: "Empying dust container",
121
+ 23: "Washing the mop",
122
+ 26: "Going to wash the mop",
123
+ 28: "In call",
124
+ 29: "Mapping",
125
+ 100: "Fully Charged",
126
+ };
127
+ return RoborockStateCodes[code] || "Unknown";
128
+ }
129
+ async isCleaning() {
130
+ return this.isCleaningState(await this.platform.roborockAPI.getVacuumDeviceStatus(this.accessory.context, "state"));
131
+ }
132
+ isCleaningState(state) {
133
+ switch (state) {
134
+ case 4: // Remote Control
135
+ case 5: // Cleaning
136
+ case 6: // Returning Dock
137
+ case 7: // Manual Mode
138
+ case 11: // Spot Cleaning
139
+ case 15: // Docking
140
+ case 16: // Go To
141
+ case 17: // Zone Clean
142
+ case 18: // Room Clean
143
+ case 23: // Washing the mop
144
+ case 26: // Going to wash the mop
145
+ return true;
146
+ default:
147
+ return false;
148
+ }
149
+ }
150
+ }
151
+ exports.default = RoborockVacuumAccessory;
152
+ //# sourceMappingURL=vacuum_accessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vacuum_accessory.js","sourceRoot":"","sources":["../src/vacuum_accessory.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "homebridge-roborock-vacuum",
3
+ "version": "0.1.0",
4
+ "description": "Roborock Vacuum Cleaner - plugin for Homebridge.",
5
+ "license": "MIT",
6
+ "keywords": [
7
+ "homebridge-plugin",
8
+ "vacuum cleaner",
9
+ "roborock app",
10
+ "roborock vacuum"
11
+ ],
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+hhttps://github.com/tasict/homebridge-roborock-vacuum"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/tasict/homebridge-roborock-vacuum/issues"
18
+ },
19
+ "homepage": "https://github.com/tasict/homebridge-roborock-vacuum",
20
+ "main": "dist/index.js",
21
+ "engines": {
22
+ "homebridge": "^1.6.0 || ^2.0.0-beta.0",
23
+ "node": "^18.20.4 || ^20.15.1"
24
+ },
25
+ "scripts": {
26
+ "clean": "rimraf ./dist",
27
+ "build": "rimraf ./dist && tsc",
28
+ "prepublishOnly": "npm run build",
29
+ "postpublish": "npm run clean",
30
+ "lint": "prettier --check .",
31
+ "lint:fix": "prettier --write .",
32
+ "test": "jest"
33
+ },
34
+ "dependencies": {
35
+ "abstract-things": "0.9.0",
36
+ "axios": "^1.7.7",
37
+ "binary-parser": "^2.2.1",
38
+ "canvas": "^2.11.2",
39
+ "chalk": "4.1.2",
40
+ "crc-32": "^1.2.2",
41
+ "debug": "4.3.5",
42
+ "deep-equal": "2.2.3",
43
+ "express": "^4.21.0",
44
+ "jszip": "^3.10.1",
45
+ "mqtt": "^5.10.1",
46
+ "node-forge": "^1.3.1",
47
+ "rxjs": "^7.5.6",
48
+ "semver": "7.6.2",
49
+ "tinkerhub-discovery": "0.3.1",
50
+ "yargs": "15.4.1"
51
+ },
52
+ "devDependencies": {
53
+ "@babel/core": "7.24.8",
54
+ "@babel/preset-env": "7.24.8",
55
+ "@babel/preset-typescript": "7.24.7",
56
+ "@types/jest": "29.5.12",
57
+ "@types/node": "20.14.10",
58
+ "@types/semver": "7.5.8",
59
+ "babel-jest": "29.7.0",
60
+ "homebridge": "1.8.3",
61
+ "jest": "29.7.0",
62
+ "prettier": "3.3.2",
63
+ "rimraf": "6.0.1",
64
+ "typescript": "5.5.3"
65
+ }
66
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "val": "{\"uid\":1466357,\"tokentype\":\"\",\"token\":\"d8fe0bd712334ee585bc2145140f07d1-1JZxT5AINkUhb5JDyL8S+w==\",\"rruid\":\"rr6238c899155830\",\"region\":\"us\",\"countrycode\":\"886\",\"country\":\"TW\",\"nickname\":\"tasict\",\"rriot\":{\"u\":\"1RQsQJ2o8bxMCo6F45pICu\",\"s\":\"cPt6Ps\",\"h\":\"Gm0QssB0Qa\",\"k\":\"R3Z3cNUh\",\"r\":{\"r\":\"US\",\"a\":\"https://api-us.roborock.com\",\"m\":\"ssl://mqtt-us.roborock.com:8883\",\"l\":\"https://wood-us.roborock.com\"}},\"tuyaDeviceState\":0,\"avatarurl\":\"https://files.roborock.com/iottest/default_avatar.png\"}",
3
+ "ack": true
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "val": "bc3fcaca-177e-4d92-97ad-84cdb8eac2d5",
3
+ "ack": true
4
+ }