daikin-local-control 0.1.1

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 (115) hide show
  1. package/DESIGN.md +98 -0
  2. package/LICENSE +674 -0
  3. package/README.md +317 -0
  4. package/UNSUPPORTED.md +43 -0
  5. package/dist/authentication.d.ts +24 -0
  6. package/dist/authentication.d.ts.map +1 -0
  7. package/dist/authentication.js +30 -0
  8. package/dist/authentication.js.map +1 -0
  9. package/dist/clients/classic.d.ts +53 -0
  10. package/dist/clients/classic.d.ts.map +1 -0
  11. package/dist/clients/classic.js +142 -0
  12. package/dist/clients/classic.js.map +1 -0
  13. package/dist/clients/client.d.ts +21 -0
  14. package/dist/clients/client.d.ts.map +1 -0
  15. package/dist/clients/client.js +2 -0
  16. package/dist/clients/client.js.map +1 -0
  17. package/dist/clients/dsiot.d.ts +28 -0
  18. package/dist/clients/dsiot.d.ts.map +1 -0
  19. package/dist/clients/dsiot.js +66 -0
  20. package/dist/clients/dsiot.js.map +1 -0
  21. package/dist/codecs/classic/capabilities.d.ts +19 -0
  22. package/dist/codecs/classic/capabilities.d.ts.map +1 -0
  23. package/dist/codecs/classic/capabilities.js +208 -0
  24. package/dist/codecs/classic/capabilities.js.map +1 -0
  25. package/dist/codecs/classic/extendedControl.d.ts +20 -0
  26. package/dist/codecs/classic/extendedControl.d.ts.map +1 -0
  27. package/dist/codecs/classic/extendedControl.js +88 -0
  28. package/dist/codecs/classic/extendedControl.js.map +1 -0
  29. package/dist/codecs/classic/keyValue.d.ts +10 -0
  30. package/dist/codecs/classic/keyValue.d.ts.map +1 -0
  31. package/dist/codecs/classic/keyValue.js +36 -0
  32. package/dist/codecs/classic/keyValue.js.map +1 -0
  33. package/dist/codecs/classic/state.d.ts +18 -0
  34. package/dist/codecs/classic/state.d.ts.map +1 -0
  35. package/dist/codecs/classic/state.js +235 -0
  36. package/dist/codecs/classic/state.js.map +1 -0
  37. package/dist/codecs/credentials.d.ts +8 -0
  38. package/dist/codecs/credentials.d.ts.map +1 -0
  39. package/dist/codecs/credentials.js +14 -0
  40. package/dist/codecs/credentials.js.map +1 -0
  41. package/dist/codecs/device.d.ts +6 -0
  42. package/dist/codecs/device.d.ts.map +1 -0
  43. package/dist/codecs/device.js +35 -0
  44. package/dist/codecs/device.js.map +1 -0
  45. package/dist/codecs/dsiot/capabilities.d.ts +5 -0
  46. package/dist/codecs/dsiot/capabilities.d.ts.map +1 -0
  47. package/dist/codecs/dsiot/capabilities.js +139 -0
  48. package/dist/codecs/dsiot/capabilities.js.map +1 -0
  49. package/dist/codecs/dsiot/multireq.d.ts +37 -0
  50. package/dist/codecs/dsiot/multireq.d.ts.map +1 -0
  51. package/dist/codecs/dsiot/multireq.js +122 -0
  52. package/dist/codecs/dsiot/multireq.js.map +1 -0
  53. package/dist/codecs/dsiot/state.d.ts +92 -0
  54. package/dist/codecs/dsiot/state.d.ts.map +1 -0
  55. package/dist/codecs/dsiot/state.js +461 -0
  56. package/dist/codecs/dsiot/state.js.map +1 -0
  57. package/dist/discovery.d.ts +17 -0
  58. package/dist/discovery.d.ts.map +1 -0
  59. package/dist/discovery.js +67 -0
  60. package/dist/discovery.js.map +1 -0
  61. package/dist/error.d.ts +15 -0
  62. package/dist/error.d.ts.map +1 -0
  63. package/dist/error.js +20 -0
  64. package/dist/error.js.map +1 -0
  65. package/dist/factory.d.ts +26 -0
  66. package/dist/factory.d.ts.map +1 -0
  67. package/dist/factory.js +31 -0
  68. package/dist/factory.js.map +1 -0
  69. package/dist/index.d.ts +22 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +21 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/models/capabilities.d.ts +42 -0
  74. package/dist/models/capabilities.d.ts.map +1 -0
  75. package/dist/models/capabilities.js +2 -0
  76. package/dist/models/capabilities.js.map +1 -0
  77. package/dist/models/device.d.ts +24 -0
  78. package/dist/models/device.d.ts.map +1 -0
  79. package/dist/models/device.js +2 -0
  80. package/dist/models/device.js.map +1 -0
  81. package/dist/models/extendedControl.d.ts +31 -0
  82. package/dist/models/extendedControl.d.ts.map +1 -0
  83. package/dist/models/extendedControl.js +7 -0
  84. package/dist/models/extendedControl.js.map +1 -0
  85. package/dist/models/state.d.ts +56 -0
  86. package/dist/models/state.d.ts.map +1 -0
  87. package/dist/models/state.js +49 -0
  88. package/dist/models/state.js.map +1 -0
  89. package/dist/transport.d.ts +75 -0
  90. package/dist/transport.d.ts.map +1 -0
  91. package/dist/transport.js +118 -0
  92. package/dist/transport.js.map +1 -0
  93. package/package.json +62 -0
  94. package/src/authentication.ts +53 -0
  95. package/src/clients/classic.ts +251 -0
  96. package/src/clients/client.ts +29 -0
  97. package/src/clients/dsiot.ts +116 -0
  98. package/src/codecs/classic/capabilities.ts +272 -0
  99. package/src/codecs/classic/extendedControl.ts +132 -0
  100. package/src/codecs/classic/keyValue.ts +39 -0
  101. package/src/codecs/classic/state.ts +302 -0
  102. package/src/codecs/credentials.ts +19 -0
  103. package/src/codecs/device.ts +41 -0
  104. package/src/codecs/dsiot/capabilities.ts +209 -0
  105. package/src/codecs/dsiot/multireq.ts +162 -0
  106. package/src/codecs/dsiot/state.ts +644 -0
  107. package/src/discovery.ts +85 -0
  108. package/src/error.ts +20 -0
  109. package/src/factory.ts +66 -0
  110. package/src/index.ts +21 -0
  111. package/src/models/capabilities.ts +52 -0
  112. package/src/models/device.ts +25 -0
  113. package/src/models/extendedControl.ts +41 -0
  114. package/src/models/state.ts +110 -0
  115. package/src/transport.ts +191 -0
