matterbridge-roborock-vacuum-plugin 1.0.8-rc07 → 1.0.8-rc09
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/dist/initialData/getOperationalStates.js +67 -0
- package/dist/platform.js +2 -2
- package/dist/roborockCommunication/broadcast/client/LocalNetworkClient.js +2 -2
- package/dist/roborockService.js +10 -3
- package/dist/rvc.js +8 -5
- package/matterbridge-roborock-vacuum-plugin.config.json +1 -1
- package/matterbridge-roborock-vacuum-plugin.schema.json +1 -1
- package/package.json +1 -1
- package/src/initialData/getOperationalStates.ts +77 -0
- package/src/platform.ts +2 -2
- package/src/platformRunner.ts +6 -0
- package/src/roborockCommunication/broadcast/client/LocalNetworkClient.ts +2 -2
- package/src/roborockCommunication/broadcast/listener/implementation/simpleMessageListener.ts +1 -0
- package/src/roborockService.ts +20 -5
- package/src/rvc.ts +10 -7
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { RvcOperationalState } from 'matterbridge/matter/clusters';
|
|
2
2
|
import { getDefaultOperationalStates } from '../behaviors/roborock.vacuum/default/initalData.js';
|
|
3
3
|
import { VacuumErrorCode } from '../roborockCommunication/Zenum/vacuumAndDockErrorCode.js';
|
|
4
|
+
import { DockingStationStatusType, hasDockingStationError } from '../model/DockingStationStatus.js';
|
|
4
5
|
export function getOperationalStates() {
|
|
5
6
|
return getDefaultOperationalStates();
|
|
6
7
|
}
|
|
@@ -13,3 +14,69 @@ export function getOperationalErrorState(errorCode) {
|
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
}
|
|
17
|
+
export function getErrorFromErrorCode(errorCode) {
|
|
18
|
+
const operationalState = getOperationalErrorState(errorCode);
|
|
19
|
+
if (operationalState) {
|
|
20
|
+
return {
|
|
21
|
+
errorStateId: RvcOperationalState.ErrorState.NoError,
|
|
22
|
+
errorStateLabel: `${RvcOperationalState.ErrorState.NoError}`,
|
|
23
|
+
errorStateDetails: `Error code: ${errorCode}`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
export function getErrorFromDSS(status) {
|
|
29
|
+
if (!status) {
|
|
30
|
+
return {
|
|
31
|
+
errorStateId: RvcOperationalState.ErrorState.NoError,
|
|
32
|
+
errorStateLabel: 'No Docking Station Status',
|
|
33
|
+
errorStateDetails: 'Docking station status is not available.',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const hasError = hasDockingStationError(status);
|
|
37
|
+
if (hasError) {
|
|
38
|
+
if (status.cleanFluidStatus === DockingStationStatusType.Error) {
|
|
39
|
+
return {
|
|
40
|
+
errorStateId: RvcOperationalState.ErrorState.MopCleaningPadMissing,
|
|
41
|
+
errorStateLabel: 'Clean Fluid Error',
|
|
42
|
+
errorStateDetails: 'The clean fluid is not available or has an issue.',
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (status.waterBoxFilterStatus === DockingStationStatusType.Error) {
|
|
46
|
+
return {
|
|
47
|
+
errorStateId: RvcOperationalState.ErrorState.WaterTankEmpty,
|
|
48
|
+
errorStateLabel: 'Water Box Filter Error',
|
|
49
|
+
errorStateDetails: 'The water box filter is not available or has an issue.',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (status.dustBagStatus === DockingStationStatusType.Error) {
|
|
53
|
+
return {
|
|
54
|
+
errorStateId: RvcOperationalState.ErrorState.DustBinMissing,
|
|
55
|
+
errorStateLabel: 'Dust Bag Error',
|
|
56
|
+
errorStateDetails: 'The dust bag is not available or has an issue.',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (status.dirtyWaterBoxStatus === DockingStationStatusType.Error) {
|
|
60
|
+
return {
|
|
61
|
+
errorStateId: RvcOperationalState.ErrorState.WaterTankEmpty,
|
|
62
|
+
errorStateLabel: 'Dirty Water Box Error',
|
|
63
|
+
errorStateDetails: 'The dirty water box is not available or has an issue.',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (status.clearWaterBoxStatus === DockingStationStatusType.Error) {
|
|
67
|
+
return {
|
|
68
|
+
errorStateId: RvcOperationalState.ErrorState.WaterTankEmpty,
|
|
69
|
+
errorStateLabel: 'Clear Water Box Error',
|
|
70
|
+
errorStateDetails: 'The clear water box is not available or has an issue.',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (status.isUpdownWaterReady === DockingStationStatusType.Error) {
|
|
74
|
+
return {
|
|
75
|
+
errorStateId: RvcOperationalState.ErrorState.WaterTankMissing,
|
|
76
|
+
errorStateLabel: 'Updown Water Ready Error',
|
|
77
|
+
errorStateDetails: 'The updown water tank is not ready or has an issue.',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
package/dist/platform.js
CHANGED
|
@@ -25,8 +25,8 @@ export class RoborockMatterbridgePlatform extends MatterbridgeDynamicPlatform {
|
|
|
25
25
|
persist;
|
|
26
26
|
constructor(matterbridge, log, config) {
|
|
27
27
|
super(matterbridge, log, config);
|
|
28
|
-
if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.0.
|
|
29
|
-
throw new Error(`This plugin requires Matterbridge version >= "3.0.
|
|
28
|
+
if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.0.7')) {
|
|
29
|
+
throw new Error(`This plugin requires Matterbridge version >= "3.0.7". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
|
|
30
30
|
}
|
|
31
31
|
this.log.info('Initializing platform:', this.config.name);
|
|
32
32
|
if (config.whiteList === undefined)
|
|
@@ -56,7 +56,7 @@ export class LocalNetworkClient extends AbstractClient {
|
|
|
56
56
|
await this.connectionListeners.onConnected();
|
|
57
57
|
}
|
|
58
58
|
async onDisconnect() {
|
|
59
|
-
this.logger.
|
|
59
|
+
this.logger.notice('LocalNetworkClient: Socket has disconnected.');
|
|
60
60
|
this.connected = false;
|
|
61
61
|
if (this.socket) {
|
|
62
62
|
this.socket.destroy();
|
|
@@ -68,7 +68,7 @@ export class LocalNetworkClient extends AbstractClient {
|
|
|
68
68
|
await this.connectionListeners.onDisconnected();
|
|
69
69
|
}
|
|
70
70
|
async onError(result) {
|
|
71
|
-
this.logger.error('Socket connection error: ' + result);
|
|
71
|
+
this.logger.error('LocalNetworkClient: Socket connection error: ' + result);
|
|
72
72
|
this.connected = false;
|
|
73
73
|
if (this.socket) {
|
|
74
74
|
this.socket.destroy();
|
package/dist/roborockService.js
CHANGED
|
@@ -158,7 +158,7 @@ export default class RoborockService {
|
|
|
158
158
|
await this.messageProcessor.getDeviceStatus(device.duid).then((response) => {
|
|
159
159
|
if (self.deviceNotify) {
|
|
160
160
|
const message = { duid: device.duid, ...response.errorStatus, ...response.message };
|
|
161
|
-
self.logger.debug('Device status update
|
|
161
|
+
self.logger.debug('Device status update', debugStringify(message));
|
|
162
162
|
self.deviceNotify(NotifyMessageTypes.LocalMessage, message);
|
|
163
163
|
}
|
|
164
164
|
});
|
|
@@ -320,6 +320,8 @@ export default class RoborockService {
|
|
|
320
320
|
self.deviceNotify(NotifyMessageTypes.BatteryUpdate, { duid: device.duid, percentage });
|
|
321
321
|
}
|
|
322
322
|
},
|
|
323
|
+
onStatusChanged: () => {
|
|
324
|
+
},
|
|
323
325
|
});
|
|
324
326
|
this.logger.debug('Local device', device.duid);
|
|
325
327
|
try {
|
|
@@ -332,16 +334,21 @@ export default class RoborockService {
|
|
|
332
334
|
this.logger.debug('initializing the local connection for this client towards ' + this.ip);
|
|
333
335
|
this.localClient = this.messageClient.registerClient(device.duid, this.ip);
|
|
334
336
|
this.localClient.connect();
|
|
335
|
-
|
|
337
|
+
let count = 0;
|
|
338
|
+
while (!this.localClient.isConnected() && count < 20) {
|
|
339
|
+
this.logger.debug('Keep waiting for local client to connect');
|
|
340
|
+
count++;
|
|
336
341
|
await this.sleep(500);
|
|
337
342
|
}
|
|
343
|
+
if (!this.localClient.isConnected()) {
|
|
344
|
+
throw new Error('Local client did not connect after 10 attempts, something is wrong');
|
|
345
|
+
}
|
|
338
346
|
this.logger.debug('LocalClient connected');
|
|
339
347
|
}
|
|
340
348
|
}
|
|
341
349
|
catch (error) {
|
|
342
350
|
this.logger.error('Error requesting network info', error);
|
|
343
351
|
}
|
|
344
|
-
this.logger.debug('Local client connected');
|
|
345
352
|
}
|
|
346
353
|
sleep(ms) {
|
|
347
354
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
package/dist/rvc.js
CHANGED
|
@@ -21,15 +21,18 @@ export class RoborockVacuumCleaner extends RoboticVacuumCleaner {
|
|
|
21
21
|
this.rrHomeId = device.rrHomeId;
|
|
22
22
|
}
|
|
23
23
|
configurateHandler(behaviorHandler) {
|
|
24
|
-
this.addCommandHandler('identify', async ({ request
|
|
25
|
-
|
|
24
|
+
this.addCommandHandler('identify', async ({ request, cluster, attributes, endpoint }) => {
|
|
25
|
+
this.log.info(`Identify command received for endpoint ${endpoint}, cluster ${cluster}, attributes ${attributes}, request: ${JSON.stringify(request)}`);
|
|
26
|
+
behaviorHandler.executeCommand('playSoundToLocate', request.identifyTime ?? 0);
|
|
26
27
|
});
|
|
27
28
|
this.addCommandHandler('selectAreas', async ({ request }) => {
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
const { newAreas } = request;
|
|
30
|
+
this.log.info(`Selecting areas: ${newAreas?.join(', ')}`);
|
|
31
|
+
behaviorHandler.executeCommand('selectAreas', newAreas);
|
|
30
32
|
});
|
|
31
33
|
this.addCommandHandler('changeToMode', async ({ request }) => {
|
|
32
|
-
|
|
34
|
+
const { newMode } = request;
|
|
35
|
+
behaviorHandler.executeCommand('changeToMode', newMode);
|
|
33
36
|
});
|
|
34
37
|
this.addCommandHandler('pause', async () => {
|
|
35
38
|
behaviorHandler.executeCommand('pause');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"title": "Matterbridge Roborock Vacuum Plugin",
|
|
3
|
-
"description": "matterbridge-roborock-vacuum-plugin v. 1.0.8-
|
|
3
|
+
"description": "matterbridge-roborock-vacuum-plugin v. 1.0.8-rc09 by https://github.com/RinDevJunior",
|
|
4
4
|
"type": "object",
|
|
5
5
|
"required": ["username", "password"],
|
|
6
6
|
"properties": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { RvcOperationalState } from 'matterbridge/matter/clusters';
|
|
2
2
|
import { getDefaultOperationalStates } from '../behaviors/roborock.vacuum/default/initalData.js';
|
|
3
3
|
import { VacuumErrorCode } from '../roborockCommunication/Zenum/vacuumAndDockErrorCode.js';
|
|
4
|
+
import { DockingStationStatus, DockingStationStatusType, hasDockingStationError } from '../model/DockingStationStatus.js';
|
|
4
5
|
|
|
5
6
|
export function getOperationalStates(): RvcOperationalState.OperationalStateStruct[] {
|
|
6
7
|
return getDefaultOperationalStates();
|
|
@@ -15,3 +16,79 @@ export function getOperationalErrorState(errorCode: VacuumErrorCode): RvcOperati
|
|
|
15
16
|
}
|
|
16
17
|
}
|
|
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
|
+
}
|
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.0.
|
|
35
|
+
if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.0.7')) {
|
|
36
36
|
throw new Error(
|
|
37
|
-
`This plugin requires Matterbridge version >= "3.0.
|
|
37
|
+
`This plugin requires Matterbridge version >= "3.0.7". 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);
|
package/src/platformRunner.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { BatteryMessage, Device, DeviceErrorMessage, DeviceStatusNotify, Home }
|
|
|
16
16
|
import { OperationStatusCode } from './roborockCommunication/Zenum/operationStatusCode.js';
|
|
17
17
|
import { getCurrentCleanModeFunc } from './share/runtimeHelper.js';
|
|
18
18
|
import { debugStringify } from 'matterbridge/logger';
|
|
19
|
+
// import { getErrorFromErrorCode } from './initialData/getOperationalStates.js';
|
|
19
20
|
|
|
20
21
|
export class PlatformRunner {
|
|
21
22
|
platform: RoborockMatterbridgePlatform;
|
|
@@ -95,6 +96,11 @@ export class PlatformRunner {
|
|
|
95
96
|
if (operationalStateId) {
|
|
96
97
|
platform.log.error(`Error occurred: ${message.errorCode}`);
|
|
97
98
|
platform.robot.updateAttribute(RvcOperationalState.Cluster.id, 'operationalState', operationalStateId, platform.log);
|
|
99
|
+
|
|
100
|
+
// const errorState = getErrorFromErrorCode(message.errorCode);
|
|
101
|
+
// if (operationalStateId === RvcOperationalState.OperationalState.Error && errorState) {
|
|
102
|
+
// platform.robot.updateAttribute(RvcOperationalState.Cluster.id, 'operationalError', errorState, platform.log);
|
|
103
|
+
// }
|
|
98
104
|
}
|
|
99
105
|
break;
|
|
100
106
|
}
|
|
@@ -67,7 +67,7 @@ export class LocalNetworkClient extends AbstractClient {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
private async onDisconnect(): Promise<void> {
|
|
70
|
-
this.logger.
|
|
70
|
+
this.logger.notice('LocalNetworkClient: Socket has disconnected.');
|
|
71
71
|
this.connected = false;
|
|
72
72
|
|
|
73
73
|
if (this.socket) {
|
|
@@ -82,7 +82,7 @@ export class LocalNetworkClient extends AbstractClient {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
private async onError(result: Error): Promise<void> {
|
|
85
|
-
this.logger.error('Socket connection error: ' + result);
|
|
85
|
+
this.logger.error('LocalNetworkClient: Socket connection error: ' + result);
|
|
86
86
|
this.connected = false;
|
|
87
87
|
|
|
88
88
|
if (this.socket) {
|
package/src/roborockCommunication/broadcast/listener/implementation/simpleMessageListener.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ResponseMessage } from '../../model/responseMessage.js';
|
|
|
2
2
|
import { AbstractMessageListener } from '../index.js';
|
|
3
3
|
import { Protocol } from '../../model/protocol.js';
|
|
4
4
|
import { AbstractMessageHandler } from '../abstractMessageHandler.js';
|
|
5
|
+
// import { DeviceStatus } from '../../../Zmodel/deviceStatus.js';
|
|
5
6
|
|
|
6
7
|
export class SimpleMessageListener implements AbstractMessageListener {
|
|
7
8
|
private handler: AbstractMessageHandler | undefined;
|
package/src/roborockService.ts
CHANGED
|
@@ -29,6 +29,7 @@ import type {
|
|
|
29
29
|
DeviceStatusNotify,
|
|
30
30
|
} from './roborockCommunication/index.js';
|
|
31
31
|
import { ServiceArea } from 'matterbridge/matter/clusters';
|
|
32
|
+
import { LocalNetworkClient } from './roborockCommunication/broadcast/client/LocalNetworkClient.js';
|
|
32
33
|
export type Factory<A, T> = (logger: AnsiLogger, arg: A) => T;
|
|
33
34
|
|
|
34
35
|
export default class RoborockService {
|
|
@@ -227,7 +228,7 @@ export default class RoborockService {
|
|
|
227
228
|
await this.messageProcessor.getDeviceStatus(device.duid).then((response: DeviceStatus) => {
|
|
228
229
|
if (self.deviceNotify) {
|
|
229
230
|
const message: DeviceStatusNotify = { duid: device.duid, ...response.errorStatus, ...response.message } as DeviceStatusNotify;
|
|
230
|
-
self.logger.debug('Device status update
|
|
231
|
+
self.logger.debug('Device status update', debugStringify(message));
|
|
231
232
|
self.deviceNotify(NotifyMessageTypes.LocalMessage, message);
|
|
232
233
|
}
|
|
233
234
|
});
|
|
@@ -419,6 +420,14 @@ export default class RoborockService {
|
|
|
419
420
|
self.deviceNotify(NotifyMessageTypes.BatteryUpdate, { duid: device.duid, percentage } as BatteryMessage);
|
|
420
421
|
}
|
|
421
422
|
},
|
|
423
|
+
onStatusChanged: () => {
|
|
424
|
+
// status: DeviceStatus
|
|
425
|
+
// if (self.deviceNotify) {
|
|
426
|
+
// const message: DeviceStatusNotify = { duid: device.duid, ...status.errorStatus, ...status.message } as DeviceStatusNotify;
|
|
427
|
+
// self.logger.debug('Device status update', debugStringify(message));
|
|
428
|
+
// self.deviceNotify(NotifyMessageTypes.LocalMessage, message);
|
|
429
|
+
// }
|
|
430
|
+
},
|
|
422
431
|
} as AbstractMessageHandler);
|
|
423
432
|
|
|
424
433
|
this.logger.debug('Local device', device.duid);
|
|
@@ -431,19 +440,25 @@ export default class RoborockService {
|
|
|
431
440
|
|
|
432
441
|
if (this.ip) {
|
|
433
442
|
this.logger.debug('initializing the local connection for this client towards ' + this.ip);
|
|
434
|
-
this.localClient = this.messageClient.registerClient(device.duid, this.ip);
|
|
443
|
+
this.localClient = this.messageClient.registerClient(device.duid, this.ip) as LocalNetworkClient;
|
|
435
444
|
this.localClient.connect();
|
|
436
445
|
|
|
437
|
-
|
|
446
|
+
let count = 0;
|
|
447
|
+
while (!this.localClient.isConnected() && count < 20) {
|
|
448
|
+
this.logger.debug('Keep waiting for local client to connect');
|
|
449
|
+
count++;
|
|
438
450
|
await this.sleep(500);
|
|
439
451
|
}
|
|
452
|
+
|
|
453
|
+
if (!this.localClient.isConnected()) {
|
|
454
|
+
throw new Error('Local client did not connect after 10 attempts, something is wrong');
|
|
455
|
+
}
|
|
456
|
+
|
|
440
457
|
this.logger.debug('LocalClient connected');
|
|
441
458
|
}
|
|
442
459
|
} catch (error) {
|
|
443
460
|
this.logger.error('Error requesting network info', error);
|
|
444
461
|
}
|
|
445
|
-
|
|
446
|
-
this.logger.debug('Local client connected');
|
|
447
462
|
}
|
|
448
463
|
|
|
449
464
|
private sleep(ms: number): Promise<void> {
|
package/src/rvc.ts
CHANGED
|
@@ -56,17 +56,20 @@ export class RoborockVacuumCleaner extends RoboticVacuumCleaner {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
public configurateHandler(behaviorHandler: BehaviorFactoryResult): void {
|
|
59
|
-
this.addCommandHandler('identify', async ({ request
|
|
60
|
-
|
|
59
|
+
this.addCommandHandler('identify', async ({ request, cluster, attributes, endpoint }) => {
|
|
60
|
+
this.log.info(`Identify command received for endpoint ${endpoint}, cluster ${cluster}, attributes ${attributes}, request: ${JSON.stringify(request)}`);
|
|
61
|
+
behaviorHandler.executeCommand('playSoundToLocate', (request as { identifyTime?: number }).identifyTime ?? 0);
|
|
61
62
|
});
|
|
62
63
|
|
|
63
|
-
this.addCommandHandler('selectAreas', async ({ request }
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
this.addCommandHandler('selectAreas', async ({ request }) => {
|
|
65
|
+
const { newAreas } = request as ServiceArea.SelectAreasRequest;
|
|
66
|
+
this.log.info(`Selecting areas: ${newAreas?.join(', ')}`);
|
|
67
|
+
behaviorHandler.executeCommand('selectAreas', newAreas);
|
|
66
68
|
});
|
|
67
69
|
|
|
68
|
-
this.addCommandHandler('changeToMode', async ({ request }
|
|
69
|
-
|
|
70
|
+
this.addCommandHandler('changeToMode', async ({ request }) => {
|
|
71
|
+
const { newMode } = request as ModeBase.ChangeToModeRequest;
|
|
72
|
+
behaviorHandler.executeCommand('changeToMode', newMode);
|
|
70
73
|
});
|
|
71
74
|
|
|
72
75
|
this.addCommandHandler('pause', async () => {
|