Skip to content

Commit

Permalink
Merge pull request #29 from baranwang/feat/hot-water
Browse files Browse the repository at this point in the history
feat: 新增热水器类型设备支持
  • Loading branch information
baranwang authored Apr 30, 2024
2 parents d9a5dee + eedf1c4 commit 9d3308c
Show file tree
Hide file tree
Showing 8 changed files with 1,058 additions and 1,253 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

</p>

# WIP: 海尔智家 Homebridge 插件
# 海尔智家 Homebridge 插件

目前支持的设备:

- [x] 空调(经过测试的有卡萨帝的壁挂空调和海尔的风管机,如果有不支持的型号可以提 issue)
- [x] 热水器 (感谢 @zwb124 提供设备支持)

计划支持的设备:

- [ ] 冰箱
- [ ] 热水器
- [ ] 更多……
2,194 changes: 948 additions & 1,246 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"packages/*"
],
"devDependencies": {
"@modern-js/eslint-config": "^2.46.1",
"@modern-js/eslint-config": "^2.49.2",
"eslint-plugin-import": "^2.28.1",
"lerna": "^8.1.2",
"prettier": "^3.2.5"
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin/nodemon.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"watch": ["src", "../api/dist"],
"watch": ["src"],
"ext": "ts",
"ignore": [],
"exec": "npm run build && npm link && homebridge -I -D",
"exec": "lerna run build && npm link && homebridge -I -D",
"signal": "SIGTERM",
"env": {
"NODE_OPTIONS": "--trace-warnings"
Expand Down
5 changes: 4 additions & 1 deletion packages/plugin/src/accessories/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export class BaseAccessory {

private devDigitalModelPromise?: Promise<DevDigitalModel>;

constructor(readonly platform: HaierHomebridgePlatform, readonly accessory: HaierPlatformAccessory) {
constructor(
readonly platform: HaierHomebridgePlatform,
readonly accessory: HaierPlatformAccessory,
) {
const { deviceInfo } = this.accessory.context;
const { Characteristic, Service } = this.platform;
this.accessory
Expand Down
95 changes: 95 additions & 0 deletions packages/plugin/src/accessories/hot-water.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { CharacteristicProps, CharacteristicValue } from 'homebridge';
import { BaseAccessory } from './base';

export class HotWaterAccessory extends BaseAccessory {
constructor(platform, accessory) {
super(platform, accessory);
this.init();
}

async init() {
this.generateServices([this.platform.Service.Thermostat]);

await this.getDevDigitalModel();

//#region Thermostat
this.services[0]
.getCharacteristic(this.Characteristic.CurrentHeatingCoolingState)
.onGet(this.getCurrentHeatingCoolingState.bind(this));

this.services[0]
.getCharacteristic(this.Characteristic.TargetHeatingCoolingState)
.onGet(this.getCurrentHeatingCoolingState.bind(this)) // 与 CurrentHeatingCoolingState 保持一致
.onSet(this.setTargetHeatingCoolingState.bind(this))
.setProps({
validValues: [
this.Characteristic.TargetHeatingCoolingState.OFF,
this.Characteristic.TargetHeatingCoolingState.HEAT,
],
});

this.services[0]
.getCharacteristic(this.Characteristic.CurrentTemperature)
.onGet(this.getTargetTemperature.bind(this)); // 与 TargetTemperature 保持一致

this.services[0]
.getCharacteristic(this.Characteristic.TargetTemperature)
.onGet(this.getTargetTemperature.bind(this))
.onSet(this.setTargetTemperature.bind(this))
.setProps(this.targetTemperatureProps);

this.services[0]
.getCharacteristic(this.Characteristic.TemperatureDisplayUnits)
.onGet(() => this.Characteristic.TemperatureDisplayUnits.CELSIUS);
//#endregion
}

private get onOffStatus() {
const onOffStatus: boolean = JSON.parse(this.devDigitalModelPropertiesMap.onOffStatus.value);
return onOffStatus;
}

private get targetTemperature() {
return this.devDigitalModelPropertiesMap.targetTemp.value;
}

private set targetTemperature(value: string) {
this.devDigitalModelPropertiesMap.targetTemp.value = value;
}

private get targetTemperatureProps() {
const { dataStep } = this.devDigitalModelPropertiesMap.targetTemp.valueRange;
const minValue = Number(dataStep.minValue);
const maxValue = Number(dataStep.maxValue);
const minStep = Number(dataStep.step);
return {
minValue,
maxValue,
minStep,
validValueRanges: [minValue, maxValue] as CharacteristicProps['validValueRanges'],
};
}

getCurrentHeatingCoolingState() {
return this.onOffStatus
? this.Characteristic.CurrentHeatingCoolingState.HEAT
: this.Characteristic.CurrentHeatingCoolingState.OFF;
}

async setTargetHeatingCoolingState(value: CharacteristicValue) {
await this.sendCommands({ onOffStatus: (!!value).toString() });
}

getTargetTemperature() {
return Number(this.targetTemperature);
}

async setTargetTemperature(value: CharacteristicValue) {
const { minValue, maxValue } = this.targetTemperatureProps;
const targetTemp = Math.min(Math.max(value as number, minValue), maxValue).toString();
try {
await this.sendCommands({ targetTemp });
this.targetTemperature = targetTemp;
} catch (error) {}
}
}
1 change: 1 addition & 0 deletions packages/plugin/src/accessories/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './air-conditioner';
export * from './hot-water';
5 changes: 4 additions & 1 deletion packages/plugin/src/platform.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HaierApi, PLATFORM_NAME, PLUGIN_NAME } from '@hb-haier/shared';

import { AirConditionerAccessory } from './accessories';
import { AirConditionerAccessory, HotWaterAccessory } from './accessories';

import type { HaierPlatformAccessory, HaierPlatformAccessoryContext } from './types';
import type { DeviceInfo, HaierApiConfig } from '@hb-haier/shared';
Expand Down Expand Up @@ -113,6 +113,9 @@ export class HaierHomebridgePlatform implements DynamicPlatformPlugin {
case '空调':
return AirConditionerAccessory;

case '热水卫浴':
return HotWaterAccessory;

default:
return undefined;
}
Expand Down

0 comments on commit 9d3308c

Please sign in to comment.