diff --git a/.github/assets/deerma-humidifier-jsq2w.jpg b/.github/assets/deerma-humidifier-jsq2w.jpg
new file mode 100644
index 0000000..5bb2d1a
Binary files /dev/null and b/.github/assets/deerma-humidifier-jsq2w.jpg differ
diff --git a/README.md b/README.md
index db7c4fa..08d2165 100644
--- a/README.md
+++ b/README.md
@@ -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:
- `zhimi.humidifier.v1`
- `zhimi.humidifier.ca1`
- `zhimi.humidifier.cb1`
- `zhimi.humidifier.ca4`
- `deerma.humidifier.mjjsq`
- `deerma.humidifier.jsq1`
- `deerma.humidifier.jsq3`
- `deerma.humidifier.jsq4`
- `deerma.humidifier.jsq5`
- `deerma.humidifier.jsqs`
- `shuii.humidifier.jsq001`
See [supported devices](#supported-devices) section for more details. | — |
+| model | One of:
- `zhimi.humidifier.v1`
- `zhimi.humidifier.ca1`
- `zhimi.humidifier.cb1`
- `zhimi.humidifier.ca4`
- `deerma.humidifier.mjjsq`
- `deerma.humidifier.jsq2w`
- `deerma.humidifier.jsq1`
- `deerma.humidifier.jsq3`
- `deerma.humidifier.jsq4`
- `deerma.humidifier.jsq5`
- `deerma.humidifier.jsqs`
- `shuii.humidifier.jsq001`
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:
- `zhimi.humidifier.{ca1,cb1,ca4}`
- `deerma.humidifier.{mjjsq,jsq1,jsq001,jsqs,jsq3,jsq4,jsq5}` | false |
@@ -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`
@@ -127,6 +127,14 @@ Model №: SCK0A45, ZNJSQ01DEM, MJJSQ03DY
+### Mi Smart Humidifier 2
+
+Model: `deerma.humidifier.jsq2w`
+
+Model №: MJJSQ05DY
+
+
+
### Mijia Pure Smart Humidifier
Model: `deerma.humidifier.jsq4`
diff --git a/config.schema.json b/config.schema.json
index 6ea847c..5b56f5d 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -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",
diff --git a/src/devices/models/deerma-jsq2w.ts b/src/devices/models/deerma-jsq2w.ts
new file mode 100644
index 0000000..afe50d0
--- /dev/null
+++ b/src/devices/models/deerma-jsq2w.ts
@@ -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 {
+ protected getCallArg(key: keyof Props): MiotArg {
+ return this.callArgs(key, null);
+ }
+
+ protected setCallArg(key: keyof Props, value: ValueOf): MiotArg {
+ return this.callArgs(key, value);
+ }
+
+ private callArgs(key: keyof Props, value: ValueOf | 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,
+ log: hb.Logging,
+ options: DeviceOptions,
+): HumidifierConfig {
+ 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,
+ })
+ : []),
+ ],
+ };
+}
\ No newline at end of file
diff --git a/src/devices/models/index.ts b/src/devices/models/index.ts
index 2995ec0..d20c41a 100644
--- a/src/devices/models/index.ts
+++ b/src/devices/models/index.ts
@@ -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";
@@ -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",
@@ -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,