daikin-local-control 0.3.0 → 0.4.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 (114) hide show
  1. package/DESIGN.md +113 -2
  2. package/README.md +131 -13
  3. package/UNSUPPORTED.md +42 -4
  4. package/dist/clients/classic.d.ts +2 -2
  5. package/dist/clients/classic.d.ts.map +1 -1
  6. package/dist/clients/classic.js +4 -4
  7. package/dist/clients/classic.js.map +1 -1
  8. package/dist/clients/client.d.ts +6 -2
  9. package/dist/clients/client.d.ts.map +1 -1
  10. package/dist/clients/dsiot.d.ts +3 -1
  11. package/dist/clients/dsiot.d.ts.map +1 -1
  12. package/dist/clients/dsiot.js +11 -3
  13. package/dist/clients/dsiot.js.map +1 -1
  14. package/dist/codecs/classic/capabilities.d.ts.map +1 -1
  15. package/dist/codecs/classic/capabilities.js +5 -11
  16. package/dist/codecs/classic/capabilities.js.map +1 -1
  17. package/dist/codecs/classic/extendedControl.d.ts.map +1 -1
  18. package/dist/codecs/classic/extendedControl.js +10 -19
  19. package/dist/codecs/classic/extendedControl.js.map +1 -1
  20. package/dist/codecs/classic/state.d.ts.map +1 -1
  21. package/dist/codecs/classic/state.js +36 -95
  22. package/dist/codecs/classic/state.js.map +1 -1
  23. package/dist/codecs/classic/tables.d.ts +32 -0
  24. package/dist/codecs/classic/tables.d.ts.map +1 -0
  25. package/dist/codecs/classic/tables.js +94 -0
  26. package/dist/codecs/classic/tables.js.map +1 -0
  27. package/dist/codecs/credentials.d.ts +3 -2
  28. package/dist/codecs/credentials.d.ts.map +1 -1
  29. package/dist/codecs/credentials.js +8 -3
  30. package/dist/codecs/credentials.js.map +1 -1
  31. package/dist/codecs/device.d.ts +2 -1
  32. package/dist/codecs/device.d.ts.map +1 -1
  33. package/dist/codecs/device.js +7 -6
  34. package/dist/codecs/device.js.map +1 -1
  35. package/dist/codecs/dsiot/capabilities.d.ts.map +1 -1
  36. package/dist/codecs/dsiot/capabilities.js +8 -15
  37. package/dist/codecs/dsiot/capabilities.js.map +1 -1
  38. package/dist/codecs/dsiot/device.d.ts +4 -2
  39. package/dist/codecs/dsiot/device.d.ts.map +1 -1
  40. package/dist/codecs/dsiot/device.js +8 -8
  41. package/dist/codecs/dsiot/device.js.map +1 -1
  42. package/dist/codecs/dsiot/multireq.d.ts +0 -18
  43. package/dist/codecs/dsiot/multireq.d.ts.map +1 -1
  44. package/dist/codecs/dsiot/multireq.js +2 -24
  45. package/dist/codecs/dsiot/multireq.js.map +1 -1
  46. package/dist/codecs/dsiot/state.d.ts +6 -62
  47. package/dist/codecs/dsiot/state.d.ts.map +1 -1
  48. package/dist/codecs/dsiot/state.js +29 -148
  49. package/dist/codecs/dsiot/state.js.map +1 -1
  50. package/dist/codecs/dsiot/tables.d.ts +116 -0
  51. package/dist/codecs/dsiot/tables.d.ts.map +1 -0
  52. package/dist/codecs/dsiot/tables.js +185 -0
  53. package/dist/codecs/dsiot/tables.js.map +1 -0
  54. package/dist/discovery.d.ts +2 -1
  55. package/dist/discovery.d.ts.map +1 -1
  56. package/dist/discovery.js +9 -5
  57. package/dist/discovery.js.map +1 -1
  58. package/dist/factory.d.ts +7 -4
  59. package/dist/factory.d.ts.map +1 -1
  60. package/dist/factory.js +4 -2
  61. package/dist/factory.js.map +1 -1
  62. package/dist/index.d.ts +2 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +2 -0
  65. package/dist/index.js.map +1 -1
  66. package/dist/models/device.d.ts +3 -1
  67. package/dist/models/device.d.ts.map +1 -1
  68. package/dist/models/state.d.ts +2 -3
  69. package/dist/models/state.d.ts.map +1 -1
  70. package/dist/simulators/classic.d.ts +61 -0
  71. package/dist/simulators/classic.d.ts.map +1 -0
  72. package/dist/simulators/classic.js +473 -0
  73. package/dist/simulators/classic.js.map +1 -0
  74. package/dist/simulators/dsiot.d.ts +49 -0
  75. package/dist/simulators/dsiot.d.ts.map +1 -0
  76. package/dist/simulators/dsiot.js +519 -0
  77. package/dist/simulators/dsiot.js.map +1 -0
  78. package/dist/simulators/index.d.ts +4 -0
  79. package/dist/simulators/index.d.ts.map +1 -0
  80. package/dist/simulators/index.js +3 -0
  81. package/dist/simulators/index.js.map +1 -0
  82. package/dist/simulators/simulator.d.ts +116 -0
  83. package/dist/simulators/simulator.d.ts.map +1 -0
  84. package/dist/simulators/simulator.js +141 -0
  85. package/dist/simulators/simulator.js.map +1 -0
  86. package/dist/transport.d.ts +6 -2
  87. package/dist/transport.d.ts.map +1 -1
  88. package/dist/transport.js +7 -2
  89. package/dist/transport.js.map +1 -1
  90. package/package.json +5 -2
  91. package/src/clients/classic.ts +8 -8
  92. package/src/clients/client.ts +7 -1
  93. package/src/clients/dsiot.ts +12 -2
  94. package/src/codecs/classic/capabilities.ts +8 -11
  95. package/src/codecs/classic/extendedControl.ts +14 -25
  96. package/src/codecs/classic/state.ts +49 -101
  97. package/src/codecs/classic/tables.ts +123 -0
  98. package/src/codecs/credentials.ts +11 -3
  99. package/src/codecs/device.ts +8 -7
  100. package/src/codecs/dsiot/capabilities.ts +10 -17
  101. package/src/codecs/dsiot/device.ts +8 -9
  102. package/src/codecs/dsiot/multireq.ts +2 -24
  103. package/src/codecs/dsiot/state.ts +57 -193
  104. package/src/codecs/dsiot/tables.ts +249 -0
  105. package/src/discovery.ts +9 -5
  106. package/src/factory.ts +7 -4
  107. package/src/index.ts +2 -0
  108. package/src/models/device.ts +3 -1
  109. package/src/models/state.ts +2 -3
  110. package/src/simulators/classic.ts +635 -0
  111. package/src/simulators/dsiot.ts +736 -0
  112. package/src/simulators/index.ts +9 -0
  113. package/src/simulators/simulator.ts +281 -0
  114. package/src/transport.ts +10 -3
