Skip to content

Commit

Permalink
Add support for Mi Smart Humidifier 2 (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
Numkovich authored Feb 6, 2023
1 parent c080d13 commit f549983
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 2 deletions.
Binary file added .github/assets/deerma-humidifier-jsq2w.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Add the following part to the "platforms" section of your [Homebridge config](ht
| name | Name of the device. This will appear in your Home app. | "Humidifier" |
| address | IP address of the device. ||
| token | Device token. See [obtaining token](https://github.com/Maxmudjon/com.xiaomi-miio/blob/master/docs/obtain_token.md). ||
| model | One of:<br />- `zhimi.humidifier.v1`<br />- `zhimi.humidifier.ca1`<br />- `zhimi.humidifier.cb1`<br />- `zhimi.humidifier.ca4`<br />- `deerma.humidifier.mjjsq`<br />- `deerma.humidifier.jsq1`<br />- `deerma.humidifier.jsq3`<br />- `deerma.humidifier.jsq4`<br />- `deerma.humidifier.jsq5`<br />- `deerma.humidifier.jsqs`<br />- `shuii.humidifier.jsq001`<br />See [supported devices](#supported-devices) section for more details. ||
| model | One of:<br />- `zhimi.humidifier.v1`<br />- `zhimi.humidifier.ca1`<br />- `zhimi.humidifier.cb1`<br />- `zhimi.humidifier.ca4`<br />- `deerma.humidifier.mjjsq`<br />- `deerma.humidifier.jsq2w`<br />- `deerma.humidifier.jsq1`<br />- `deerma.humidifier.jsq3`<br />- `deerma.humidifier.jsq4`<br />- `deerma.humidifier.jsq5`<br />- `deerma.humidifier.jsqs`<br />- `shuii.humidifier.jsq001`<br />See [supported devices](#supported-devices) section for more details. ||
| updateInterval | Device values update interval in seconds. This value affects how often data (humidity, temperature, etc.) from the device is updated. | 30 |
| disabled | Disable the devices. Can be used to temporary hide the device when it is not required without removing it from config. | false |
| autoSwitchToHumidityMode | Automatically switches mode to "humidity" when target humidity is changed. Affects models: <br /> - `zhimi.humidifier.{ca1,cb1,ca4}`<br /> - `deerma.humidifier.{mjjsq,jsq1,jsq001,jsqs,jsq3,jsq4,jsq5}` | false |
Expand All @@ -87,7 +87,7 @@ Add the following part to the "platforms" section of your [Homebridge config](ht

## Supported devices

### Smartmi Humidifier
### Smartmi Humidifier

Model: `zhimi.humidifier.v1`

Expand Down Expand Up @@ -127,6 +127,14 @@ Model №: SCK0A45, ZNJSQ01DEM, MJJSQ03DY

<img src="./.github/assets/deerma-humidifier-mjjsq.png" width="300px" />

### Mi Smart Humidifier 2

Model: `deerma.humidifier.jsq2w`

Model №: MJJSQ05DY

<img src="./.github/assets/deerma-humidifier-jsq2w.jpg" width="300px" />

### Mijia Pure Smart Humidifier

Model: `deerma.humidifier.jsq4`
Expand Down
1 change: 1 addition & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"zhimi.humidifier.ca4",
"deerma.humidifier.mjjsq",
"deerma.humidifier.jsq1",
"deerma.humidifier.jsq2w",
"deerma.humidifier.jsq3",
"deerma.humidifier.jsq4",
"deerma.humidifier.jsq5",
Expand Down
118 changes: 118 additions & 0 deletions src/devices/models/deerma-jsq2w.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import type * as hb from "homebridge";
import * as miio from "miio-api";
import { MiotProtocol, MiotArg } from "../protocols";
import { DeviceOptions } from "../../platform";
import { ValueOf } from "../utils";
import { Features } from "../features";
import { HumidifierConfig } from ".";

enum Mode {
Level1 = 1,
Level2 = 2,
Level3 = 3,
Humidity = 4,
}

type Props = {
power: boolean;
fan_level: Mode;
target_humidity: number;
temperature: number;
relative_humidity: number;
switch_status: boolean;
buzzer: boolean;
};

class Proto extends MiotProtocol<Props> {
protected getCallArg(key: keyof Props): MiotArg {
return this.callArgs(key, null);
}

protected setCallArg(key: keyof Props, value: ValueOf<Props>): MiotArg {
return this.callArgs(key, value);
}

private callArgs(key: keyof Props, value: ValueOf<Props> | null): MiotArg {
const common = { did: key, value };

switch (key) {
case "power":
return { ...common, siid: 2, piid: 1 };
case "fan_level":
return { ...common, siid: 2, piid: 5 };
case "target_humidity":
return { ...common, siid: 2, piid: 6 };
case "relative_humidity":
return { ...common, siid: 3, piid: 1 };
case "switch_status":
return { ...common, siid: 6, piid: 1 };
case "buzzer":
return { ...common, siid: 5, piid: 1 };
case "temperature":
return { ...common, siid: 3, piid: 7 };
}
}
}

export function deermaJSQ2W(
device: miio.Device,
feat: Features<Props>,
log: hb.Logging,
options: DeviceOptions,
): HumidifierConfig<Props> {
return {
protocol: new Proto(device),
features: [
feat.targetState(),
feat.currentState("power", { on: true, off: false }),
feat.active("power", "set_properties", { on: true, off: false }),
feat.rotationSpeed("fan_level", "set_properties", {
modes: [Mode.Level1, Mode.Level2, Mode.Level3, Mode.Humidity],
}),
feat.humidity("relative_humidity"),
...(options.ledBulb?.enabled
? feat.ledBulb("switch_status", "set_properties", {
name: options.ledBulb.name,
modes: [true, false],
on: true,
off: false,
})
: []),

...(!options.disableTargetHumidity
? [
feat.humidityThreshold("target_humidity", "set_properties", {
min: 40,
max: 70,
switchToMode: options.autoSwitchToHumidityMode
? {
key: "fan_level",
call: "set_properties",
value: Mode.Humidity,
}
: undefined,
}),
]
: []),

...(options.buzzerSwitch?.enabled
? feat.buzzerSwitch("buzzer", "set_properties", {
name: options.buzzerSwitch.name,
on: true,
off: false,
})
: []),
...(options.temperatureSensor?.enabled
? feat.temperatureSensor("temperature", {
name: options.temperatureSensor.name,
toChar: (it) => it,
})
: []),
...(options.humiditySensor?.enabled
? feat.humiditySensor("relative_humidity", {
name: options.humiditySensor.name,
})
: []),
],
};
}
3 changes: 3 additions & 0 deletions src/devices/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { zhimiV1 } from "./zhimi-v1";
import { zhimiCA1, zhimiCB1 } from "./zhimi-cab1";
import { zhimiCA4 } from "./zhimi-ca4";
import { deermaMJJSQ } from "./deerma-mjjsq";
import { deermaJSQ2W as deermaJSQ2W } from "./deerma-jsq2w";
import { deermaJSQ4 } from "./deerma-jsq4";
import { deermaJSQ5 } from "./deerma-jsq5";
import { shuiiJSQ001 } from "./shuii-jsq001";
Expand All @@ -31,6 +32,7 @@ export enum HumidifierModel {
ZHIMI_CA4 = "zhimi.humidifier.ca4",
DEERMA_MJJSQ = "deerma.humidifier.mjjsq",
DEERMA_JSQ = "deerma.humidifier.jsq1",
DEERMA_JSQ2W = "deerma.humidifier.jsq2w",
DEERMA_JSQ4 = "deerma.humidifier.jsq4",
DEERMA_JSQ3 = "deerma.humidifier.jsq3",
DEERMA_JSQ5 = "deerma.humidifier.jsq5",
Expand All @@ -45,6 +47,7 @@ export const HumidifierFactory = {
[HumidifierModel.ZHIMI_CA4]: zhimiCA4,
[HumidifierModel.DEERMA_MJJSQ]: deermaMJJSQ,
[HumidifierModel.DEERMA_JSQ]: deermaMJJSQ,
[HumidifierModel.DEERMA_JSQ2W]: deermaJSQ2W,
[HumidifierModel.DEERMA_JSQ4]: deermaJSQ4,
[HumidifierModel.DEERMA_JSQ3]: deermaJSQ5,
[HumidifierModel.DEERMA_JSQ5]: deermaJSQ5,
Expand Down

0 comments on commit f549983

Please sign in to comment.