Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small viomi fixes & documentation enhancements #543

Merged
merged 9 commits into from
Jun 28, 2020
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ If you have these firmware versions installed, you will not be able to root the
#### Viomi Vacuums
Currently, there's WIP support for the following Viomi Vacuums:
* Xiaomi Mijia STYJ02YM *viomi.vacuum.v7*
* Xiaomi Mijia STYTJ02YM *viomi.vacuum.v8*

See [here](https://valetudo.cloud/pages/installation/viomi.html) for more information on that.

Expand Down
38 changes: 19 additions & 19 deletions docs/_pages/installation/viomi.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ Then, set up the robot to talk to your host instead of the xiaomi cloud:

```shell
ssh root@viomi
echo "110.43.0.83 ot.io.mi.com ott.io.mi.com" >> /etc/hosts
for domain in "" de. ea. in. pv. ru. sg. st. tw. us.; do
echo "110.43.0.83 ${domain}ot.io.mi.com ${domain}ott.io.mi.com" >> /etc/hosts
done
cat >/etc/rc.d/S51valetudo <<EOF
#!/bin/sh
iptables -F OUTPUT
Expand All @@ -64,26 +66,20 @@ you can do a `iptables -F; iptables -F -t nat` and comment out the line in `/etc
Simply follow the [development guide](https://valetudo.cloud/pages/development/building-and-modifying-valetudo.html)

You can get the required model settings for the following by doing `cat /etc/miio/device.conf` and
`hexdump -C /etc/miio/device.token | cut -b 10-60 | head -n1 | sed 's/ //g'` on the robot.

`type` has to be `viomi.vacuum.v7`
`cat /etc/miio/device.token` on the robot.

`type` has to be `viomi.vacuum.v7` or `viomi.vacuum.v8`.

Furthermore, you need to customize these settings in the config.json:

"spoofedIP": "110.43.0.83"
"map_upload_host": "http://110.43.0.83"
"spoofedIP": "110.43.0.83",
"map_upload_host": "http://110.43.0.83",

## Deploying

Do build the binary for the viomi (which runs on OpenWRT with musl libc), you need a corresponding build for pkg.

mkdir -p ~/.pkg-cache/v2.5
(cd ~/.pkg-cache/v2.5; wget https://github.com/robertsLando/pkg-binaries/raw/master/arm32/fetched-v10.4.1-alpine-armv6)

Now you can run

npm run build_viomi
npm run build

And deploy the `valetudo` binary to your robot:

Expand All @@ -94,16 +90,20 @@ And deploy the `valetudo` binary to your robot:

## Firmware updates

You can perform firmware updates up to v3.5.3_0046 without risking root (see the
You can perform firmware updates up to v3.5.3_0047 without risking root (see the
[firmware update analysis](https://itooktheredpill.irgendwo.org/2020/viomi-firmware-update-analysis/)
for details). Make sure you use ssh-keys and don't rely on password login.
for details).

**Important:** Make sure you use ssh-keys and don't rely on password login
otherwise your root access may be lost.

For this you currently need to:
To perform a firmware upgrade you currently need to:

* uninstall Valetudo (because the diskspace is needed for the upgrade) and
* use the app to perform the upgrade (because upgrades are unsupported by
Valetudo / only supported via cloud interface and there's no public source
for the binaries in the first place).
* [uninstall Valetudo](#uninstall-valetudo) (because the diskspace is needed for the upgrade) and
* use the Xiaomi Home App to perform the upgrade (because upgrades are
unsupported by Valetudo / only supported via cloud interface and there's
no public source for the binaries in the first place).
* [reinstall Valetudo](#deploying)

## Uninstall Valetudo

Expand Down
43 changes: 43 additions & 0 deletions docs/_pages/knowledge_base/supported-xiaomi-devices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: Supported Xiamoi Devices
category: Knowledge Base
order: 52
---
# Supported Xiaomi Devices
1. [Mijia STYJ02YM (viomi-v7)](#viomi-v7)
2. [Mijia STYTJ02YM (viomi-v8)](#viomi-v8)

If you're looking for Roborock devices, take a look at the [Roborock page](supported-roborock-devices).

## Mijia STYJ02YM (viomi-v7) <a name="viomi-v7"></a>

### Features
These are the Hardware specs

| Property | Value | Notes |
|------------------|----------|-------|
| Height | TBD | |
| Width | TBD | |
| Battery Capacity | TBD | |
| Dustbin Size | TBD | |
| Suction Power | TBD | |
| Climbing Ability | TBD | |
| Washable Filter | ❌ | |
| Mop Feature | ✔ | |
| Water Pump | ✔ | |

And here are the Software specs.
This table is based on FW Version 4007

| Feature | Value | Valetudo Support | Notes |
|---------------------|-------|------------------|-----------------------------------------------------------------------------|
| Zoned Cleanup | ✔ | ✔ | |
| Persistent Maps | ✔ | ✔ | |
| Virtual Walls | ✔ | ❌ | |
| Room Detection | ✔ | n/a | handled by robot firmware, not by Valetudo |
| Carpet Detection | ❌ | ❌ | |
| Bin State Reporting | ❌ | ❌ | only reports the kind of bin, not any fill level |

## Mijia STYTJ02YM (viomi-v8) <a name="viomi-v8"></a>

TBD
1 change: 1 addition & 0 deletions lib/Valetudo.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ const MODEL_TO_IMPLEMENTATION = {
"rockrobo.vacuum.v1": RoborockV1,
"roborock.vacuum.s5": RoborockS5,
"viomi.vacuum.v7": Viomi,
"viomi.vacuum.v8": Viomi,
"roborock.vacuum.t6": RoborockGen3,
"roborock.vacuum.s6": RoborockGen3,
"roborock.vacuum.s5e": RoborockGen3,
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/MiioVacuum.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class MiioVacuum {
// Deal with any changes that we observed.
const diffKeys = Object.keys(diff);
if (diffKeys.length != 0) {
Logger.trace("New Status:", diff);
Logger.debug("New Status:", diff);
this.events.emitStatusUpdated(this.status);
this.onStatusChange(diffKeys);
}
Expand Down
38 changes: 25 additions & 13 deletions lib/devices/Viomi.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const BoxType = Object.freeze({
const Mode = Object.freeze({
NORMAL_CLEANING: 0,
MOP_MOVES: 1, // back and forth mopping movement (unsure if this has an effect without mop-mode)
ZONED_CLEAN: 3,
OUTLINE: 2, // Only clean the rooms outline.
ZONED_CLEAN_OR_MOPPING: 3,
});

/** Maps MiioVacuum.FAN_SPEEDS to Viomi suction grades. */
Expand Down Expand Up @@ -62,8 +63,8 @@ function toZoneSpec(areas, restricted) {
}

/**
* Implements the viomi.vacuum.v7 device.
* Still incomplete contributions are welcome.
* Implements the viomi.vacuum.v7 and .v8 device.
* Still partially incomplete, contributions are welcome.
*/
class Viomi extends MiioVacuum {
constructor(options) {
Expand Down Expand Up @@ -142,9 +143,6 @@ class Viomi extends MiioVacuum {
if ("box_type" in newState) {
this.box_type = newState["box_type"];
}
if ("mode" in newState) {
this.mode = newState["mode"];
}
if ("err_state" in newState) {
let code = newState["err_state"]; // TODO adopt to viomi codes
if (ERROR_MAP[code] !== undefined) {
Expand All @@ -170,7 +168,10 @@ class Viomi extends MiioVacuum {

/** @override */
onStatusChange(changedProperties) {
if (changedProperties.includes("box_type") || changedProperties.includes("mop_type")) {
// TODO: Store the box type in the Status object.
if (changedProperties.includes("viomi.vacuum.v7_box_type") ||
changedProperties.includes("viomi.vacuum.v8_box_type") ||
changedProperties.includes("has_mop")) {
this.checkMopMode();
}
if (changedProperties.includes("state")) {
Expand All @@ -188,17 +189,28 @@ class Viomi extends MiioVacuum {
* @param {boolean} enable Whether to enable or disable mopping.
*/
enableMopMode(enable) {
let mopMode = enable
? (this.box_type == BoxType.VACUUM_AND_WATER ? MopMode.MIXED : MopMode.MOP)
: MopMode.VACUUM;
this.mode = this.box_type == BoxType.VACUUM ? Mode.NORMAL_CLEANING : Mode.MOP_MOVES;
let mopMode = MopMode.VACUUM;
this.mode = Mode.NORMAL_CLEANING;
if (enable) {
mopMode = this.box_type == BoxType.VACUUM_AND_WATER ? MopMode.MIXED : MopMode.MOP;
if (this.box_type == BoxType.WATER) {
// doesn't support mop_moves with water-only tank
this.mode = Mode.ZONED_CLEAN_OR_MOPPING;
} else if (this.box_type != BoxType.VACUUM) {
this.mode = Mode.MOP_MOVES;
}
}
return this.sendCommand("set_mop", [mopMode]);
}

/** Checks that the mop mode setting is compatible with the current box_type and mop_type. */
checkMopMode() {
let mopping_enabled = this.mop_mode != MopMode.VACUUM;
let mopping_enabled =
this.mop_mode != MopMode.VACUUM ||
(this.mode == Mode.MOP_MOVES || this.mode == Mode.ZONED_CLEAN_OR_MOPPING);
let vacuum_enabled = this.mop_mode != MopMode.MOP;
Logger.debug("checkMopMode: ",
{mopping_enabled, vacuum_enabled, mop_mode: this.mop_mode, mode: this.mode});
if (this.box_type == BoxType.VACUUM && mopping_enabled) {
Logger.info("Vacuum box doesn't support mopping. Mopping disabled.");
this.enableMopMode(false);
Expand Down Expand Up @@ -329,7 +341,7 @@ class Viomi extends MiioVacuum {
/** @type {Array} */
const args = [specs.length];
await this.sendCommand("set_zone", args.concat(specs));
await this.startOperation([Mode.ZONED_CLEAN, 1]);
await this.startOperation([Mode.ZONED_CLEAN_OR_MOPPING, 1]);
} else {
throw new Error("No zones to clean");
}
Expand Down
3 changes: 2 additions & 1 deletion lib/miio/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ class Model {
*/
getCapabilities() {
return {
"persistent_data": this.identifier !== "rockrobo.vacuum.v1" && this.identifier !== "viomi.vacuum.v7"
"persistent_data": this.identifier !== "rockrobo.vacuum.v1" &&
!this.identifier.startsWith("viomi.vacuum")
};
}

Expand Down