@@ -0,0 +1,473 @@
1
+ import { CLASSIC_COOLING_ONLY_TYPE, CLASSIC_FAN_SPEED_CODES, CLASSIC_HORIZONTAL_POSITION_CODES, CLASSIC_HUMIDITY_SETTING_CODES, CLASSIC_LOUVER_STOP, CLASSIC_LOUVER_SWING, CLASSIC_NO_SETPOINT, CLASSIC_OPERATING_MODE_CODES, CLASSIC_REMOTE_METHODS, CLASSIC_SPECIAL_MODE_ADV_CODES, CLASSIC_SPECIAL_MODE_BITS, CLASSIC_SPECIAL_MODE_KIND_CODES, CLASSIC_SWING_MODE_CODES, CLASSIC_TERMINAL_SCOPE_CODES, CLASSIC_VERTICAL_POSITION_CODES, } from "../codecs/classic/tables.js";
2
+ import { formatKeyValue, startSimulator, unanswered, } from "./simulator.js";
3
+ // A classic adapter (BRP069, BRP072) as an HTTP server. It reads the adapter's
4
+ // codes from the codecs' tables and shares none of their functions: see
5
+ // DESIGN.md#simulators.
6
+ const DEFAULT_BASIC_INFO = {
7
+ type: "aircon",
8
+ reg: "th",
9
+ ver: "1_2_51",
10
+ name: "Simulator",
11
+ icon: "0",
12
+ method: CLASSIC_REMOTE_METHODS.homeOnly,
13
+ adp_kind: "4",
14
+ cpv: "3",
15
+ cpv_minor: "20",
16
+ led: "1",
17
+ mac: "02DA1C000001",
18
+ en_hol: "0",
19
+ grp_name: "",
20
+ en_grp: "0",
21
+ };
22
+ const DEFAULT_MODEL_INFO = {
23
+ model: "0ABB",
24
+ type: "N",
25
+ en_frate: "1",
26
+ en_frate_auto: "1",
27
+ en_frate_silent: "1",
28
+ frate_steps: "5",
29
+ en_fdir: "1",
30
+ s_fdir: "3",
31
+ s_humd: "0",
32
+ en_spmode: "7",
33
+ elec: "1",
34
+ dmnd: "1",
35
+ en_scdltmr: "1",
36
+ };
37
+ const DEFAULT_CONTROL_INFO = {
38
+ pow: "0",
39
+ mode: "3",
40
+ adv: "",
41
+ stemp: "24.0",
42
+ shum: "0",
43
+ dt1: "25.0",
44
+ dt2: "M",
45
+ dt3: "24.0",
46
+ dt4: "25.0",
47
+ dh1: "0",
48
+ dh2: "0",
49
+ dh3: "0",
50
+ dh4: "0",
51
+ f_rate: "A",
52
+ f_dir: "0",
53
+ dfr1: "A",
54
+ dfr2: "A",
55
+ dfr3: "A",
56
+ dfr4: "A",
57
+ dfr6: "A",
58
+ dfd1: "0",
59
+ dfd2: "0",
60
+ dfd3: "0",
61
+ dfd4: "0",
62
+ dfd6: "0",
63
+ };
64
+ const DEFAULT_SENSOR_INFO = {
65
+ htemp: "26.0",
66
+ hhum: "55",
67
+ otemp: "30.0",
68
+ };
69
+ const DEFAULT_REMOTE_METHOD = {
70
+ notice_ip_int: "3600",
71
+ notice_sync_int: "60",
72
+ };
73
+ const REGISTER_TERMINAL_PATH = "/common/register_terminal";
74
+ // A `set_control_info` without one of these is answered `PARAM NG`. `shum`
75
+ // joins them on a unit whose `get_control_info` reports it.
76
+ const REQUIRED_CONTROL_PARAMETERS = ["pow", "mode", "stemp", "f_rate"];
77
+ // The parameters `set_control_info` stores: the control fields, and the
78
+ // memory of a mode by name, such as `dt3` and `dfd4`.
79
+ const CONTROL_PARAMETER_PATTERN = /^(pow|mode|stemp|shum|f_rate|f_dir|f_dir_ud|f_dir_lr|(dt|dh|dfd)\w)$/;
80
+ // The control field each memory prefix remembers: `dt3` holds the `stemp` of
81
+ // mode 3.
82
+ const MODE_MEMORY_FIELDS = {
83
+ dt: "stemp",
84
+ dh: "shum",
85
+ dfr: "f_rate",
86
+ dfd: "f_dir",
87
+ };
88
+ // `spmode_kind` 4 is heat plus, which `adv` reports as 4. It is outside
89
+ // `SpecialMode`: see UNSUPPORTED.md.
90
+ const HEAT_PLUS_KIND_CODE = "4";
91
+ const HEAT_PLUS_ADV_CODE = "4";
92
+ // Powerful, econo and heat plus replace one another in `adv`.
93
+ const ADV_CODES_BY_SPECIAL_MODE_KIND = {
94
+ [CLASSIC_SPECIAL_MODE_KIND_CODES.powerful]: CLASSIC_SPECIAL_MODE_ADV_CODES.powerful,
95
+ [CLASSIC_SPECIAL_MODE_KIND_CODES.econo]: CLASSIC_SPECIAL_MODE_ADV_CODES.econo,
96
+ [HEAT_PLUS_KIND_CODE]: HEAT_PLUS_ADV_CODE,
97
+ };
98
+ // A sensor field the unit has no reading for.
99
+ const NO_READING = "-";
100
+ // `type` in `get_model_info` on a heat pump.
101
+ const HEAT_PUMP_TYPE = "N";
102
+ // `s_fdir`: the axes the louvers swing on.
103
+ const SWING_AXES_CODES = { none: "0", vertical: "1", both: "3" };
104
+ /** Starts a classic adapter on a free port, as a heat pump that is off, in
105
+ * cool at 24 °C. It answers the endpoints `ClassicDaikinClient` has a typed
106
+ * method for, over HTTP, and answers any other request with HTTP 501:
107
+ * UNSUPPORTED.md lists what it leaves out and where its answer is not known
108
+ * to be an adapter's. Call `stop` when done with it. */
109
+ export async function startClassicSimulator(options = {}) {
110
+ const basicInfo = {
111
+ ...DEFAULT_BASIC_INFO,
112
+ lpw_flag: flag(options.localPassword !== undefined),
113
+ ...(options.key === undefined ? {} : { en_secure: "1" }),
114
+ ...options.basicInfo,
115
+ };
116
+ const modelInfo = {
117
+ ...DEFAULT_MODEL_INFO,
118
+ ...encodeUnit(options.unit ?? {}),
119
+ ...options.modelInfo,
120
+ };
121
+ const controlInfo = { ...DEFAULT_CONTROL_INFO, ...options.controlInfo };
122
+ const sensorInfo = { ...DEFAULT_SENSOR_INFO, ...options.sensorInfo };
123
+ const remoteMethod = { ...DEFAULT_REMOTE_METHOD };
124
+ const registeredTerminalUuids = new Set();
125
+ const setState = (state) => applyState(controlInfo, state);
126
+ const setSensors = (sensors) => Object.assign(sensorInfo, encodeSensors(sensors));
127
+ // Before the server starts, so a state that throws leaves nothing
128
+ // listening.
129
+ Object.assign(basicInfo, encodeDeviceInfo(options.deviceInfo ?? {}));
130
+ setState(options.state ?? {});
131
+ setSensors(options.sensors ?? {});
132
+ const reads = {
133
+ "/common/basic_info": basicInfo,
134
+ "/common/get_remote_method": remoteMethod,
135
+ "/aircon/get_model_info": modelInfo,
136
+ "/aircon/get_control_info": controlInfo,
137
+ "/aircon/get_sensor_info": sensorInfo,
138
+ };
139
+ // Each write returns false for a request that lacks a parameter.
140
+ const writes = {
141
+ "/aircon/set_control_info": (query) => {
142
+ const required = "shum" in controlInfo
143
+ ? [...REQUIRED_CONTROL_PARAMETERS, "shum"]
144
+ : REQUIRED_CONTROL_PARAMETERS;
145
+ if (!hasEvery(query, required)) {
146
+ return false;
147
+ }
148
+ for (const [name, value] of Object.entries(query)) {
149
+ if (CONTROL_PARAMETER_PATTERN.test(name) && name in controlInfo) {
150
+ controlInfo[name] = value;
151
+ }
152
+ }
153
+ rememberMode(controlInfo);
154
+ return true;
155
+ },
156
+ "/aircon/set_special_mode": (query) => {
157
+ const codes = new Set(controlInfo.adv?.split("/").filter(Boolean));
158
+ const kindCode = ADV_CODES_BY_SPECIAL_MODE_KIND[query.spmode_kind ?? ""];
159
+ if (query.en_streamer !== undefined) {
160
+ codes.delete(CLASSIC_SPECIAL_MODE_ADV_CODES.streamer);
161
+ if (query.en_streamer === "1") {
162
+ codes.add(CLASSIC_SPECIAL_MODE_ADV_CODES.streamer);
163
+ }
164
+ }
165
+ else if (query.set_spmode !== undefined && kindCode !== undefined) {
166
+ for (const code of Object.values(ADV_CODES_BY_SPECIAL_MODE_KIND)) {
167
+ codes.delete(code);
168
+ }
169
+ if (query.set_spmode === "1") {
170
+ codes.add(kindCode);
171
+ }
172
+ }
173
+ else {
174
+ return false;
175
+ }
176
+ controlInfo.adv = [...codes]
177
+ .sort((first, second) => Number(first) - Number(second))
178
+ .join("/");
179
+ return true;
180
+ },
181
+ "/aircon/set_demand_control": (query) => hasEvery(query, ["demand_type", "en_demand", "mode", "max_pow"]),
182
+ "/aircon/set_price": (query) => hasEvery(query, ["price_int", "price_dec"]),
183
+ "/aircon/set_target": (query) => hasEvery(query, ["target"]),
184
+ "/common/set_led": (query) => copy(query, basicInfo, ["led"]),
185
+ "/common/set_holiday": (query) => copy(query, basicInfo, ["en_hol"]),
186
+ "/common/set_icon": (query) => copy(query, basicInfo, ["icon"]),
187
+ "/common/set_name": (query) => {
188
+ if (query.name === undefined) {
189
+ return false;
190
+ }
191
+ basicInfo.name = encodeURIComponent(query.name);
192
+ return true;
193
+ },
194
+ "/common/set_group": (query) => {
195
+ if (query.grp_name === undefined || query.en_grp === undefined) {
196
+ return false;
197
+ }
198
+ basicInfo.grp_name = encodeURIComponent(query.grp_name);
199
+ basicInfo.en_grp = query.en_grp;
200
+ return true;
201
+ },
202
+ "/common/set_remote_method": (query) => {
203
+ if (!copy(query, basicInfo, ["method"])) {
204
+ return false;
205
+ }
206
+ for (const name of Object.keys(remoteMethod)) {
207
+ const value = query[name];
208
+ if (value !== undefined) {
209
+ remoteMethod[name] = value;
210
+ }
211
+ }
212
+ return true;
213
+ },
214
+ "/common/reboot": () => true,
215
+ "/common/unregister_terminal": (query, terminalUuid) => {
216
+ const others = [...registeredTerminalUuids].filter((uuid) => uuid !== terminalUuid);
217
+ if (query.type === CLASSIC_TERMINAL_SCOPE_CODES.self &&
218
+ terminalUuid !== undefined) {
219
+ registeredTerminalUuids.delete(terminalUuid);
220
+ }
221
+ else if (query.type === CLASSIC_TERMINAL_SCOPE_CODES.others) {
222
+ for (const uuid of others) {
223
+ registeredTerminalUuids.delete(uuid);
224
+ }
225
+ }
226
+ else if (query.type === CLASSIC_TERMINAL_SCOPE_CODES.all) {
227
+ registeredTerminalUuids.clear();
228
+ }
229
+ else {
230
+ return false;
231
+ }
232
+ return true;
233
+ },
234
+ };
235
+ const answer = (request) => {
236
+ const fields = reads[request.path];
237
+ const write = writes[request.path];
238
+ const registers = request.path === REGISTER_TERMINAL_PATH;
239
+ if (request.method !== "GET" ||
240
+ (fields === undefined && write === undefined && !registers)) {
241
+ return unanswered(request);
242
+ }
243
+ const terminalUuid = terminalUuidOf(request);
244
+ if (registers) {
245
+ if (options.key === undefined) {
246
+ return unanswered(request);
247
+ }
248
+ if (request.query.key !== options.key || terminalUuid === undefined) {
249
+ return FORBIDDEN;
250
+ }
251
+ registeredTerminalUuids.add(terminalUuid);
252
+ return reply("OK");
253
+ }
254
+ if (options.key !== undefined &&
255
+ (terminalUuid === undefined || !registeredTerminalUuids.has(terminalUuid))) {
256
+ return FORBIDDEN;
257
+ }
258
+ if (options.localPassword !== undefined &&
259
+ request.query.lpw !== options.localPassword) {
260
+ return reply("LPW NG");
261
+ }
262
+ if (fields !== undefined) {
263
+ return reply("OK", fields);
264
+ }
265
+ return reply(write?.(request.query, terminalUuid) ? "OK" : "PARAM NG");
266
+ };
267
+ // The discovery reply carries the fields of `basic_info`.
268
+ const server = await startSimulator(options, answer, () => basicInfo);
269
+ return {
270
+ ...server,
271
+ basicInfo,
272
+ modelInfo,
273
+ controlInfo,
274
+ sensorInfo,
275
+ remoteMethod,
276
+ registeredTerminalUuids,
277
+ setState,
278
+ setSensors,
279
+ };
280
+ }
281
+ // The `get_model_info` fields that say what `unit` has. A field `unit` leaves
282
+ // out is left to the defaults.
283
+ function encodeUnit(unit) {
284
+ const fields = {};
285
+ if (unit.coolingOnly !== undefined) {
286
+ fields.type = unit.coolingOnly ? CLASSIC_COOLING_ONLY_TYPE : HEAT_PUMP_TYPE;
287
+ }
288
+ if (unit.fan !== undefined) {
289
+ fields.en_frate = flag(unit.fan);
290
+ }
291
+ if (unit.fanLevels !== undefined) {
292
+ fields.frate_steps = String(unit.fanLevels);
293
+ }
294
+ if (unit.swing !== undefined) {
295
+ fields.en_fdir = flag(unit.swing !== "none");
296
+ fields.s_fdir = SWING_AXES_CODES[unit.swing];
297
+ }
298
+ if (unit.specialModes !== undefined) {
299
+ fields.en_spmode = String(unit.specialModes.reduce((bits, mode) => bits | CLASSIC_SPECIAL_MODE_BITS[mode], 0));
300
+ }
301
+ if (unit.coolTemperaturesInC !== undefined) {
302
+ fields.cmlmt_l = unit.coolTemperaturesInC.min.toFixed(1);
303
+ fields.cmlmt_h = unit.coolTemperaturesInC.max.toFixed(1);
304
+ }
305
+ if (unit.heatTemperaturesInC !== undefined) {
306
+ fields.hmlmt_l = unit.heatTemperaturesInC.min.toFixed(1);
307
+ fields.hmlmt_h = unit.heatTemperaturesInC.max.toFixed(1);
308
+ }
309
+ return fields;
310
+ }
311
+ // The `basic_info` fields: the name percent-encoded, the MAC address without
312
+ // its colons, and the version with underscores for its dots.
313
+ function encodeDeviceInfo(info) {
314
+ return {
315
+ ...(info.name === undefined ? {} : { name: encodeURIComponent(info.name) }),
316
+ ...(info.macAddress === undefined
317
+ ? {}
318
+ : { mac: info.macAddress.replaceAll(":", "") }),
319
+ ...(info.firmwareVersion === undefined
320
+ ? {}
321
+ : { ver: info.firmwareVersion.replaceAll(".", "_") }),
322
+ };
323
+ }
324
+ function encodeSensors(sensors) {
325
+ const fields = {};
326
+ const { indoorTemperatureInC, outdoorTemperatureInC, indoorHumidityInPercent, } = sensors;
327
+ if (indoorTemperatureInC !== undefined) {
328
+ fields.htemp = indoorTemperatureInC?.toFixed(1) ?? NO_READING;
329
+ }
330
+ if (outdoorTemperatureInC !== undefined) {
331
+ fields.otemp = outdoorTemperatureInC?.toFixed(1) ?? NO_READING;
332
+ }
333
+ if (indoorHumidityInPercent !== undefined) {
334
+ fields.hhum = indoorHumidityInPercent?.toFixed(0) ?? NO_READING;
335
+ }
336
+ return fields;
337
+ }
338
+ // Changes `controlInfo` as the unit's remote control would: see
339
+ // `DaikinSimulator.setState`.
340
+ function applyState(controlInfo, state) {
341
+ const hold = (field, value) => {
342
+ if (!(field in controlInfo)) {
343
+ throw new Error(`The simulated unit reports no ${field} to set`);
344
+ }
345
+ controlInfo[field] = value;
346
+ };
347
+ const hasLouvers = "f_dir_ud" in controlInfo && "f_dir_lr" in controlInfo;
348
+ if (state.power != null) {
349
+ hold("pow", flag(state.power));
350
+ }
351
+ if (state.mode != null &&
352
+ CLASSIC_OPERATING_MODE_CODES[state.mode] !== controlInfo.mode) {
353
+ controlInfo.mode = CLASSIC_OPERATING_MODE_CODES[state.mode];
354
+ recallMode(controlInfo);
355
+ }
356
+ if (state.targetTemperatureInC != null) {
357
+ hold("stemp", state.targetTemperatureInC.toFixed(1));
358
+ }
359
+ if (state.targetHumidity != null) {
360
+ hold("shum", typeof state.targetHumidity === "string"
361
+ ? CLASSIC_HUMIDITY_SETTING_CODES[state.targetHumidity]
362
+ : String(state.targetHumidity.percent));
363
+ }
364
+ if (state.fanSpeed != null) {
365
+ hold("f_rate", CLASSIC_FAN_SPEED_CODES[state.fanSpeed]);
366
+ }
367
+ if (state.swingMode != null) {
368
+ const swings = {
369
+ f_dir_ud: state.swingMode === "vertical" || state.swingMode === "both",
370
+ f_dir_lr: state.swingMode === "horizontal" || state.swingMode === "both",
371
+ };
372
+ if (hasLouvers) {
373
+ // An axis that stops swinging stops, and one at a fixed position
374
+ // keeps it.
375
+ for (const [field, swing] of Object.entries(swings)) {
376
+ if (swing) {
377
+ controlInfo[field] = CLASSIC_LOUVER_SWING;
378
+ }
379
+ else if (controlInfo[field] === CLASSIC_LOUVER_SWING) {
380
+ controlInfo[field] = CLASSIC_LOUVER_STOP;
381
+ }
382
+ }
383
+ }
384
+ else {
385
+ hold("f_dir", CLASSIC_SWING_MODE_CODES[state.swingMode]);
386
+ }
387
+ }
388
+ if (state.verticalPosition != null) {
389
+ hold("f_dir_ud", CLASSIC_VERTICAL_POSITION_CODES[state.verticalPosition]);
390
+ }
391
+ if (state.horizontalPosition != null) {
392
+ hold("f_dir_lr", CLASSIC_HORIZONTAL_POSITION_CODES[state.horizontalPosition]);
393
+ }
394
+ // `f_dir` sets bit 1 while the vertical louver swings and bit 2 while the
395
+ // horizontal one does.
396
+ if (hasLouvers && "f_dir" in controlInfo) {
397
+ controlInfo.f_dir = String((controlInfo.f_dir_ud === CLASSIC_LOUVER_SWING ? 1 : 0) |
398
+ (controlInfo.f_dir_lr === CLASSIC_LOUVER_SWING ? 2 : 0));
399
+ }
400
+ if (state.specialModes != null) {
401
+ hold("adv", state.specialModes
402
+ .map((mode) => Number(CLASSIC_SPECIAL_MODE_ADV_CODES[mode]))
403
+ .sort((first, second) => first - second)
404
+ .join("/"));
405
+ }
406
+ rememberMode(controlInfo);
407
+ }
408
+ // Takes up what the unit remembers for the mode it is now in. A mode without
409
+ // a `dt` or a `dh` has no setpoint or humidity setting.
410
+ function recallMode(controlInfo) {
411
+ const mode = controlInfo.mode ?? "";
412
+ for (const [prefix, field] of Object.entries(MODE_MEMORY_FIELDS)) {
413
+ if (field in controlInfo) {
414
+ controlInfo[field] =
415
+ controlInfo[`${prefix}${mode}`] ??
416
+ (prefix === "dt" || prefix === "dh"
417
+ ? CLASSIC_NO_SETPOINT
418
+ : (controlInfo[field] ?? ""));
419
+ }
420
+ }
421
+ const [vertical, horizontal] = controlInfo[`ndfd${mode}`] ?? "";
422
+ if ("f_dir_ud" in controlInfo && vertical !== undefined) {
423
+ controlInfo.f_dir_ud = vertical;
424
+ }
425
+ if ("f_dir_lr" in controlInfo && horizontal !== undefined) {
426
+ controlInfo.f_dir_lr = horizontal;
427
+ }
428
+ }
429
+ const FORBIDDEN = { statusCode: 403, body: "" };
430
+ // A classic adapter answers HTTP 200 whatever the `ret`.
431
+ function reply(ret, fields) {
432
+ return { statusCode: 200, body: formatKeyValue(ret, fields) };
433
+ }
434
+ function terminalUuidOf(request) {
435
+ const header = request.headers["x-daikin-uuid"];
436
+ return typeof header === "string" ? header : undefined;
437
+ }
438
+ function flag(on) {
439
+ return on ? "1" : "0";
440
+ }
441
+ function hasEvery(query, names) {
442
+ return names.every((name) => name in query);
443
+ }
444
+ function copy(query, fields, names) {
445
+ if (!hasEvery(query, names)) {
446
+ return false;
447
+ }
448
+ for (const name of names) {
449
+ fields[name] = query[name] ?? "";
450
+ }
451
+ return true;
452
+ }
453
+ // An adapter remembers the setpoint, humidity, fan speed and direction of
454
+ // each mode, and answers them as `dt3`, `dh3`, `dfr3` and `dfd3` for mode 3.
455
+ // It takes `dt`, `dh` and `dfd` as parameters and no `dfr`, so it keeps the
456
+ // memory of the mode the unit is in equal to what the unit holds. `ndfd3`
457
+ // holds the `f_dir_ud` value of mode 3, then its `f_dir_lr` value.
458
+ function rememberMode(controlInfo) {
459
+ const mode = controlInfo.mode ?? "";
460
+ for (const [prefix, field] of Object.entries(MODE_MEMORY_FIELDS)) {
461
+ const value = controlInfo[field];
462
+ if (`${prefix}${mode}` in controlInfo && value !== undefined) {
463
+ controlInfo[`${prefix}${mode}`] = value;
464
+ }
465
+ }
466
+ const { f_dir_ud: vertical, f_dir_lr: horizontal } = controlInfo;
467
+ if (`ndfd${mode}` in controlInfo &&
468
+ vertical !== undefined &&
469
+ horizontal !== undefined) {
470
+ controlInfo[`ndfd${mode}`] = `${vertical}${horizontal}`;
471
+ }
472
+ }
473
+ //# sourceMappingURL=classic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classic.js","sourceRoot":"","sources":["../../src/simulators/classic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { type DaikinSimulator, type DaikinSimulatorUnit, type StartSimulatorOptions } from "./simulator.js";
2
+ /** One leaf of an adapter's property trees. */
3
+ export interface DsiotSimulatorLeaf {
4
+ /** The leaf's value. In a `dgc_status` tree it is hex bytes in upper case,
5
+ * the low byte first where there are several. */
6
+ pv: string;
7
+ /** 2 or 3. A special mode's leaf is 2 on a unit that takes the mode. What
8
+ * else tells the two apart is not known: the simulator takes a write to
9
+ * either, and its own leaves are 2 where a write is known for the leaf. */
10
+ pt: number;
11
+ /** A setpoint's lowest and highest value in `mi` and `mx`, a louver's values
12
+ * as a bit mask in `mx`, and a humidity value's step in `st`. */
13
+ md?: {
14
+ pt: string;
15
+ st?: string;
16
+ mi?: string;
17
+ mx?: string;
18
+ };
19
+ }
20
+ export interface StartDsiotSimulatorOptions extends StartSimulatorOptions {
21
+ /** What the unit has. Defaults to a heat pump with every fan speed, five
22
+ * fixed vertical louver positions, swing on both axes and all three special
23
+ * modes. A leaf in `leaves` replaces what this sets. */
24
+ unit?: DaikinSimulatorUnit;
25
+ /** Leaves added to the adapter's, each replacing a default at the same
26
+ * address: see `DsiotDaikinSimulator.leaves`. Defaults to none. */
27
+ leaves?: Record<string, DsiotSimulatorLeaf>;
28
+ /** The child lock code. With one, the adapter answers `rsc` 4001 to a
29
+ * request whose `Authorization` is not `Basic` and this code. Defaults to
30
+ * none: no request needs an `Authorization`. */
31
+ localPassword?: string;
32
+ }
33
+ /** A DSIOT adapter and the unit behind it. */
34
+ export interface DsiotDaikinSimulator extends DaikinSimulator {
35
+ /** Every leaf the adapter reports, by its address: the `to` of its
36
+ * resource, then the names down to the leaf, such as
37
+ * `/dsiot/edge/adr_0100.dgc_status.e_1002.e_A002.p_01` for the power. A
38
+ * write through the adapter changes a `pv`, and so do `setState` and
39
+ * `setSensors`. For what those two do not cover, set a `pv` directly, and
40
+ * delete a leaf or add one to change what the unit has. */
41
+ readonly leaves: Record<string, DsiotSimulatorLeaf>;
42
+ }
43
+ /** Starts a DSIOT adapter on a free port, as a heat pump that is off, in
44
+ * cool at 24 °C. It answers `/dsiot/multireq` reads and writes and
45
+ * `/config/system/reboot`, over HTTP, and answers any other request with HTTP
46
+ * 501: UNSUPPORTED.md lists what it leaves out and where its answer is not
47
+ * known to be an adapter's. Call `stop` when done with it. */
48
+ export declare function startDsiotSimulator(options?: StartDsiotSimulatorOptions): Promise<DsiotDaikinSimulator>;
49
+ //# sourceMappingURL=dsiot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsiot.d.ts","sourceRoot":"","sources":["../../src/simulators/dsiot.ts"],"names":[],"mappings":"AA0BA,OAAO,EACL,KAAK,eAAe,EAGpB,KAAK,mBAAmB,EAExB,KAAK,qBAAqB,EAG3B,MAAM,gBAAgB,CAAC;AA8HxB,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC;qDACiD;IACjD,EAAE,EAAE,MAAM,CAAC;IACX;;+EAE2E;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX;qEACiE;IACjE,EAAE,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D;AAED,MAAM,WAAW,0BAA2B,SAAQ,qBAAqB;IACvE;;4DAEwD;IACxD,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B;uEACmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC5C;;oDAEgD;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,8CAA8C;AAC9C,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D;;;;;+DAK2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CACrD;AAUD;;;;8DAI8D;AAC9D,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,oBAAoB,CAAC,CA0I/B"}