homebridge-smarthq-client 1.2.10 → 1.3.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/beta-release.yml +46 -0
- package/.github/workflows/release.yml +1 -1
- package/Readme.md +12 -0
- package/config.schema.json +25 -0
- package/dist/dehumidifier/dehumidifier.d.ts +78 -0
- package/dist/dehumidifier/dehumidifier.js +385 -0
- package/dist/dehumidifier/dehumidifier.js.map +1 -0
- package/dist/dehumidifierServices.d.ts +5 -0
- package/dist/dehumidifierServices.js +5 -0
- package/dist/dehumidifierServices.js.map +1 -0
- package/dist/platform.js +6 -0
- package/dist/platform.js.map +1 -1
- package/package.json +1 -1
- package/src/dehumidifier/dehumidifier.ts +455 -0
- package/src/dehumidifierServices.ts +8 -0
- package/src/platform.ts +7 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Auto Beta Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- beta
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
TAG_NAME: ""
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
create-beta:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout code
|
|
19
|
+
uses: actions/checkout@v7
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
|
|
23
|
+
- name: Generate Beta Tag Version
|
|
24
|
+
id: versioning
|
|
25
|
+
run: |
|
|
26
|
+
BASE_VERSION="1.3.0"
|
|
27
|
+
BUILD_NUMBER=$(git rev-list --count HEAD)
|
|
28
|
+
TAG_NAME="v${BASE_VERSION}-beta.${BUILD_NUMBER}"
|
|
29
|
+
|
|
30
|
+
# Writing to GITHUB_ENV makes it available to later steps
|
|
31
|
+
echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV
|
|
32
|
+
echo "Generated Tag: $TAG_NAME"
|
|
33
|
+
|
|
34
|
+
- name: Create GitHub Pre-Release
|
|
35
|
+
uses: softprops/action-gh-release@v3
|
|
36
|
+
with:
|
|
37
|
+
# Adding quotes around the expression satisfies the VS Code schema validator
|
|
38
|
+
tag_name: "${{ env.TAG_NAME }}"
|
|
39
|
+
name: "Beta Release ${{ env.TAG_NAME }}"
|
|
40
|
+
body: |
|
|
41
|
+
Automated beta release compiled from branch `beta`.
|
|
42
|
+
|
|
43
|
+
**Latest Commit:** ${{ github.sha }}
|
|
44
|
+
prerelease: true
|
|
45
|
+
env:
|
|
46
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
package/Readme.md
CHANGED
|
@@ -6,6 +6,7 @@ A homebridge plugin for GE appliances using the SmartHQ API s (Identity and Acce
|
|
|
6
6
|
* refrigerator
|
|
7
7
|
* dishwasher
|
|
8
8
|
* air conditioner
|
|
9
|
+
* dehumidifier
|
|
9
10
|
* Other devices will be discovered and service information could be written to the log to assist in adding support for more devices.
|
|
10
11
|
|
|
11
12
|
The refrigerator services include controls for:
|
|
@@ -34,6 +35,14 @@ The air conditioner services include controls for:
|
|
|
34
35
|
* AC fan speed
|
|
35
36
|
* AC modes (Cool, ECO, Dry, Fan Only)
|
|
36
37
|
|
|
38
|
+
The dehumidifier services include controls for:
|
|
39
|
+
* Target humidity
|
|
40
|
+
* Current humidity
|
|
41
|
+
* Fan speed
|
|
42
|
+
* Filter Maintenance
|
|
43
|
+
* Leak Sensor
|
|
44
|
+
* Continuous mode switch
|
|
45
|
+
|
|
37
46
|
|
|
38
47
|
|
|
39
48
|
## Installation
|
|
@@ -158,6 +167,9 @@ These switches will appear in Accessories as *Alert Door*, *Alert Temp*, *Alert
|
|
|
158
167
|
(for air conditioners)
|
|
159
168
|
For air conditioner models that support a DRY mode if the user attempts to change the temperature while in DRY mode, the mode will be set to COOL and the temperature will be adjusted.
|
|
160
169
|
|
|
170
|
+
(for dehumidifiers)
|
|
171
|
+
Model used is GE 25 pt. Residential Dehumidifier ADSE25WWT
|
|
172
|
+
|
|
161
173
|
(for refrigerator)
|
|
162
174
|
|
|
163
175
|
The *water filter maintenance* option uses the Filter Maintenance Service in the Homebridge API.
|
package/config.schema.json
CHANGED
|
@@ -105,6 +105,16 @@
|
|
|
105
105
|
"title": "Add Control Lock Control",
|
|
106
106
|
"default": false
|
|
107
107
|
},
|
|
108
|
+
"humidityMin": {
|
|
109
|
+
"type": "integer",
|
|
110
|
+
"title": "Minimum Humidity Threshold",
|
|
111
|
+
"default": 35
|
|
112
|
+
},
|
|
113
|
+
"humidityMax": {
|
|
114
|
+
"type": "integer",
|
|
115
|
+
"title": "Maximum Humidity Threshold",
|
|
116
|
+
"default": 80
|
|
117
|
+
},
|
|
108
118
|
"debugLogging": {
|
|
109
119
|
"type": "boolean",
|
|
110
120
|
"title": "Plugin Debug Logging w/Chalk Colors",
|
|
@@ -146,6 +156,21 @@
|
|
|
146
156
|
}
|
|
147
157
|
]
|
|
148
158
|
},
|
|
159
|
+
{
|
|
160
|
+
"type": "section",
|
|
161
|
+
"title": "Dehumidifier Settings",
|
|
162
|
+
"expandable": true,
|
|
163
|
+
"expanded": false,
|
|
164
|
+
"items": [
|
|
165
|
+
{
|
|
166
|
+
"description": "Include the selected dehumidifier settings.",
|
|
167
|
+
"items": [
|
|
168
|
+
"humidityMin",
|
|
169
|
+
"humidityMax"
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
},
|
|
149
174
|
{
|
|
150
175
|
"type": "section",
|
|
151
176
|
"title": "Dishwasher Services",
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { PlatformAccessory, Service, Characteristic } from 'homebridge';
|
|
2
|
+
import { DeviceService } from 'ge-smarthq';
|
|
3
|
+
import { SmartHqPlatform } from '../platform.js';
|
|
4
|
+
/**
|
|
5
|
+
* GE SmartHQ Dehumidifier (e.g. model ADSE25WWT).
|
|
6
|
+
*
|
|
7
|
+
* The dehumidifier exposes the SAME thermostat.v1 service the window AC uses, so
|
|
8
|
+
* this accessory is modeled on airConditioner.ts. Mapping:
|
|
9
|
+
*
|
|
10
|
+
* thermostat.v1 / domain.thermostat -> on, mode (on/off/continuous),
|
|
11
|
+
* fanSpeed (high/low/smart.dry),
|
|
12
|
+
* humidity (target %, 35-80)
|
|
13
|
+
* integer / domain.humidity.ambient -> current relative humidity (value %)
|
|
14
|
+
* toggle / domain.bucket.status -> bucket full (on == full)
|
|
15
|
+
* toggle / domain.filter.status -> clean filter (on == needs cleaning)
|
|
16
|
+
*
|
|
17
|
+
* HomeKit surface (all on one accessory):
|
|
18
|
+
* HumidifierDehumidifier -> Active, Current/Target state, CurrentRelativeHumidity,
|
|
19
|
+
* RelativeHumidityDehumidifierThreshold (target),
|
|
20
|
+
* RotationSpeed (fan), WaterLevel (bucket)
|
|
21
|
+
* FilterMaintenance -> FilterChangeIndication
|
|
22
|
+
* LeakSensor -> bucket full (drives Home push notifications)
|
|
23
|
+
* Switch "Continuous" -> toggles continuous mode
|
|
24
|
+
*/
|
|
25
|
+
export declare class Dehumidifier {
|
|
26
|
+
private readonly platform;
|
|
27
|
+
private readonly accessory;
|
|
28
|
+
private readonly deviceServices;
|
|
29
|
+
private readonly deviceId;
|
|
30
|
+
private readonly DEVICE_TYPE;
|
|
31
|
+
private readonly SVC_THERMOSTAT;
|
|
32
|
+
private readonly DOM_THERMOSTAT;
|
|
33
|
+
private readonly SVC_INTEGER;
|
|
34
|
+
private readonly DOM_HUMIDITY_AMBIENT;
|
|
35
|
+
private readonly SVC_TOGGLE;
|
|
36
|
+
private readonly DOM_BUCKET;
|
|
37
|
+
private readonly DOM_FILTER;
|
|
38
|
+
private readonly CMD_SET;
|
|
39
|
+
private readonly MODE_ON;
|
|
40
|
+
private readonly MODE_OFF;
|
|
41
|
+
private readonly MODE_CONTINUOUS;
|
|
42
|
+
private readonly FAN_LOW;
|
|
43
|
+
private readonly FAN_HIGH;
|
|
44
|
+
private readonly FAN_SMART_DRY;
|
|
45
|
+
private isOn;
|
|
46
|
+
private lastActiveMode;
|
|
47
|
+
private lastActiveFanSpeed;
|
|
48
|
+
private targetHumidity;
|
|
49
|
+
private currentHumidity;
|
|
50
|
+
private bucketFull;
|
|
51
|
+
private filterNeedsCleaning;
|
|
52
|
+
private humidityMin;
|
|
53
|
+
private humidityMax;
|
|
54
|
+
private disposed;
|
|
55
|
+
private readonly serviceUpdateListener;
|
|
56
|
+
private client;
|
|
57
|
+
private api;
|
|
58
|
+
Service: typeof Service;
|
|
59
|
+
Characteristic: typeof Characteristic;
|
|
60
|
+
private parentAccessory;
|
|
61
|
+
private dhum;
|
|
62
|
+
private filterService;
|
|
63
|
+
private bucketLeak;
|
|
64
|
+
private continuousSwitch;
|
|
65
|
+
constructor(platform: SmartHqPlatform, accessory: PlatformAccessory, deviceServices: DeviceService[], deviceId: string);
|
|
66
|
+
private setupServices;
|
|
67
|
+
private handleUpdate;
|
|
68
|
+
private sendThermostat;
|
|
69
|
+
private sendCommand;
|
|
70
|
+
private findService;
|
|
71
|
+
private clampHumidity;
|
|
72
|
+
private fanSpeedToPercent;
|
|
73
|
+
private percentToFanSpeed;
|
|
74
|
+
private computeCurrentState;
|
|
75
|
+
private refreshCurrentState;
|
|
76
|
+
private setupWebSocket;
|
|
77
|
+
dispose(): Promise<void>;
|
|
78
|
+
}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { SmartHQClient } from 'ge-smarthq';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
/**
|
|
4
|
+
* GE SmartHQ Dehumidifier (e.g. model ADSE25WWT).
|
|
5
|
+
*
|
|
6
|
+
* The dehumidifier exposes the SAME thermostat.v1 service the window AC uses, so
|
|
7
|
+
* this accessory is modeled on airConditioner.ts. Mapping:
|
|
8
|
+
*
|
|
9
|
+
* thermostat.v1 / domain.thermostat -> on, mode (on/off/continuous),
|
|
10
|
+
* fanSpeed (high/low/smart.dry),
|
|
11
|
+
* humidity (target %, 35-80)
|
|
12
|
+
* integer / domain.humidity.ambient -> current relative humidity (value %)
|
|
13
|
+
* toggle / domain.bucket.status -> bucket full (on == full)
|
|
14
|
+
* toggle / domain.filter.status -> clean filter (on == needs cleaning)
|
|
15
|
+
*
|
|
16
|
+
* HomeKit surface (all on one accessory):
|
|
17
|
+
* HumidifierDehumidifier -> Active, Current/Target state, CurrentRelativeHumidity,
|
|
18
|
+
* RelativeHumidityDehumidifierThreshold (target),
|
|
19
|
+
* RotationSpeed (fan), WaterLevel (bucket)
|
|
20
|
+
* FilterMaintenance -> FilterChangeIndication
|
|
21
|
+
* LeakSensor -> bucket full (drives Home push notifications)
|
|
22
|
+
* Switch "Continuous" -> toggles continuous mode
|
|
23
|
+
*/
|
|
24
|
+
export class Dehumidifier {
|
|
25
|
+
platform;
|
|
26
|
+
accessory;
|
|
27
|
+
deviceServices;
|
|
28
|
+
deviceId;
|
|
29
|
+
// ======== SmartHQ constants ========
|
|
30
|
+
DEVICE_TYPE = 'cloud.smarthq.device.dehumidifier';
|
|
31
|
+
SVC_THERMOSTAT = 'cloud.smarthq.service.thermostat.v1';
|
|
32
|
+
DOM_THERMOSTAT = 'cloud.smarthq.domain.thermostat';
|
|
33
|
+
SVC_INTEGER = 'cloud.smarthq.service.integer';
|
|
34
|
+
DOM_HUMIDITY_AMBIENT = 'cloud.smarthq.domain.humidity.ambient';
|
|
35
|
+
SVC_TOGGLE = 'cloud.smarthq.service.toggle';
|
|
36
|
+
DOM_BUCKET = 'cloud.smarthq.domain.bucket.status';
|
|
37
|
+
DOM_FILTER = 'cloud.smarthq.domain.filter.status';
|
|
38
|
+
CMD_SET = 'cloud.smarthq.command.thermostat.v1.set';
|
|
39
|
+
MODE_ON = 'cloud.smarthq.type.thermostatmode.on';
|
|
40
|
+
MODE_OFF = 'cloud.smarthq.type.thermostatmode.off';
|
|
41
|
+
MODE_CONTINUOUS = 'cloud.smarthq.type.thermostatmode.continuous';
|
|
42
|
+
FAN_LOW = 'cloud.smarthq.type.fanspeed.low';
|
|
43
|
+
FAN_HIGH = 'cloud.smarthq.type.fanspeed.high';
|
|
44
|
+
FAN_SMART_DRY = 'cloud.smarthq.type.fanspeed.smart.dry';
|
|
45
|
+
// ======== State cache ========
|
|
46
|
+
isOn = false;
|
|
47
|
+
lastActiveMode = this.MODE_ON;
|
|
48
|
+
lastActiveFanSpeed = this.FAN_HIGH;
|
|
49
|
+
targetHumidity = 45;
|
|
50
|
+
currentHumidity = 50;
|
|
51
|
+
bucketFull = false;
|
|
52
|
+
filterNeedsCleaning = false;
|
|
53
|
+
humidityMin;
|
|
54
|
+
humidityMax;
|
|
55
|
+
disposed = false;
|
|
56
|
+
serviceUpdateListener;
|
|
57
|
+
client;
|
|
58
|
+
api;
|
|
59
|
+
Service;
|
|
60
|
+
Characteristic;
|
|
61
|
+
parentAccessory;
|
|
62
|
+
// Services
|
|
63
|
+
dhum;
|
|
64
|
+
filterService;
|
|
65
|
+
bucketLeak;
|
|
66
|
+
continuousSwitch;
|
|
67
|
+
constructor(platform, accessory, deviceServices, deviceId) {
|
|
68
|
+
this.platform = platform;
|
|
69
|
+
this.accessory = accessory;
|
|
70
|
+
this.deviceServices = deviceServices;
|
|
71
|
+
this.deviceId = deviceId;
|
|
72
|
+
this.api = platform.api;
|
|
73
|
+
this.Service = this.api.hap.Service;
|
|
74
|
+
this.Characteristic = this.api.hap.Characteristic;
|
|
75
|
+
this.parentAccessory = accessory;
|
|
76
|
+
this.client = new SmartHQClient({
|
|
77
|
+
clientId: platform.config.clientId,
|
|
78
|
+
clientSecret: platform.config.clientSecret,
|
|
79
|
+
redirectUri: platform.config.redirectUri,
|
|
80
|
+
debug: platform.config.debugLogging || false,
|
|
81
|
+
});
|
|
82
|
+
// Initialize humidity thresholds from config
|
|
83
|
+
this.humidityMin = platform.config.humidityMin ?? 35;
|
|
84
|
+
this.humidityMax = platform.config.humidityMax ?? 80;
|
|
85
|
+
// ---- Seed initial state from discovery snapshot ----
|
|
86
|
+
const thermostat = this.findService(this.SVC_THERMOSTAT, this.DOM_THERMOSTAT);
|
|
87
|
+
if (thermostat?.state) {
|
|
88
|
+
const s = thermostat.state;
|
|
89
|
+
if (s.on != null)
|
|
90
|
+
this.isOn = s.on;
|
|
91
|
+
if (s.mode != null)
|
|
92
|
+
this.lastActiveMode = s.mode;
|
|
93
|
+
if (s.fanSpeed != null)
|
|
94
|
+
this.lastActiveFanSpeed = s.fanSpeed;
|
|
95
|
+
if (s.humidity != null)
|
|
96
|
+
this.targetHumidity = s.humidity;
|
|
97
|
+
}
|
|
98
|
+
if (thermostat?.config) {
|
|
99
|
+
const c = thermostat.config;
|
|
100
|
+
if (c.humidityMinimum != null)
|
|
101
|
+
this.humidityMin = c.humidityMinimum;
|
|
102
|
+
if (c.humidityMaximum != null)
|
|
103
|
+
this.humidityMax = c.humidityMaximum;
|
|
104
|
+
}
|
|
105
|
+
const ambient = this.findService(this.SVC_INTEGER, this.DOM_HUMIDITY_AMBIENT);
|
|
106
|
+
if (ambient?.state?.value != null) {
|
|
107
|
+
this.currentHumidity = ambient.state.value;
|
|
108
|
+
}
|
|
109
|
+
const bucket = this.findService(this.SVC_TOGGLE, this.DOM_BUCKET);
|
|
110
|
+
if (bucket?.state?.on != null)
|
|
111
|
+
this.bucketFull = bucket.state.on;
|
|
112
|
+
const filter = this.findService(this.SVC_TOGGLE, this.DOM_FILTER);
|
|
113
|
+
if (filter?.state?.on != null)
|
|
114
|
+
this.filterNeedsCleaning = filter.state.on;
|
|
115
|
+
this.setupServices();
|
|
116
|
+
this.setupWebSocket();
|
|
117
|
+
this.serviceUpdateListener = (message) => {
|
|
118
|
+
if (message.deviceId !== this.deviceId)
|
|
119
|
+
return;
|
|
120
|
+
this.handleUpdate(message);
|
|
121
|
+
};
|
|
122
|
+
this.client.on('service_update', this.serviceUpdateListener);
|
|
123
|
+
}
|
|
124
|
+
// ---------------------------
|
|
125
|
+
// SERVICE SETUP
|
|
126
|
+
// ---------------------------
|
|
127
|
+
setupServices() {
|
|
128
|
+
// Clean up any stale services HomeKit may have cached for this accessory.
|
|
129
|
+
const keepUUIDs = new Set([
|
|
130
|
+
this.Service.AccessoryInformation.UUID,
|
|
131
|
+
this.Service.HumidifierDehumidifier.UUID,
|
|
132
|
+
this.Service.FilterMaintenance.UUID,
|
|
133
|
+
this.Service.LeakSensor.UUID,
|
|
134
|
+
this.Service.Switch.UUID,
|
|
135
|
+
]);
|
|
136
|
+
for (const svc of [...this.parentAccessory.services]) {
|
|
137
|
+
if (!keepUUIDs.has(svc.UUID)) {
|
|
138
|
+
this.parentAccessory.removeService(svc);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Accessory info
|
|
142
|
+
const info = this.parentAccessory.getService(this.Service.AccessoryInformation);
|
|
143
|
+
info
|
|
144
|
+
.setCharacteristic(this.Characteristic.Manufacturer, 'GE')
|
|
145
|
+
.setCharacteristic(this.Characteristic.Model, this.parentAccessory.context.device.model || 'Dehumidifier')
|
|
146
|
+
.setCharacteristic(this.Characteristic.SerialNumber, this.parentAccessory.context.device.serial || 'Unknown');
|
|
147
|
+
const name = this.parentAccessory.displayName;
|
|
148
|
+
// ======== HumidifierDehumidifier ========
|
|
149
|
+
this.dhum =
|
|
150
|
+
this.parentAccessory.getService(this.Service.HumidifierDehumidifier) ||
|
|
151
|
+
this.parentAccessory.addService(this.Service.HumidifierDehumidifier, name, `${this.deviceId}-dhum`);
|
|
152
|
+
this.dhum
|
|
153
|
+
.getCharacteristic(this.Characteristic.Active)
|
|
154
|
+
.onGet(() => (this.isOn ? 1 : 0))
|
|
155
|
+
.onSet(async (value) => {
|
|
156
|
+
this.isOn = value === 1;
|
|
157
|
+
const command = { on: this.isOn, commandType: this.CMD_SET };
|
|
158
|
+
if (this.isOn) {
|
|
159
|
+
command.mode = this.lastActiveMode === this.MODE_OFF ? this.MODE_ON : this.lastActiveMode;
|
|
160
|
+
}
|
|
161
|
+
this.sendThermostat(command);
|
|
162
|
+
this.refreshCurrentState();
|
|
163
|
+
});
|
|
164
|
+
this.dhum
|
|
165
|
+
.getCharacteristic(this.Characteristic.CurrentHumidifierDehumidifierState)
|
|
166
|
+
.setProps({
|
|
167
|
+
validValues: [
|
|
168
|
+
this.Characteristic.CurrentHumidifierDehumidifierState.INACTIVE,
|
|
169
|
+
this.Characteristic.CurrentHumidifierDehumidifierState.IDLE,
|
|
170
|
+
this.Characteristic.CurrentHumidifierDehumidifierState.DEHUMIDIFYING,
|
|
171
|
+
],
|
|
172
|
+
})
|
|
173
|
+
.onGet(() => this.computeCurrentState());
|
|
174
|
+
this.dhum
|
|
175
|
+
.getCharacteristic(this.Characteristic.TargetHumidifierDehumidifierState)
|
|
176
|
+
.setProps({ validValues: [this.Characteristic.TargetHumidifierDehumidifierState.DEHUMIDIFIER] })
|
|
177
|
+
.onGet(() => this.Characteristic.TargetHumidifierDehumidifierState.DEHUMIDIFIER)
|
|
178
|
+
.onSet(async () => {
|
|
179
|
+
// Locked to DEHUMIDIFIER
|
|
180
|
+
});
|
|
181
|
+
this.dhum
|
|
182
|
+
.getCharacteristic(this.Characteristic.CurrentRelativeHumidity)
|
|
183
|
+
.onGet(() => this.currentHumidity);
|
|
184
|
+
this.dhum
|
|
185
|
+
.getCharacteristic(this.Characteristic.RelativeHumidityDehumidifierThreshold)
|
|
186
|
+
.setProps({ minValue: this.humidityMin, maxValue: this.humidityMax, minStep: 5 })
|
|
187
|
+
.onGet(() => this.clampHumidity(this.targetHumidity))
|
|
188
|
+
.onSet(async (value) => {
|
|
189
|
+
this.targetHumidity = this.clampHumidity(value);
|
|
190
|
+
this.sendThermostat({ humidity: this.targetHumidity, commandType: this.CMD_SET });
|
|
191
|
+
});
|
|
192
|
+
// Fan speed via RotationSpeed (low / high / smart-dry mapped to 3 buckets)
|
|
193
|
+
this.dhum
|
|
194
|
+
.getCharacteristic(this.Characteristic.RotationSpeed)
|
|
195
|
+
.setProps({ minValue: 0, maxValue: 100, minStep: 1 })
|
|
196
|
+
.onGet(() => this.fanSpeedToPercent(this.lastActiveFanSpeed))
|
|
197
|
+
.onSet(async (value) => {
|
|
198
|
+
const fan = this.percentToFanSpeed(value);
|
|
199
|
+
this.lastActiveFanSpeed = fan;
|
|
200
|
+
this.sendThermostat({ fanSpeed: fan, commandType: this.CMD_SET });
|
|
201
|
+
});
|
|
202
|
+
this.dhum
|
|
203
|
+
.getCharacteristic(this.Characteristic.WaterLevel)
|
|
204
|
+
.onGet(() => (this.bucketFull ? 100 : 0));
|
|
205
|
+
// ======== Filter maintenance ========
|
|
206
|
+
this.filterService =
|
|
207
|
+
this.parentAccessory.getService(this.Service.FilterMaintenance) ||
|
|
208
|
+
this.parentAccessory.addService(this.Service.FilterMaintenance, 'Filter', `${this.deviceId}-filter`);
|
|
209
|
+
this.filterService
|
|
210
|
+
.getCharacteristic(this.Characteristic.FilterChangeIndication)
|
|
211
|
+
.onGet(() => this.filterNeedsCleaning
|
|
212
|
+
? this.Characteristic.FilterChangeIndication.CHANGE_FILTER
|
|
213
|
+
: this.Characteristic.FilterChangeIndication.FILTER_OK);
|
|
214
|
+
// ======== Bucket full -> LeakSensor (for Home notifications) ========
|
|
215
|
+
this.bucketLeak =
|
|
216
|
+
this.parentAccessory.getService(this.Service.LeakSensor) ||
|
|
217
|
+
this.parentAccessory.addService(this.Service.LeakSensor, 'Bucket Full', `${this.deviceId}-bucket`);
|
|
218
|
+
this.bucketLeak
|
|
219
|
+
.getCharacteristic(this.Characteristic.LeakDetected)
|
|
220
|
+
.onGet(() => this.bucketFull
|
|
221
|
+
? this.Characteristic.LeakDetected.LEAK_DETECTED
|
|
222
|
+
: this.Characteristic.LeakDetected.LEAK_NOT_DETECTED);
|
|
223
|
+
// ======== Continuous mode switch ========
|
|
224
|
+
this.continuousSwitch =
|
|
225
|
+
this.parentAccessory.getService('Continuous Mode') ||
|
|
226
|
+
this.parentAccessory.addService(this.Service.Switch, 'Continuous Mode', `${this.deviceId}-continuous`);
|
|
227
|
+
this.continuousSwitch
|
|
228
|
+
.getCharacteristic(this.Characteristic.On)
|
|
229
|
+
.onGet(() => this.lastActiveMode === this.MODE_CONTINUOUS)
|
|
230
|
+
.onSet(async (value) => {
|
|
231
|
+
this.lastActiveMode = value ? this.MODE_CONTINUOUS : this.MODE_ON;
|
|
232
|
+
this.sendThermostat({ on: true, mode: this.lastActiveMode, commandType: this.CMD_SET });
|
|
233
|
+
this.isOn = true;
|
|
234
|
+
this.dhum.updateCharacteristic(this.Characteristic.Active, 1);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
// ---------------------------
|
|
238
|
+
// WEBSOCKET UPDATES
|
|
239
|
+
// ---------------------------
|
|
240
|
+
handleUpdate(message) {
|
|
241
|
+
const state = message.state;
|
|
242
|
+
if (!state)
|
|
243
|
+
return;
|
|
244
|
+
switch (message.domainType) {
|
|
245
|
+
case this.DOM_THERMOSTAT: {
|
|
246
|
+
if (state.on !== undefined) {
|
|
247
|
+
this.isOn = state.on;
|
|
248
|
+
this.dhum.updateCharacteristic(this.Characteristic.Active, this.isOn ? 1 : 0);
|
|
249
|
+
}
|
|
250
|
+
if (state.mode !== undefined) {
|
|
251
|
+
this.lastActiveMode = state.mode;
|
|
252
|
+
this.continuousSwitch.updateCharacteristic(this.Characteristic.On, this.lastActiveMode === this.MODE_CONTINUOUS);
|
|
253
|
+
}
|
|
254
|
+
if (state.fanSpeed !== undefined) {
|
|
255
|
+
this.lastActiveFanSpeed = state.fanSpeed;
|
|
256
|
+
this.dhum.updateCharacteristic(this.Characteristic.RotationSpeed, this.fanSpeedToPercent(this.lastActiveFanSpeed));
|
|
257
|
+
}
|
|
258
|
+
if (state.humidity !== undefined) {
|
|
259
|
+
this.targetHumidity = this.clampHumidity(state.humidity);
|
|
260
|
+
this.dhum.updateCharacteristic(this.Characteristic.RelativeHumidityDehumidifierThreshold, this.targetHumidity);
|
|
261
|
+
}
|
|
262
|
+
this.refreshCurrentState();
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
case this.DOM_HUMIDITY_AMBIENT: {
|
|
266
|
+
if (state.value !== undefined) {
|
|
267
|
+
this.currentHumidity = state.value;
|
|
268
|
+
this.dhum.updateCharacteristic(this.Characteristic.CurrentRelativeHumidity, this.currentHumidity);
|
|
269
|
+
this.refreshCurrentState();
|
|
270
|
+
}
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case this.DOM_BUCKET: {
|
|
274
|
+
if (state.on !== undefined) {
|
|
275
|
+
this.bucketFull = state.on;
|
|
276
|
+
this.dhum.updateCharacteristic(this.Characteristic.WaterLevel, this.bucketFull ? 100 : 0);
|
|
277
|
+
this.bucketLeak.updateCharacteristic(this.Characteristic.LeakDetected, this.bucketFull
|
|
278
|
+
? this.Characteristic.LeakDetected.LEAK_DETECTED
|
|
279
|
+
: this.Characteristic.LeakDetected.LEAK_NOT_DETECTED);
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
case this.DOM_FILTER: {
|
|
284
|
+
if (state.on !== undefined) {
|
|
285
|
+
this.filterNeedsCleaning = state.on;
|
|
286
|
+
this.filterService.updateCharacteristic(this.Characteristic.FilterChangeIndication, this.filterNeedsCleaning
|
|
287
|
+
? this.Characteristic.FilterChangeIndication.CHANGE_FILTER
|
|
288
|
+
: this.Characteristic.FilterChangeIndication.FILTER_OK);
|
|
289
|
+
}
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
default:
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// ---------------------------
|
|
297
|
+
// COMMAND SENDER
|
|
298
|
+
// ---------------------------
|
|
299
|
+
sendThermostat(command) {
|
|
300
|
+
const cmdBody = {
|
|
301
|
+
command,
|
|
302
|
+
kind: 'service#command',
|
|
303
|
+
deviceId: this.deviceId,
|
|
304
|
+
serviceDeviceType: this.DEVICE_TYPE,
|
|
305
|
+
serviceType: this.SVC_THERMOSTAT,
|
|
306
|
+
domainType: this.DOM_THERMOSTAT,
|
|
307
|
+
};
|
|
308
|
+
this.sendCommand(cmdBody);
|
|
309
|
+
}
|
|
310
|
+
async sendCommand(cmdBody) {
|
|
311
|
+
try {
|
|
312
|
+
const response = await this.client.sendCommand(cmdBody);
|
|
313
|
+
if (response == null) {
|
|
314
|
+
this.client.debug('No response from send command');
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
return response.success;
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
321
|
+
this.platform.log.error(chalk.red(`Dehumidifier sendCommand failed: ${message}`));
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// ---------------------------
|
|
326
|
+
// HELPERS
|
|
327
|
+
// ---------------------------
|
|
328
|
+
findService(serviceType, domainType) {
|
|
329
|
+
return this.deviceServices.find((service) => service.serviceType === serviceType && service.domainType === domainType);
|
|
330
|
+
}
|
|
331
|
+
clampHumidity(value) {
|
|
332
|
+
return Math.max(this.humidityMin, Math.min(this.humidityMax, Math.round(value)));
|
|
333
|
+
}
|
|
334
|
+
fanSpeedToPercent(fan) {
|
|
335
|
+
switch (fan) {
|
|
336
|
+
case this.FAN_LOW: return 33;
|
|
337
|
+
case this.FAN_HIGH: return 66;
|
|
338
|
+
case this.FAN_SMART_DRY: return 100;
|
|
339
|
+
default: return 66;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
percentToFanSpeed(percent) {
|
|
343
|
+
if (percent <= 40)
|
|
344
|
+
return this.FAN_LOW;
|
|
345
|
+
if (percent <= 75)
|
|
346
|
+
return this.FAN_HIGH;
|
|
347
|
+
return this.FAN_SMART_DRY;
|
|
348
|
+
}
|
|
349
|
+
computeCurrentState() {
|
|
350
|
+
const C = this.Characteristic.CurrentHumidifierDehumidifierState;
|
|
351
|
+
if (!this.isOn)
|
|
352
|
+
return C.INACTIVE;
|
|
353
|
+
return this.currentHumidity > this.targetHumidity ? C.DEHUMIDIFYING : C.IDLE;
|
|
354
|
+
}
|
|
355
|
+
refreshCurrentState() {
|
|
356
|
+
this.dhum.updateCharacteristic(this.Characteristic.CurrentHumidifierDehumidifierState, this.computeCurrentState());
|
|
357
|
+
}
|
|
358
|
+
async setupWebSocket() {
|
|
359
|
+
try {
|
|
360
|
+
await this.client.authenticate();
|
|
361
|
+
await this.client.connect();
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
this.platform.log.error(`Failed to connect to SmartHQ WebSocket for Dehumidifier ${this.deviceId}:`, error);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
async dispose() {
|
|
368
|
+
if (this.disposed)
|
|
369
|
+
return;
|
|
370
|
+
this.disposed = true;
|
|
371
|
+
try {
|
|
372
|
+
this.client.removeListener('service_update', this.serviceUpdateListener);
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
// best-effort
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
await this.client.disconnect();
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
this.platform.log.error(`Failed to disconnect SmartHQ client for Dehumidifier ${this.deviceId}:`, error);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=dehumidifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dehumidifier.js","sourceRoot":"","sources":["../../src/dehumidifier/dehumidifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Dehumidifier } from './dehumidifier/dehumidifier.js';
|
|
2
|
+
import { PlatformAccessory } from 'homebridge';
|
|
3
|
+
import { SmartHqPlatform } from './platform.js';
|
|
4
|
+
import { DeviceService } from 'ge-smarthq';
|
|
5
|
+
export declare function setupDehumidifierServices(this: SmartHqPlatform, accessory: PlatformAccessory, deviceServices: DeviceService[], deviceId: string): Dehumidifier;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dehumidifierServices.js","sourceRoot":"","sources":["../src/dehumidifierServices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAK9D,MAAM,UAAU,yBAAyB,CAAwB,SAA4B,EAAE,cAA+B,EAAE,QAAgB;IAC9I,OAAO,IAAI,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;AACrE,CAAC"}
|
package/dist/platform.js
CHANGED
|
@@ -5,6 +5,7 @@ import chalk from 'chalk';
|
|
|
5
5
|
import { setupDishwasherServices } from './dishwasherServices.js';
|
|
6
6
|
import { setupRefrigeratorServices } from './refrigeratorServices.js';
|
|
7
7
|
import { setupAirConditionerServices } from './airConditionerServices.js';
|
|
8
|
+
import { setupDehumidifierServices } from './dehumidifierServices.js';
|
|
8
9
|
export class SmartHqPlatform {
|
|
9
10
|
log;
|
|
10
11
|
config;
|
|
@@ -132,6 +133,11 @@ export class SmartHqPlatform {
|
|
|
132
133
|
setupAirConditionerServices.call(this, accessoryType, deviceServices, device.deviceId, [groupModesUuid, groupFanUuid]);
|
|
133
134
|
break;
|
|
134
135
|
}
|
|
136
|
+
case 'cloud.smarthq.device.dehumidifier': {
|
|
137
|
+
this.debug('green', `Setting up Dehumidifier services for ${device.nickname}`);
|
|
138
|
+
setupDehumidifierServices.call(this, accessoryType, deviceServices, device.deviceId);
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
135
141
|
default:
|
|
136
142
|
this.debug('red', `not implemented device : for device ${device.nickname}`);
|
|
137
143
|
}
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE3D,OAAO,EAAU,aAAa,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,aAAa;AACb,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import {
|
|
2
|
+
API,
|
|
3
|
+
PlatformAccessory,
|
|
4
|
+
Service,
|
|
5
|
+
Characteristic,
|
|
6
|
+
} from 'homebridge';
|
|
7
|
+
|
|
8
|
+
import { SmartHQClient, DeviceService, SendCommandRequest } from 'ge-smarthq';
|
|
9
|
+
import { SmartHqPlatform } from '../platform.js';
|
|
10
|
+
import { ServiceMessage } from '../index.js';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* GE SmartHQ Dehumidifier (e.g. model ADSE25WWT).
|
|
15
|
+
*
|
|
16
|
+
* The dehumidifier exposes the SAME thermostat.v1 service the window AC uses, so
|
|
17
|
+
* this accessory is modeled on airConditioner.ts. Mapping:
|
|
18
|
+
*
|
|
19
|
+
* thermostat.v1 / domain.thermostat -> on, mode (on/off/continuous),
|
|
20
|
+
* fanSpeed (high/low/smart.dry),
|
|
21
|
+
* humidity (target %, 35-80)
|
|
22
|
+
* integer / domain.humidity.ambient -> current relative humidity (value %)
|
|
23
|
+
* toggle / domain.bucket.status -> bucket full (on == full)
|
|
24
|
+
* toggle / domain.filter.status -> clean filter (on == needs cleaning)
|
|
25
|
+
*
|
|
26
|
+
* HomeKit surface (all on one accessory):
|
|
27
|
+
* HumidifierDehumidifier -> Active, Current/Target state, CurrentRelativeHumidity,
|
|
28
|
+
* RelativeHumidityDehumidifierThreshold (target),
|
|
29
|
+
* RotationSpeed (fan), WaterLevel (bucket)
|
|
30
|
+
* FilterMaintenance -> FilterChangeIndication
|
|
31
|
+
* LeakSensor -> bucket full (drives Home push notifications)
|
|
32
|
+
* Switch "Continuous" -> toggles continuous mode
|
|
33
|
+
*/
|
|
34
|
+
export class Dehumidifier {
|
|
35
|
+
// ======== SmartHQ constants ========
|
|
36
|
+
private readonly DEVICE_TYPE = 'cloud.smarthq.device.dehumidifier';
|
|
37
|
+
private readonly SVC_THERMOSTAT = 'cloud.smarthq.service.thermostat.v1';
|
|
38
|
+
private readonly DOM_THERMOSTAT = 'cloud.smarthq.domain.thermostat';
|
|
39
|
+
private readonly SVC_INTEGER = 'cloud.smarthq.service.integer';
|
|
40
|
+
private readonly DOM_HUMIDITY_AMBIENT = 'cloud.smarthq.domain.humidity.ambient';
|
|
41
|
+
private readonly SVC_TOGGLE = 'cloud.smarthq.service.toggle';
|
|
42
|
+
private readonly DOM_BUCKET = 'cloud.smarthq.domain.bucket.status';
|
|
43
|
+
private readonly DOM_FILTER = 'cloud.smarthq.domain.filter.status';
|
|
44
|
+
private readonly CMD_SET = 'cloud.smarthq.command.thermostat.v1.set';
|
|
45
|
+
|
|
46
|
+
private readonly MODE_ON = 'cloud.smarthq.type.thermostatmode.on';
|
|
47
|
+
private readonly MODE_OFF = 'cloud.smarthq.type.thermostatmode.off';
|
|
48
|
+
private readonly MODE_CONTINUOUS = 'cloud.smarthq.type.thermostatmode.continuous';
|
|
49
|
+
|
|
50
|
+
private readonly FAN_LOW = 'cloud.smarthq.type.fanspeed.low';
|
|
51
|
+
private readonly FAN_HIGH = 'cloud.smarthq.type.fanspeed.high';
|
|
52
|
+
private readonly FAN_SMART_DRY = 'cloud.smarthq.type.fanspeed.smart.dry';
|
|
53
|
+
|
|
54
|
+
// ======== State cache ========
|
|
55
|
+
private isOn = false;
|
|
56
|
+
private lastActiveMode = this.MODE_ON;
|
|
57
|
+
private lastActiveFanSpeed = this.FAN_HIGH;
|
|
58
|
+
private targetHumidity = 45;
|
|
59
|
+
private currentHumidity = 50;
|
|
60
|
+
private bucketFull = false;
|
|
61
|
+
private filterNeedsCleaning = false;
|
|
62
|
+
|
|
63
|
+
private humidityMin: number;
|
|
64
|
+
private humidityMax: number;
|
|
65
|
+
|
|
66
|
+
private disposed = false;
|
|
67
|
+
private readonly serviceUpdateListener: (message: ServiceMessage) => void;
|
|
68
|
+
|
|
69
|
+
private client: SmartHQClient;
|
|
70
|
+
private api: API;
|
|
71
|
+
public Service: typeof Service;
|
|
72
|
+
public Characteristic: typeof Characteristic;
|
|
73
|
+
|
|
74
|
+
private parentAccessory: PlatformAccessory;
|
|
75
|
+
|
|
76
|
+
// Services
|
|
77
|
+
private dhum!: Service;
|
|
78
|
+
private filterService!: Service;
|
|
79
|
+
private bucketLeak!: Service;
|
|
80
|
+
private continuousSwitch!: Service;
|
|
81
|
+
|
|
82
|
+
constructor(
|
|
83
|
+
private readonly platform: SmartHqPlatform,
|
|
84
|
+
private readonly accessory: PlatformAccessory,
|
|
85
|
+
private readonly deviceServices: DeviceService[],
|
|
86
|
+
private readonly deviceId: string,
|
|
87
|
+
) {
|
|
88
|
+
this.api = platform.api;
|
|
89
|
+
this.Service = this.api.hap.Service;
|
|
90
|
+
this.Characteristic = this.api.hap.Characteristic;
|
|
91
|
+
this.parentAccessory = accessory;
|
|
92
|
+
|
|
93
|
+
this.client = new SmartHQClient({
|
|
94
|
+
clientId: platform.config.clientId,
|
|
95
|
+
clientSecret: platform.config.clientSecret,
|
|
96
|
+
redirectUri: platform.config.redirectUri,
|
|
97
|
+
debug: platform.config.debugLogging || false,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Initialize humidity thresholds from config
|
|
101
|
+
this.humidityMin = (platform.config.humidityMin as number) ?? 35;
|
|
102
|
+
this.humidityMax = (platform.config.humidityMax as number) ?? 80;
|
|
103
|
+
|
|
104
|
+
// ---- Seed initial state from discovery snapshot ----
|
|
105
|
+
const thermostat = this.findService(this.SVC_THERMOSTAT, this.DOM_THERMOSTAT);
|
|
106
|
+
if (thermostat?.state) {
|
|
107
|
+
const s = thermostat.state;
|
|
108
|
+
if (s.on != null) this.isOn = s.on as boolean;
|
|
109
|
+
if (s.mode != null) this.lastActiveMode = s.mode as string;
|
|
110
|
+
if (s.fanSpeed != null) this.lastActiveFanSpeed = s.fanSpeed as string;
|
|
111
|
+
if (s.humidity != null) this.targetHumidity = s.humidity as number;
|
|
112
|
+
}
|
|
113
|
+
if (thermostat?.config) {
|
|
114
|
+
const c = thermostat.config;
|
|
115
|
+
if (c.humidityMinimum != null) this.humidityMin = c.humidityMinimum as number;
|
|
116
|
+
if (c.humidityMaximum != null) this.humidityMax = c.humidityMaximum as number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const ambient = this.findService(this.SVC_INTEGER, this.DOM_HUMIDITY_AMBIENT);
|
|
120
|
+
if (ambient?.state?.value != null) {
|
|
121
|
+
this.currentHumidity = ambient.state.value as number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const bucket = this.findService(this.SVC_TOGGLE, this.DOM_BUCKET);
|
|
125
|
+
if (bucket?.state?.on != null) this.bucketFull = bucket.state.on as boolean;
|
|
126
|
+
|
|
127
|
+
const filter = this.findService(this.SVC_TOGGLE, this.DOM_FILTER);
|
|
128
|
+
if (filter?.state?.on != null) this.filterNeedsCleaning = filter.state.on as boolean;
|
|
129
|
+
|
|
130
|
+
this.setupServices();
|
|
131
|
+
this.setupWebSocket();
|
|
132
|
+
|
|
133
|
+
this.serviceUpdateListener = (message: ServiceMessage) => {
|
|
134
|
+
if (message.deviceId !== this.deviceId) return;
|
|
135
|
+
this.handleUpdate(message);
|
|
136
|
+
};
|
|
137
|
+
this.client.on('service_update', this.serviceUpdateListener);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ---------------------------
|
|
141
|
+
// SERVICE SETUP
|
|
142
|
+
// ---------------------------
|
|
143
|
+
private setupServices() {
|
|
144
|
+
// Clean up any stale services HomeKit may have cached for this accessory.
|
|
145
|
+
const keepUUIDs = new Set<string>([
|
|
146
|
+
this.Service.AccessoryInformation.UUID,
|
|
147
|
+
this.Service.HumidifierDehumidifier.UUID,
|
|
148
|
+
this.Service.FilterMaintenance.UUID,
|
|
149
|
+
this.Service.LeakSensor.UUID,
|
|
150
|
+
this.Service.Switch.UUID,
|
|
151
|
+
]);
|
|
152
|
+
for (const svc of [...this.parentAccessory.services]) {
|
|
153
|
+
if (!keepUUIDs.has(svc.UUID)) {
|
|
154
|
+
this.parentAccessory.removeService(svc);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Accessory info
|
|
159
|
+
const info = this.parentAccessory.getService(this.Service.AccessoryInformation)!;
|
|
160
|
+
info
|
|
161
|
+
.setCharacteristic(this.Characteristic.Manufacturer, 'GE')
|
|
162
|
+
.setCharacteristic(
|
|
163
|
+
this.Characteristic.Model,
|
|
164
|
+
this.parentAccessory.context.device.model || 'Dehumidifier',
|
|
165
|
+
)
|
|
166
|
+
.setCharacteristic(
|
|
167
|
+
this.Characteristic.SerialNumber,
|
|
168
|
+
this.parentAccessory.context.device.serial || 'Unknown',
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const name = this.parentAccessory.displayName;
|
|
172
|
+
|
|
173
|
+
// ======== HumidifierDehumidifier ========
|
|
174
|
+
this.dhum =
|
|
175
|
+
this.parentAccessory.getService(this.Service.HumidifierDehumidifier) ||
|
|
176
|
+
this.parentAccessory.addService(this.Service.HumidifierDehumidifier, name, `${this.deviceId}-dhum`);
|
|
177
|
+
|
|
178
|
+
this.dhum
|
|
179
|
+
.getCharacteristic(this.Characteristic.Active)
|
|
180
|
+
.onGet(() => (this.isOn ? 1 : 0))
|
|
181
|
+
.onSet(async (value) => {
|
|
182
|
+
this.isOn = (value as number) === 1;
|
|
183
|
+
const command: Record<string, unknown> = { on: this.isOn, commandType: this.CMD_SET };
|
|
184
|
+
if (this.isOn) {
|
|
185
|
+
command.mode = this.lastActiveMode === this.MODE_OFF ? this.MODE_ON : this.lastActiveMode;
|
|
186
|
+
}
|
|
187
|
+
this.sendThermostat(command);
|
|
188
|
+
this.refreshCurrentState();
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
this.dhum
|
|
192
|
+
.getCharacteristic(this.Characteristic.CurrentHumidifierDehumidifierState)
|
|
193
|
+
.setProps({
|
|
194
|
+
validValues: [
|
|
195
|
+
this.Characteristic.CurrentHumidifierDehumidifierState.INACTIVE,
|
|
196
|
+
this.Characteristic.CurrentHumidifierDehumidifierState.IDLE,
|
|
197
|
+
this.Characteristic.CurrentHumidifierDehumidifierState.DEHUMIDIFYING,
|
|
198
|
+
],
|
|
199
|
+
})
|
|
200
|
+
.onGet(() => this.computeCurrentState());
|
|
201
|
+
|
|
202
|
+
this.dhum
|
|
203
|
+
.getCharacteristic(this.Characteristic.TargetHumidifierDehumidifierState)
|
|
204
|
+
.setProps({ validValues: [this.Characteristic.TargetHumidifierDehumidifierState.DEHUMIDIFIER] })
|
|
205
|
+
.onGet(() => this.Characteristic.TargetHumidifierDehumidifierState.DEHUMIDIFIER)
|
|
206
|
+
.onSet(async () => {
|
|
207
|
+
// Locked to DEHUMIDIFIER
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
this.dhum
|
|
211
|
+
.getCharacteristic(this.Characteristic.CurrentRelativeHumidity)
|
|
212
|
+
.onGet(() => this.currentHumidity);
|
|
213
|
+
|
|
214
|
+
this.dhum
|
|
215
|
+
.getCharacteristic(this.Characteristic.RelativeHumidityDehumidifierThreshold)
|
|
216
|
+
.setProps({ minValue: this.humidityMin, maxValue: this.humidityMax, minStep: 5 })
|
|
217
|
+
.onGet(() => this.clampHumidity(this.targetHumidity))
|
|
218
|
+
.onSet(async (value) => {
|
|
219
|
+
this.targetHumidity = this.clampHumidity(value as number);
|
|
220
|
+
this.sendThermostat({ humidity: this.targetHumidity, commandType: this.CMD_SET });
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Fan speed via RotationSpeed (low / high / smart-dry mapped to 3 buckets)
|
|
224
|
+
this.dhum
|
|
225
|
+
.getCharacteristic(this.Characteristic.RotationSpeed)
|
|
226
|
+
.setProps({ minValue: 0, maxValue: 100, minStep: 1 })
|
|
227
|
+
.onGet(() => this.fanSpeedToPercent(this.lastActiveFanSpeed))
|
|
228
|
+
.onSet(async (value) => {
|
|
229
|
+
const fan = this.percentToFanSpeed(value as number);
|
|
230
|
+
this.lastActiveFanSpeed = fan;
|
|
231
|
+
this.sendThermostat({ fanSpeed: fan, commandType: this.CMD_SET });
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
this.dhum
|
|
235
|
+
.getCharacteristic(this.Characteristic.WaterLevel)
|
|
236
|
+
.onGet(() => (this.bucketFull ? 100 : 0));
|
|
237
|
+
|
|
238
|
+
// ======== Filter maintenance ========
|
|
239
|
+
this.filterService =
|
|
240
|
+
this.parentAccessory.getService(this.Service.FilterMaintenance) ||
|
|
241
|
+
this.parentAccessory.addService(this.Service.FilterMaintenance, 'Filter', `${this.deviceId}-filter`);
|
|
242
|
+
this.filterService
|
|
243
|
+
.getCharacteristic(this.Characteristic.FilterChangeIndication)
|
|
244
|
+
.onGet(() =>
|
|
245
|
+
this.filterNeedsCleaning
|
|
246
|
+
? this.Characteristic.FilterChangeIndication.CHANGE_FILTER
|
|
247
|
+
: this.Characteristic.FilterChangeIndication.FILTER_OK,
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// ======== Bucket full -> LeakSensor (for Home notifications) ========
|
|
251
|
+
this.bucketLeak =
|
|
252
|
+
this.parentAccessory.getService(this.Service.LeakSensor) ||
|
|
253
|
+
this.parentAccessory.addService(this.Service.LeakSensor, 'Bucket Full', `${this.deviceId}-bucket`);
|
|
254
|
+
this.bucketLeak
|
|
255
|
+
.getCharacteristic(this.Characteristic.LeakDetected)
|
|
256
|
+
.onGet(() =>
|
|
257
|
+
this.bucketFull
|
|
258
|
+
? this.Characteristic.LeakDetected.LEAK_DETECTED
|
|
259
|
+
: this.Characteristic.LeakDetected.LEAK_NOT_DETECTED,
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
// ======== Continuous mode switch ========
|
|
263
|
+
this.continuousSwitch =
|
|
264
|
+
this.parentAccessory.getService('Continuous Mode') ||
|
|
265
|
+
this.parentAccessory.addService(this.Service.Switch, 'Continuous Mode', `${this.deviceId}-continuous`);
|
|
266
|
+
this.continuousSwitch
|
|
267
|
+
.getCharacteristic(this.Characteristic.On)
|
|
268
|
+
.onGet(() => this.lastActiveMode === this.MODE_CONTINUOUS)
|
|
269
|
+
.onSet(async (value) => {
|
|
270
|
+
this.lastActiveMode = value ? this.MODE_CONTINUOUS : this.MODE_ON;
|
|
271
|
+
this.sendThermostat({ on: true, mode: this.lastActiveMode, commandType: this.CMD_SET });
|
|
272
|
+
this.isOn = true;
|
|
273
|
+
this.dhum.updateCharacteristic(this.Characteristic.Active, 1);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// ---------------------------
|
|
278
|
+
// WEBSOCKET UPDATES
|
|
279
|
+
// ---------------------------
|
|
280
|
+
private handleUpdate(message: ServiceMessage) {
|
|
281
|
+
const state = message.state;
|
|
282
|
+
if (!state) return;
|
|
283
|
+
|
|
284
|
+
switch (message.domainType) {
|
|
285
|
+
case this.DOM_THERMOSTAT: {
|
|
286
|
+
if (state.on !== undefined) {
|
|
287
|
+
this.isOn = state.on as boolean;
|
|
288
|
+
this.dhum.updateCharacteristic(this.Characteristic.Active, this.isOn ? 1 : 0);
|
|
289
|
+
}
|
|
290
|
+
if (state.mode !== undefined) {
|
|
291
|
+
this.lastActiveMode = state.mode as string;
|
|
292
|
+
this.continuousSwitch.updateCharacteristic(
|
|
293
|
+
this.Characteristic.On,
|
|
294
|
+
this.lastActiveMode === this.MODE_CONTINUOUS,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
if (state.fanSpeed !== undefined) {
|
|
298
|
+
this.lastActiveFanSpeed = state.fanSpeed as string;
|
|
299
|
+
this.dhum.updateCharacteristic(
|
|
300
|
+
this.Characteristic.RotationSpeed,
|
|
301
|
+
this.fanSpeedToPercent(this.lastActiveFanSpeed),
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
if (state.humidity !== undefined) {
|
|
305
|
+
this.targetHumidity = this.clampHumidity(state.humidity as number);
|
|
306
|
+
this.dhum.updateCharacteristic(
|
|
307
|
+
this.Characteristic.RelativeHumidityDehumidifierThreshold,
|
|
308
|
+
this.targetHumidity,
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
this.refreshCurrentState();
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
case this.DOM_HUMIDITY_AMBIENT: {
|
|
315
|
+
if (state.value !== undefined) {
|
|
316
|
+
this.currentHumidity = state.value as number;
|
|
317
|
+
this.dhum.updateCharacteristic(this.Characteristic.CurrentRelativeHumidity, this.currentHumidity);
|
|
318
|
+
this.refreshCurrentState();
|
|
319
|
+
}
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case this.DOM_BUCKET: {
|
|
323
|
+
if (state.on !== undefined) {
|
|
324
|
+
this.bucketFull = state.on as boolean;
|
|
325
|
+
this.dhum.updateCharacteristic(
|
|
326
|
+
this.Characteristic.WaterLevel,
|
|
327
|
+
this.bucketFull ? 100 : 0,
|
|
328
|
+
);
|
|
329
|
+
this.bucketLeak.updateCharacteristic(
|
|
330
|
+
this.Characteristic.LeakDetected,
|
|
331
|
+
this.bucketFull
|
|
332
|
+
? this.Characteristic.LeakDetected.LEAK_DETECTED
|
|
333
|
+
: this.Characteristic.LeakDetected.LEAK_NOT_DETECTED,
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
case this.DOM_FILTER: {
|
|
339
|
+
if (state.on !== undefined) {
|
|
340
|
+
this.filterNeedsCleaning = state.on as boolean;
|
|
341
|
+
this.filterService.updateCharacteristic(
|
|
342
|
+
this.Characteristic.FilterChangeIndication,
|
|
343
|
+
this.filterNeedsCleaning
|
|
344
|
+
? this.Characteristic.FilterChangeIndication.CHANGE_FILTER
|
|
345
|
+
: this.Characteristic.FilterChangeIndication.FILTER_OK,
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
default:
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// ---------------------------
|
|
356
|
+
// COMMAND SENDER
|
|
357
|
+
// ---------------------------
|
|
358
|
+
private sendThermostat(command: Record<string, unknown>) {
|
|
359
|
+
const cmdBody = {
|
|
360
|
+
command,
|
|
361
|
+
kind: 'service#command',
|
|
362
|
+
deviceId: this.deviceId,
|
|
363
|
+
serviceDeviceType: this.DEVICE_TYPE,
|
|
364
|
+
serviceType: this.SVC_THERMOSTAT,
|
|
365
|
+
domainType: this.DOM_THERMOSTAT,
|
|
366
|
+
} as unknown as SendCommandRequest;
|
|
367
|
+
this.sendCommand(cmdBody);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
private async sendCommand(cmdBody: SendCommandRequest) {
|
|
371
|
+
try {
|
|
372
|
+
const response = await this.client.sendCommand(cmdBody);
|
|
373
|
+
if (response == null) {
|
|
374
|
+
this.client.debug('No response from send command');
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
return response.success;
|
|
378
|
+
} catch (error: unknown) {
|
|
379
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
380
|
+
this.platform.log.error(chalk.red(`Dehumidifier sendCommand failed: ${message}`));
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// ---------------------------
|
|
386
|
+
// HELPERS
|
|
387
|
+
// ---------------------------
|
|
388
|
+
private findService(serviceType: string, domainType: string) {
|
|
389
|
+
return this.deviceServices.find(
|
|
390
|
+
(service) => service.serviceType === serviceType && service.domainType === domainType,
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
private clampHumidity(value: number): number {
|
|
395
|
+
return Math.max(this.humidityMin, Math.min(this.humidityMax, Math.round(value)));
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
private fanSpeedToPercent(fan: string): number {
|
|
399
|
+
switch (fan) {
|
|
400
|
+
case this.FAN_LOW: return 33;
|
|
401
|
+
case this.FAN_HIGH: return 66;
|
|
402
|
+
case this.FAN_SMART_DRY: return 100;
|
|
403
|
+
default: return 66;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private percentToFanSpeed(percent: number): string {
|
|
408
|
+
if (percent <= 40) return this.FAN_LOW;
|
|
409
|
+
if (percent <= 75) return this.FAN_HIGH;
|
|
410
|
+
return this.FAN_SMART_DRY;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
private computeCurrentState(): number {
|
|
414
|
+
const C = this.Characteristic.CurrentHumidifierDehumidifierState;
|
|
415
|
+
if (!this.isOn) return C.INACTIVE;
|
|
416
|
+
return this.currentHumidity > this.targetHumidity ? C.DEHUMIDIFYING : C.IDLE;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
private refreshCurrentState() {
|
|
420
|
+
this.dhum.updateCharacteristic(
|
|
421
|
+
this.Characteristic.CurrentHumidifierDehumidifierState,
|
|
422
|
+
this.computeCurrentState(),
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
private async setupWebSocket() {
|
|
427
|
+
try {
|
|
428
|
+
await this.client.authenticate();
|
|
429
|
+
await this.client.connect();
|
|
430
|
+
} catch (error) {
|
|
431
|
+
this.platform.log.error(
|
|
432
|
+
`Failed to connect to SmartHQ WebSocket for Dehumidifier ${this.deviceId}:`,
|
|
433
|
+
error,
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
public async dispose(): Promise<void> {
|
|
439
|
+
if (this.disposed) return;
|
|
440
|
+
this.disposed = true;
|
|
441
|
+
try {
|
|
442
|
+
this.client.removeListener('service_update', this.serviceUpdateListener);
|
|
443
|
+
} catch {
|
|
444
|
+
// best-effort
|
|
445
|
+
}
|
|
446
|
+
try {
|
|
447
|
+
await this.client.disconnect();
|
|
448
|
+
} catch (error) {
|
|
449
|
+
this.platform.log.error(
|
|
450
|
+
`Failed to disconnect SmartHQ client for Dehumidifier ${this.deviceId}:`,
|
|
451
|
+
error,
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Dehumidifier } from './dehumidifier/dehumidifier.js';
|
|
2
|
+
import { PlatformAccessory } from 'homebridge';
|
|
3
|
+
import { SmartHqPlatform } from './platform.js';
|
|
4
|
+
import { DeviceService } from 'ge-smarthq';
|
|
5
|
+
|
|
6
|
+
export function setupDehumidifierServices(this: SmartHqPlatform, accessory: PlatformAccessory, deviceServices: DeviceService[], deviceId: string) {
|
|
7
|
+
return new Dehumidifier(this, accessory, deviceServices, deviceId);
|
|
8
|
+
}
|
package/src/platform.ts
CHANGED
|
@@ -15,6 +15,7 @@ import chalk from 'chalk';
|
|
|
15
15
|
import { setupDishwasherServices } from './dishwasherServices.js';
|
|
16
16
|
import { setupRefrigeratorServices } from './refrigeratorServices.js';
|
|
17
17
|
import { setupAirConditionerServices } from './airConditionerServices.js';
|
|
18
|
+
import { setupDehumidifierServices } from './dehumidifierServices.js';
|
|
18
19
|
|
|
19
20
|
export class SmartHqPlatform implements DynamicPlatformPlugin {
|
|
20
21
|
private client: SmartHQClient;
|
|
@@ -224,6 +225,12 @@ export class SmartHqPlatform implements DynamicPlatformPlugin {
|
|
|
224
225
|
break;
|
|
225
226
|
}
|
|
226
227
|
|
|
228
|
+
case 'cloud.smarthq.device.dehumidifier': {
|
|
229
|
+
this.debug('green', `Setting up Dehumidifier services for ${device.nickname}`);
|
|
230
|
+
setupDehumidifierServices.call(this, accessoryType!, deviceServices, device.deviceId);
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
|
|
227
234
|
default:
|
|
228
235
|
this.debug('red', `not implemented device : for device ${device.nickname}`);
|
|
229
236
|
}
|