daikin-airbase 0.1.6 → 0.3.0
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/dist/index.cjs +208 -69
- package/dist/index.d.mts +252 -25
- package/dist/index.d.ts +252 -25
- package/dist/index.mjs +196 -67
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,7 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
|
|
33
|
+
Client: () => Client,
|
|
34
34
|
ControlMode: () => ControlMode,
|
|
35
35
|
DaikinClient: () => DaikinClient,
|
|
36
36
|
FanSpeed: () => FanSpeed,
|
|
@@ -39,15 +39,26 @@ __export(index_exports, {
|
|
|
39
39
|
Zones: () => Zones,
|
|
40
40
|
basic_info: () => basic_info,
|
|
41
41
|
discover: () => discover,
|
|
42
|
-
|
|
42
|
+
getNetwork_setting: () => getNetwork_setting,
|
|
43
|
+
get_control_info: () => get_control_info,
|
|
44
|
+
get_datetime: () => get_datetime,
|
|
45
|
+
get_dealer_info: () => get_dealer_info,
|
|
46
|
+
get_model_info: () => get_model_info,
|
|
47
|
+
get_quick_timer: () => get_quick_timer,
|
|
48
|
+
get_sensor_info: () => get_sensor_info,
|
|
49
|
+
get_wifi_setting: () => get_wifi_setting,
|
|
50
|
+
get_zone_settings: () => get_zone_settings,
|
|
51
|
+
set_control_info: () => set_control_info,
|
|
52
|
+
set_zone_setting: () => set_zone_setting
|
|
43
53
|
});
|
|
44
54
|
module.exports = __toCommonJS(index_exports);
|
|
45
55
|
|
|
46
56
|
// src/ParamParser.ts
|
|
47
|
-
|
|
57
|
+
var int = (v) => Math.round(v);
|
|
58
|
+
var bool = (v) => v ? 1 : 0;
|
|
59
|
+
function deserialize(data) {
|
|
48
60
|
const result = {};
|
|
49
|
-
const
|
|
50
|
-
for (const part of parts) {
|
|
61
|
+
for (const part of data) {
|
|
51
62
|
const [key, value] = part.split("=");
|
|
52
63
|
if (key === void 0) continue;
|
|
53
64
|
const maybeNumber = Number(value);
|
|
@@ -59,10 +70,20 @@ function parse(str) {
|
|
|
59
70
|
}
|
|
60
71
|
return result;
|
|
61
72
|
}
|
|
73
|
+
function serialize(parameters) {
|
|
74
|
+
const queries = [];
|
|
75
|
+
for (const key in parameters) {
|
|
76
|
+
const value = parameters[key];
|
|
77
|
+
if (value === void 0) continue;
|
|
78
|
+
const encoded = encodeURIComponent(typeof value === "string" ? value : value !== null ? `${int(value)}` : "");
|
|
79
|
+
queries.push(`${key}=${encoded}`);
|
|
80
|
+
}
|
|
81
|
+
return queries;
|
|
82
|
+
}
|
|
62
83
|
|
|
63
|
-
// src/api/
|
|
84
|
+
// src/api/Client.ts
|
|
64
85
|
var import_node_http = __toESM(require("http"));
|
|
65
|
-
var
|
|
86
|
+
var Client = class {
|
|
66
87
|
host;
|
|
67
88
|
constructor(host) {
|
|
68
89
|
this.host = host;
|
|
@@ -70,16 +91,8 @@ var API = class {
|
|
|
70
91
|
async request(endpoint, parameters) {
|
|
71
92
|
const body = await new Promise((resolve, reject) => {
|
|
72
93
|
const url = new URL(`/skyfi${endpoint}`, `http://${this.host}/`);
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
for (const key in parameters) {
|
|
76
|
-
const value = parameters[key];
|
|
77
|
-
if (value === void 0) continue;
|
|
78
|
-
const encoded = encodeURIComponent(`${value ?? ""}`);
|
|
79
|
-
queries.push(`${key}=${encoded}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
const search = queries.length > 0 ? `?${queries.join("&")}` : "";
|
|
94
|
+
const serialized = parameters ? serialize(parameters) : [];
|
|
95
|
+
const search = serialized.length > 0 ? `?${serialized.join("&")}` : "";
|
|
83
96
|
const req = import_node_http.default.request(
|
|
84
97
|
{
|
|
85
98
|
host: url.hostname,
|
|
@@ -102,7 +115,7 @@ var API = class {
|
|
|
102
115
|
req.on("error", reject);
|
|
103
116
|
req.end();
|
|
104
117
|
});
|
|
105
|
-
return
|
|
118
|
+
return deserialize(body.split(","));
|
|
106
119
|
}
|
|
107
120
|
};
|
|
108
121
|
|
|
@@ -125,7 +138,7 @@ function discover(timeoutMs = 3e3) {
|
|
|
125
138
|
});
|
|
126
139
|
socket.on("message", (msg, rinfo) => {
|
|
127
140
|
const raw = msg.toString("utf8");
|
|
128
|
-
const info =
|
|
141
|
+
const info = deserialize(raw.split(","));
|
|
129
142
|
const key = `${info.mac || info.id || rinfo.address}`;
|
|
130
143
|
availableUnits.set(key, {
|
|
131
144
|
discoveredAddress: rinfo.address,
|
|
@@ -152,15 +165,42 @@ function discover(timeoutMs = 3e3) {
|
|
|
152
165
|
});
|
|
153
166
|
}
|
|
154
167
|
|
|
155
|
-
// src/api/
|
|
156
|
-
var
|
|
168
|
+
// src/api/aircon/get_control_info.ts
|
|
169
|
+
var get_control_info = (http2) => http2.request("/aircon/get_control_info");
|
|
170
|
+
|
|
171
|
+
// src/api/aircon/get_model_info.ts
|
|
172
|
+
var get_model_info = (http2) => http2.request("/aircon/get_model_info");
|
|
173
|
+
|
|
174
|
+
// src/api/aircon/get_quick_timer.ts
|
|
175
|
+
var get_quick_timer = (http2) => http2.request("/aircon/get_quick_timer");
|
|
176
|
+
|
|
177
|
+
// src/api/aircon/get_sensor_info.ts
|
|
178
|
+
var get_sensor_info = (http2) => http2.request("/aircon/get_sensor_info");
|
|
157
179
|
|
|
158
180
|
// src/api/aircon/get_zone_setting.ts
|
|
159
181
|
var get_zone_settings = (http2) => http2.request("/aircon/get_zone_setting");
|
|
160
182
|
|
|
183
|
+
// src/api/aircon/set_control_info.ts
|
|
184
|
+
var set_control_info = (http2, params) => http2.request("/aircon/set_control_info", params);
|
|
185
|
+
|
|
161
186
|
// src/api/aircon/set_zone_setting.ts
|
|
162
187
|
var set_zone_setting = (http2, params) => http2.request("/aircon/set_zone_setting", params);
|
|
163
188
|
|
|
189
|
+
// src/api/common/basic_info.ts
|
|
190
|
+
var basic_info = (http2) => http2.request("/common/basic_info");
|
|
191
|
+
|
|
192
|
+
// src/api/common/get_datetime.ts
|
|
193
|
+
var get_datetime = (http2) => http2.request("/common/get_datetime");
|
|
194
|
+
|
|
195
|
+
// src/api/common/get_dealer_info.ts
|
|
196
|
+
var get_dealer_info = (http2) => http2.request("/common/get_dealer_info");
|
|
197
|
+
|
|
198
|
+
// src/api/common/get_network_setting.ts
|
|
199
|
+
var getNetwork_setting = (http2) => http2.request("/common/get_network_setting");
|
|
200
|
+
|
|
201
|
+
// src/api/common/get_wifi_setting.ts
|
|
202
|
+
var get_wifi_setting = (http2) => http2.request("/common/get_wifi_setting");
|
|
203
|
+
|
|
164
204
|
// src/Zones.ts
|
|
165
205
|
var Zones = class {
|
|
166
206
|
zones = [];
|
|
@@ -168,69 +208,105 @@ var Zones = class {
|
|
|
168
208
|
constructor(client) {
|
|
169
209
|
this.client = client;
|
|
170
210
|
}
|
|
171
|
-
/**
|
|
172
|
-
|
|
211
|
+
/**
|
|
212
|
+
* Requests all the zones current state from the airbase controller.
|
|
213
|
+
* Results are cached.
|
|
214
|
+
* @returns the current state of all zones.
|
|
215
|
+
*/
|
|
216
|
+
async getZones() {
|
|
173
217
|
const response = await get_zone_settings(this.client.api);
|
|
174
|
-
const
|
|
175
|
-
const
|
|
176
|
-
|
|
218
|
+
const names = response.zone_name.split(";");
|
|
219
|
+
const onoff = response.zone_onoff.split(";");
|
|
220
|
+
const temprartures = response.lztemp_c ? response.lztemp_c.split(";") : null;
|
|
221
|
+
const humidities = response.lztemp_h ? response.lztemp_h.split(";") : null;
|
|
222
|
+
return this.zones = names.map((name, index) => Object.freeze({
|
|
223
|
+
index,
|
|
177
224
|
name,
|
|
178
|
-
|
|
225
|
+
isOn: onoff[index] === "1",
|
|
226
|
+
humidity: humidities ? +`${humidities[index]}` : void 0,
|
|
227
|
+
temperature: temprartures ? +`${temprartures[index]}` : void 0
|
|
179
228
|
}));
|
|
180
229
|
}
|
|
181
230
|
/**
|
|
182
231
|
* Gets the state of all cached zones.
|
|
183
232
|
*/
|
|
184
233
|
getCachedZones() {
|
|
185
|
-
return
|
|
234
|
+
return this.zones;
|
|
186
235
|
}
|
|
187
236
|
/**
|
|
188
|
-
* Gets
|
|
237
|
+
* Gets the current state of a zone with the matching name.
|
|
238
|
+
* @param name
|
|
189
239
|
*/
|
|
190
|
-
async
|
|
191
|
-
return await this.
|
|
240
|
+
async getZone(name) {
|
|
241
|
+
return await this.getZones().then(() => this.getCachedZone(name));
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Gets the current state of a zone at the given controller index.
|
|
245
|
+
* @param index
|
|
246
|
+
* @throws Error if the index is out of bounds.
|
|
247
|
+
*/
|
|
248
|
+
async getZoneAt(index) {
|
|
249
|
+
return await this.getZones().then(() => this.getCachedZoneAt(index));
|
|
192
250
|
}
|
|
193
251
|
/**
|
|
194
252
|
* Gets the cached state of a zone
|
|
195
253
|
* @param name
|
|
196
254
|
*/
|
|
197
255
|
getCachedZone(name) {
|
|
198
|
-
return this.zones.find((zone) => zone.name === name)
|
|
256
|
+
return this.zones.find((zone) => zone.name === name);
|
|
199
257
|
}
|
|
200
258
|
/**
|
|
201
|
-
* Gets the state of a
|
|
202
|
-
* @param
|
|
259
|
+
* Gets the cached state of a zone at the given controller index.
|
|
260
|
+
* @param index
|
|
261
|
+
* @throws Error if the index is out of bounds.
|
|
203
262
|
*/
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
263
|
+
getCachedZoneAt(index) {
|
|
264
|
+
if (index < 0 || index >= this.zones.length || this.zones[index] === void 0)
|
|
265
|
+
throw new Error(`Zone index ${index} is out of bounds`);
|
|
266
|
+
if (this.zones[index].index !== index)
|
|
267
|
+
throw new Error(`Zone at ${index} does not believe it is in the correct spot.`);
|
|
268
|
+
return this.zones[index];
|
|
207
269
|
}
|
|
208
270
|
/**
|
|
209
|
-
*
|
|
210
|
-
* @param name
|
|
211
|
-
* @param
|
|
271
|
+
* Updates a zone
|
|
272
|
+
* @param name the name of the zone to update
|
|
273
|
+
* @param info the new data to replace
|
|
212
274
|
*/
|
|
213
|
-
async
|
|
214
|
-
await this.
|
|
275
|
+
async updateZone(name, info) {
|
|
276
|
+
const zones = await this.getZones();
|
|
277
|
+
const index = zones.findIndex((zone) => zone.name === name);
|
|
278
|
+
zones[index] = { ...zones[index], ...info };
|
|
279
|
+
await this.setZones(zones);
|
|
280
|
+
return zones[index];
|
|
215
281
|
}
|
|
216
282
|
/**
|
|
217
|
-
*
|
|
218
|
-
* @param
|
|
283
|
+
* Bulk updates all the zones
|
|
284
|
+
* @param zones the new zones. These are sorted by index and pushed into the API in that order.
|
|
285
|
+
* @returns the updated zones
|
|
219
286
|
*/
|
|
220
|
-
async setZones(
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
287
|
+
async setZones(zones) {
|
|
288
|
+
let names = [];
|
|
289
|
+
let onoff = [];
|
|
290
|
+
let humidity = [];
|
|
291
|
+
let temperature = [];
|
|
292
|
+
const sortedZones = zones.sort((a, b) => a.index - b.index);
|
|
293
|
+
for (const zone of sortedZones) {
|
|
294
|
+
names.push(zone.name);
|
|
295
|
+
onoff.push(`${bool(zone.isOn)}`);
|
|
296
|
+
if (zone.humidity !== void 0)
|
|
297
|
+
humidity.push(`${int(zone.humidity)}`);
|
|
298
|
+
if (zone.temperature !== void 0)
|
|
299
|
+
temperature.push(`${int(zone.temperature)}`);
|
|
227
300
|
}
|
|
228
301
|
const response = await set_zone_setting(this.client.api, {
|
|
229
|
-
zone_name:
|
|
230
|
-
zone_onoff:
|
|
302
|
+
zone_name: names.join(";"),
|
|
303
|
+
zone_onoff: onoff.join(";"),
|
|
304
|
+
lztemp_h: humidity.length > 0 ? humidity.join(";") : void 0,
|
|
305
|
+
lztemp_c: temperature.length > 0 ? temperature.join(";") : void 0
|
|
231
306
|
});
|
|
232
307
|
if (response.ret !== "OK")
|
|
233
308
|
throw new Error(`Failed to set zones: ${response.ret}`);
|
|
309
|
+
return this.zones = zones.map((zone) => Object.freeze({ ...zone }));
|
|
234
310
|
}
|
|
235
311
|
};
|
|
236
312
|
|
|
@@ -262,27 +338,26 @@ var RemoteType = /* @__PURE__ */ ((RemoteType3) => {
|
|
|
262
338
|
return RemoteType3;
|
|
263
339
|
})(RemoteType || {});
|
|
264
340
|
|
|
265
|
-
// src/api/aircon/get_control_info.ts
|
|
266
|
-
var get_control_info = (http2) => http2.request("/aircon/get_control_info");
|
|
267
|
-
|
|
268
|
-
// src/api/aircon/set_control_info.ts
|
|
269
|
-
var set_control_info = (http2, params) => http2.request("/aircon/set_control_info", params);
|
|
270
|
-
|
|
271
341
|
// src/DaikinClient.ts
|
|
272
342
|
var DaikinClient = class {
|
|
273
343
|
options;
|
|
274
344
|
api;
|
|
275
345
|
zones;
|
|
276
346
|
cachedControlInfo;
|
|
347
|
+
cachedSensorInfo;
|
|
277
348
|
constructor(options) {
|
|
278
349
|
this.options = options;
|
|
279
350
|
if ("host" in options) {
|
|
280
|
-
this.api = new
|
|
351
|
+
this.api = new Client(options.host);
|
|
281
352
|
} else {
|
|
282
|
-
this.api = new
|
|
353
|
+
this.api = new Client(options.device.discoveredAddress);
|
|
283
354
|
}
|
|
284
355
|
this.zones = new Zones(this);
|
|
285
356
|
}
|
|
357
|
+
/**
|
|
358
|
+
* Gets the current state of the aircon.
|
|
359
|
+
* @returns the current state of the aircon.
|
|
360
|
+
*/
|
|
286
361
|
async getControlInfo() {
|
|
287
362
|
const response = await get_control_info(this.api);
|
|
288
363
|
const responseValues = Object.entries(response);
|
|
@@ -292,7 +367,7 @@ var DaikinClient = class {
|
|
|
292
367
|
fanAuto: response.f_auto != 0,
|
|
293
368
|
fanAirside: response.f_airside != 0,
|
|
294
369
|
targetTemperature: response.stemp,
|
|
295
|
-
|
|
370
|
+
controlTemperature: responseValues.filter(([k, v]) => k.startsWith("dt")).map(([k, v]) => +v),
|
|
296
371
|
power: response.pow != 0,
|
|
297
372
|
status: Number(response.operate),
|
|
298
373
|
swinging: response.f_dir != 0,
|
|
@@ -301,21 +376,40 @@ var DaikinClient = class {
|
|
|
301
376
|
remoteControlType: Number(response.remo)
|
|
302
377
|
};
|
|
303
378
|
}
|
|
379
|
+
/** Gets the cached state of the aircon. */
|
|
304
380
|
getCachedControlInfo() {
|
|
305
381
|
return this.cachedControlInfo;
|
|
306
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* Retrieves the power state of the unit.
|
|
385
|
+
*/
|
|
307
386
|
async getPowered() {
|
|
308
387
|
return (await this.getControlInfo()).power;
|
|
309
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* Sets the powered state of the unit.
|
|
391
|
+
* @param state true to turn the unit on.
|
|
392
|
+
*/
|
|
310
393
|
async setPowered(state) {
|
|
311
394
|
return await this.setControlInfo({ power: state });
|
|
312
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* Gets the current mode of the unit.
|
|
398
|
+
*/
|
|
313
399
|
async getMode() {
|
|
314
400
|
return (await this.getControlInfo()).mode;
|
|
315
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* Sets the mode of the unit.
|
|
404
|
+
* @param mode The mode to set
|
|
405
|
+
*/
|
|
316
406
|
async setMode(mode) {
|
|
317
407
|
return await this.setControlInfo({ mode });
|
|
318
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* Gets the current fan settings of the unit.
|
|
411
|
+
* @returns the current fan settings.
|
|
412
|
+
*/
|
|
319
413
|
async getFan() {
|
|
320
414
|
const info = await this.getControlInfo();
|
|
321
415
|
return {
|
|
@@ -324,26 +418,34 @@ var DaikinClient = class {
|
|
|
324
418
|
airside: info.fanAirside
|
|
325
419
|
};
|
|
326
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* Sets the fan settings of the unit.
|
|
423
|
+
* @param fan the fan settings to set.
|
|
424
|
+
*/
|
|
327
425
|
async setFan(fan) {
|
|
328
426
|
return await this.setControlInfo({ fanSpeed: fan.speed, fanAuto: fan.auto, fanAirside: fan.airside ?? false });
|
|
329
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Gets the current target temperature of the unit
|
|
430
|
+
*/
|
|
330
431
|
async getTargetTemperature() {
|
|
331
432
|
return (await this.getControlInfo()).targetTemperature;
|
|
332
433
|
}
|
|
434
|
+
/**
|
|
435
|
+
* Sets the target temperature of the unit.
|
|
436
|
+
* @param temperature the temperature to set. This is rounded to the nearest integer.
|
|
437
|
+
*/
|
|
333
438
|
async setTargetTemperature(temperature) {
|
|
334
439
|
return await this.setControlInfo({ targetTemperature: temperature });
|
|
335
440
|
}
|
|
336
|
-
|
|
337
|
-
return (await this.getControlInfo()).sensorTemperatures;
|
|
338
|
-
}
|
|
441
|
+
/** Gets the current status of the unit. */
|
|
339
442
|
async getStatus() {
|
|
340
443
|
return (await this.getControlInfo()).status;
|
|
341
444
|
}
|
|
445
|
+
/** Sets the control state of the unit. */
|
|
342
446
|
async setControlInfo(info) {
|
|
343
447
|
const latest = await this.getControlInfo();
|
|
344
448
|
const update = { ...latest, ...info };
|
|
345
|
-
const int = (v) => Math.round(v);
|
|
346
|
-
const bool = (v) => v ? 1 : 0;
|
|
347
449
|
const params = {
|
|
348
450
|
f_airside: 0,
|
|
349
451
|
f_auto: bool(update.fanAuto),
|
|
@@ -363,6 +465,32 @@ var DaikinClient = class {
|
|
|
363
465
|
throw new Error(`Failed to update control info: ${response.ret}`);
|
|
364
466
|
this.cachedControlInfo = update;
|
|
365
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* Get the current reading of the temperature sensors.
|
|
470
|
+
*/
|
|
471
|
+
async getSensorInfo() {
|
|
472
|
+
const response = await get_sensor_info(this.api);
|
|
473
|
+
return this.cachedSensorInfo = {
|
|
474
|
+
insideTemperature: response.htemp,
|
|
475
|
+
outsideTemperature: response.otemp === "-" ? void 0 : response.otemp
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
/** Gets the current indoor temperature reading. */
|
|
479
|
+
async getInsideTemperature() {
|
|
480
|
+
return (await this.getSensorInfo()).insideTemperature;
|
|
481
|
+
}
|
|
482
|
+
/** Gets the current outdoor temperature reading. */
|
|
483
|
+
async getOutsideTemperature() {
|
|
484
|
+
return (await this.getSensorInfo()).outsideTemperature;
|
|
485
|
+
}
|
|
486
|
+
/** Gets the cached state of the sensor info. */
|
|
487
|
+
getCachedSensorInfo() {
|
|
488
|
+
return this.cachedSensorInfo;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Gets the basic information about the aircon.
|
|
492
|
+
* @returns the basic information about the aircon.
|
|
493
|
+
*/
|
|
366
494
|
async getBasicInfo() {
|
|
367
495
|
const response = await basic_info(this.api);
|
|
368
496
|
return {
|
|
@@ -380,13 +508,14 @@ var DaikinClient = class {
|
|
|
380
508
|
adp_kind: response.adp_kind
|
|
381
509
|
};
|
|
382
510
|
}
|
|
511
|
+
/** Broadcasts a request to discover devices on the network. */
|
|
383
512
|
static async discover(timeoutMs = 3e3) {
|
|
384
513
|
return discover(timeoutMs);
|
|
385
514
|
}
|
|
386
515
|
};
|
|
387
516
|
// Annotate the CommonJS export names for ESM import in node:
|
|
388
517
|
0 && (module.exports = {
|
|
389
|
-
|
|
518
|
+
Client,
|
|
390
519
|
ControlMode,
|
|
391
520
|
DaikinClient,
|
|
392
521
|
FanSpeed,
|
|
@@ -395,5 +524,15 @@ var DaikinClient = class {
|
|
|
395
524
|
Zones,
|
|
396
525
|
basic_info,
|
|
397
526
|
discover,
|
|
398
|
-
|
|
527
|
+
getNetwork_setting,
|
|
528
|
+
get_control_info,
|
|
529
|
+
get_datetime,
|
|
530
|
+
get_dealer_info,
|
|
531
|
+
get_model_info,
|
|
532
|
+
get_quick_timer,
|
|
533
|
+
get_sensor_info,
|
|
534
|
+
get_wifi_setting,
|
|
535
|
+
get_zone_settings,
|
|
536
|
+
set_control_info,
|
|
537
|
+
set_zone_setting
|
|
399
538
|
});
|