Skip to content

Commit

Permalink
fix(vacuum.viomi): Hackishly fixed map parsing for viomi v6 + fan spe…
Browse files Browse the repository at this point in the history
…ed settings for all viomi
  • Loading branch information
Hypfer committed Jul 17, 2020
1 parent e1565d0 commit ffbb8e7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
22 changes: 19 additions & 3 deletions lib/ViomiMapParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ class ViomiMapParser {
let realtimePose = this.take(21, "realtime");
this.realtimePose = {position: this.readFloatPosition(realtimePose, 9)};
}

//v6 example: 5b590f5f00000001
//v7 example: e35a185e00000001
this.take(8, "unknown8");
this.parseRooms();
// more stuff i don't understand
Expand Down Expand Up @@ -278,14 +281,18 @@ class ViomiMapParser {
e3 5a 18 5e 07[e5 9c b0 e5 9b be 31]01 00 00 00 '地图1'
*/
let mapArg;

do {
let mapName = this.readString();
mapArg = this.take(4, "mapArg:" + mapName).readUInt32LE(0);
maps[mapName] = mapArg;
} while (mapArg > 1);

let length = this.take(4, "room length").readUInt32LE(0);

/** @type {Object<number, {name: string, outline?: Array<Pose>}>} */
let rooms = {};

for (let i = 0; i < length; i++) {
let nameLen = this.buf.readUInt8(this.offset + 1);
let id = this.buf.readUInt8(this.offset);
Expand All @@ -295,20 +302,29 @@ class ViomiMapParser {
this.log("room" + id + ": " + rooms[id].name, this.offset);
this.offset += 3 + nameLen + 8;
}

this.rooms = rooms;
this.take(6, "unknown");

if (length) { // TODO: unclear what the condition is
this.take(12, "rooms2head");
length = this.take(4, "rooms2 length").readUInt32LE(0);
this.take(length * 2, "room data");
const rooms2length = this.take(4, "rooms2 length").readUInt32LE(0);

//RoomData looks like this:
//0a010b010c010d010e01
//Repeated for every room there is
this.take(rooms2length * 2, "room data");
let x = this.take(4, "unknown2").readUInt32BE(0); // big endian!!!

let index = [45, 21, 12][x];

if (index) {
this.take([45, 21, 12][x], "unknown");
} else {
//TODO!
//TODO: HACK
//While this is certainly a logic error somewhere else,
//this seems to fix map parsing for v6 Version 34 for now
this.offset -= 3;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/MiioVacuum.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class MiioVacuum {
/**
* @protected
* @abstract
* @returns {Promise<void>}
* @returns {Promise<any|void>}
*/
async pollStatus() {
throw new NotImplementedError();
Expand Down
36 changes: 21 additions & 15 deletions lib/devices/Viomi.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ const ViomiMovementMode = Object.freeze({

/** Maps MiioVacuum.FAN_SPEEDS to Viomi suction grades. */
const FAN_GRADES = Object.freeze({
"LOW": 0,
"MEDIUM": 1,
"HIGH": 2,
"MAX": 3
"low": 0,
"medium": 1,
"high": 2,
"max": 3
});

const FAN_SPEEDS = Object.freeze({
Expand Down Expand Up @@ -366,12 +366,13 @@ class Viomi extends MiioVacuum {

let vacuum_enabled = currentOperationMode.value !== stateAttrs.OperationModeStateAttribute.VALUE.MOP;

/*
Logger.debug("checkMopMode: ", {
mopping_enabled: mopping_enabled,
vacuum_enabled: vacuum_enabled,
currentOperationMode: currentOperationMode,
currentMovementMode: currentMovementMode
});
}); */

if (dustbinAttribute && !waterboxAttribute && mopping_enabled) {
Logger.info("Vacuum box doesn't support mopping. Mopping disabled.");
Expand Down Expand Up @@ -408,13 +409,15 @@ class Viomi extends MiioVacuum {
}

async pollStatus() {
return this.getCurrentStatus();
}

async getCurrentStatus() {
let res = await this.sendCommand("get_prop", STATE_PROPERTIES);
let statusDict = {};
STATE_PROPERTIES.forEach((key, index) => statusDict[key] = res[index]);
this.updateStatus(statusDict);
}

async getCurrentStatus() { //TODO: this is weird. Why isn't this fetching the latest status?
return this.robotState;
}

Expand Down Expand Up @@ -538,19 +541,22 @@ class Viomi extends MiioVacuum {
operation[0] = options.movementMode;
}

if (options.additionalParameters && options.additionalParameters.length > 0) {
if (Array.isArray(options.additionalParameters)) {
command = "set_mode_withroom";
operation.push(options.additionalParameters.length);
operation = operation.concat(options.additionalParameters);
} else {
operation.push(0); //Probably the count of additional arguments?
}

return this.sendCommand(command, operation);

}

async startCleaning() {
await this.startOperation({operation: ViomiOperation.START});
await this.startOperation({
operation: ViomiOperation.START,
additionalParameters: []
//Intentional empty array to force set_mode_withroom command since the viomi api is utterly broken
});
}

/** @param {Array<number>} zone_ids */
Expand All @@ -568,7 +574,7 @@ class Viomi extends MiioVacuum {
if (zone_ids_from_map.length) {
await this.startOperation({
operation: ViomiOperation.START,
additionalParameters: [zone_ids_from_map.length].concat(zone_ids_from_map)
additionalParameters: zone_ids_from_map
});
} else if (zones_from_user.length) {
const areas = [];
Expand Down Expand Up @@ -609,7 +615,8 @@ class Viomi extends MiioVacuum {
if (typeof speed === "string") {
if (FAN_GRADES[speed] !== undefined) {
await this.sendCommand("set_suction", [FAN_GRADES[speed]]);
return this.pollStatus();
await this.pollStatus();
return;
}
}

Expand Down Expand Up @@ -673,8 +680,7 @@ const STATUS_PROP_MAP = Object.freeze({
value: stateAttrs.StatusStateAttribute.VALUE.IDLE
},
1: {
value: stateAttrs.StatusStateAttribute.VALUE.MOVING,
flag: stateAttrs.StatusStateAttribute.FLAG.TARGET
value: stateAttrs.StatusStateAttribute.VALUE.PAUSED
},
2: {
value: stateAttrs.StatusStateAttribute.VALUE.IDLE
Expand Down

0 comments on commit ffbb8e7

Please sign in to comment.