@@ -0,0 +1,461 @@
1
+ import { FIXED_LOUVER_POSITIONS, HORIZONTAL_POSITIONS, VERTICAL_POSITIONS, } from "../../models/state.js";
2
+ /** Full dotted paths into the `dgc_status` trees. `e_1002` lives on the indoor
3
+ * edge and `e_1003` on the outdoor edge. */
4
+ export const DSIOT_PATHS = {
5
+ power: "dgc_status.e_1002.e_A002.p_01",
6
+ /** Sent with every control. */
7
+ powerTransition: "dgc_status.e_1002.e_3003.p_2D",
8
+ mode: "dgc_status.e_1002.e_3001.p_01",
9
+ indoorTemperature: "dgc_status.e_1002.e_A00B.p_01",
10
+ indoorHumidity: "dgc_status.e_1002.e_A00B.p_02",
11
+ outdoorTemperature: "dgc_status.e_1003.e_A00D.p_01",
12
+ model: "dgc_status.e_1002.e_A001.p_0D",
13
+ modelType: "dgc_status.e_1002.e_A001.p_07",
14
+ energyMonitoring: "dgc_status.e_1002.e_A011.p_01",
15
+ };
16
+ export const DSIOT_MODE_NODE = "dgc_status.e_1002.e_3001";
17
+ export const DSIOT_MODE_PATHS = {
18
+ auto: {
19
+ setpoint: { path: `${DSIOT_MODE_NODE}.p_1D`, signed: true, writable: true },
20
+ humidity: {
21
+ value: `${DSIOT_MODE_NODE}.p_2E`,
22
+ flag: `${DSIOT_MODE_NODE}.p_2F`,
23
+ },
24
+ fanSpeed: `${DSIOT_MODE_NODE}.p_26`,
25
+ vertical: `${DSIOT_MODE_NODE}.p_20`,
26
+ horizontal: `${DSIOT_MODE_NODE}.p_21`,
27
+ },
28
+ dehumidify: {
29
+ setpoint: {
30
+ path: `${DSIOT_MODE_NODE}.p_1E`,
31
+ signed: true,
32
+ writable: false,
33
+ },
34
+ humidity: {
35
+ value: `${DSIOT_MODE_NODE}.p_30`,
36
+ flag: `${DSIOT_MODE_NODE}.p_31`,
37
+ },
38
+ fanSpeed: `${DSIOT_MODE_NODE}.p_27`,
39
+ vertical: `${DSIOT_MODE_NODE}.p_22`,
40
+ horizontal: `${DSIOT_MODE_NODE}.p_23`,
41
+ },
42
+ cool: {
43
+ setpoint: {
44
+ path: `${DSIOT_MODE_NODE}.p_02`,
45
+ signed: false,
46
+ writable: true,
47
+ },
48
+ humidity: {
49
+ value: `${DSIOT_MODE_NODE}.p_0B`,
50
+ flag: `${DSIOT_MODE_NODE}.p_0C`,
51
+ },
52
+ fanSpeed: `${DSIOT_MODE_NODE}.p_09`,
53
+ vertical: `${DSIOT_MODE_NODE}.p_05`,
54
+ horizontal: `${DSIOT_MODE_NODE}.p_06`,
55
+ },
56
+ heat: {
57
+ setpoint: {
58
+ path: `${DSIOT_MODE_NODE}.p_03`,
59
+ signed: false,
60
+ writable: true,
61
+ },
62
+ humidity: {
63
+ value: `${DSIOT_MODE_NODE}.p_2C`,
64
+ flag: `${DSIOT_MODE_NODE}.p_2D`,
65
+ },
66
+ fanSpeed: `${DSIOT_MODE_NODE}.p_0A`,
67
+ vertical: `${DSIOT_MODE_NODE}.p_07`,
68
+ horizontal: `${DSIOT_MODE_NODE}.p_08`,
69
+ },
70
+ fan: {
71
+ fanSpeed: `${DSIOT_MODE_NODE}.p_28`,
72
+ vertical: `${DSIOT_MODE_NODE}.p_24`,
73
+ horizontal: `${DSIOT_MODE_NODE}.p_25`,
74
+ },
75
+ };
76
+ // --- value encodings -------------------------------------------------------
77
+ // Leaf values are hex strings. Multi-byte values are little-endian, and
78
+ // temperatures count half degrees.
79
+ export function encodeDsiotBoolean(on) {
80
+ return on ? "01" : "00";
81
+ }
82
+ export function decodeDsiotBoolean(pv) {
83
+ return pv !== undefined && Number.parseInt(pv, 16) > 0;
84
+ }
85
+ export function decodeDsiotLittleEndian(pv) {
86
+ const bytes = pv.match(/../g) ?? [];
87
+ return Number.parseInt(bytes.reverse().join(""), 16);
88
+ }
89
+ export function encodeDsiotSetpoint(setpointInC) {
90
+ return (Math.trunc(setpointInC * 2) & 0xff).toString(16);
91
+ }
92
+ export function decodeDsiotSetpoint(pv, signed) {
93
+ if (!pv) {
94
+ return null;
95
+ }
96
+ const halfDegrees = signed ? signedByte(pv) : decodeDsiotLittleEndian(pv);
97
+ return Number.isFinite(halfDegrees) ? halfDegrees / 2 : null;
98
+ }
99
+ /** Indoor temperature: a signed byte of whole °C. */
100
+ export function decodeDsiotIndoorTemperature(pv) {
101
+ return pv ? nullIfNaN(signedByte(pv)) : null;
102
+ }
103
+ /** Indoor humidity: an unsigned byte of %. */
104
+ export function decodeDsiotIndoorHumidity(pv) {
105
+ return pv ? nullIfNaN(Number.parseInt(pv, 16)) : null;
106
+ }
107
+ /** Outdoor temperature: a signed little-endian 16-bit count of half degrees. */
108
+ export function decodeDsiotOutdoorTemperature(pv) {
109
+ if (!pv) {
110
+ return null;
111
+ }
112
+ const unsigned = decodeDsiotLittleEndian(pv);
113
+ // The shift turns NaN into 0, so a value that is not hex is caught first.
114
+ return Number.isFinite(unsigned) ? ((unsigned << 16) >> 16) / 2 : null;
115
+ }
116
+ function signedByte(pv) {
117
+ const byte = Number.parseInt(pv.slice(0, 2), 16);
118
+ return byte > 0x7f ? byte - 0x100 : byte;
119
+ }
120
+ function nullIfNaN(value) {
121
+ return Number.isFinite(value) ? value : null;
122
+ }
123
+ const OPERATING_MODE_CODES = {
124
+ fan: "0000",
125
+ heat: "0100",
126
+ cool: "0200",
127
+ auto: "0300",
128
+ dehumidify: "0500",
129
+ };
130
+ const OPERATING_MODES_BY_CODE = {
131
+ "0000": "fan",
132
+ "0100": "heat",
133
+ "0200": "cool",
134
+ "0300": "auto",
135
+ "0500": "dehumidify",
136
+ "0900": "cool",
137
+ "0A00": "heat",
138
+ };
139
+ export function encodeDsiotMode(mode) {
140
+ return OPERATING_MODE_CODES[mode];
141
+ }
142
+ export function decodeDsiotMode(pv) {
143
+ return OPERATING_MODES_BY_CODE[(pv ?? "").toUpperCase()];
144
+ }
145
+ const FAN_SPEED_CODES = {
146
+ auto: "0A00",
147
+ silent: "0B00",
148
+ level1: "0300",
149
+ level2: "0400",
150
+ level3: "0500",
151
+ level4: "0600",
152
+ level5: "0700",
153
+ };
154
+ const FAN_SPEEDS_BY_CODE = Object.fromEntries(Object.entries(FAN_SPEED_CODES).map(([speed, code]) => [
155
+ code,
156
+ speed,
157
+ ]));
158
+ export function encodeDsiotFanSpeed(speed) {
159
+ return FAN_SPEED_CODES[speed];
160
+ }
161
+ export function decodeDsiotFanSpeed(pv) {
162
+ return FAN_SPEEDS_BY_CODE[(pv ?? "").toUpperCase()];
163
+ }
164
+ /** The values a louver leaf holds besides a fixed position, which is 1-14.
165
+ * The leaf is three bytes, little-endian, and bit n of its `md.mx` is set
166
+ * when the unit takes value n. */
167
+ export const DSIOT_LOUVER_VALUES = {
168
+ stop: 0,
169
+ swing: 15,
170
+ auto: 16,
171
+ naturalWind: 19,
172
+ floorWarming: 25,
173
+ };
174
+ const FIXED_LOUVER_VALUES = Array.from({ length: 14 }, (_, index) => index + 1);
175
+ export const DSIOT_LOUVER_STOP = "000000";
176
+ export const DSIOT_LOUVER_SWING = "0F0000";
177
+ export function isDsiotLouverSwinging(pv) {
178
+ return (pv ?? "").toUpperCase() === DSIOT_LOUVER_SWING;
179
+ }
180
+ /** The value each `VerticalPosition` is held as. A fixed position has none: it
181
+ * is held as the value at its rank among the fixed values the unit takes. */
182
+ export const DSIOT_VERTICAL_POSITION_VALUES = {
183
+ stop: DSIOT_LOUVER_VALUES.stop,
184
+ swing: DSIOT_LOUVER_VALUES.swing,
185
+ naturalWind: DSIOT_LOUVER_VALUES.naturalWind,
186
+ auto: DSIOT_LOUVER_VALUES.auto,
187
+ floorWarming: DSIOT_LOUVER_VALUES.floorWarming,
188
+ };
189
+ const FIXED_VERTICAL_POSITIONS = FIXED_LOUVER_POSITIONS;
190
+ /** The value each `HorizontalPosition` is held as. `stop` and a fixed position
191
+ * have none: see UNSUPPORTED.md. */
192
+ export const DSIOT_HORIZONTAL_POSITION_VALUES = {
193
+ swing: DSIOT_LOUVER_VALUES.swing,
194
+ auto: DSIOT_LOUVER_VALUES.auto,
195
+ };
196
+ function positionOf(positions, held, value) {
197
+ return positions.find((position) => held[position] === value) ?? null;
198
+ }
199
+ function isFixedLouverValue(value) {
200
+ return value >= 1 && value <= 14;
201
+ }
202
+ function fixedLouverValues(values, path) {
203
+ const mask = decodeDsiotLittleEndian(values[`${path}.md.mx`] ?? "");
204
+ return FIXED_LOUVER_VALUES.filter((value) => mask & (1 << value));
205
+ }
206
+ function encodeLouver(value) {
207
+ return `${value.toString(16).toUpperCase().padStart(2, "0")}0000`;
208
+ }
209
+ // A fixed vertical position is named by its rank among the values the unit
210
+ // takes: a unit taking 2, 4 and 6 reports them as `position1`, `position2` and
211
+ // `position3`. A value the unit does not list reads as `stop`.
212
+ function parseVerticalPosition(values, path) {
213
+ const pv = values[path];
214
+ if (pv === undefined) {
215
+ return null;
216
+ }
217
+ const value = decodeDsiotLittleEndian(pv);
218
+ if (!isFixedLouverValue(value)) {
219
+ return positionOf(VERTICAL_POSITIONS, DSIOT_VERTICAL_POSITION_VALUES, value);
220
+ }
221
+ const rank = fixedLouverValues(values, path).indexOf(value);
222
+ return rank === -1 ? "stop" : (FIXED_VERTICAL_POSITIONS[rank] ?? null);
223
+ }
224
+ // `undefined` for a position the unit does not take in this mode.
225
+ function encodeVerticalPosition(position, values, path) {
226
+ const rank = FIXED_VERTICAL_POSITIONS.indexOf(position);
227
+ const value = rank === -1
228
+ ? DSIOT_VERTICAL_POSITION_VALUES[position]
229
+ : fixedLouverValues(values, path)[rank];
230
+ return value === undefined ? undefined : encodeLouver(value);
231
+ }
232
+ // A fixed horizontal position reads as `stop`: see UNSUPPORTED.md.
233
+ function parseHorizontalPosition(pv) {
234
+ if (pv === undefined) {
235
+ return null;
236
+ }
237
+ const value = decodeDsiotLittleEndian(pv);
238
+ return value === DSIOT_LOUVER_VALUES.stop || isFixedLouverValue(value)
239
+ ? "stop"
240
+ : positionOf(HORIZONTAL_POSITIONS, DSIOT_HORIZONTAL_POSITION_VALUES, value);
241
+ }
242
+ // `undefined` for a fixed position, which has no encoding: see UNSUPPORTED.md.
243
+ function encodeHorizontalPosition(position, current) {
244
+ if (position === "stop") {
245
+ // Stopping the axis keeps a fixed position it already holds.
246
+ return current !== undefined &&
247
+ isFixedLouverValue(decodeDsiotLittleEndian(current))
248
+ ? current
249
+ : DSIOT_LOUVER_STOP;
250
+ }
251
+ const value = DSIOT_HORIZONTAL_POSITION_VALUES[position];
252
+ return value === undefined ? undefined : encodeLouver(value);
253
+ }
254
+ const HUMIDITY_OFF = "00";
255
+ const HUMIDITY_ON = "01";
256
+ // Also reads as off, and a control that switches humidity off leaves it.
257
+ const HUMIDITY_OFF_KEPT = "05";
258
+ const HUMIDITY_SETTING_FLAGS = {
259
+ auto: "02",
260
+ autoHigh: "03",
261
+ autoLow: "04",
262
+ continuous: "06",
263
+ };
264
+ const HUMIDITY_SETTINGS_BY_FLAG = Object.fromEntries(Object.entries(HUMIDITY_SETTING_FLAGS).map(([setting, flag]) => [
265
+ flag,
266
+ setting,
267
+ ]));
268
+ // A step (`md.st`) is one byte, in decimal: the low nibble counts, and the
269
+ // high nibble, as a signed nibble, is the power of ten that scales the count.
270
+ // A value is used as it is when its leaf has no step, or a step of zero.
271
+ function decodeStep(st) {
272
+ const byte = Number(st ?? Number.NaN);
273
+ if (!Number.isInteger(byte) || byte < 0 || byte > 255) {
274
+ return 1;
275
+ }
276
+ const exponent = byte >> 4;
277
+ return (byte & 0x0f) * 10 ** (exponent < 8 ? exponent : exponent - 16) || 1;
278
+ }
279
+ function parseTargetHumidity(values, humidity) {
280
+ const flag = humidity && values[humidity.flag];
281
+ if (flag === HUMIDITY_OFF || flag === HUMIDITY_OFF_KEPT) {
282
+ return "off";
283
+ }
284
+ if (humidity === undefined || flag !== HUMIDITY_ON) {
285
+ return HUMIDITY_SETTINGS_BY_FLAG[flag ?? ""] ?? null;
286
+ }
287
+ const count = Number.parseInt(values[humidity.value] ?? "", 16);
288
+ return Number.isFinite(count)
289
+ ? {
290
+ percent: Math.trunc(count * decodeStep(values[`${humidity.value}.md.st`])),
291
+ }
292
+ : null;
293
+ }
294
+ function applyTargetHumidity(values, { value, flag }, targetHumidity) {
295
+ if (targetHumidity === "off") {
296
+ return [
297
+ {
298
+ path: flag,
299
+ value: values[flag] === HUMIDITY_OFF_KEPT ? HUMIDITY_OFF_KEPT : HUMIDITY_OFF,
300
+ },
301
+ ];
302
+ }
303
+ if (typeof targetHumidity === "string") {
304
+ return [{ path: flag, value: HUMIDITY_SETTING_FLAGS[targetHumidity] }];
305
+ }
306
+ const count = Math.trunc(targetHumidity.percent / decodeStep(values[`${value}.md.st`]));
307
+ return [
308
+ { path: flag, value: HUMIDITY_ON },
309
+ { path: value, value: count.toString(16).toUpperCase().padStart(2, "0") },
310
+ ];
311
+ }
312
+ // Whether the mode's humidity setting is on once the control is applied.
313
+ function isHumidityOn(values, humidity, targetHumidity) {
314
+ const flag = humidity && values[humidity.flag];
315
+ if (flag === undefined) {
316
+ return false;
317
+ }
318
+ return targetHumidity == null
319
+ ? flag !== HUMIDITY_OFF && flag !== HUMIDITY_OFF_KEPT
320
+ : targetHumidity !== "off";
321
+ }
322
+ const POWER_TRANSITIONS = {
323
+ turningOn: "00",
324
+ turningOff: "01",
325
+ unchanged: "02",
326
+ };
327
+ /** Turns the flattened indoor `dgc_status` tree, read with `md`, into a
328
+ * `DaikinState`. Every value is per mode: the setpoint, humidity, fan speed and
329
+ * louvers each have a leaf for each mode, and the state reads the current
330
+ * mode's. */
331
+ export function parseDsiotState(values) {
332
+ const mode = decodeDsiotMode(values[DSIOT_PATHS.mode]) ?? "auto";
333
+ const paths = DSIOT_MODE_PATHS[mode];
334
+ return {
335
+ power: decodeDsiotBoolean(values[DSIOT_PATHS.power]),
336
+ mode,
337
+ targetTemperatureInC: paths.setpoint
338
+ ? decodeDsiotSetpoint(values[paths.setpoint.path], paths.setpoint.signed)
339
+ : null,
340
+ targetHumidity: parseTargetHumidity(values, paths.humidity),
341
+ fanSpeed: decodeDsiotFanSpeed(values[paths.fanSpeed]) ?? "auto",
342
+ swingMode: decodeSwing(values[paths.vertical], values[paths.horizontal]),
343
+ verticalPosition: parseVerticalPosition(values, paths.vertical),
344
+ horizontalPosition: parseHorizontalPosition(values[paths.horizontal]),
345
+ };
346
+ }
347
+ /** Turns `values`, the flattened indoor `dgc_status` tree read with `md`, and
348
+ * a control into the leaves `buildDsiotMultireqUpdate` writes: power, its
349
+ * transition and the mode every time, then whichever of the target mode's
350
+ * leaves the control changes. It drops a `targetTemperatureInC` in a mode without
351
+ * a writable setpoint, a `targetHumidity` in a mode the unit has no humidity
352
+ * leaves for, and a louver position the unit does not take. It always writes
353
+ * the `auto` fan speed in dehumidify, and in cool while a humidity setting is
354
+ * on. A unit in a mode outside `OperatingMode` keeps it unless the control
355
+ * sets one, and gets power, its transition and that mode alone. */
356
+ export function applyDsiotControl(values, control) {
357
+ const currentPower = decodeDsiotBoolean(values[DSIOT_PATHS.power]);
358
+ const power = control.power ?? currentPower;
359
+ const heldMode = control.mode === undefined
360
+ ? (values[DSIOT_PATHS.mode] ?? encodeDsiotMode("auto"))
361
+ : encodeDsiotMode(control.mode);
362
+ const mode = decodeDsiotMode(heldMode);
363
+ const updates = [
364
+ { path: DSIOT_PATHS.power, value: encodeDsiotBoolean(power) },
365
+ {
366
+ path: DSIOT_PATHS.powerTransition,
367
+ value: power === currentPower
368
+ ? POWER_TRANSITIONS.unchanged
369
+ : power
370
+ ? POWER_TRANSITIONS.turningOn
371
+ : POWER_TRANSITIONS.turningOff,
372
+ },
373
+ {
374
+ path: DSIOT_PATHS.mode,
375
+ value: mode === undefined ? heldMode : encodeDsiotMode(mode),
376
+ },
377
+ ];
378
+ // Which leaves a mode outside the model reads and writes is not known.
379
+ if (mode === undefined) {
380
+ return updates;
381
+ }
382
+ const paths = DSIOT_MODE_PATHS[mode];
383
+ if (control.targetTemperatureInC != null && paths.setpoint?.writable) {
384
+ updates.push({
385
+ path: paths.setpoint.path,
386
+ value: encodeDsiotSetpoint(control.targetTemperatureInC),
387
+ });
388
+ }
389
+ if (control.targetHumidity != null &&
390
+ paths.humidity &&
391
+ paths.humidity.flag in values) {
392
+ updates.push(...applyTargetHumidity(values, paths.humidity, control.targetHumidity));
393
+ }
394
+ // Dehumidify runs the fan on auto only, and so does cool while a humidity
395
+ // setting is on.
396
+ if (mode === "dehumidify" ||
397
+ (mode === "cool" &&
398
+ isHumidityOn(values, paths.humidity, control.targetHumidity))) {
399
+ updates.push({ path: paths.fanSpeed, value: encodeDsiotFanSpeed("auto") });
400
+ }
401
+ else if (control.fanSpeed !== undefined) {
402
+ updates.push({
403
+ path: paths.fanSpeed,
404
+ value: encodeDsiotFanSpeed(control.fanSpeed),
405
+ });
406
+ }
407
+ let vertical;
408
+ let horizontal;
409
+ if (control.swingMode !== undefined) {
410
+ const swingsVertically = control.swingMode === "vertical" || control.swingMode === "both";
411
+ const swingsHorizontally = control.swingMode === "horizontal" || control.swingMode === "both";
412
+ vertical = louver(swingsVertically, values[paths.vertical]);
413
+ horizontal = louver(swingsHorizontally, values[paths.horizontal]);
414
+ }
415
+ // A position overrides the swing mode sent with it.
416
+ if (control.verticalPosition != null) {
417
+ vertical =
418
+ encodeVerticalPosition(control.verticalPosition, values, paths.vertical) ?? vertical;
419
+ }
420
+ if (control.horizontalPosition != null) {
421
+ horizontal =
422
+ encodeHorizontalPosition(control.horizontalPosition, values[paths.horizontal]) ?? horizontal;
423
+ }
424
+ if (vertical !== undefined) {
425
+ updates.push({ path: paths.vertical, value: vertical });
426
+ }
427
+ if (horizontal !== undefined) {
428
+ updates.push({ path: paths.horizontal, value: horizontal });
429
+ }
430
+ return updates;
431
+ }
432
+ export function parseDsiotSensors(values) {
433
+ return {
434
+ indoorTemperatureInC: decodeDsiotIndoorTemperature(values[DSIOT_PATHS.indoorTemperature]),
435
+ indoorHumidityInPercent: decodeDsiotIndoorHumidity(values[DSIOT_PATHS.indoorHumidity]),
436
+ outdoorTemperatureInC: decodeDsiotOutdoorTemperature(values[DSIOT_PATHS.outdoorTemperature]),
437
+ };
438
+ }
439
+ function decodeSwing(vertical, horizontal) {
440
+ const swingsVertically = isDsiotLouverSwinging(vertical);
441
+ const swingsHorizontally = isDsiotLouverSwinging(horizontal);
442
+ if (swingsVertically && swingsHorizontally) {
443
+ return "both";
444
+ }
445
+ return swingsVertically
446
+ ? "vertical"
447
+ : swingsHorizontally
448
+ ? "horizontal"
449
+ : "off";
450
+ }
451
+ // Stopping a swinging axis stops the louver; an axis already at a fixed
452
+ // position keeps it.
453
+ function louver(swing, current) {
454
+ if (swing) {
455
+ return DSIOT_LOUVER_SWING;
456
+ }
457
+ return current === undefined || isDsiotLouverSwinging(current)
458
+ ? DSIOT_LOUVER_STOP
459
+ : current;
460
+ }
461
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/codecs/dsiot/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { DaikinDevice } from "./models/device.js";
2
+ export interface DiscoverDevicesOptions {
3
+ /** How long to listen for replies, in milliseconds. Defaults to 3000. */
4
+ timeoutInMs?: number;
5
+ }
6
+ /** Finds the adapters on the LAN: broadcasts `DAIKIN_UDP/common/basic_info` to
7
+ * UDP port 30050 and collects the `basic_info` replies, which carry the same
8
+ * `key=value` payload as the HTTP `/common/basic_info`. Classic and DSIOT
9
+ * adapters both answer, and `parseDevice` picks the protocol from the reply.
10
+ * Anything on the LAN can send to the port it listens on, so it ignores a
11
+ * datagram whose `ret` is not `OK`.
12
+ *
13
+ * It resolves once `timeoutInMs` has passed, never earlier, with one device
14
+ * per replying address. It binds UDP port 30000, and rejects with the socket's
15
+ * error when the socket fails. */
16
+ export declare function discoverDevices(options?: DiscoverDevicesOptions): Promise<DaikinDevice[]>;
17
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAcvD,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;kCASkC;AAClC,wBAAsB,eAAe,CACnC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,YAAY,EAAE,CAAC,CA+CzB"}
@@ -0,0 +1,67 @@
1
+ import { createSocket } from "node:dgram";
2
+ import { isClassicOk, parseClassicKeyValue, } from "./codecs/classic/keyValue.js";
3
+ import { parseDevice } from "./codecs/device.js";
4
+ // The UDP discovery probe: broadcast this to :30050, listen for `basic_info`
5
+ // replies.
6
+ const DISCOVERY_PROBE = "DAIKIN_UDP/common/basic_info";
7
+ const DISCOVERY_SEND_PORT = 30000;
8
+ const DISCOVERY_LISTEN_PORT = 30050;
9
+ const DEFAULT_DISCOVERY_TIMEOUT_IN_MS = 3_000;
10
+ const BROADCAST_ADDRESS = "255.255.255.255";
11
+ // UDP drops packets, so the probe goes out 10 times, 200 ms apart.
12
+ const PROBE_COUNT = 10;
13
+ const PROBE_INTERVAL_IN_MS = 200;
14
+ /** Finds the adapters on the LAN: broadcasts `DAIKIN_UDP/common/basic_info` to
15
+ * UDP port 30050 and collects the `basic_info` replies, which carry the same
16
+ * `key=value` payload as the HTTP `/common/basic_info`. Classic and DSIOT
17
+ * adapters both answer, and `parseDevice` picks the protocol from the reply.
18
+ * Anything on the LAN can send to the port it listens on, so it ignores a
19
+ * datagram whose `ret` is not `OK`.
20
+ *
21
+ * It resolves once `timeoutInMs` has passed, never earlier, with one device
22
+ * per replying address. It binds UDP port 30000, and rejects with the socket's
23
+ * error when the socket fails. */
24
+ export async function discoverDevices(options = {}) {
25
+ const socket = createSocket({ type: "udp4", reuseAddr: true });
26
+ const devices = new Map();
27
+ return new Promise((resolve, reject) => {
28
+ let probesSent = 0;
29
+ let probeTimer;
30
+ const listenTimer = setTimeout(() => {
31
+ clearInterval(probeTimer);
32
+ socket.close();
33
+ resolve([...devices.values()]);
34
+ }, options.timeoutInMs ?? DEFAULT_DISCOVERY_TIMEOUT_IN_MS);
35
+ socket.on("error", (error) => {
36
+ clearInterval(probeTimer);
37
+ // A socket throws when it is closed twice, so the timer must not fire.
38
+ clearTimeout(listenTimer);
39
+ socket.close();
40
+ reject(error);
41
+ });
42
+ socket.on("message", (message, remote) => {
43
+ if (devices.has(remote.address)) {
44
+ return;
45
+ }
46
+ const fields = parseClassicKeyValue(message.toString("utf8"));
47
+ if (!isClassicOk(fields)) {
48
+ return;
49
+ }
50
+ devices.set(remote.address, parseDevice(remote.address, fields));
51
+ });
52
+ socket.bind(DISCOVERY_SEND_PORT, () => {
53
+ socket.setBroadcast(true);
54
+ const probe = Buffer.from(DISCOVERY_PROBE, "utf8");
55
+ const sendProbe = () => {
56
+ socket.send(probe, DISCOVERY_LISTEN_PORT, BROADCAST_ADDRESS);
57
+ probesSent += 1;
58
+ if (probesSent >= PROBE_COUNT) {
59
+ clearInterval(probeTimer);
60
+ }
61
+ };
62
+ sendProbe();
63
+ probeTimer = setInterval(sendProbe, PROBE_INTERVAL_IN_MS);
64
+ });
65
+ });
66
+ }
67
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export declare class DaikinError extends Error {
2
+ /** The adapter's own HTTP status, or the status this package gives a
3
+ * failure that has none: the README's "Errors and retries" lists them. */
4
+ readonly httpStatusCode: number;
5
+ constructor(message: string,
6
+ /** The adapter's own HTTP status, or the status this package gives a
7
+ * failure that has none: the README's "Errors and retries" lists them. */
8
+ httpStatusCode: number);
9
+ }
10
+ /** The adapter refused or dropped the connection before answering. The only
11
+ * failure `withRetry` repeats: see DESIGN.md#retries. */
12
+ export declare class DaikinConnectionError extends DaikinError {
13
+ constructor(message: string);
14
+ }
15
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;IAGlC;8EAC0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,MAAM;IAJjC,YACE,OAAO,EAAE,MAAM;IACf;8EAC0E;IACjE,cAAc,EAAE,MAAM,EAIhC;CACF;AAED;yDACyD;AACzD,qBAAa,qBAAsB,SAAQ,WAAW;IACpD,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF"}
package/dist/error.js ADDED
@@ -0,0 +1,20 @@
1
+ export class DaikinError extends Error {
2
+ httpStatusCode;
3
+ constructor(message,
4
+ /** The adapter's own HTTP status, or the status this package gives a
5
+ * failure that has none: the README's "Errors and retries" lists them. */
6
+ httpStatusCode) {
7
+ super(message);
8
+ this.httpStatusCode = httpStatusCode;
9
+ this.name = "DaikinError";
10
+ }
11
+ }
12
+ /** The adapter refused or dropped the connection before answering. The only
13
+ * failure `withRetry` repeats: see DESIGN.md#retries. */
14
+ export class DaikinConnectionError extends DaikinError {
15
+ constructor(message) {
16
+ super(message, 503);
17
+ this.name = "DaikinConnectionError";
18
+ }
19
+ }
20
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,WAAY,SAAQ,KAAK;IAKzB,cAAc;IAJzB,YACE,OAAe;IACf;8EAC0E;IACjE,cAAsB;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;8BAFN,cAAc;QAGvB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;yDACyD;AACzD,MAAM,OAAO,qBAAsB,SAAQ,WAAW;IACpD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ import type { DaikinClient } from "./clients/client.js";
2
+ import type { DaikinDevice } from "./models/device.js";
3
+ import { type DaikinRetryOptions, type DaikinTlsOptions } from "./transport.js";
4
+ export interface CreateDaikinClientOptions {
5
+ /** The terminal uuid, sent as `X-Daikin-uuid`. Generate one and reuse it:
6
+ * an adapter that requires registration remembers it. */
7
+ terminalUuid: string;
8
+ /** The child lock code, for a device whose `requiresLocalPassword` is true. */
9
+ localPassword?: string;
10
+ /** How long, in milliseconds, a request waits for the adapter. Defaults to
11
+ * 10000: see `DaikinTransportOptions.timeoutInMs`. */
12
+ timeoutInMs?: number;
13
+ /** The waits between retries of a refused or dropped connection. Defaults to
14
+ * waits of 0, 50, 100, 200 and 400 milliseconds: see
15
+ * `DaikinRetryOptions.delaysInMs`. */
16
+ retry?: DaikinRetryOptions;
17
+ /** HTTPS adapters only. Without a CA the adapter's certificate isn't verified. */
18
+ tls?: DaikinTlsOptions;
19
+ }
20
+ /** Builds the client for a device: a `DsiotDaikinClient` when
21
+ * `device.protocol` is `dsiot`, a `ClassicDaikinClient` otherwise. The client
22
+ * sends over HTTPS when `device.usesHttps` is set, and sends the local
23
+ * password when `options.localPassword` is given. Call `close` on the client
24
+ * when done with the unit. */
25
+ export declare function createDaikinClient(device: DaikinDevice, options: CreateDaikinClientOptions): DaikinClient;
26
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EAEtB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,yBAAyB;IACxC;6DACyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;0DACsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;0CAEsC;IACtC,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,kFAAkF;IAClF,GAAG,CAAC,EAAE,gBAAgB,CAAC;CACxB;AAED;;;;8BAI8B;AAC9B,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,yBAAyB,GACjC,YAAY,CAad"}