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

Support for Xiaomi Smart Humidifier 2 #113

Open
tobiasbueschel opened this issue Sep 15, 2022 · 3 comments
Open

Support for Xiaomi Smart Humidifier 2 #113

tobiasbueschel opened this issue Sep 15, 2022 · 3 comments

Comments

@tobiasbueschel
Copy link

Hi @russtone,

thanks for this great plugin - Xiaomi released the Smart Humidifier 2, model number: MJJSQ05DY, are you planning to add support for it?

Happy to help create a PR once I receive my device:
https://www.mi.com/global/product/xiaomi-smart-humidifier-2/

image

@fantasytu
Copy link

  1. Navigate to plugin folder.
  2. Add ""deerma.humidifier.jsq2g" to config.schema.json "model>enum".
  3. Modify "devices/models/index.ts"
import type * as hb from "homebridge";
import * as miio from "miio-api";
import { DeviceOptions } from "../../platform";
import { BasePropsType } from "../humidifier";
import { zhimiV1 } from "./zhimi-v1";
import { zhimiCA1, zhimiCB1 } from "./zhimi-cab1";
import { zhimiCA4 } from "./zhimi-ca4";
import { deermaMJJSQ } from "./deerma-mjjsq";
import { deermaJSQ2 } from "./deerma-mjjsq2";
import { deermaJSQ4 } from "./deerma-jsq4";
import { deermaJSQ5 } from "./deerma-jsq5";
import { shuiiJSQ001 } from "./shuii-jsq001";
import { Protocol } from "../protocols";
import { Features, AnyCharacteristicConfig } from "../features";

export type HumidifierConfig<PropsType> = {
  protocol: Protocol<PropsType>;
  features: Array<AnyCharacteristicConfig<PropsType>>;
};

export type HumidifierConfigFunc<PropsType extends BasePropsType> = (
  device: miio.Device,
  feat: Features<PropsType>,
  log: hb.Logging,
  options: DeviceOptions,
) => HumidifierConfig<PropsType>;

export enum HumidifierModel {
  ZHIMI_V1 = "zhimi.humidifier.v1",
  ZHIMI_CA1 = "zhimi.humidifier.ca1",
  ZHIMI_CB1 = "zhimi.humidifier.cb1",
  ZHIMI_CA4 = "zhimi.humidifier.ca4",
  DEERMA_MJJSQ = "deerma.humidifier.mjjsq",
  DEERMA_JSQ = "deerma.humidifier.jsq1",
  DEERMA_JSQ2 = "deerma.humidifier.jsq2g",
  DEERMA_JSQ4 = "deerma.humidifier.jsq4",
  DEERMA_JSQ3 = "deerma.humidifier.jsq3",
  DEERMA_JSQ5 = "deerma.humidifier.jsq5",
  DEERMA_JSQS = "deerma.humidifier.jsqs",
  SHUII_JSQ001 = "shuii.humidifier.jsq001",
}

export const HumidifierFactory = {
  [HumidifierModel.ZHIMI_V1]: zhimiV1,
  [HumidifierModel.ZHIMI_CA1]: zhimiCA1,
  [HumidifierModel.ZHIMI_CB1]: zhimiCB1,
  [HumidifierModel.ZHIMI_CA4]: zhimiCA4,
  [HumidifierModel.DEERMA_MJJSQ]: deermaMJJSQ,
  [HumidifierModel.DEERMA_JSQ]: deermaMJJSQ,
  [HumidifierModel.DEERMA_JSQ2]: deermaJSQ2,
  [HumidifierModel.DEERMA_JSQ4]: deermaJSQ4,
  [HumidifierModel.DEERMA_JSQ3]: deermaJSQ5,
  [HumidifierModel.DEERMA_JSQ5]: deermaJSQ5,
  [HumidifierModel.DEERMA_JSQS]: deermaJSQ5,
  [HumidifierModel.SHUII_JSQ001]: shuiiJSQ001,
};
  1. Add "devices/models/deerma-mjjsq2.ts"
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;
  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 };
    }
  }
}

export function deermaJSQ2(
  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.humiditySensor?.enabled
        ? feat.humiditySensor("relative_humidity", {
            name: options.humiditySensor.name,
          })
        : []),
    ],
  };
}
  1. run "npm run build" in plugin folder. Done

@TheGamerFace
Copy link

I received my Humidifier 2 today, but it has the following model number: deerma.humidifier.jsq2w
I still tried to add the thread creator's model with the above tips, but fail at the npm run build point

Can anyone help me further?
in which directory do i have to run the build command? i tried in /var/lib/homebridge/node_modules but get the error

npm ERR! Missing script: "build"
npm ERR!
npm ERR! To see a list of scripts, run:
npm ERR! npm run

@toniojst
Copy link

toniojst commented Feb 3, 2023

I have same problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants