nt0xa / homebridge-mi-humidifier

A Xiaomi Mi humidifier plugin for Homebridge
MIT License
64 stars 24 forks source link

Support for Xiaomi Smart Humidifier 2 #113

Open tobiasbueschel opened 2 years ago

tobiasbueschel commented 2 years ago

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 commented 2 years ago
  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 commented 1 year ago

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 commented 1 year ago

I have same problem.