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.
Files changed (150) hide show
  1. package/DESIGN.md +156 -2
  2. package/README.md +274 -48
  3. package/UNSUPPORTED.md +66 -3
  4. package/dist/clients/airbase.d.ts +64 -0
  5. package/dist/clients/airbase.d.ts.map +1 -0
  6. package/dist/clients/airbase.js +175 -0
  7. package/dist/clients/airbase.js.map +1 -0
  8. package/dist/clients/classic.d.ts +2 -2
  9. package/dist/clients/classic.d.ts.map +1 -1
  10. package/dist/clients/classic.js +4 -4
  11. package/dist/clients/classic.js.map +1 -1
  12. package/dist/clients/client.d.ts +7 -2
  13. package/dist/clients/client.d.ts.map +1 -1
  14. package/dist/clients/dsiot.d.ts +3 -1
  15. package/dist/clients/dsiot.d.ts.map +1 -1
  16. package/dist/clients/dsiot.js +7 -2
  17. package/dist/clients/dsiot.js.map +1 -1
  18. package/dist/codecs/airbase/capabilities.d.ts +23 -0
  19. package/dist/codecs/airbase/capabilities.d.ts.map +1 -0
  20. package/dist/codecs/airbase/capabilities.js +108 -0
  21. package/dist/codecs/airbase/capabilities.js.map +1 -0
  22. package/dist/codecs/airbase/state.d.ts +29 -0
  23. package/dist/codecs/airbase/state.d.ts.map +1 -0
  24. package/dist/codecs/airbase/state.js +166 -0
  25. package/dist/codecs/airbase/state.js.map +1 -0
  26. package/dist/codecs/airbase/tables.d.ts +7 -0
  27. package/dist/codecs/airbase/tables.d.ts.map +1 -0
  28. package/dist/codecs/airbase/tables.js +27 -0
  29. package/dist/codecs/airbase/tables.js.map +1 -0
  30. package/dist/codecs/airbase/zone.d.ts +12 -0
  31. package/dist/codecs/airbase/zone.d.ts.map +1 -0
  32. package/dist/codecs/airbase/zone.js +50 -0
  33. package/dist/codecs/airbase/zone.js.map +1 -0
  34. package/dist/codecs/classic/capabilities.d.ts.map +1 -1
  35. package/dist/codecs/classic/capabilities.js +5 -11
  36. package/dist/codecs/classic/capabilities.js.map +1 -1
  37. package/dist/codecs/classic/extendedControl.d.ts.map +1 -1
  38. package/dist/codecs/classic/extendedControl.js +10 -19
  39. package/dist/codecs/classic/extendedControl.js.map +1 -1
  40. package/dist/codecs/classic/state.d.ts.map +1 -1
  41. package/dist/codecs/classic/state.js +36 -95
  42. package/dist/codecs/classic/state.js.map +1 -1
  43. package/dist/codecs/classic/tables.d.ts +34 -0
  44. package/dist/codecs/classic/tables.d.ts.map +1 -0
  45. package/dist/codecs/classic/tables.js +96 -0
  46. package/dist/codecs/classic/tables.js.map +1 -0
  47. package/dist/codecs/credentials.d.ts +3 -2
  48. package/dist/codecs/credentials.d.ts.map +1 -1
  49. package/dist/codecs/credentials.js +8 -3
  50. package/dist/codecs/credentials.js.map +1 -1
  51. package/dist/codecs/device.d.ts +7 -1
  52. package/dist/codecs/device.d.ts.map +1 -1
  53. package/dist/codecs/device.js +15 -3
  54. package/dist/codecs/device.js.map +1 -1
  55. package/dist/codecs/dsiot/capabilities.d.ts.map +1 -1
  56. package/dist/codecs/dsiot/capabilities.js +8 -15
  57. package/dist/codecs/dsiot/capabilities.js.map +1 -1
  58. package/dist/codecs/dsiot/device.d.ts.map +1 -1
  59. package/dist/codecs/dsiot/device.js +4 -8
  60. package/dist/codecs/dsiot/device.js.map +1 -1
  61. package/dist/codecs/dsiot/multireq.d.ts +0 -19
  62. package/dist/codecs/dsiot/multireq.d.ts.map +1 -1
  63. package/dist/codecs/dsiot/multireq.js +2 -25
  64. package/dist/codecs/dsiot/multireq.js.map +1 -1
  65. package/dist/codecs/dsiot/state.d.ts +6 -62
  66. package/dist/codecs/dsiot/state.d.ts.map +1 -1
  67. package/dist/codecs/dsiot/state.js +29 -148
  68. package/dist/codecs/dsiot/state.js.map +1 -1
  69. package/dist/codecs/dsiot/tables.d.ts +119 -0
  70. package/dist/codecs/dsiot/tables.d.ts.map +1 -0
  71. package/dist/codecs/dsiot/tables.js +188 -0
  72. package/dist/codecs/dsiot/tables.js.map +1 -0
  73. package/dist/discovery.d.ts +20 -9
  74. package/dist/discovery.d.ts.map +1 -1
  75. package/dist/discovery.js +102 -32
  76. package/dist/discovery.js.map +1 -1
  77. package/dist/factory.d.ts +13 -7
  78. package/dist/factory.d.ts.map +1 -1
  79. package/dist/factory.js +16 -4
  80. package/dist/factory.js.map +1 -1
  81. package/dist/index.d.ts +8 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +8 -0
  84. package/dist/index.js.map +1 -1
  85. package/dist/models/device.d.ts +3 -2
  86. package/dist/models/device.d.ts.map +1 -1
  87. package/dist/models/device.js +1 -1
  88. package/dist/models/device.js.map +1 -1
  89. package/dist/models/state.d.ts +2 -3
  90. package/dist/models/state.d.ts.map +1 -1
  91. package/dist/models/zone.d.ts +9 -0
  92. package/dist/models/zone.d.ts.map +1 -0
  93. package/dist/models/zone.js +2 -0
  94. package/dist/models/zone.js.map +1 -0
  95. package/dist/simulators/airbase.d.ts +82 -0
  96. package/dist/simulators/airbase.d.ts.map +1 -0
  97. package/dist/simulators/airbase.js +352 -0
  98. package/dist/simulators/airbase.js.map +1 -0
  99. package/dist/simulators/classic.d.ts +61 -0
  100. package/dist/simulators/classic.d.ts.map +1 -0
  101. package/dist/simulators/classic.js +473 -0
  102. package/dist/simulators/classic.js.map +1 -0
  103. package/dist/simulators/dsiot.d.ts +49 -0
  104. package/dist/simulators/dsiot.d.ts.map +1 -0
  105. package/dist/simulators/dsiot.js +519 -0
  106. package/dist/simulators/dsiot.js.map +1 -0
  107. package/dist/simulators/index.d.ts +5 -0
  108. package/dist/simulators/index.d.ts.map +1 -0
  109. package/dist/simulators/index.js +4 -0
  110. package/dist/simulators/index.js.map +1 -0
  111. package/dist/simulators/simulator.d.ts +117 -0
  112. package/dist/simulators/simulator.d.ts.map +1 -0
  113. package/dist/simulators/simulator.js +141 -0
  114. package/dist/simulators/simulator.js.map +1 -0
  115. package/dist/transport.d.ts +8 -3
  116. package/dist/transport.d.ts.map +1 -1
  117. package/dist/transport.js +10 -2
  118. package/dist/transport.js.map +1 -1
  119. package/package.json +11 -4
  120. package/src/clients/airbase.ts +274 -0
  121. package/src/clients/classic.ts +8 -8
  122. package/src/clients/client.ts +8 -1
  123. package/src/clients/dsiot.ts +8 -1
  124. package/src/codecs/airbase/capabilities.ts +150 -0
  125. package/src/codecs/airbase/state.ts +223 -0
  126. package/src/codecs/airbase/tables.ts +32 -0
  127. package/src/codecs/airbase/zone.ts +62 -0
  128. package/src/codecs/classic/capabilities.ts +8 -11
  129. package/src/codecs/classic/extendedControl.ts +14 -25
  130. package/src/codecs/classic/state.ts +49 -101
  131. package/src/codecs/classic/tables.ts +126 -0
  132. package/src/codecs/credentials.ts +11 -3
  133. package/src/codecs/device.ts +19 -3
  134. package/src/codecs/dsiot/capabilities.ts +10 -17
  135. package/src/codecs/dsiot/device.ts +4 -9
  136. package/src/codecs/dsiot/multireq.ts +2 -25
  137. package/src/codecs/dsiot/state.ts +57 -193
  138. package/src/codecs/dsiot/tables.ts +253 -0
  139. package/src/discovery.ts +107 -34
  140. package/src/factory.ts +26 -7
  141. package/src/index.ts +8 -0
  142. package/src/models/device.ts +3 -2
  143. package/src/models/state.ts +2 -3
  144. package/src/models/zone.ts +8 -0
  145. package/src/simulators/airbase.ts +495 -0
  146. package/src/simulators/classic.ts +636 -0
  147. package/src/simulators/dsiot.ts +736 -0
  148. package/src/simulators/index.ts +10 -0
  149. package/src/simulators/simulator.ts +282 -0
  150. 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
@@ -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"}
@@ -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;AAE9D;;uEAEuE;AACvE,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"}
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"}
@@ -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"}
@@ -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`: a
54
- * classic adapter is set one with `ClassicDaikinClient.setSpecialMode`, and
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;;;;;;2DAM2D;AAC3D,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"}
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=zone.js.map
@@ -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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"}