daikin-local-control 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +156 -2
- package/README.md +274 -48
- package/UNSUPPORTED.md +66 -3
- package/dist/clients/airbase.d.ts +64 -0
- package/dist/clients/airbase.d.ts.map +1 -0
- package/dist/clients/airbase.js +175 -0
- package/dist/clients/airbase.js.map +1 -0
- package/dist/clients/classic.d.ts +2 -2
- package/dist/clients/classic.d.ts.map +1 -1
- package/dist/clients/classic.js +4 -4
- package/dist/clients/classic.js.map +1 -1
- package/dist/clients/client.d.ts +7 -2
- package/dist/clients/client.d.ts.map +1 -1
- package/dist/clients/dsiot.d.ts +3 -1
- package/dist/clients/dsiot.d.ts.map +1 -1
- package/dist/clients/dsiot.js +7 -2
- package/dist/clients/dsiot.js.map +1 -1
- package/dist/codecs/airbase/capabilities.d.ts +23 -0
- package/dist/codecs/airbase/capabilities.d.ts.map +1 -0
- package/dist/codecs/airbase/capabilities.js +108 -0
- package/dist/codecs/airbase/capabilities.js.map +1 -0
- package/dist/codecs/airbase/state.d.ts +29 -0
- package/dist/codecs/airbase/state.d.ts.map +1 -0
- package/dist/codecs/airbase/state.js +166 -0
- package/dist/codecs/airbase/state.js.map +1 -0
- package/dist/codecs/airbase/tables.d.ts +7 -0
- package/dist/codecs/airbase/tables.d.ts.map +1 -0
- package/dist/codecs/airbase/tables.js +27 -0
- package/dist/codecs/airbase/tables.js.map +1 -0
- package/dist/codecs/airbase/zone.d.ts +12 -0
- package/dist/codecs/airbase/zone.d.ts.map +1 -0
- package/dist/codecs/airbase/zone.js +50 -0
- package/dist/codecs/airbase/zone.js.map +1 -0
- package/dist/codecs/classic/capabilities.d.ts.map +1 -1
- package/dist/codecs/classic/capabilities.js +5 -11
- package/dist/codecs/classic/capabilities.js.map +1 -1
- package/dist/codecs/classic/extendedControl.d.ts.map +1 -1
- package/dist/codecs/classic/extendedControl.js +10 -19
- package/dist/codecs/classic/extendedControl.js.map +1 -1
- package/dist/codecs/classic/state.d.ts.map +1 -1
- package/dist/codecs/classic/state.js +36 -95
- package/dist/codecs/classic/state.js.map +1 -1
- package/dist/codecs/classic/tables.d.ts +34 -0
- package/dist/codecs/classic/tables.d.ts.map +1 -0
- package/dist/codecs/classic/tables.js +96 -0
- package/dist/codecs/classic/tables.js.map +1 -0
- package/dist/codecs/credentials.d.ts +3 -2
- package/dist/codecs/credentials.d.ts.map +1 -1
- package/dist/codecs/credentials.js +8 -3
- package/dist/codecs/credentials.js.map +1 -1
- package/dist/codecs/device.d.ts +7 -1
- package/dist/codecs/device.d.ts.map +1 -1
- package/dist/codecs/device.js +15 -3
- package/dist/codecs/device.js.map +1 -1
- package/dist/codecs/dsiot/capabilities.d.ts.map +1 -1
- package/dist/codecs/dsiot/capabilities.js +8 -15
- package/dist/codecs/dsiot/capabilities.js.map +1 -1
- package/dist/codecs/dsiot/device.d.ts.map +1 -1
- package/dist/codecs/dsiot/device.js +4 -8
- package/dist/codecs/dsiot/device.js.map +1 -1
- package/dist/codecs/dsiot/multireq.d.ts +0 -19
- package/dist/codecs/dsiot/multireq.d.ts.map +1 -1
- package/dist/codecs/dsiot/multireq.js +2 -25
- package/dist/codecs/dsiot/multireq.js.map +1 -1
- package/dist/codecs/dsiot/state.d.ts +6 -62
- package/dist/codecs/dsiot/state.d.ts.map +1 -1
- package/dist/codecs/dsiot/state.js +29 -148
- package/dist/codecs/dsiot/state.js.map +1 -1
- package/dist/codecs/dsiot/tables.d.ts +119 -0
- package/dist/codecs/dsiot/tables.d.ts.map +1 -0
- package/dist/codecs/dsiot/tables.js +188 -0
- package/dist/codecs/dsiot/tables.js.map +1 -0
- package/dist/discovery.d.ts +20 -9
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +102 -32
- package/dist/discovery.js.map +1 -1
- package/dist/factory.d.ts +13 -7
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +16 -4
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/models/device.d.ts +3 -2
- package/dist/models/device.d.ts.map +1 -1
- package/dist/models/device.js +1 -1
- package/dist/models/device.js.map +1 -1
- package/dist/models/state.d.ts +2 -3
- package/dist/models/state.d.ts.map +1 -1
- package/dist/models/zone.d.ts +9 -0
- package/dist/models/zone.d.ts.map +1 -0
- package/dist/models/zone.js +2 -0
- package/dist/models/zone.js.map +1 -0
- package/dist/simulators/airbase.d.ts +82 -0
- package/dist/simulators/airbase.d.ts.map +1 -0
- package/dist/simulators/airbase.js +352 -0
- package/dist/simulators/airbase.js.map +1 -0
- package/dist/simulators/classic.d.ts +61 -0
- package/dist/simulators/classic.d.ts.map +1 -0
- package/dist/simulators/classic.js +473 -0
- package/dist/simulators/classic.js.map +1 -0
- package/dist/simulators/dsiot.d.ts +49 -0
- package/dist/simulators/dsiot.d.ts.map +1 -0
- package/dist/simulators/dsiot.js +519 -0
- package/dist/simulators/dsiot.js.map +1 -0
- package/dist/simulators/index.d.ts +5 -0
- package/dist/simulators/index.d.ts.map +1 -0
- package/dist/simulators/index.js +4 -0
- package/dist/simulators/index.js.map +1 -0
- package/dist/simulators/simulator.d.ts +117 -0
- package/dist/simulators/simulator.d.ts.map +1 -0
- package/dist/simulators/simulator.js +141 -0
- package/dist/simulators/simulator.js.map +1 -0
- package/dist/transport.d.ts +8 -3
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +10 -2
- package/dist/transport.js.map +1 -1
- package/package.json +11 -4
- package/src/clients/airbase.ts +274 -0
- package/src/clients/classic.ts +8 -8
- package/src/clients/client.ts +8 -1
- package/src/clients/dsiot.ts +8 -1
- package/src/codecs/airbase/capabilities.ts +150 -0
- package/src/codecs/airbase/state.ts +223 -0
- package/src/codecs/airbase/tables.ts +32 -0
- package/src/codecs/airbase/zone.ts +62 -0
- package/src/codecs/classic/capabilities.ts +8 -11
- package/src/codecs/classic/extendedControl.ts +14 -25
- package/src/codecs/classic/state.ts +49 -101
- package/src/codecs/classic/tables.ts +126 -0
- package/src/codecs/credentials.ts +11 -3
- package/src/codecs/device.ts +19 -3
- package/src/codecs/dsiot/capabilities.ts +10 -17
- package/src/codecs/dsiot/device.ts +4 -9
- package/src/codecs/dsiot/multireq.ts +2 -25
- package/src/codecs/dsiot/state.ts +57 -193
- package/src/codecs/dsiot/tables.ts +253 -0
- package/src/discovery.ts +107 -34
- package/src/factory.ts +26 -7
- package/src/index.ts +8 -0
- package/src/models/device.ts +3 -2
- package/src/models/state.ts +2 -3
- package/src/models/zone.ts +8 -0
- package/src/simulators/airbase.ts +495 -0
- package/src/simulators/classic.ts +636 -0
- package/src/simulators/dsiot.ts +736 -0
- package/src/simulators/index.ts +10 -0
- package/src/simulators/simulator.ts +282 -0
- package/src/transport.ts +15 -4
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type DaikinSimulator, type DaikinSimulatorUnit, type StartSimulatorOptions } from "./simulator.js";
|
|
2
|
+
/** What a simulated classic unit has. */
|
|
3
|
+
export interface ClassicSimulatorUnit extends DaikinSimulatorUnit {
|
|
4
|
+
/** How many fan levels the unit takes: `level1` and `level5` for 2,
|
|
5
|
+
* `level3` as well for 3, and all five for 5. Defaults to 5. */
|
|
6
|
+
fanLevels?: 2 | 3 | 5;
|
|
7
|
+
}
|
|
8
|
+
export interface StartClassicSimulatorOptions extends StartSimulatorOptions {
|
|
9
|
+
/** What the unit has. Defaults to a heat pump with every fan speed, swing
|
|
10
|
+
* on both axes and all three special modes. A field of `modelInfo`
|
|
11
|
+
* replaces what this sets. */
|
|
12
|
+
unit?: ClassicSimulatorUnit;
|
|
13
|
+
/** Fields added to the `/common/basic_info` reply, each replacing a default
|
|
14
|
+
* of the same name. Defaults to none. */
|
|
15
|
+
basicInfo?: Record<string, string>;
|
|
16
|
+
/** Fields added to the `/aircon/get_model_info` reply, each replacing a
|
|
17
|
+
* default of the same name. Defaults to none. */
|
|
18
|
+
modelInfo?: Record<string, string>;
|
|
19
|
+
/** Fields added to the `/aircon/get_control_info` reply, each replacing a
|
|
20
|
+
* default of the same name. Defaults to none. */
|
|
21
|
+
controlInfo?: Record<string, string>;
|
|
22
|
+
/** Fields added to the `/aircon/get_sensor_info` reply, each replacing a
|
|
23
|
+
* default of the same name. Defaults to none. */
|
|
24
|
+
sensorInfo?: Record<string, string>;
|
|
25
|
+
/** The KEY on the adapter's label. With one, the adapter requires
|
|
26
|
+
* registration: it reports `en_secure=1`, and answers a terminal uuid with
|
|
27
|
+
* HTTP 403 until `/common/register_terminal` is sent this key. Defaults to
|
|
28
|
+
* none: every terminal is answered. */
|
|
29
|
+
key?: string;
|
|
30
|
+
/** The child lock code. With one, the adapter reports `lpw_flag=1`, and
|
|
31
|
+
* answers `ret=LPW NG` to a request whose `lpw` is not this code. Defaults
|
|
32
|
+
* to none: no request needs an `lpw`. */
|
|
33
|
+
localPassword?: string;
|
|
34
|
+
}
|
|
35
|
+
/** A classic adapter and the unit behind it. Each field map is what its
|
|
36
|
+
* endpoint answers, in the adapter's own names and encodings, without the
|
|
37
|
+
* `ret`. A write through the adapter changes them, and so do `setState` and
|
|
38
|
+
* `setSensors`. Change a field directly for what those two do not cover. */
|
|
39
|
+
export interface ClassicDaikinSimulator extends DaikinSimulator {
|
|
40
|
+
/** What `/common/basic_info` answers. `name` and `grp_name` are held
|
|
41
|
+
* percent-encoded, as the reply carries them. */
|
|
42
|
+
readonly basicInfo: Record<string, string>;
|
|
43
|
+
/** What `/aircon/get_model_info` answers. */
|
|
44
|
+
readonly modelInfo: Record<string, string>;
|
|
45
|
+
/** What `/aircon/get_control_info` answers. */
|
|
46
|
+
readonly controlInfo: Record<string, string>;
|
|
47
|
+
/** What `/aircon/get_sensor_info` answers. */
|
|
48
|
+
readonly sensorInfo: Record<string, string>;
|
|
49
|
+
/** What `/common/get_remote_method` answers. */
|
|
50
|
+
readonly remoteMethod: Record<string, string>;
|
|
51
|
+
/** The terminal uuids `/common/register_terminal` has registered. Only an
|
|
52
|
+
* adapter started with a `key` checks them. */
|
|
53
|
+
readonly registeredTerminalUuids: Set<string>;
|
|
54
|
+
}
|
|
55
|
+
/** Starts a classic adapter on a free port, as a heat pump that is off, in
|
|
56
|
+
* cool at 24 °C. It answers the endpoints `ClassicDaikinClient` has a typed
|
|
57
|
+
* method for, over HTTP, and answers any other request with HTTP 501:
|
|
58
|
+
* UNSUPPORTED.md lists what it leaves out and where its answer is not known
|
|
59
|
+
* to be an adapter's. Call `stop` when done with it. */
|
|
60
|
+
export declare function startClassicSimulator(options?: StartClassicSimulatorOptions): Promise<ClassicDaikinSimulator>;
|
|
61
|
+
//# sourceMappingURL=classic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classic.d.ts","sourceRoot":"","sources":["../../src/simulators/classic.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,mBAAmB,EAGxB,KAAK,qBAAqB,EAG3B,MAAM,gBAAgB,CAAC;AAoHxB,yCAAyC;AACzC,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D;oEACgE;IAChE,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,4BAA6B,SAAQ,qBAAqB;IACzE;;kCAE8B;IAC9B,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;6CACyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;qDACiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;qDACiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC;qDACiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC;;;2CAGuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;6CAEyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;4EAG4E;AAC5E,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D;qDACiD;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,gDAAgD;IAChD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C;mDAC+C;IAC/C,QAAQ,CAAC,uBAAuB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/C;AAED;;;;wDAIwD;AACxD,wBAAsB,qBAAqB,CACzC,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,sBAAsB,CAAC,CA+LjC"}
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
import { CLASSIC_ADAPTER_TYPE, 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: CLASSIC_ADAPTER_TYPE,
|
|
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"}
|