daikin-local-control 0.4.0 → 0.5.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/DESIGN.md +47 -4
- package/README.md +154 -46
- package/UNSUPPORTED.md +27 -2
- package/dist/clients/airbase.d.ts +64 -0
- package/dist/clients/airbase.d.ts.map +1 -0
- package/dist/clients/airbase.js +175 -0
- package/dist/clients/airbase.js.map +1 -0
- package/dist/clients/client.d.ts +3 -2
- package/dist/clients/client.d.ts.map +1 -1
- package/dist/codecs/airbase/capabilities.d.ts +23 -0
- package/dist/codecs/airbase/capabilities.d.ts.map +1 -0
- package/dist/codecs/airbase/capabilities.js +108 -0
- package/dist/codecs/airbase/capabilities.js.map +1 -0
- package/dist/codecs/airbase/state.d.ts +29 -0
- package/dist/codecs/airbase/state.d.ts.map +1 -0
- package/dist/codecs/airbase/state.js +166 -0
- package/dist/codecs/airbase/state.js.map +1 -0
- package/dist/codecs/airbase/tables.d.ts +7 -0
- package/dist/codecs/airbase/tables.d.ts.map +1 -0
- package/dist/codecs/airbase/tables.js +27 -0
- package/dist/codecs/airbase/tables.js.map +1 -0
- package/dist/codecs/airbase/zone.d.ts +12 -0
- package/dist/codecs/airbase/zone.d.ts.map +1 -0
- package/dist/codecs/airbase/zone.js +50 -0
- package/dist/codecs/airbase/zone.js.map +1 -0
- package/dist/codecs/classic/tables.d.ts +2 -0
- package/dist/codecs/classic/tables.d.ts.map +1 -1
- package/dist/codecs/classic/tables.js +2 -0
- package/dist/codecs/classic/tables.js.map +1 -1
- package/dist/codecs/device.d.ts +7 -1
- package/dist/codecs/device.d.ts.map +1 -1
- package/dist/codecs/device.js +14 -2
- package/dist/codecs/device.js.map +1 -1
- package/dist/codecs/dsiot/tables.d.ts +3 -0
- package/dist/codecs/dsiot/tables.d.ts.map +1 -1
- package/dist/codecs/dsiot/tables.js +3 -0
- package/dist/codecs/dsiot/tables.js.map +1 -1
- package/dist/discovery.d.ts +20 -10
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +96 -30
- package/dist/discovery.js.map +1 -1
- package/dist/factory.d.ts +8 -5
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +13 -3
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/models/device.d.ts +3 -2
- package/dist/models/device.d.ts.map +1 -1
- package/dist/models/device.js +1 -1
- package/dist/models/device.js.map +1 -1
- package/dist/models/zone.d.ts +9 -0
- package/dist/models/zone.d.ts.map +1 -0
- package/dist/models/zone.js +2 -0
- package/dist/models/zone.js.map +1 -0
- package/dist/simulators/airbase.d.ts +82 -0
- package/dist/simulators/airbase.d.ts.map +1 -0
- package/dist/simulators/airbase.js +352 -0
- package/dist/simulators/airbase.js.map +1 -0
- package/dist/simulators/classic.d.ts.map +1 -1
- package/dist/simulators/classic.js +2 -2
- package/dist/simulators/classic.js.map +1 -1
- package/dist/simulators/index.d.ts +1 -0
- package/dist/simulators/index.d.ts.map +1 -1
- package/dist/simulators/index.js +1 -0
- package/dist/simulators/index.js.map +1 -1
- package/dist/simulators/simulator.d.ts +11 -10
- package/dist/simulators/simulator.d.ts.map +1 -1
- package/dist/simulators/simulator.js +2 -2
- package/dist/simulators/simulator.js.map +1 -1
- package/dist/transport.d.ts +3 -2
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +4 -1
- package/dist/transport.js.map +1 -1
- package/package.json +7 -3
- package/src/clients/airbase.ts +274 -0
- package/src/clients/client.ts +3 -2
- package/src/codecs/airbase/capabilities.ts +150 -0
- package/src/codecs/airbase/state.ts +223 -0
- package/src/codecs/airbase/tables.ts +32 -0
- package/src/codecs/airbase/zone.ts +62 -0
- package/src/codecs/classic/tables.ts +3 -0
- package/src/codecs/device.ts +18 -2
- package/src/codecs/dsiot/tables.ts +4 -0
- package/src/discovery.ts +101 -32
- package/src/factory.ts +21 -5
- package/src/index.ts +6 -0
- package/src/models/device.ts +3 -2
- package/src/models/zone.ts +8 -0
- package/src/simulators/airbase.ts +495 -0
- package/src/simulators/classic.ts +2 -1
- package/src/simulators/index.ts +1 -0
- package/src/simulators/simulator.ts +13 -12
- package/src/transport.ts +7 -3
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { mergeAirbaseCapabilityFields, parseAirbaseCapabilities, parseAirbaseZoneCount, takesAirbaseAirside, takesAirbaseFanAuto, } from "../codecs/airbase/capabilities.js";
|
|
2
|
+
import { applyAirbaseAirside, applyAirbaseControl, applyAirbaseFanAuto, parseAirbaseAirside, parseAirbaseFanAuto, parseAirbaseSensors, parseAirbaseState, } from "../codecs/airbase/state.js";
|
|
3
|
+
import { applyAirbaseZone, parseAirbaseZones } from "../codecs/airbase/zone.js";
|
|
4
|
+
import { assertClassicOk, isClassicOk, parseClassicKeyValue, } from "../codecs/classic/keyValue.js";
|
|
5
|
+
import { parseDeviceInfo } from "../codecs/device.js";
|
|
6
|
+
import { DaikinError } from "../error.js";
|
|
7
|
+
import { withRetry, } from "../transport.js";
|
|
8
|
+
import { SetStateCache } from "./setStateCache.js";
|
|
9
|
+
// An Airbase adapter answers the endpoints of a classic adapter under this
|
|
10
|
+
// path, and HTTP 404 at the paths a classic adapter answers.
|
|
11
|
+
const AIRBASE_ROOT = "/skyfi";
|
|
12
|
+
const AIRBASE_ROUTES = {
|
|
13
|
+
basicInfo: "/common/basic_info",
|
|
14
|
+
getModelInfo: "/aircon/get_model_info",
|
|
15
|
+
getControlInfo: "/aircon/get_control_info",
|
|
16
|
+
setControlInfo: "/aircon/set_control_info",
|
|
17
|
+
getSensorInfo: "/aircon/get_sensor_info",
|
|
18
|
+
getZoneSetting: "/aircon/get_zone_setting",
|
|
19
|
+
setZoneSetting: "/aircon/set_zone_setting",
|
|
20
|
+
};
|
|
21
|
+
const NOT_FOUND = 404;
|
|
22
|
+
/** Whether the adapter `transport` reaches is an Airbase adapter: one that
|
|
23
|
+
* answers HTTP 404 at `/common/basic_info`, where a classic adapter answers,
|
|
24
|
+
* and `ret=OK` at `/skyfi/common/basic_info`. It sends the second request
|
|
25
|
+
* only after that 404, and retries a refused or dropped connection as
|
|
26
|
+
* `withRetry` does by default: an adapter drops one while it answers another
|
|
27
|
+
* caller. It resolves with `false` when either request fails any other way.
|
|
28
|
+
* `discoverDevices` calls it, and `src/index.ts` does not export it. */
|
|
29
|
+
export async function isAirbaseAdapter(transport) {
|
|
30
|
+
const get = (path) => withRetry(() => transport.send({ method: "GET", path }));
|
|
31
|
+
try {
|
|
32
|
+
await get(AIRBASE_ROUTES.basicInfo);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (!(error instanceof DaikinError) || error.httpStatusCode !== NOT_FOUND) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
return isClassicOk(parseClassicKeyValue(await get(`${AIRBASE_ROOT}${AIRBASE_ROUTES.basicInfo}`)));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Airbase adapter (BRP15B61), on a ducted unit. Reads and writes are HTTP GET
|
|
48
|
+
* with query parameters, as on a classic adapter, at paths under `/skyfi`.
|
|
49
|
+
* It takes no terminal uuid and no local password. */
|
|
50
|
+
export class AirbaseDaikinClient {
|
|
51
|
+
transport;
|
|
52
|
+
retryOptions;
|
|
53
|
+
// A unit's capabilities don't change, so they are read once.
|
|
54
|
+
capabilityFields;
|
|
55
|
+
setStateCache;
|
|
56
|
+
/** `close` closes `transport`, so give each client a transport of its own.
|
|
57
|
+
* `maxStateAgeForSetStateInMs` defaults to 0: see
|
|
58
|
+
* `CreateDaikinClientOptions.maxStateAgeForSetStateInMs`. */
|
|
59
|
+
constructor(transport, retryOptions, maxStateAgeForSetStateInMs = 0) {
|
|
60
|
+
this.transport = transport;
|
|
61
|
+
this.retryOptions = retryOptions;
|
|
62
|
+
this.setStateCache = new SetStateCache(maxStateAgeForSetStateInMs);
|
|
63
|
+
}
|
|
64
|
+
close() {
|
|
65
|
+
return this.transport.close();
|
|
66
|
+
}
|
|
67
|
+
async getDeviceInfo() {
|
|
68
|
+
return parseDeviceInfo(await this.command(AIRBASE_ROUTES.basicInfo));
|
|
69
|
+
}
|
|
70
|
+
async getCapabilities() {
|
|
71
|
+
return parseAirbaseCapabilities(await this.readCapabilityFields());
|
|
72
|
+
}
|
|
73
|
+
async getState() {
|
|
74
|
+
return parseAirbaseState(await this.readControlInfo());
|
|
75
|
+
}
|
|
76
|
+
async setState(control) {
|
|
77
|
+
const current = this.setStateCache.get() ??
|
|
78
|
+
(await this.command(AIRBASE_ROUTES.getControlInfo));
|
|
79
|
+
await this.command(AIRBASE_ROUTES.setControlInfo, applyAirbaseControl(current, control));
|
|
80
|
+
}
|
|
81
|
+
async getSensors() {
|
|
82
|
+
return parseAirbaseSensors(await this.command(AIRBASE_ROUTES.getSensorInfo));
|
|
83
|
+
}
|
|
84
|
+
async getStateAndSensors() {
|
|
85
|
+
return { state: await this.getState(), sensors: await this.getSensors() };
|
|
86
|
+
}
|
|
87
|
+
/** Rejects with a `DaikinError` whose status is 501: an Airbase adapter has
|
|
88
|
+
* no known request for a special mode. */
|
|
89
|
+
async setSpecialMode(_mode, _enabled) {
|
|
90
|
+
throw new DaikinError("An Airbase adapter takes no special mode", 501);
|
|
91
|
+
}
|
|
92
|
+
// --- extended controls ---------------------------------------------------
|
|
93
|
+
/** Whether fan auto is on: the unit then picks the fan speed itself, up to
|
|
94
|
+
* the one that is set. `null` on a unit that takes no fan auto. */
|
|
95
|
+
async getFanAuto() {
|
|
96
|
+
return takesAirbaseFanAuto(await this.readCapabilityFields())
|
|
97
|
+
? parseAirbaseFanAuto(await this.readControlInfo())
|
|
98
|
+
: null;
|
|
99
|
+
}
|
|
100
|
+
/** Switches fan auto on or off. It switches airside off, and keeps the fan
|
|
101
|
+
* speed. Check `getFanAuto` first: the client sends it to any unit. */
|
|
102
|
+
async setFanAuto(enabled) {
|
|
103
|
+
await this.command(AIRBASE_ROUTES.setControlInfo, applyAirbaseFanAuto(await this.command(AIRBASE_ROUTES.getControlInfo), enabled));
|
|
104
|
+
}
|
|
105
|
+
/** Whether airside is on. `null` on a unit that takes no airside. */
|
|
106
|
+
async getAirside() {
|
|
107
|
+
return takesAirbaseAirside(await this.readCapabilityFields())
|
|
108
|
+
? parseAirbaseAirside(await this.readControlInfo())
|
|
109
|
+
: null;
|
|
110
|
+
}
|
|
111
|
+
/** Switches airside on or off. Switching it on switches fan auto off and
|
|
112
|
+
* sets the lowest fan speed. Check `getAirside` first: the client sends it
|
|
113
|
+
* to any unit. */
|
|
114
|
+
async setAirside(enabled) {
|
|
115
|
+
await this.command(AIRBASE_ROUTES.setControlInfo, applyAirbaseAirside(await this.command(AIRBASE_ROUTES.getControlInfo), enabled));
|
|
116
|
+
}
|
|
117
|
+
/** The unit's zones, in the unit's order; empty on a unit without zones,
|
|
118
|
+
* which is not asked for any. */
|
|
119
|
+
async getZones() {
|
|
120
|
+
const capabilityFields = await this.readCapabilityFields();
|
|
121
|
+
return parseAirbaseZones(await this.readZoneSetting(capabilityFields), capabilityFields);
|
|
122
|
+
}
|
|
123
|
+
/** Opens or closes the zone at `index` in `getZones`, counted from 0. It
|
|
124
|
+
* rejects with an `Error` for an index the unit has no zone at. */
|
|
125
|
+
async setZone(index, enabled) {
|
|
126
|
+
const capabilityFields = await this.readCapabilityFields();
|
|
127
|
+
const current = await this.readZoneSetting(capabilityFields);
|
|
128
|
+
await this.command(AIRBASE_ROUTES.setZoneSetting, applyAirbaseZone(current, capabilityFields, index, enabled));
|
|
129
|
+
}
|
|
130
|
+
/** Calls any endpoint by its path below `/skyfi`, such as
|
|
131
|
+
* `/aircon/get_control_info`, with query parameters, and returns the reply's
|
|
132
|
+
* `key=value` fields. It throws a `DaikinError` when the reply's `ret` is
|
|
133
|
+
* not `OK`. */
|
|
134
|
+
async command(path, parameters, { retry = true } = {}) {
|
|
135
|
+
const send = () => this.transport.send({
|
|
136
|
+
method: "GET",
|
|
137
|
+
path: `${AIRBASE_ROOT}${path}`,
|
|
138
|
+
...(parameters ? { query: parameters } : {}),
|
|
139
|
+
});
|
|
140
|
+
try {
|
|
141
|
+
const fields = parseClassicKeyValue(await (retry ? withRetry(send, this.retryOptions) : send()));
|
|
142
|
+
assertClassicOk(fields);
|
|
143
|
+
return fields;
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
// Every request that changes the unit takes parameters, and any of them
|
|
147
|
+
// may change what `get_control_info` answers, even one that failed: a
|
|
148
|
+
// request that timed out may still have reached the unit.
|
|
149
|
+
if (parameters) {
|
|
150
|
+
this.setStateCache.clear();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// What a unit without zones answers at `get_zone_setting` is not known, so
|
|
155
|
+
// it is not asked.
|
|
156
|
+
async readZoneSetting(capabilityFields) {
|
|
157
|
+
return parseAirbaseZoneCount(capabilityFields) === 0
|
|
158
|
+
? {}
|
|
159
|
+
: this.command(AIRBASE_ROUTES.getZoneSetting);
|
|
160
|
+
}
|
|
161
|
+
async readControlInfo() {
|
|
162
|
+
const fields = await this.command(AIRBASE_ROUTES.getControlInfo);
|
|
163
|
+
this.setStateCache.set(fields);
|
|
164
|
+
return fields;
|
|
165
|
+
}
|
|
166
|
+
readCapabilityFields() {
|
|
167
|
+
this.capabilityFields ??= (async () => mergeAirbaseCapabilityFields(await this.command(AIRBASE_ROUTES.basicInfo), await this.command(AIRBASE_ROUTES.getModelInfo)))();
|
|
168
|
+
// A failed read is not cached, so the next call tries again.
|
|
169
|
+
this.capabilityFields.catch(() => {
|
|
170
|
+
this.capabilityFields = undefined;
|
|
171
|
+
});
|
|
172
|
+
return this.capabilityFields;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=airbase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"airbase.js","sourceRoot":"","sources":["../../src/clients/airbase.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EACL,eAAe,EACf,WAAW,EACX,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAW1C,OAAO,EAIL,SAAS,GACV,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,2EAA2E;AAC3E,6DAA6D;AAC7D,MAAM,YAAY,GAAG,QAAQ,CAAC;AAE9B,MAAM,cAAc,GAAG;IACrB,SAAS,EAAE,oBAAoB;IAC/B,YAAY,EAAE,wBAAwB;IACtC,cAAc,EAAE,0BAA0B;IAC1C,cAAc,EAAE,0BAA0B;IAC1C,aAAa,EAAE,yBAAyB;IACxC,cAAc,EAAE,0BAA0B;IAC1C,cAAc,EAAE,0BAA0B;CAClC,CAAC;AAEX,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB;;;;;;wEAMwE;AACxE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAA0B;IAE1B,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAC3B,SAAS,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,WAAW,CAAC,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YAC1E,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,OAAO,WAAW,CAChB,oBAAoB,CAClB,MAAM,GAAG,CAAC,GAAG,YAAY,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC,CACxD,CACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;sDAEsD;AACtD,MAAM,OAAO,mBAAmB;IASX,SAAS;IACT,YAAY;IAT/B,6DAA6D;IACrD,gBAAgB,CAA8C;IACrD,aAAa,CAAgB;IAE9C;;iEAE6D;IAC7D,YACmB,SAA0B,EAC1B,YAAiC,EAClD,0BAA0B,GAAG,CAAC;yBAFb,SAAS;4BACT,YAAY;QAG7B,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,0BAA0B,CAAC,CAAC;IACrE,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,OAAO,eAAe,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,OAAO,wBAAwB,CAAC,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,OAAO,iBAAiB,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAsB;QACnC,MAAM,OAAO,GACX,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE;YACxB,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,OAAO,CAChB,cAAc,CAAC,cAAc,EAC7B,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CACtC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU;QACd,OAAO,mBAAmB,CACxB,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,CACjD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;IAC5E,CAAC;IAED;8CAC0C;IAC1C,KAAK,CAAC,cAAc,CAAC,KAAkB,EAAE,QAAiB;QACxD,MAAM,IAAI,WAAW,CAAC,0CAA0C,EAAE,GAAG,CAAC,CAAC;IACzE,CAAC;IAED,4EAA4E;IAE5E;uEACmE;IACnE,KAAK,CAAC,UAAU;QACd,OAAO,mBAAmB,CAAC,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC3D,CAAC,CAAC,mBAAmB,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACnD,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED;2EACuE;IACvE,KAAK,CAAC,UAAU,CAAC,OAAgB;QAC/B,MAAM,IAAI,CAAC,OAAO,CAChB,cAAc,CAAC,cAAc,EAC7B,mBAAmB,CACjB,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,EACjD,OAAO,CACR,CACF,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,UAAU;QACd,OAAO,mBAAmB,CAAC,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC3D,CAAC,CAAC,mBAAmB,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACnD,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED;;sBAEkB;IAClB,KAAK,CAAC,UAAU,CAAC,OAAgB;QAC/B,MAAM,IAAI,CAAC,OAAO,CAChB,cAAc,CAAC,cAAc,EAC7B,mBAAmB,CACjB,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,EACjD,OAAO,CACR,CACF,CAAC;IACJ,CAAC;IAED;qCACiC;IACjC,KAAK,CAAC,QAAQ;QACZ,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC3D,OAAO,iBAAiB,CACtB,MAAM,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAC5C,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED;uEACmE;IACnE,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,OAAgB;QAC3C,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC3D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;QAC7D,MAAM,IAAI,CAAC,OAAO,CAChB,cAAc,CAAC,cAAc,EAC7B,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,CAAC,CAC5D,CAAC;IACJ,CAAC;IAED;;;mBAGe;IACf,KAAK,CAAC,OAAO,CACX,IAAY,EACZ,UAAmC,EACnC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAyB,EAAE;QAE3C,MAAM,IAAI,GAAG,GAAG,EAAE,CAChB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAClB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,GAAG,YAAY,GAAG,IAAI,EAAE;YAC9B,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C,CAAC,CAAC;QACL,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,oBAAoB,CACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAC5D,CAAC;YACF,eAAe,CAAC,MAAM,CAAC,CAAC;YACxB,OAAO,MAAM,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,wEAAwE;YACxE,sEAAsE;YACtE,0DAA0D;YAC1D,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,mBAAmB;IACX,KAAK,CAAC,eAAe,CAC3B,gBAAwC;QAExC,OAAO,qBAAqB,CAAC,gBAAgB,CAAC,KAAK,CAAC;YAClD,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;IAClD,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;QACjE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,gBAAgB,KAAK,CAAC,KAAK,IAAI,EAAE,CACpC,4BAA4B,CAC1B,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,EAC5C,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAChD,CAAC,EAAE,CAAC;QACP,6DAA6D;QAC7D,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE;YAC/B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACpC,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;CACF"}
|
package/dist/clients/client.d.ts
CHANGED
|
@@ -20,13 +20,14 @@ export interface DaikinClient {
|
|
|
20
20
|
setState(control: DaikinControl): Promise<void>;
|
|
21
21
|
/** Turn powerful, econo or streamer on or off, with a request of its own.
|
|
22
22
|
* `DaikinCapabilities.specialModes` lists the ones the unit takes in each
|
|
23
|
-
* mode, and the client sends any other as given.
|
|
23
|
+
* mode, and the client sends any other as given. An `AirbaseDaikinClient`
|
|
24
|
+
* rejects every one with status 501. */
|
|
24
25
|
setSpecialMode(mode: SpecialMode, enabled: boolean): Promise<void>;
|
|
25
26
|
/** Read-only temperature / humidity readings. */
|
|
26
27
|
getSensors(): Promise<DaikinSensors>;
|
|
27
28
|
/** What `getState` and `getSensors` resolve with, together. A DSIOT adapter
|
|
28
29
|
* answers both in one request, where calling the two sends the same request
|
|
29
|
-
* twice. A classic adapter takes one request for each. */
|
|
30
|
+
* twice. A classic or an Airbase adapter takes one request for each. */
|
|
30
31
|
getStateAndSensors(): Promise<DaikinStateAndSensors>;
|
|
31
32
|
/** Close the connection to the adapter. */
|
|
32
33
|
close(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/clients/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAE5B;;;;2CAI2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE3C,qCAAqC;IACrC,eAAe,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/C,kCAAkC;IAClC,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAEjC;;;iEAG6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/clients/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAE5B;;;;2CAI2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE3C,qCAAqC;IACrC,eAAe,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/C,kCAAkC;IAClC,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAEjC;;;iEAG6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;;4CAGwC;IACxC,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnE,iDAAiD;IACjD,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAErC;;4EAEwE;IACxE,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAErD,2CAA2C;IAC3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { DaikinCapabilities } from "../../models/capabilities.js";
|
|
2
|
+
/** Merges the `basic_info` and `get_model_info` replies of an Airbase adapter
|
|
3
|
+
* into the one field map `parseAirbaseCapabilities`, `takesAirbaseFanAuto`,
|
|
4
|
+
* `takesAirbaseAirside` and `parseAirbaseZones` read. */
|
|
5
|
+
export declare function mergeAirbaseCapabilityFields(basicInfo: Record<string, string>, modelInfo: Record<string, string>): Record<string, string>;
|
|
6
|
+
/** Turns the field map from `mergeAirbaseCapabilityFields` into
|
|
7
|
+
* `DaikinCapabilities`. A unit with zones (`en_zone`) takes no `auto` fan
|
|
8
|
+
* speed and no direction. It lists no humidity setting, louver position or
|
|
9
|
+
* special mode, and reports `energyMonitoring` and `demandControl` as
|
|
10
|
+
* `false`: which field says a unit has either is not known. */
|
|
11
|
+
export declare function parseAirbaseCapabilities(fields: Record<string, string>): DaikinCapabilities;
|
|
12
|
+
/** Whether a unit takes fan auto, read from the field map of
|
|
13
|
+
* `mergeAirbaseCapabilityFields`: one with zones that counts its fan speeds
|
|
14
|
+
* (`frate_steps`), unless `en_frate_auto` is 0. */
|
|
15
|
+
export declare function takesAirbaseFanAuto(fields: Record<string, string>): boolean;
|
|
16
|
+
/** Whether a unit takes airside, read from the field map of
|
|
17
|
+
* `mergeAirbaseCapabilityFields`: one with zones that reports
|
|
18
|
+
* `en_airside=1`. */
|
|
19
|
+
export declare function takesAirbaseAirside(fields: Record<string, string>): boolean;
|
|
20
|
+
/** How many zones a unit has, read from the field map of
|
|
21
|
+
* `mergeAirbaseCapabilityFields`: `en_zone`, and none without it. */
|
|
22
|
+
export declare function parseAirbaseZoneCount(fields: Record<string, string>): number;
|
|
23
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/codecs/airbase/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,8BAA8B,CAAC;AAYtC;;yDAEyD;AACzD,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExB;AAED;;;;+DAI+D;AAC/D,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,kBAAkB,CAkCpB;AAED;;mDAEmD;AACnD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAQ3E;AAED;;qBAEqB;AACrB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAI3E;AAED;qEACqE;AACrE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAG5E"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { OPERATING_MODES, SWING_MODES, } from "../../models/state.js";
|
|
2
|
+
const ALWAYS_OFFERED_MODES = ["cool", "heat", "fan"];
|
|
3
|
+
const THREE_FAN_LEVELS = ["level1", "level3", "level5"];
|
|
4
|
+
const TWO_FAN_LEVELS = ["level1", "level5"];
|
|
5
|
+
/** Merges the `basic_info` and `get_model_info` replies of an Airbase adapter
|
|
6
|
+
* into the one field map `parseAirbaseCapabilities`, `takesAirbaseFanAuto`,
|
|
7
|
+
* `takesAirbaseAirside` and `parseAirbaseZones` read. */
|
|
8
|
+
export function mergeAirbaseCapabilityFields(basicInfo, modelInfo) {
|
|
9
|
+
return { ...basicInfo, ...modelInfo };
|
|
10
|
+
}
|
|
11
|
+
/** Turns the field map from `mergeAirbaseCapabilityFields` into
|
|
12
|
+
* `DaikinCapabilities`. A unit with zones (`en_zone`) takes no `auto` fan
|
|
13
|
+
* speed and no direction. It lists no humidity setting, louver position or
|
|
14
|
+
* special mode, and reports `energyMonitoring` and `demandControl` as
|
|
15
|
+
* `false`: which field says a unit has either is not known. */
|
|
16
|
+
export function parseAirbaseCapabilities(fields) {
|
|
17
|
+
const offeredModes = OPERATING_MODES.filter((mode) => ALWAYS_OFFERED_MODES.includes(mode) ||
|
|
18
|
+
(mode === "auto" && fields.en_auto === "1") ||
|
|
19
|
+
(mode === "dehumidify" && fields.en_dry === "1"));
|
|
20
|
+
const offered = (mode, range) => offeredModes.includes(mode) ? range : null;
|
|
21
|
+
const none = { auto: [], dehumidify: [], cool: [], heat: [], fan: [] };
|
|
22
|
+
return {
|
|
23
|
+
modes: offeredModes,
|
|
24
|
+
fanSpeeds: fanSpeeds(fields),
|
|
25
|
+
swingModes: !hasZones(fields) && fields.en_fdir === "1" ? [...SWING_MODES] : [],
|
|
26
|
+
verticalPositions: [],
|
|
27
|
+
horizontalPositions: [],
|
|
28
|
+
targetTemperaturesInC: {
|
|
29
|
+
// Auto runs from the lowest setpoint of cool to the highest of heat.
|
|
30
|
+
auto: offered("auto", range(fields.cool_l, 18, fields.heat_h, 30)),
|
|
31
|
+
cool: offered("cool", range(fields.cool_l, 18, fields.cool_h, 32)),
|
|
32
|
+
heat: offered("heat", range(fields.heat_l, 10, fields.heat_h, 30)),
|
|
33
|
+
dehumidify: null,
|
|
34
|
+
fan: null,
|
|
35
|
+
},
|
|
36
|
+
targetHumidities: none,
|
|
37
|
+
specialModes: none,
|
|
38
|
+
specialOutlet: false,
|
|
39
|
+
energyMonitoring: false,
|
|
40
|
+
demandControl: false,
|
|
41
|
+
scheduleTimer: ["1", "2"].includes(fields.en_scdltmr ?? ""),
|
|
42
|
+
model: fields.model,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Whether a unit takes fan auto, read from the field map of
|
|
46
|
+
* `mergeAirbaseCapabilityFields`: one with zones that counts its fan speeds
|
|
47
|
+
* (`frate_steps`), unless `en_frate_auto` is 0. */
|
|
48
|
+
export function takesAirbaseFanAuto(fields) {
|
|
49
|
+
return (isFanControllable(fields) &&
|
|
50
|
+
hasZones(fields) &&
|
|
51
|
+
fanLevels(fields).length > 0 &&
|
|
52
|
+
"frate_steps" in fields &&
|
|
53
|
+
(fields.en_frate_auto ?? "1") === "1");
|
|
54
|
+
}
|
|
55
|
+
/** Whether a unit takes airside, read from the field map of
|
|
56
|
+
* `mergeAirbaseCapabilityFields`: one with zones that reports
|
|
57
|
+
* `en_airside=1`. */
|
|
58
|
+
export function takesAirbaseAirside(fields) {
|
|
59
|
+
return (isFanControllable(fields) && hasZones(fields) && fields.en_airside === "1");
|
|
60
|
+
}
|
|
61
|
+
/** How many zones a unit has, read from the field map of
|
|
62
|
+
* `mergeAirbaseCapabilityFields`: `en_zone`, and none without it. */
|
|
63
|
+
export function parseAirbaseZoneCount(fields) {
|
|
64
|
+
const count = Number.parseInt(fields.en_zone ?? "", 10);
|
|
65
|
+
return count > 0 ? count : 0;
|
|
66
|
+
}
|
|
67
|
+
function hasZones(fields) {
|
|
68
|
+
return "en_zone" in fields && fields.en_zone !== "0";
|
|
69
|
+
}
|
|
70
|
+
// A unit that sets each zone's airflow itself (`en_linear_zone=1`) takes no
|
|
71
|
+
// fan speed.
|
|
72
|
+
function isFanControllable(fields) {
|
|
73
|
+
return ((fields.reg ?? "") !== "" &&
|
|
74
|
+
fields.reg !== "jp" &&
|
|
75
|
+
fields.en_frate === "1" &&
|
|
76
|
+
fields.en_linear_zone !== "1");
|
|
77
|
+
}
|
|
78
|
+
// Three levels unless `frate_steps` is 2, and none when it is not a number.
|
|
79
|
+
function fanLevels(fields) {
|
|
80
|
+
if (!("frate_steps" in fields)) {
|
|
81
|
+
return THREE_FAN_LEVELS;
|
|
82
|
+
}
|
|
83
|
+
const steps = Number.parseInt(fields.frate_steps ?? "", 10);
|
|
84
|
+
if (!Number.isFinite(steps)) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
return steps === 2 ? TWO_FAN_LEVELS : THREE_FAN_LEVELS;
|
|
88
|
+
}
|
|
89
|
+
function fanSpeeds(fields) {
|
|
90
|
+
if (!isFanControllable(fields)) {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
const takesAuto = !hasZones(fields) && fields.en_frate_auto === "1";
|
|
94
|
+
return [...(takesAuto ? ["auto"] : []), ...fanLevels(fields)];
|
|
95
|
+
}
|
|
96
|
+
// Setpoint limits are whole °C on the wire; any fraction is dropped.
|
|
97
|
+
function range(low, fallbackMin, high, fallbackMax) {
|
|
98
|
+
return {
|
|
99
|
+
min: wholeCelsius(low, fallbackMin),
|
|
100
|
+
max: wholeCelsius(high, fallbackMax),
|
|
101
|
+
step: 1,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function wholeCelsius(value, fallback) {
|
|
105
|
+
const parsed = Number.parseFloat(value ?? "");
|
|
106
|
+
return Number.isFinite(parsed) ? Math.trunc(parsed) : fallback;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/codecs/airbase/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { DaikinControl, DaikinSensors, DaikinState } from "../../models/state.js";
|
|
2
|
+
/** Turns a `get_control_info` reply into a `DaikinState`. A `mode` or `f_rate`
|
|
3
|
+
* outside the model reads as `auto`, and an `f_dir` outside it as `off`. It
|
|
4
|
+
* reports no humidity setting, louver position or special mode: an Airbase
|
|
5
|
+
* unit is not known to have any. */
|
|
6
|
+
export declare function parseAirbaseState(fields: Record<string, string>): DaikinState;
|
|
7
|
+
export declare function parseAirbaseSensors(fields: Record<string, string>): DaikinSensors;
|
|
8
|
+
/** Whether fan auto is on in a `get_control_info` reply: the unit then picks
|
|
9
|
+
* the fan speed itself, up to the one that is set. */
|
|
10
|
+
export declare function parseAirbaseFanAuto(fields: Record<string, string>): boolean;
|
|
11
|
+
/** Whether airside is on in a `get_control_info` reply. */
|
|
12
|
+
export declare function parseAirbaseAirside(fields: Record<string, string>): boolean;
|
|
13
|
+
/** Turns `current`, the `get_control_info` reply, and a control into the
|
|
14
|
+
* `set_control_info` query: power, mode, setpoint, humidity, fan speed, fan
|
|
15
|
+
* auto, airside and direction, every time. When the mode changes, the
|
|
16
|
+
* setpoint, the fan and the direction come from what the unit remembers for
|
|
17
|
+
* cool or for heat. It drops a `targetTemperatureInC` in fan and dehumidify,
|
|
18
|
+
* every `targetHumidity` and louver position, and sends `shum` back as the
|
|
19
|
+
* unit holds it. A `fanSpeed` switches airside off and keeps fan auto. */
|
|
20
|
+
export declare function applyAirbaseControl(current: Record<string, string>, control: DaikinControl): Record<string, string>;
|
|
21
|
+
/** Turns `current`, the `get_control_info` reply, into the `set_control_info`
|
|
22
|
+
* query that switches fan auto on or off. It switches airside off, and keeps
|
|
23
|
+
* the fan speed. */
|
|
24
|
+
export declare function applyAirbaseFanAuto(current: Record<string, string>, enabled: boolean): Record<string, string>;
|
|
25
|
+
/** Turns `current`, the `get_control_info` reply, into the `set_control_info`
|
|
26
|
+
* query that switches airside on or off. Switching it on switches fan auto
|
|
27
|
+
* off and sets the lowest fan speed, which airside runs at. */
|
|
28
|
+
export declare function applyAirbaseAirside(current: Record<string, string>, enabled: boolean): Record<string, string>;
|
|
29
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/codecs/airbase/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,WAAW,EAIZ,MAAM,uBAAuB,CAAC;AA2C/B;;;oCAGoC;AACpC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,CAY7E;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,aAAa,CAMf;AAED;sDACsD;AACtD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAE3E;AAED,2DAA2D;AAC3D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAE3E;AAED;;;;;;0EAM0E;AAC1E,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,EAAE,aAAa,GACrB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExB;AAED;;oBAEoB;AACpB,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExB;AAED;;+DAE+D;AAC/D,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExB"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { AIRBASE_FAN_SPEED_CODES, AIRBASE_NO_SETPOINT, AIRBASE_OPERATING_MODE_CODES, AIRBASE_SWING_MODE_CODES, } from "./tables.js";
|
|
2
|
+
// Maps between `DaikinState` and an Airbase adapter's `control_info` fields,
|
|
3
|
+
// and reads `DaikinSensors` from its `get_sensor_info`.
|
|
4
|
+
//
|
|
5
|
+
// The unit remembers a setpoint, a fan and a direction for cool and for heat
|
|
6
|
+
// alone: `dt2`, `dfr2`, `dfd2`, `auto2` and `airside2` for cool, and the same
|
|
7
|
+
// fields ending in 1 for heat. Auto, fan and dehumidify run on one of the
|
|
8
|
+
// two, the one `bk_auto` names.
|
|
9
|
+
const OPERATING_MODES_BY_CODE = Object.fromEntries(Object.entries(AIRBASE_OPERATING_MODE_CODES).map(([mode, code]) => [
|
|
10
|
+
code,
|
|
11
|
+
mode,
|
|
12
|
+
]));
|
|
13
|
+
const FAN_SPEEDS_BY_CODE = Object.fromEntries(Object.entries(AIRBASE_FAN_SPEED_CODES).map(([speed, code]) => [
|
|
14
|
+
code,
|
|
15
|
+
speed,
|
|
16
|
+
]));
|
|
17
|
+
const SWING_MODES_BY_CODE = Object.fromEntries(Object.entries(AIRBASE_SWING_MODE_CODES).map(([swing, code]) => [
|
|
18
|
+
code,
|
|
19
|
+
swing,
|
|
20
|
+
]));
|
|
21
|
+
const ON = "1";
|
|
22
|
+
const OFF = "0";
|
|
23
|
+
// What airside runs the fan at.
|
|
24
|
+
const AIRSIDE_FAN_SPEED = AIRBASE_FAN_SPEED_CODES.level1;
|
|
25
|
+
/** Turns a `get_control_info` reply into a `DaikinState`. A `mode` or `f_rate`
|
|
26
|
+
* outside the model reads as `auto`, and an `f_dir` outside it as `off`. It
|
|
27
|
+
* reports no humidity setting, louver position or special mode: an Airbase
|
|
28
|
+
* unit is not known to have any. */
|
|
29
|
+
export function parseAirbaseState(fields) {
|
|
30
|
+
return {
|
|
31
|
+
power: fields.pow === ON,
|
|
32
|
+
mode: OPERATING_MODES_BY_CODE[fields.mode ?? ""] ?? "auto",
|
|
33
|
+
targetTemperatureInC: parseNumeric(fields.stemp),
|
|
34
|
+
targetHumidity: null,
|
|
35
|
+
fanSpeed: FAN_SPEEDS_BY_CODE[fields.f_rate ?? ""] ?? "auto",
|
|
36
|
+
swingMode: SWING_MODES_BY_CODE[fields.f_dir ?? ""] ?? "off",
|
|
37
|
+
verticalPosition: null,
|
|
38
|
+
horizontalPosition: null,
|
|
39
|
+
specialModes: [],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function parseAirbaseSensors(fields) {
|
|
43
|
+
return {
|
|
44
|
+
indoorTemperatureInC: parseNumeric(fields.htemp),
|
|
45
|
+
outdoorTemperatureInC: parseNumeric(fields.otemp),
|
|
46
|
+
indoorHumidityInPercent: parseNumeric(fields.hhum),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Whether fan auto is on in a `get_control_info` reply: the unit then picks
|
|
50
|
+
* the fan speed itself, up to the one that is set. */
|
|
51
|
+
export function parseAirbaseFanAuto(fields) {
|
|
52
|
+
return fields.f_auto === ON;
|
|
53
|
+
}
|
|
54
|
+
/** Whether airside is on in a `get_control_info` reply. */
|
|
55
|
+
export function parseAirbaseAirside(fields) {
|
|
56
|
+
return fields.f_airside === ON;
|
|
57
|
+
}
|
|
58
|
+
/** Turns `current`, the `get_control_info` reply, and a control into the
|
|
59
|
+
* `set_control_info` query: power, mode, setpoint, humidity, fan speed, fan
|
|
60
|
+
* auto, airside and direction, every time. When the mode changes, the
|
|
61
|
+
* setpoint, the fan and the direction come from what the unit remembers for
|
|
62
|
+
* cool or for heat. It drops a `targetTemperatureInC` in fan and dehumidify,
|
|
63
|
+
* every `targetHumidity` and louver position, and sends `shum` back as the
|
|
64
|
+
* unit holds it. A `fanSpeed` switches airside off and keeps fan auto. */
|
|
65
|
+
export function applyAirbaseControl(current, control) {
|
|
66
|
+
return buildControl(current, control, {});
|
|
67
|
+
}
|
|
68
|
+
/** Turns `current`, the `get_control_info` reply, into the `set_control_info`
|
|
69
|
+
* query that switches fan auto on or off. It switches airside off, and keeps
|
|
70
|
+
* the fan speed. */
|
|
71
|
+
export function applyAirbaseFanAuto(current, enabled) {
|
|
72
|
+
return buildControl(current, {}, { auto: enabled });
|
|
73
|
+
}
|
|
74
|
+
/** Turns `current`, the `get_control_info` reply, into the `set_control_info`
|
|
75
|
+
* query that switches airside on or off. Switching it on switches fan auto
|
|
76
|
+
* off and sets the lowest fan speed, which airside runs at. */
|
|
77
|
+
export function applyAirbaseAirside(current, enabled) {
|
|
78
|
+
return buildControl(current, {}, { airside: enabled });
|
|
79
|
+
}
|
|
80
|
+
function buildControl(current, control, fan) {
|
|
81
|
+
const { cool, heat, fan: fanMode, dehumidify } = AIRBASE_OPERATING_MODE_CODES;
|
|
82
|
+
// A mode outside the model is sent back as it came.
|
|
83
|
+
const currentMode = current.mode ?? "";
|
|
84
|
+
const mode = control.mode === undefined
|
|
85
|
+
? currentMode
|
|
86
|
+
: AIRBASE_OPERATING_MODE_CODES[control.mode];
|
|
87
|
+
const modeChanged = mode !== currentMode;
|
|
88
|
+
// A change to cool or to heat makes that mode the one the others run on.
|
|
89
|
+
const backing = modeChanged && (mode === cool || mode === heat) ? mode : current.bk_auto;
|
|
90
|
+
// Which of the two memories applies: heat's, or cool's for anything else.
|
|
91
|
+
const memory = (backing || mode) === heat ? heat : cool;
|
|
92
|
+
const remembered = (field, memoryPrefix, fallback) => (modeChanged ? current[`${memoryPrefix}${memory}`] : undefined) ||
|
|
93
|
+
current[field] ||
|
|
94
|
+
fallback;
|
|
95
|
+
const power = control.power ?? current.pow === ON;
|
|
96
|
+
const next = { pow: power ? ON : OFF, mode };
|
|
97
|
+
if (backing) {
|
|
98
|
+
next.bk_auto = backing;
|
|
99
|
+
}
|
|
100
|
+
next.stemp =
|
|
101
|
+
mode === dehumidify
|
|
102
|
+
? AIRBASE_NO_SETPOINT
|
|
103
|
+
: control.targetTemperatureInC != null && mode !== fanMode
|
|
104
|
+
? control.targetTemperatureInC.toFixed(1)
|
|
105
|
+
: remembered("stemp", "dt", AIRBASE_NO_SETPOINT);
|
|
106
|
+
// Each mode's setpoint is written to its own memory as well, and auto's to
|
|
107
|
+
// the memory of the mode it runs on.
|
|
108
|
+
const setpointMemory = mode === cool || mode === heat || mode === fanMode || mode === dehumidify
|
|
109
|
+
? mode
|
|
110
|
+
: mode === AIRBASE_OPERATING_MODE_CODES.auto && backing
|
|
111
|
+
? memory
|
|
112
|
+
: undefined;
|
|
113
|
+
if (setpointMemory !== undefined) {
|
|
114
|
+
next[`dt${setpointMemory}`] = next.stemp;
|
|
115
|
+
}
|
|
116
|
+
next.shum = current.shum || AIRBASE_NO_SETPOINT;
|
|
117
|
+
next.f_rate =
|
|
118
|
+
control.fanSpeed === undefined
|
|
119
|
+
? remembered("f_rate", "dfr", AIRBASE_FAN_SPEED_CODES.auto)
|
|
120
|
+
: AIRBASE_FAN_SPEED_CODES[control.fanSpeed];
|
|
121
|
+
next.f_auto = remembered("f_auto", "auto", OFF);
|
|
122
|
+
next.f_airside = remembered("f_airside", "airside", OFF);
|
|
123
|
+
const fanChanged = control.fanSpeed !== undefined || fan.auto !== undefined;
|
|
124
|
+
if (fan.auto !== undefined) {
|
|
125
|
+
next.f_auto = fan.auto ? ON : OFF;
|
|
126
|
+
}
|
|
127
|
+
if (fanChanged) {
|
|
128
|
+
next.f_airside = OFF;
|
|
129
|
+
}
|
|
130
|
+
if (fan.airside !== undefined) {
|
|
131
|
+
next.f_airside = fan.airside ? ON : OFF;
|
|
132
|
+
}
|
|
133
|
+
if (fan.airside) {
|
|
134
|
+
next.f_rate = AIRSIDE_FAN_SPEED;
|
|
135
|
+
}
|
|
136
|
+
// Airside and fan auto are never on together.
|
|
137
|
+
if (next.f_airside === ON) {
|
|
138
|
+
next.f_auto = OFF;
|
|
139
|
+
}
|
|
140
|
+
// A change to the fan is written to the memory as well.
|
|
141
|
+
if (fanChanged) {
|
|
142
|
+
next[`dfr${memory}`] = next.f_rate;
|
|
143
|
+
next[`auto${memory}`] = next.f_auto;
|
|
144
|
+
}
|
|
145
|
+
if (fanChanged || fan.airside !== undefined) {
|
|
146
|
+
next[`airside${memory}`] = next.f_airside;
|
|
147
|
+
}
|
|
148
|
+
next.f_dir =
|
|
149
|
+
control.swingMode === undefined
|
|
150
|
+
? remembered("f_dir", "dfd", AIRBASE_SWING_MODE_CODES.off)
|
|
151
|
+
: AIRBASE_SWING_MODE_CODES[control.swingMode];
|
|
152
|
+
if (control.swingMode !== undefined) {
|
|
153
|
+
next[`dfd${memory}`] = next.f_dir;
|
|
154
|
+
}
|
|
155
|
+
return next;
|
|
156
|
+
}
|
|
157
|
+
function parseNumeric(value) {
|
|
158
|
+
if (value === undefined || value === "") {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
const parsed = Number(value);
|
|
162
|
+
// A reading the unit lacks is "-", and a mode without a setpoint holds
|
|
163
|
+
// "--" or a letter, none of which is a number.
|
|
164
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/codecs/airbase/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FanSpeed, OperatingMode, SwingMode } from "../../models/state.js";
|
|
2
|
+
export declare const AIRBASE_OPERATING_MODE_CODES: Record<OperatingMode, string>;
|
|
3
|
+
export declare const AIRBASE_FAN_SPEED_CODES: Record<FanSpeed, string>;
|
|
4
|
+
export declare const AIRBASE_SWING_MODE_CODES: Record<SwingMode, string>;
|
|
5
|
+
/** What `stemp` holds in a mode without a setpoint, such as dehumidify. */
|
|
6
|
+
export declare const AIRBASE_NO_SETPOINT = "--";
|
|
7
|
+
//# sourceMappingURL=tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../../src/codecs/airbase/tables.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKhF,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAMtE,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAQ5D,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAK9D,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,OAAO,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// The codes an Airbase adapter holds each value of a model as. It numbers
|
|
2
|
+
// the modes and the fan speeds differently from a classic adapter.
|
|
3
|
+
export const AIRBASE_OPERATING_MODE_CODES = {
|
|
4
|
+
fan: "0",
|
|
5
|
+
heat: "1",
|
|
6
|
+
cool: "2",
|
|
7
|
+
auto: "3",
|
|
8
|
+
dehumidify: "7",
|
|
9
|
+
};
|
|
10
|
+
export const AIRBASE_FAN_SPEED_CODES = {
|
|
11
|
+
auto: "0",
|
|
12
|
+
silent: "B",
|
|
13
|
+
level1: "1",
|
|
14
|
+
level2: "2",
|
|
15
|
+
level3: "3",
|
|
16
|
+
level4: "4",
|
|
17
|
+
level5: "5",
|
|
18
|
+
};
|
|
19
|
+
export const AIRBASE_SWING_MODE_CODES = {
|
|
20
|
+
off: "0",
|
|
21
|
+
vertical: "1",
|
|
22
|
+
horizontal: "2",
|
|
23
|
+
both: "3",
|
|
24
|
+
};
|
|
25
|
+
/** What `stemp` holds in a mode without a setpoint, such as dehumidify. */
|
|
26
|
+
export const AIRBASE_NO_SETPOINT = "--";
|
|
27
|
+
//# sourceMappingURL=tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../../../src/codecs/airbase/tables.ts"],"names":[],"mappings":"AAEA,0EAA0E;AAC1E,mEAAmE;AAEnE,MAAM,CAAC,MAAM,4BAA4B,GAAkC;IACzE,GAAG,EAAE,GAAG;IACR,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,UAAU,EAAE,GAAG;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAA6B;IAC/D,IAAI,EAAE,GAAG;IACT,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;CACZ,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAA8B;IACjE,GAAG,EAAE,GAAG;IACR,QAAQ,EAAE,GAAG;IACb,UAAU,EAAE,GAAG;IACf,IAAI,EAAE,GAAG;CACV,CAAC;AAEF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DaikinZone } from "../../models/zone.js";
|
|
2
|
+
/** Turns a `get_zone_setting` reply into the unit's zones, the first
|
|
3
|
+
* `en_zone` of them. `capabilityFields` is the field map of
|
|
4
|
+
* `mergeAirbaseCapabilityFields`. */
|
|
5
|
+
export declare function parseAirbaseZones(zoneSetting: Record<string, string>, capabilityFields: Record<string, string>): DaikinZone[];
|
|
6
|
+
/** Turns `current`, the `get_zone_setting` reply, into the `set_zone_setting`
|
|
7
|
+
* query that opens or closes the zone at `index`, counted from 0. Every name
|
|
8
|
+
* goes back as the unit holds it, with each zone's temperatures where the
|
|
9
|
+
* unit has them. It throws an `Error` for an index the unit has no zone
|
|
10
|
+
* at. */
|
|
11
|
+
export declare function applyAirbaseZone(current: Record<string, string>, capabilityFields: Record<string, string>, index: number, enabled: boolean): Record<string, string>;
|
|
12
|
+
//# sourceMappingURL=zone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zone.d.ts","sourceRoot":"","sources":["../../../src/codecs/airbase/zone.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAiBvD;;qCAEqC;AACrC,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC,UAAU,EAAE,CAQd;AAED;;;;SAIS;AACT,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBxB"}
|