daikin-local-control 0.3.1 → 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 +156 -2
- package/README.md +274 -48
- package/UNSUPPORTED.md +66 -3
- 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/classic.d.ts +2 -2
- package/dist/clients/classic.d.ts.map +1 -1
- package/dist/clients/classic.js +4 -4
- package/dist/clients/classic.js.map +1 -1
- package/dist/clients/client.d.ts +7 -2
- package/dist/clients/client.d.ts.map +1 -1
- package/dist/clients/dsiot.d.ts +3 -1
- package/dist/clients/dsiot.d.ts.map +1 -1
- package/dist/clients/dsiot.js +7 -2
- package/dist/clients/dsiot.js.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/capabilities.d.ts.map +1 -1
- package/dist/codecs/classic/capabilities.js +5 -11
- package/dist/codecs/classic/capabilities.js.map +1 -1
- package/dist/codecs/classic/extendedControl.d.ts.map +1 -1
- package/dist/codecs/classic/extendedControl.js +10 -19
- package/dist/codecs/classic/extendedControl.js.map +1 -1
- package/dist/codecs/classic/state.d.ts.map +1 -1
- package/dist/codecs/classic/state.js +36 -95
- package/dist/codecs/classic/state.js.map +1 -1
- package/dist/codecs/classic/tables.d.ts +34 -0
- package/dist/codecs/classic/tables.d.ts.map +1 -0
- package/dist/codecs/classic/tables.js +96 -0
- package/dist/codecs/classic/tables.js.map +1 -0
- package/dist/codecs/credentials.d.ts +3 -2
- package/dist/codecs/credentials.d.ts.map +1 -1
- package/dist/codecs/credentials.js +8 -3
- package/dist/codecs/credentials.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 +15 -3
- package/dist/codecs/device.js.map +1 -1
- package/dist/codecs/dsiot/capabilities.d.ts.map +1 -1
- package/dist/codecs/dsiot/capabilities.js +8 -15
- package/dist/codecs/dsiot/capabilities.js.map +1 -1
- package/dist/codecs/dsiot/device.d.ts.map +1 -1
- package/dist/codecs/dsiot/device.js +4 -8
- package/dist/codecs/dsiot/device.js.map +1 -1
- package/dist/codecs/dsiot/multireq.d.ts +0 -19
- package/dist/codecs/dsiot/multireq.d.ts.map +1 -1
- package/dist/codecs/dsiot/multireq.js +2 -25
- package/dist/codecs/dsiot/multireq.js.map +1 -1
- package/dist/codecs/dsiot/state.d.ts +6 -62
- package/dist/codecs/dsiot/state.d.ts.map +1 -1
- package/dist/codecs/dsiot/state.js +29 -148
- package/dist/codecs/dsiot/state.js.map +1 -1
- package/dist/codecs/dsiot/tables.d.ts +119 -0
- package/dist/codecs/dsiot/tables.d.ts.map +1 -0
- package/dist/codecs/dsiot/tables.js +188 -0
- package/dist/codecs/dsiot/tables.js.map +1 -0
- package/dist/discovery.d.ts +20 -9
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +102 -32
- package/dist/discovery.js.map +1 -1
- package/dist/factory.d.ts +13 -7
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +16 -4
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -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/state.d.ts +2 -3
- package/dist/models/state.d.ts.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 +61 -0
- package/dist/simulators/classic.d.ts.map +1 -0
- package/dist/simulators/classic.js +473 -0
- package/dist/simulators/classic.js.map +1 -0
- package/dist/simulators/dsiot.d.ts +49 -0
- package/dist/simulators/dsiot.d.ts.map +1 -0
- package/dist/simulators/dsiot.js +519 -0
- package/dist/simulators/dsiot.js.map +1 -0
- package/dist/simulators/index.d.ts +5 -0
- package/dist/simulators/index.d.ts.map +1 -0
- package/dist/simulators/index.js +4 -0
- package/dist/simulators/index.js.map +1 -0
- package/dist/simulators/simulator.d.ts +117 -0
- package/dist/simulators/simulator.d.ts.map +1 -0
- package/dist/simulators/simulator.js +141 -0
- package/dist/simulators/simulator.js.map +1 -0
- package/dist/transport.d.ts +8 -3
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +10 -2
- package/dist/transport.js.map +1 -1
- package/package.json +11 -4
- package/src/clients/airbase.ts +274 -0
- package/src/clients/classic.ts +8 -8
- package/src/clients/client.ts +8 -1
- package/src/clients/dsiot.ts +8 -1
- 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/capabilities.ts +8 -11
- package/src/codecs/classic/extendedControl.ts +14 -25
- package/src/codecs/classic/state.ts +49 -101
- package/src/codecs/classic/tables.ts +126 -0
- package/src/codecs/credentials.ts +11 -3
- package/src/codecs/device.ts +19 -3
- package/src/codecs/dsiot/capabilities.ts +10 -17
- package/src/codecs/dsiot/device.ts +4 -9
- package/src/codecs/dsiot/multireq.ts +2 -25
- package/src/codecs/dsiot/state.ts +57 -193
- package/src/codecs/dsiot/tables.ts +253 -0
- package/src/discovery.ts +107 -34
- package/src/factory.ts +26 -7
- package/src/index.ts +8 -0
- package/src/models/device.ts +3 -2
- package/src/models/state.ts +2 -3
- package/src/models/zone.ts +8 -0
- package/src/simulators/airbase.ts +495 -0
- package/src/simulators/classic.ts +636 -0
- package/src/simulators/dsiot.ts +736 -0
- package/src/simulators/index.ts +10 -0
- package/src/simulators/simulator.ts +282 -0
- package/src/transport.ts +15 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
export type { DaikinAuthentication } from "./authentication.js";
|
|
2
|
+
export { AirbaseDaikinClient } from "./clients/airbase.js";
|
|
2
3
|
export * from "./clients/classic.js";
|
|
3
4
|
export * from "./clients/client.js";
|
|
4
5
|
export * from "./clients/dsiot.js";
|
|
6
|
+
export * from "./codecs/airbase/capabilities.js";
|
|
7
|
+
export * from "./codecs/airbase/state.js";
|
|
8
|
+
export * from "./codecs/airbase/tables.js";
|
|
9
|
+
export * from "./codecs/airbase/zone.js";
|
|
5
10
|
export * from "./codecs/classic/capabilities.js";
|
|
6
11
|
export * from "./codecs/classic/extendedControl.js";
|
|
7
12
|
export * from "./codecs/classic/keyValue.js";
|
|
8
13
|
export * from "./codecs/classic/state.js";
|
|
14
|
+
export * from "./codecs/classic/tables.js";
|
|
9
15
|
export * from "./codecs/credentials.js";
|
|
10
16
|
export * from "./codecs/device.js";
|
|
11
17
|
export * from "./codecs/dsiot/capabilities.js";
|
|
12
18
|
export * from "./codecs/dsiot/device.js";
|
|
13
19
|
export * from "./codecs/dsiot/multireq.js";
|
|
14
20
|
export * from "./codecs/dsiot/state.js";
|
|
21
|
+
export * from "./codecs/dsiot/tables.js";
|
|
15
22
|
export * from "./discovery.js";
|
|
16
23
|
export * from "./error.js";
|
|
17
24
|
export * from "./factory.js";
|
|
@@ -19,5 +26,6 @@ export * from "./models/capabilities.js";
|
|
|
19
26
|
export * from "./models/device.js";
|
|
20
27
|
export * from "./models/extendedControl.js";
|
|
21
28
|
export * from "./models/state.js";
|
|
29
|
+
export * from "./models/zone.js";
|
|
22
30
|
export * from "./transport.js";
|
|
23
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
+
export { AirbaseDaikinClient } from "./clients/airbase.js";
|
|
1
2
|
export * from "./clients/classic.js";
|
|
2
3
|
export * from "./clients/client.js";
|
|
3
4
|
export * from "./clients/dsiot.js";
|
|
5
|
+
export * from "./codecs/airbase/capabilities.js";
|
|
6
|
+
export * from "./codecs/airbase/state.js";
|
|
7
|
+
export * from "./codecs/airbase/tables.js";
|
|
8
|
+
export * from "./codecs/airbase/zone.js";
|
|
4
9
|
export * from "./codecs/classic/capabilities.js";
|
|
5
10
|
export * from "./codecs/classic/extendedControl.js";
|
|
6
11
|
export * from "./codecs/classic/keyValue.js";
|
|
7
12
|
export * from "./codecs/classic/state.js";
|
|
13
|
+
export * from "./codecs/classic/tables.js";
|
|
8
14
|
export * from "./codecs/credentials.js";
|
|
9
15
|
export * from "./codecs/device.js";
|
|
10
16
|
export * from "./codecs/dsiot/capabilities.js";
|
|
11
17
|
export * from "./codecs/dsiot/device.js";
|
|
12
18
|
export * from "./codecs/dsiot/multireq.js";
|
|
13
19
|
export * from "./codecs/dsiot/state.js";
|
|
20
|
+
export * from "./codecs/dsiot/tables.js";
|
|
14
21
|
export * from "./discovery.js";
|
|
15
22
|
export * from "./error.js";
|
|
16
23
|
export * from "./factory.js";
|
|
@@ -18,5 +25,6 @@ export * from "./models/capabilities.js";
|
|
|
18
25
|
export * from "./models/device.js";
|
|
19
26
|
export * from "./models/extendedControl.js";
|
|
20
27
|
export * from "./models/state.js";
|
|
28
|
+
export * from "./models/zone.js";
|
|
21
29
|
export * from "./transport.js";
|
|
22
30
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC"}
|
package/dist/models/device.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export declare const DAIKIN_PROTOCOLS: readonly ["classic", "dsiot"];
|
|
1
|
+
export declare const DAIKIN_PROTOCOLS: readonly ["classic", "dsiot", "airbase"];
|
|
2
2
|
/** The wire protocol an adapter speaks, and the only difference between
|
|
3
3
|
* adapters that takes a separate `DaikinClient` implementation: `classic` for
|
|
4
|
-
* a CGI adapter such as the BRP069 or BRP072, `dsiot` for a BRP084
|
|
4
|
+
* a CGI adapter such as the BRP069 or BRP072, `dsiot` for a BRP084, and
|
|
5
|
+
* `airbase` for the BRP15B61 of a ducted unit. */
|
|
5
6
|
export type DaikinProtocol = (typeof DAIKIN_PROTOCOLS)[number];
|
|
6
7
|
/** What an adapter reports to identify itself. `discoverDevices` fills it into
|
|
7
8
|
* each `DaikinDevice`, and `DaikinClient.getDeviceInfo` reads it for a device
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/models/device.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,YAAI,SAAS,EAAE,OAAO,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/models/device.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,YAAI,SAAS,EAAE,OAAO,EAAE,SAAS,CAAU,CAAC;AAEzE;;;kDAGkD;AAClD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D;;sBAEsB;AACtB,MAAM,WAAW,gBAAgB;IAC/B;+BAC2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;sEACkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;8DAC0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;iBAGiB;AACjB,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB;wEACoE;IACpE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;2BACuB;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oEAAoE;IACpE,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC"}
|
package/dist/models/device.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const DAIKIN_PROTOCOLS = ["classic", "dsiot"];
|
|
1
|
+
export const DAIKIN_PROTOCOLS = ["classic", "dsiot", "airbase"];
|
|
2
2
|
//# sourceMappingURL=device.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/models/device.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,OAAO,CAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/models/device.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAU,CAAC"}
|
package/dist/models/state.d.ts
CHANGED
|
@@ -50,9 +50,8 @@ export interface DaikinState {
|
|
|
50
50
|
* fields to change. The client overlays the control on the state the unit
|
|
51
51
|
* holds, and writes the whole state back. It drops a field the unit does not take in
|
|
52
52
|
* the target mode, such as a louver position outside
|
|
53
|
-
* `DaikinCapabilities.verticalPositions`. It takes no `specialModes`:
|
|
54
|
-
*
|
|
55
|
-
* UNSUPPORTED.md says what is not known about the rest. */
|
|
53
|
+
* `DaikinCapabilities.verticalPositions`. It takes no `specialModes`:
|
|
54
|
+
* `DaikinClient.setSpecialMode` turns one on or off. */
|
|
56
55
|
export type DaikinControl = Partial<Omit<DaikinState, "specialModes">>;
|
|
57
56
|
/** A reading is `null` when the unit does not report it. */
|
|
58
57
|
export interface DaikinSensors {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/models/state.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,YAC1B,MAAM,EACN,YAAY,EACZ,MAAM,EACN,MAAM,EACN,KAAK,CACG,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,eAAO,MAAM,UAAU,YACrB,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,CACA,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,eAAO,MAAM,WAAW,YAAI,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,CAAU,CAAC;AAE9E;;;uCAGuC;AACvC,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,6DAA6D;AAC7D,eAAO,MAAM,sBAAsB,YACjC,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,CACH,CAAC;AAEX,eAAO,MAAM,kBAAkB,oIAOrB,CAAC;AAEX;uDACuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,eAAO,MAAM,oBAAoB,qGAKvB,CAAC;AAEX,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,eAAO,MAAM,iBAAiB,YAC5B,KAAK,EACL,SAAS,EACT,MAAM,EACN,UAAU,EACV,YAAY,CACJ,CAAC;AAEX,qDAAqD;AACrD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;6EAC6E;AAC7E,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,eAAO,MAAM,aAAa,YAAI,UAAU,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AAExE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,sEAAsE;IACtE,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,oDAAoD;IACpD,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;IACrB;6BACyB;IACzB,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C;+BAC2B;IAC3B,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC9C;yEACqE;IACrE,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/models/state.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,YAC1B,MAAM,EACN,YAAY,EACZ,MAAM,EACN,MAAM,EACN,KAAK,CACG,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,eAAO,MAAM,UAAU,YACrB,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,CACA,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,eAAO,MAAM,WAAW,YAAI,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,CAAU,CAAC;AAE9E;;;uCAGuC;AACvC,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,6DAA6D;AAC7D,eAAO,MAAM,sBAAsB,YACjC,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,CACH,CAAC;AAEX,eAAO,MAAM,kBAAkB,oIAOrB,CAAC;AAEX;uDACuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,eAAO,MAAM,oBAAoB,qGAKvB,CAAC;AAEX,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,eAAO,MAAM,iBAAiB,YAC5B,KAAK,EACL,SAAS,EACT,MAAM,EACN,UAAU,EACV,YAAY,CACJ,CAAC;AAEX,qDAAqD;AACrD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;6EAC6E;AAC7E,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,eAAO,MAAM,aAAa,YAAI,UAAU,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AAExE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,sEAAsE;IACtE,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,oDAAoD;IACpD,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;IACrB;6BACyB;IACzB,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C;+BAC2B;IAC3B,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC9C;yEACqE;IACrE,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED;;;;;wDAKwD;AACxD,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;AAEvE,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;CACxB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** One zone of a ducted unit on an Airbase adapter: a damper that opens or
|
|
2
|
+
* closes the air to part of the building. */
|
|
3
|
+
export interface DaikinZone {
|
|
4
|
+
/** The name the zone was given, without the spaces around it. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** Whether the zone is open. */
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=zone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zone.d.ts","sourceRoot":"","sources":["../../src/models/zone.ts"],"names":[],"mappings":"AAAA;6CAC6C;AAC7C,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;CAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zone.js","sourceRoot":"","sources":["../../src/models/zone.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type DaikinSimulator, type DaikinSimulatorTemperatures, type StartSimulatorOptions } from "./simulator.js";
|
|
2
|
+
/** What a simulated Airbase unit has. Anything else about it is set in the
|
|
3
|
+
* adapter's own terms, in `modelInfo`. */
|
|
4
|
+
export interface AirbaseSimulatorUnit {
|
|
5
|
+
/** The names of the unit's zones, each open at the start. Defaults to none:
|
|
6
|
+
* a unit without zones. A unit with zones takes fan auto, and neither the
|
|
7
|
+
* `auto` fan speed nor a direction. */
|
|
8
|
+
zones?: readonly string[];
|
|
9
|
+
/** Whether the unit offers auto. Defaults to true. */
|
|
10
|
+
auto?: boolean;
|
|
11
|
+
/** Whether the unit offers dehumidify. Defaults to true. */
|
|
12
|
+
dehumidify?: boolean;
|
|
13
|
+
/** Whether the fan speed can be set. Defaults to true. */
|
|
14
|
+
fan?: boolean;
|
|
15
|
+
/** How many fan levels the unit takes: `level1` and `level5` for 2, and
|
|
16
|
+
* `level3` as well for 3. Defaults to 3. */
|
|
17
|
+
fanLevels?: 2 | 3;
|
|
18
|
+
/** Whether a unit with zones takes airside. Defaults to false. */
|
|
19
|
+
airside?: boolean;
|
|
20
|
+
/** Whether a unit without zones takes a direction. Defaults to true. */
|
|
21
|
+
swing?: boolean;
|
|
22
|
+
/** The setpoints cool takes, in whole degrees. Defaults to none
|
|
23
|
+
* reported. */
|
|
24
|
+
coolTemperaturesInC?: DaikinSimulatorTemperatures;
|
|
25
|
+
/** The setpoints heat takes, in whole degrees. Defaults to none
|
|
26
|
+
* reported. */
|
|
27
|
+
heatTemperaturesInC?: DaikinSimulatorTemperatures;
|
|
28
|
+
}
|
|
29
|
+
export interface StartAirbaseSimulatorOptions extends StartSimulatorOptions {
|
|
30
|
+
/** What the unit has. Defaults to a unit without zones that offers every
|
|
31
|
+
* mode, three fan levels and the `auto` fan speed, and takes a direction.
|
|
32
|
+
* A field of `modelInfo` replaces what this sets. */
|
|
33
|
+
unit?: AirbaseSimulatorUnit;
|
|
34
|
+
/** Fields added to the `/skyfi/common/basic_info` reply, each replacing a
|
|
35
|
+
* default of the same name. Defaults to none. */
|
|
36
|
+
basicInfo?: Record<string, string>;
|
|
37
|
+
/** Fields added to the `/skyfi/aircon/get_model_info` reply, each replacing
|
|
38
|
+
* a default of the same name. Defaults to none. */
|
|
39
|
+
modelInfo?: Record<string, string>;
|
|
40
|
+
/** Fields added to the `/skyfi/aircon/get_control_info` reply, each
|
|
41
|
+
* replacing a default of the same name. Defaults to none. */
|
|
42
|
+
controlInfo?: Record<string, string>;
|
|
43
|
+
/** Fields added to the `/skyfi/aircon/get_sensor_info` reply, each replacing
|
|
44
|
+
* a default of the same name. Defaults to none. */
|
|
45
|
+
sensorInfo?: Record<string, string>;
|
|
46
|
+
/** Fields added to the `/skyfi/aircon/get_zone_setting` reply, each
|
|
47
|
+
* replacing what `unit.zones` sets. Defaults to none. */
|
|
48
|
+
zoneSetting?: Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
/** An Airbase adapter and the unit behind it. Each field map is what its
|
|
51
|
+
* endpoint answers, in the adapter's own names and encodings, without the
|
|
52
|
+
* `ret`. A write through the adapter changes them, and so do `setState`,
|
|
53
|
+
* `setSensors` and `setZone`. Change a field directly for what those do not
|
|
54
|
+
* cover, such as `controlInfo.f_auto` for fan auto. */
|
|
55
|
+
export interface AirbaseDaikinSimulator extends DaikinSimulator {
|
|
56
|
+
/** What `/skyfi/common/basic_info` answers. `name` is held percent-encoded,
|
|
57
|
+
* as the reply carries it. */
|
|
58
|
+
readonly basicInfo: Record<string, string>;
|
|
59
|
+
/** What `/skyfi/aircon/get_model_info` answers. */
|
|
60
|
+
readonly modelInfo: Record<string, string>;
|
|
61
|
+
/** What `/skyfi/aircon/get_control_info` answers. */
|
|
62
|
+
readonly controlInfo: Record<string, string>;
|
|
63
|
+
/** What `/skyfi/aircon/get_sensor_info` answers. */
|
|
64
|
+
readonly sensorInfo: Record<string, string>;
|
|
65
|
+
/** What `/skyfi/aircon/get_zone_setting` answers, each list held
|
|
66
|
+
* percent-encoded, as the reply carries it. Empty on a unit without
|
|
67
|
+
* zones. */
|
|
68
|
+
readonly zoneSetting: Record<string, string>;
|
|
69
|
+
/** Opens or closes the zone at `index`, counted from 0, as the unit's wall
|
|
70
|
+
* controller would. It throws an `Error` for an index the unit has no zone
|
|
71
|
+
* at. */
|
|
72
|
+
setZone(index: number, enabled: boolean): void;
|
|
73
|
+
}
|
|
74
|
+
/** Starts an Airbase adapter on a free port, as a unit without zones that is
|
|
75
|
+
* off, in cool at 24 °C. It answers the endpoints `AirbaseDaikinClient` has a
|
|
76
|
+
* typed method for, below `/skyfi`, and takes no terminal uuid and no local
|
|
77
|
+
* password. It answers HTTP 404 to a path outside `/skyfi`, as an Airbase
|
|
78
|
+
* adapter does, and HTTP 501 to any other request it has no answer for:
|
|
79
|
+
* UNSUPPORTED.md lists what it leaves out and where its answer is not known
|
|
80
|
+
* to be an adapter's. Call `stop` when done with it. */
|
|
81
|
+
export declare function startAirbaseSimulator(options?: StartAirbaseSimulatorOptions): Promise<AirbaseDaikinSimulator>;
|
|
82
|
+
//# sourceMappingURL=airbase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"airbase.d.ts","sourceRoot":"","sources":["../../src/simulators/airbase.ts"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,2BAA2B,EAGhC,KAAK,qBAAqB,EAG3B,MAAM,gBAAgB,CAAC;AA4FxB;0CAC0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC;;2CAEuC;IACvC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,sDAAsD;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;gDAC4C;IAC5C,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAClB,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;mBACe;IACf,mBAAmB,CAAC,EAAE,2BAA2B,CAAC;IAClD;mBACe;IACf,mBAAmB,CAAC,EAAE,2BAA2B,CAAC;CACnD;AAED,MAAM,WAAW,4BAA6B,SAAQ,qBAAqB;IACzE;;yDAEqD;IACrD,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;qDACiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;uDACmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;iEAC6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC;uDACmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC;6DACyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;;;uDAIuD;AACvD,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D;kCAC8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,qDAAqD;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C;;gBAEY;IACZ,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C;;aAES;IACT,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAChD;AAED;;;;;;wDAMwD;AACxD,wBAAsB,qBAAqB,CACzC,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,sBAAsB,CAAC,CA8GjC"}
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { AIRBASE_FAN_SPEED_CODES, AIRBASE_NO_SETPOINT, AIRBASE_OPERATING_MODE_CODES, AIRBASE_SWING_MODE_CODES, } from "../codecs/airbase/tables.js";
|
|
2
|
+
import { CLASSIC_ADAPTER_TYPE } from "../codecs/classic/tables.js";
|
|
3
|
+
import { formatKeyValue, startSimulator, unanswered, } from "./simulator.js";
|
|
4
|
+
// An Airbase adapter (BRP15B61) as an HTTP server. It reads the adapter's
|
|
5
|
+
// codes from the codec's tables and shares none of its functions: see
|
|
6
|
+
// DESIGN.md#simulators.
|
|
7
|
+
// Every endpoint is below this path, and any other path is answered HTTP 404.
|
|
8
|
+
const ROOT = "/skyfi";
|
|
9
|
+
// An Airbase adapter replies to the discovery probe as a classic adapter of
|
|
10
|
+
// an air conditioner does.
|
|
11
|
+
const DEFAULT_BASIC_INFO = {
|
|
12
|
+
type: CLASSIC_ADAPTER_TYPE,
|
|
13
|
+
reg: "au",
|
|
14
|
+
ver: "1_1_8",
|
|
15
|
+
name: "Simulator",
|
|
16
|
+
mac: "02DA1C000002",
|
|
17
|
+
lpw_flag: "0",
|
|
18
|
+
};
|
|
19
|
+
const DEFAULT_MODEL_INFO = {
|
|
20
|
+
model: "NOTSUPPORT",
|
|
21
|
+
en_auto: "1",
|
|
22
|
+
en_dry: "1",
|
|
23
|
+
en_frate: "1",
|
|
24
|
+
en_frate_auto: "1",
|
|
25
|
+
frate_steps: "3",
|
|
26
|
+
en_fdir: "1",
|
|
27
|
+
};
|
|
28
|
+
const { cool: COOL, heat: HEAT } = AIRBASE_OPERATING_MODE_CODES;
|
|
29
|
+
const DEFAULT_CONTROL_INFO = {
|
|
30
|
+
pow: "0",
|
|
31
|
+
mode: COOL,
|
|
32
|
+
bk_auto: COOL,
|
|
33
|
+
stemp: "24.0",
|
|
34
|
+
f_rate: AIRBASE_FAN_SPEED_CODES.auto,
|
|
35
|
+
f_auto: "0",
|
|
36
|
+
f_airside: "0",
|
|
37
|
+
f_dir: AIRBASE_SWING_MODE_CODES.off,
|
|
38
|
+
dt1: "25.0",
|
|
39
|
+
dt2: "24.0",
|
|
40
|
+
dfr1: AIRBASE_FAN_SPEED_CODES.auto,
|
|
41
|
+
dfr2: AIRBASE_FAN_SPEED_CODES.auto,
|
|
42
|
+
dfd1: AIRBASE_SWING_MODE_CODES.off,
|
|
43
|
+
dfd2: AIRBASE_SWING_MODE_CODES.off,
|
|
44
|
+
auto1: "0",
|
|
45
|
+
auto2: "0",
|
|
46
|
+
airside1: "0",
|
|
47
|
+
airside2: "0",
|
|
48
|
+
};
|
|
49
|
+
const DEFAULT_SENSOR_INFO = {
|
|
50
|
+
htemp: "26.0",
|
|
51
|
+
otemp: "30.0",
|
|
52
|
+
};
|
|
53
|
+
// A `set_control_info` without one of these is answered `PARAM NG`.
|
|
54
|
+
const REQUIRED_CONTROL_PARAMETERS = [
|
|
55
|
+
"pow",
|
|
56
|
+
"mode",
|
|
57
|
+
"stemp",
|
|
58
|
+
"shum",
|
|
59
|
+
"f_rate",
|
|
60
|
+
"f_auto",
|
|
61
|
+
"f_airside",
|
|
62
|
+
"f_dir",
|
|
63
|
+
];
|
|
64
|
+
// The parameters `set_control_info` stores: the control fields, and what the
|
|
65
|
+
// unit remembers for cool and for heat, such as `dt2` and `auto1`.
|
|
66
|
+
const CONTROL_PARAMETER_PATTERN = /^(pow|mode|bk_auto|stemp|shum|f_rate|f_auto|f_airside|f_dir|(dt|dfr|dfd|auto|airside)\w)$/;
|
|
67
|
+
// The control field each memory prefix remembers: `dfr2` holds the `f_rate`
|
|
68
|
+
// of cool.
|
|
69
|
+
const MEMORY_FIELDS = {
|
|
70
|
+
dt: "stemp",
|
|
71
|
+
dfr: "f_rate",
|
|
72
|
+
dfd: "f_dir",
|
|
73
|
+
auto: "f_auto",
|
|
74
|
+
airside: "f_airside",
|
|
75
|
+
};
|
|
76
|
+
// The lists of `get_zone_setting` are joined by this, percent-encoded.
|
|
77
|
+
const ZONE_SEPARATOR = ";";
|
|
78
|
+
const ZONE_PARAMETERS = ["zone_name", "zone_onoff"];
|
|
79
|
+
// A unit that sets a temperature for each zone holds these as well.
|
|
80
|
+
const ZONE_TEMPERATURE_PARAMETERS = ["lztemp_c", "lztemp_h"];
|
|
81
|
+
// A sensor field the unit has no reading for.
|
|
82
|
+
const NO_READING = "-";
|
|
83
|
+
/** Starts an Airbase adapter on a free port, as a unit without zones that is
|
|
84
|
+
* off, in cool at 24 °C. It answers the endpoints `AirbaseDaikinClient` has a
|
|
85
|
+
* typed method for, below `/skyfi`, and takes no terminal uuid and no local
|
|
86
|
+
* password. It answers HTTP 404 to a path outside `/skyfi`, as an Airbase
|
|
87
|
+
* adapter does, and HTTP 501 to any other request it has no answer for:
|
|
88
|
+
* UNSUPPORTED.md lists what it leaves out and where its answer is not known
|
|
89
|
+
* to be an adapter's. Call `stop` when done with it. */
|
|
90
|
+
export async function startAirbaseSimulator(options = {}) {
|
|
91
|
+
const unit = options.unit ?? {};
|
|
92
|
+
const basicInfo = { ...DEFAULT_BASIC_INFO, ...options.basicInfo };
|
|
93
|
+
const modelInfo = {
|
|
94
|
+
...DEFAULT_MODEL_INFO,
|
|
95
|
+
...encodeUnit(unit),
|
|
96
|
+
...options.modelInfo,
|
|
97
|
+
};
|
|
98
|
+
const controlInfo = { ...DEFAULT_CONTROL_INFO, ...options.controlInfo };
|
|
99
|
+
const sensorInfo = { ...DEFAULT_SENSOR_INFO, ...options.sensorInfo };
|
|
100
|
+
const zoneSetting = {
|
|
101
|
+
...encodeZones(unit.zones ?? []),
|
|
102
|
+
...options.zoneSetting,
|
|
103
|
+
};
|
|
104
|
+
const setState = (state) => applyState(controlInfo, state);
|
|
105
|
+
const setSensors = (sensors) => Object.assign(sensorInfo, encodeSensors(sensors));
|
|
106
|
+
const setZone = (index, enabled) => {
|
|
107
|
+
const flags = decodeList(zoneSetting.zone_onoff);
|
|
108
|
+
if (!Number.isInteger(index) || index < 0 || index >= flags.length) {
|
|
109
|
+
throw new Error(`The simulated unit has no zone ${index}`);
|
|
110
|
+
}
|
|
111
|
+
flags[index] = flag(enabled);
|
|
112
|
+
zoneSetting.zone_onoff = encodeList(flags);
|
|
113
|
+
};
|
|
114
|
+
// Before the server starts, so a state that throws leaves nothing
|
|
115
|
+
// listening.
|
|
116
|
+
Object.assign(basicInfo, encodeDeviceInfo(options.deviceInfo ?? {}));
|
|
117
|
+
setState(options.state ?? {});
|
|
118
|
+
setSensors(options.sensors ?? {});
|
|
119
|
+
const hasZones = () => "zone_name" in zoneSetting;
|
|
120
|
+
const reads = {
|
|
121
|
+
"/common/basic_info": () => basicInfo,
|
|
122
|
+
"/aircon/get_model_info": () => modelInfo,
|
|
123
|
+
"/aircon/get_control_info": () => controlInfo,
|
|
124
|
+
"/aircon/get_sensor_info": () => sensorInfo,
|
|
125
|
+
// What a unit without zones answers is not known.
|
|
126
|
+
"/aircon/get_zone_setting": () => (hasZones() ? zoneSetting : undefined),
|
|
127
|
+
};
|
|
128
|
+
// Each write returns false for a request that lacks a parameter, and
|
|
129
|
+
// `undefined` for one the simulator has no answer for.
|
|
130
|
+
const writes = {
|
|
131
|
+
"/aircon/set_control_info": (query) => {
|
|
132
|
+
if (!hasEvery(query, REQUIRED_CONTROL_PARAMETERS)) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
for (const [name, value] of Object.entries(query)) {
|
|
136
|
+
if (CONTROL_PARAMETER_PATTERN.test(name) && name in controlInfo) {
|
|
137
|
+
controlInfo[name] = value;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
remember(controlInfo);
|
|
141
|
+
return true;
|
|
142
|
+
},
|
|
143
|
+
"/aircon/set_zone_setting": (query) => {
|
|
144
|
+
if (!hasZones()) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
if (!hasEvery(query, ZONE_PARAMETERS)) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
for (const name of [...ZONE_PARAMETERS, ...ZONE_TEMPERATURE_PARAMETERS]) {
|
|
151
|
+
const value = query[name];
|
|
152
|
+
if (value !== undefined && name in zoneSetting) {
|
|
153
|
+
zoneSetting[name] = encodeURIComponent(value);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return true;
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
const answer = (request) => {
|
|
160
|
+
if (!request.path.startsWith(`${ROOT}/`)) {
|
|
161
|
+
return NOT_FOUND;
|
|
162
|
+
}
|
|
163
|
+
if (request.method !== "GET") {
|
|
164
|
+
return unanswered(request);
|
|
165
|
+
}
|
|
166
|
+
const path = request.path.slice(ROOT.length);
|
|
167
|
+
const fields = reads[path]?.();
|
|
168
|
+
if (fields !== undefined) {
|
|
169
|
+
return reply("OK", fields);
|
|
170
|
+
}
|
|
171
|
+
const written = writes[path]?.(request.query);
|
|
172
|
+
return written === undefined
|
|
173
|
+
? unanswered(request)
|
|
174
|
+
: reply(written ? "OK" : "PARAM NG");
|
|
175
|
+
};
|
|
176
|
+
// The discovery reply carries the fields of `basic_info`.
|
|
177
|
+
const server = await startSimulator(options, answer, () => basicInfo);
|
|
178
|
+
return {
|
|
179
|
+
...server,
|
|
180
|
+
basicInfo,
|
|
181
|
+
modelInfo,
|
|
182
|
+
controlInfo,
|
|
183
|
+
sensorInfo,
|
|
184
|
+
zoneSetting,
|
|
185
|
+
setState,
|
|
186
|
+
setSensors,
|
|
187
|
+
setZone,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
// The `get_model_info` fields that say what `unit` has. A field `unit` leaves
|
|
191
|
+
// out is left to the defaults.
|
|
192
|
+
function encodeUnit(unit) {
|
|
193
|
+
const fields = {};
|
|
194
|
+
if (unit.zones !== undefined && unit.zones.length > 0) {
|
|
195
|
+
fields.en_zone = String(unit.zones.length);
|
|
196
|
+
}
|
|
197
|
+
if (unit.auto !== undefined) {
|
|
198
|
+
fields.en_auto = flag(unit.auto);
|
|
199
|
+
}
|
|
200
|
+
if (unit.dehumidify !== undefined) {
|
|
201
|
+
fields.en_dry = flag(unit.dehumidify);
|
|
202
|
+
}
|
|
203
|
+
if (unit.fan !== undefined) {
|
|
204
|
+
fields.en_frate = flag(unit.fan);
|
|
205
|
+
}
|
|
206
|
+
if (unit.fanLevels !== undefined) {
|
|
207
|
+
fields.frate_steps = String(unit.fanLevels);
|
|
208
|
+
}
|
|
209
|
+
if (unit.airside !== undefined) {
|
|
210
|
+
fields.en_airside = flag(unit.airside);
|
|
211
|
+
}
|
|
212
|
+
if (unit.swing !== undefined) {
|
|
213
|
+
fields.en_fdir = flag(unit.swing);
|
|
214
|
+
}
|
|
215
|
+
if (unit.coolTemperaturesInC !== undefined) {
|
|
216
|
+
fields.cool_l = unit.coolTemperaturesInC.min.toFixed(0);
|
|
217
|
+
fields.cool_h = unit.coolTemperaturesInC.max.toFixed(0);
|
|
218
|
+
}
|
|
219
|
+
if (unit.heatTemperaturesInC !== undefined) {
|
|
220
|
+
fields.heat_l = unit.heatTemperaturesInC.min.toFixed(0);
|
|
221
|
+
fields.heat_h = unit.heatTemperaturesInC.max.toFixed(0);
|
|
222
|
+
}
|
|
223
|
+
return fields;
|
|
224
|
+
}
|
|
225
|
+
// The `get_zone_setting` fields of a unit with these zones, each open. A unit
|
|
226
|
+
// without zones has none.
|
|
227
|
+
function encodeZones(names) {
|
|
228
|
+
return names.length === 0
|
|
229
|
+
? {}
|
|
230
|
+
: {
|
|
231
|
+
zone_name: encodeList(names),
|
|
232
|
+
zone_onoff: encodeList(names.map(() => flag(true))),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function encodeList(values) {
|
|
236
|
+
return encodeURIComponent(values.join(ZONE_SEPARATOR));
|
|
237
|
+
}
|
|
238
|
+
function decodeList(value) {
|
|
239
|
+
return value === undefined
|
|
240
|
+
? []
|
|
241
|
+
: decodeURIComponent(value).split(ZONE_SEPARATOR);
|
|
242
|
+
}
|
|
243
|
+
// The `basic_info` fields: the name percent-encoded, the MAC address without
|
|
244
|
+
// its colons, and the version with underscores for its dots.
|
|
245
|
+
function encodeDeviceInfo(info) {
|
|
246
|
+
return {
|
|
247
|
+
...(info.name === undefined ? {} : { name: encodeURIComponent(info.name) }),
|
|
248
|
+
...(info.macAddress === undefined
|
|
249
|
+
? {}
|
|
250
|
+
: { mac: info.macAddress.replaceAll(":", "") }),
|
|
251
|
+
...(info.firmwareVersion === undefined
|
|
252
|
+
? {}
|
|
253
|
+
: { ver: info.firmwareVersion.replaceAll(".", "_") }),
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function encodeSensors(sensors) {
|
|
257
|
+
const fields = {};
|
|
258
|
+
const { indoorTemperatureInC, outdoorTemperatureInC, indoorHumidityInPercent, } = sensors;
|
|
259
|
+
if (indoorTemperatureInC !== undefined) {
|
|
260
|
+
fields.htemp = indoorTemperatureInC?.toFixed(1) ?? NO_READING;
|
|
261
|
+
}
|
|
262
|
+
if (outdoorTemperatureInC !== undefined) {
|
|
263
|
+
fields.otemp = outdoorTemperatureInC?.toFixed(1) ?? NO_READING;
|
|
264
|
+
}
|
|
265
|
+
if (indoorHumidityInPercent !== undefined) {
|
|
266
|
+
fields.hhum = indoorHumidityInPercent?.toFixed(0) ?? NO_READING;
|
|
267
|
+
}
|
|
268
|
+
return fields;
|
|
269
|
+
}
|
|
270
|
+
// Changes `controlInfo` as the unit's wall controller would: see
|
|
271
|
+
// `DaikinSimulator.setState`.
|
|
272
|
+
function applyState(controlInfo, state) {
|
|
273
|
+
for (const field of [
|
|
274
|
+
"targetHumidity",
|
|
275
|
+
"verticalPosition",
|
|
276
|
+
"horizontalPosition",
|
|
277
|
+
]) {
|
|
278
|
+
if (state[field] != null) {
|
|
279
|
+
throw new Error(`The simulated unit has no ${field} to set`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (state.specialModes != null && state.specialModes.length > 0) {
|
|
283
|
+
throw new Error("The simulated unit has no specialModes to set");
|
|
284
|
+
}
|
|
285
|
+
if (state.power != null) {
|
|
286
|
+
controlInfo.pow = flag(state.power);
|
|
287
|
+
}
|
|
288
|
+
if (state.mode != null &&
|
|
289
|
+
AIRBASE_OPERATING_MODE_CODES[state.mode] !== controlInfo.mode) {
|
|
290
|
+
controlInfo.mode = AIRBASE_OPERATING_MODE_CODES[state.mode];
|
|
291
|
+
recall(controlInfo);
|
|
292
|
+
}
|
|
293
|
+
if (state.targetTemperatureInC != null) {
|
|
294
|
+
controlInfo.stemp = state.targetTemperatureInC.toFixed(1);
|
|
295
|
+
}
|
|
296
|
+
if (state.fanSpeed != null) {
|
|
297
|
+
controlInfo.f_rate = AIRBASE_FAN_SPEED_CODES[state.fanSpeed];
|
|
298
|
+
}
|
|
299
|
+
if (state.swingMode != null) {
|
|
300
|
+
controlInfo.f_dir = AIRBASE_SWING_MODE_CODES[state.swingMode];
|
|
301
|
+
}
|
|
302
|
+
remember(controlInfo);
|
|
303
|
+
}
|
|
304
|
+
// The unit remembers a setpoint, a fan and a direction for cool and for heat
|
|
305
|
+
// alone, and every other mode runs on the one `bk_auto` names. A unit set to
|
|
306
|
+
// cool or to heat names that mode there.
|
|
307
|
+
function memoryOf(controlInfo) {
|
|
308
|
+
if (controlInfo.mode === COOL || controlInfo.mode === HEAT) {
|
|
309
|
+
controlInfo.bk_auto = controlInfo.mode;
|
|
310
|
+
}
|
|
311
|
+
return controlInfo.bk_auto === HEAT ? HEAT : COOL;
|
|
312
|
+
}
|
|
313
|
+
// Takes up what the unit remembers for the mode it is now in. Dehumidify has
|
|
314
|
+
// no setpoint.
|
|
315
|
+
function recall(controlInfo) {
|
|
316
|
+
const memory = memoryOf(controlInfo);
|
|
317
|
+
for (const [prefix, field] of Object.entries(MEMORY_FIELDS)) {
|
|
318
|
+
const remembered = controlInfo[`${prefix}${memory}`];
|
|
319
|
+
if (remembered !== undefined) {
|
|
320
|
+
controlInfo[field] = remembered;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (controlInfo.mode === AIRBASE_OPERATING_MODE_CODES.dehumidify) {
|
|
324
|
+
controlInfo.stemp = AIRBASE_NO_SETPOINT;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// Keeps what the unit remembers for the mode it runs on equal to what it
|
|
328
|
+
// holds. A setpoint is remembered in cool and in heat alone.
|
|
329
|
+
function remember(controlInfo) {
|
|
330
|
+
const memory = memoryOf(controlInfo);
|
|
331
|
+
for (const [prefix, field] of Object.entries(MEMORY_FIELDS)) {
|
|
332
|
+
const value = controlInfo[field];
|
|
333
|
+
const isSetpoint = prefix === "dt";
|
|
334
|
+
if (`${prefix}${memory}` in controlInfo &&
|
|
335
|
+
value !== undefined &&
|
|
336
|
+
(!isSetpoint || controlInfo.mode === memory)) {
|
|
337
|
+
controlInfo[`${prefix}${memory}`] = value;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const NOT_FOUND = { statusCode: 404, body: "" };
|
|
342
|
+
// An Airbase adapter answers HTTP 200 whatever the `ret`.
|
|
343
|
+
function reply(ret, fields) {
|
|
344
|
+
return { statusCode: 200, body: formatKeyValue(ret, fields) };
|
|
345
|
+
}
|
|
346
|
+
function flag(on) {
|
|
347
|
+
return on ? "1" : "0";
|
|
348
|
+
}
|
|
349
|
+
function hasEvery(query, names) {
|
|
350
|
+
return names.every((name) => name in query);
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=airbase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"airbase.js","sourceRoot":"","sources":["../../src/simulators/airbase.ts"],"names":[],"mappings":"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"}
|