mclimate-payload-helper 1.3.4 → 1.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 (61) hide show
  1. package/CONTEXT.md +165 -0
  2. package/dist/decoders/commandsReadingHelper.d.ts.map +1 -1
  3. package/dist/decoders/commandsReadingHelper.js +64 -2
  4. package/dist/decoders/commandsReadingHelper.js.map +1 -1
  5. package/dist/decoders/payloadParsers/types/vicki.d.ts +2 -0
  6. package/dist/decoders/payloadParsers/types/vicki.d.ts.map +1 -1
  7. package/dist/decoders/payloadParsers/vickiPayloadParser.d.ts.map +1 -1
  8. package/dist/decoders/payloadParsers/vickiPayloadParser.js +4 -0
  9. package/dist/decoders/payloadParsers/vickiPayloadParser.js.map +1 -1
  10. package/dist/encoders/FanCoilThermostatCommands.d.ts +7 -0
  11. package/dist/encoders/FanCoilThermostatCommands.d.ts.map +1 -1
  12. package/dist/encoders/FanCoilThermostatCommands.js +63 -2
  13. package/dist/encoders/FanCoilThermostatCommands.js.map +1 -1
  14. package/dist/encoders/FanCoilThermostatCommands.test.js +21 -0
  15. package/dist/encoders/FanCoilThermostatCommands.test.js.map +1 -1
  16. package/dist/encoders/HTSensorCommands.d.ts +4 -0
  17. package/dist/encoders/HTSensorCommands.d.ts.map +1 -1
  18. package/dist/encoders/HTSensorCommands.js +50 -0
  19. package/dist/encoders/HTSensorCommands.js.map +1 -1
  20. package/dist/encoders/HTSensorCommands.test.js +18 -0
  21. package/dist/encoders/HTSensorCommands.test.js.map +1 -1
  22. package/dist/encoders/TValveCommands.d.ts +1 -0
  23. package/dist/encoders/TValveCommands.d.ts.map +1 -1
  24. package/dist/encoders/TValveCommands.js +3 -0
  25. package/dist/encoders/TValveCommands.js.map +1 -1
  26. package/dist/encoders/TValveCommands.test.js +3 -0
  27. package/dist/encoders/TValveCommands.test.js.map +1 -1
  28. package/dist/encoders/VickiCommands.d.ts +6 -0
  29. package/dist/encoders/VickiCommands.d.ts.map +1 -1
  30. package/dist/encoders/VickiCommands.js +76 -0
  31. package/dist/encoders/VickiCommands.js.map +1 -1
  32. package/dist/encoders/VickiCommands.test.js +33 -0
  33. package/dist/encoders/VickiCommands.test.js.map +1 -1
  34. package/dist/encoders/WirelessThermostatCommands.d.ts +5 -0
  35. package/dist/encoders/WirelessThermostatCommands.d.ts.map +1 -1
  36. package/dist/encoders/WirelessThermostatCommands.js +57 -0
  37. package/dist/encoders/WirelessThermostatCommands.js.map +1 -1
  38. package/dist/encoders/WirelessThermostatCommands.test.js +21 -0
  39. package/dist/encoders/WirelessThermostatCommands.test.js.map +1 -1
  40. package/dist/encoders/types/schemas.d.ts +402 -24
  41. package/dist/encoders/types/schemas.d.ts.map +1 -1
  42. package/dist/encoders/types/schemas.js +67 -1
  43. package/dist/encoders/types/schemas.js.map +1 -1
  44. package/dist/test/payloadDecoders.test.js +90 -0
  45. package/dist/test/payloadDecoders.test.js.map +1 -1
  46. package/package.json +1 -1
  47. package/src/decoders/commandsReadingHelper.ts +59 -2
  48. package/src/decoders/payloadParsers/types/vicki.ts +2 -0
  49. package/src/decoders/payloadParsers/vickiPayloadParser.ts +4 -0
  50. package/src/encoders/FanCoilThermostatCommands.test.ts +38 -0
  51. package/src/encoders/FanCoilThermostatCommands.ts +66 -2
  52. package/src/encoders/HTSensorCommands.test.ts +34 -0
  53. package/src/encoders/HTSensorCommands.ts +50 -0
  54. package/src/encoders/TValveCommands.test.ts +4 -0
  55. package/src/encoders/TValveCommands.ts +4 -0
  56. package/src/encoders/VickiCommands.test.ts +59 -0
  57. package/src/encoders/VickiCommands.ts +76 -0
  58. package/src/encoders/WirelessThermostatCommands.test.ts +38 -0
  59. package/src/encoders/WirelessThermostatCommands.ts +60 -0
  60. package/src/encoders/types/schemas.ts +104 -2
  61. package/src/test/payloadDecoders.test.ts +98 -0
package/CONTEXT.md ADDED
@@ -0,0 +1,165 @@
1
+ # CONTEXT.md
2
+
3
+ This file is the canonical, high-level reference for the `mclimate-payload-helper` repository. It is intended for AI assistants and new contributors so they can orient quickly without re-reading the entire codebase.
4
+
5
+ ## 1. Project Overview
6
+
7
+ - **Name:** `mclimate-payload-helper` (npm package)
8
+ - **Version:** `1.3.4` (see `package.json`)
9
+ - **Language / Runtime:** TypeScript, compiled to CommonJS for Node.js consumers
10
+ - **Purpose:** Encode LoRaWAN downlink commands and decode uplink payloads for MClimate IoT devices (Vicki, Relay 16, T-Valve, T-Flood, CO₂ sensors/displays, Fan-Coil thermostat, PIR Mini, etc.).
11
+ - **Distribution:** Published to npm; consumers import `uplinkPayloadParser`, `CommandBuilder`, `DeviceType`, schemas and per-device command classes.
12
+ - **License:** ISC. **Author:** MClimate.
13
+
14
+ ## 2. Tech Stack and Dependencies
15
+
16
+ - **Runtime dep:** `zod` (^3.23.8) — schema validation for command parameters.
17
+ - **Build:** `typescript` (^5.5.4) + `tsc-alias` (resolves `@/*` path aliases in emitted JS) + `typescript-transform-paths` (rewrites paths inside `.d.ts`).
18
+ - **Test:** `jest` (^29) + `ts-jest`.
19
+ - **Lint/Format:** `eslint` (with `@typescript-eslint`), `prettier`, `eslint-config-prettier`, `eslint-plugin-jest`.
20
+ - **Git hooks:** `husky` runs format/type-check/lint/test on pre-commit (see `.husky/pre-commit`).
21
+ - **TS Config:** `target: ES2016`, `module: commonjs`, `strict: true`, `rootDir: ./src`, `outDir: ./dist`, path alias `@/* -> ./src/*` (see `tsconfig.json`).
22
+
23
+ ## 3. Project Structure
24
+
25
+ ```
26
+ .
27
+ ├── src/
28
+ │ ├── index.ts # Public package entry — re-exports parser, CommandBuilder, device commands, schemas, enums, CustomError
29
+ │ ├── decoders/
30
+ │ │ ├── index.ts
31
+ │ │ ├── commandsReadingHelper.ts # Large helper that decodes command-response bytes embedded in keepalives
32
+ │ │ └── payloadParsers/
33
+ │ │ ├── index.ts
34
+ │ │ ├── uplinkPayloadParser.ts # Switch on DeviceType → device-specific parser
35
+ │ │ ├── <Device>PayloadParser.ts # One file per device (Vicki, HTSensor, TFlood, TValve, CO2*, Relay16*, PirMini, MultiSensor, Melissa, etc.)
36
+ │ │ └── types/ # DeviceType enum + Vicki/Relay enum types
37
+ │ ├── encoders/
38
+ │ │ ├── index.ts # Re-exports BaseCommand, CommandBuilder, all device command classes & mixins
39
+ │ │ ├── BaseCommand.ts # Hex serialization (cmdId + params → hex string)
40
+ │ │ ├── CommandBuilder.ts # Registry: device_type → command class; build(command, params), combine([...])
41
+ │ │ ├── GeneralCommands.ts # Shared commands (keepalive, uplinkType, watchdog, region, customHex, joinRetry, deviceVersion)
42
+ │ │ ├── DisplayCommands.ts # Mixin
43
+ │ │ ├── TemperatureCommonCommands.ts # Mixin
44
+ │ │ ├── PIRCommands.ts # Mixin
45
+ │ │ ├── ChildLockCommands.ts # Mixin
46
+ │ │ ├── <Device>Commands.ts # One per device, extends GeneralCommands (+ mixins via applyMixins)
47
+ │ │ ├── <Device>Commands.test.ts # Jest tests colocated with each command class
48
+ │ │ └── types/
49
+ │ │ ├── index.ts
50
+ │ │ └── schemas.ts # All Zod schemas + per-device enums (large, ~82KB)
51
+ │ ├── helpers/ # byteArrayParser, decbin, toBool
52
+ │ ├── utils/ # caseConverter (toCamelCase), customErrorHandler (CustomError), decToHex, delMethods, mixin (applyMixins)
53
+ │ └── test/
54
+ │ └── payloadDecoders.test.ts # Consolidated decoder tests (all devices)
55
+ ├── docs/ # External LoRaWAN API docs (PDFs + how-to-add-new-device.md, PIR Mini API)
56
+ ├── add-encoder-command-existing.md # Step-by-step guide for adding a command to an existing device
57
+ ├── add-encoder-command-new.md # Step-by-step guide for adding a brand-new device
58
+ ├── README.md # Public-facing usage doc
59
+ ├── CLAUDE.md # AI assistant guidance (overlap with this file)
60
+ ├── package.json / package-lock.json
61
+ ├── tsconfig.json
62
+ ├── jest.config.ts
63
+ ├── .eslintrc.cjs / .prettierrc
64
+ └── .husky/pre-commit
65
+ ```
66
+
67
+ ## 4. Core Flows
68
+
69
+ ### 4.1 Uplink decode flow
70
+
71
+ 1. Consumer calls `uplinkPayloadParser(hexData, DeviceType)` (`src/decoders/payloadParsers/uplinkPayloadParser.ts`).
72
+ 2. Switch dispatches to a device-specific parser function (e.g. `vickiPayloadParser`, `pirMiniPayloadParser`).
73
+ 3. The parser reads bytes (hex pairs) from the head, identifies the frame type by the first byte (e.g. keepalive command id), and returns a typed object of decoded fields (temperatures, humidity, battery, status flags, etc.).
74
+ 4. If the frame contains a response to a previously-sent command, the parser delegates remaining bytes to `commandsReadingHelper.ts`, which switches on the response cmdId to populate the appropriate fields.
75
+ 5. **Default fallback:** if `DeviceType` does not match any case, `vickiPayloadParser` is used (see TODO comment in `uplinkPayloadParser.ts`).
76
+
77
+ ### 4.2 Downlink encode flow
78
+
79
+ 1. Consumer constructs `new CommandBuilder(device_type)` (string matching the `DeviceType` enum value, e.g. `'vicki'`).
80
+ 2. Calls `.build(commandName, params?)`.
81
+ - `commandName` is converted via `toCamelCase` (snake_case or kebab → camelCase), then looked up as a static method on the registered command class.
82
+ - The static method validates `params` with a Zod schema from `src/encoders/types/schemas.ts`; on failure, throws a `CustomError` wrapping the `ZodError`.
83
+ - On success it returns a `BaseCommand(cmdName, cmdId, ...hexParams)`.
84
+ 3. `BaseCommand.toHex()` produces the wire hex (cmdId padded to 2 chars + each param padded to 2 chars). Special case for `SetOpenWindow` skips param padding.
85
+ 4. Multiple commands can be concatenated for a single downlink via `commandBuilder.combine([cmd1, cmd2, ...])`.
86
+
87
+ ### 4.3 Mixin / inheritance pattern
88
+
89
+ - `GeneralCommands` is the base class — every device class extends it.
90
+ - Reusable command sets live in mixin classes (`DisplayCommands`, `TemperatureCommonCommands`, `PIRCommands`, `ChildLockCommands`).
91
+ - Mixins are applied via `applyMixins` in `src/utils/mixin.ts`. `delMethods` is used to remove inherited methods that don't apply to a particular device.
92
+
93
+ ## 5. Data Stores
94
+
95
+ None. This package is a pure library — no database, no cache, no I/O at runtime. All inputs are hex strings / JS objects; outputs are decoded objects / hex strings.
96
+
97
+ ## 6. Environment Variables
98
+
99
+ None required by the library or its tests.
100
+
101
+ ## 7. How to Run and Test
102
+
103
+ ```bash
104
+ npm install
105
+ npm run build # tsc + tsc-alias → ./dist
106
+ npm test # jest
107
+ npm test -- VickiCommands # filter by file/pattern
108
+ npm run type-check # tsc --noEmit
109
+ npm run lint # eslint
110
+ npm run format # prettier --write .
111
+ npm run format:check # prettier --check .
112
+ ```
113
+
114
+ Publishing:
115
+
116
+ ```bash
117
+ npm version patch|minor|major # bump + git tag
118
+ npm publish # prepublishOnly runs build
119
+ ```
120
+
121
+ ## 8. Key Patterns and Conventions
122
+
123
+ - **Path alias `@/`** maps to `src/` everywhere (imports, tests, build output).
124
+ - **Public entry** is `src/index.ts` only — keep new exports there.
125
+ - **Device registration is three-sided.** When adding a device, all three sides must be updated:
126
+ 1. `DeviceType` enum in `src/decoders/payloadParsers/types/allDevices.ts`.
127
+ 2. Decoder: new `xxxPayloadParser.ts` exported via `src/decoders/payloadParsers/index.ts` and wired into the switch in `uplinkPayloadParser.ts`.
128
+ 3. Encoder: new `XxxCommands.ts` (extends `GeneralCommands`, optional mixins) exported via `src/encoders/index.ts`, registered in `CommandBuilder.commandRegistry`, and re-exported in `src/index.ts`. Add Zod schemas + enums under `src/encoders/types/schemas.ts`.
129
+ - **Command class style:** all commands are `static` methods on the class. Each set/get pair returns `new BaseCommand(name, cmdId, ...params)`. `decToHex` from `src/utils/decToHex.ts` is the standard numeric-to-hex helper.
130
+ - **Validation:** every command with parameters parses with Zod first, wrapping failures in `CustomError` (`src/utils/customErrorHandler.ts`).
131
+ - **Error type:** `CustomError` is the only error type the library throws publicly.
132
+ - **Tests live next to encoders** (`<Class>.test.ts`); decoder tests are consolidated in `src/test/payloadDecoders.test.ts`.
133
+ - **Encoding helpers:** keep numeric → hex conversions in `src/utils/decToHex.ts`. Bit/byte parsing helpers live in `src/helpers/` (`byteArrayParser`, `decbin`, `toBool`).
134
+ - **Naming:** Device class files are PascalCase (`VickiCommands.ts`); decoder parser files are mixed (`vickiPayloadParser.ts`, `htSensorPayloadParser.ts`, `CO2SensorPayloadParser.ts`) — match the existing neighbours when adding new ones.
135
+
136
+ ## 9. Known Gotchas
137
+
138
+ - **`uplinkPayloadParser` defaults to Vicki** when an unknown `DeviceType` is passed (see comment `// Q: is this OK?`). New devices that aren't wired into the switch will silently be parsed as Vicki.
139
+ - **`BaseCommand.toHex` has a Vicki-specific branch** for `SetOpenWindow` (skips per-param padding). Don't reuse that command name elsewhere.
140
+ - **`CommandBuilder.build` uses `toCamelCase`** on the command string; consumers can pass `"set_target_temperature"` or `"setTargetTemperature"` and both resolve. Method names on command classes must therefore be camelCase.
141
+ - **`commandsReadingHelper.ts` is shared across devices.** The same response cmdId can mean different things on different devices (e.g. `0x3d` → `pirDemoMode` for PirMini, `integralGain` for Vicki, `pirSensorStatus` elsewhere). When adding a new response, check existing case branches before reusing a byte.
142
+ - **Husky pre-commit is strict:** format-check, type-check, lint, and tests must all pass. CI/local commits will fail otherwise.
143
+ - **`prepublishOnly` runs `npm run build`.** Always bump the version in `package.json` before `npm publish` or it will be rejected by the registry.
144
+ - **Mixins + `delMethods`:** if a device inherits a command via a mixin that it should not expose, it must explicitly delete that method (pattern used in several command classes).
145
+
146
+ ## 10. Key Files to Read First
147
+
148
+ When starting a new task, read these in order:
149
+
150
+ 1. `src/index.ts` — public API surface.
151
+ 2. `src/decoders/payloadParsers/uplinkPayloadParser.ts` and `src/decoders/payloadParsers/types/allDevices.ts` — supported devices.
152
+ 3. `src/encoders/CommandBuilder.ts` — device → command-class registry.
153
+ 4. `src/encoders/BaseCommand.ts` and `src/encoders/GeneralCommands.ts` — base command shape and shared commands.
154
+ 5. `src/encoders/types/schemas.ts` — Zod schemas + device enums (large, scan by section).
155
+ 6. `src/decoders/commandsReadingHelper.ts` — shared response decoder switch (large).
156
+ 7. The specific `<Device>PayloadParser.ts` and `<Device>Commands.ts` for the device you are touching.
157
+ 8. `add-encoder-command-existing.md` / `add-encoder-command-new.md` / `docs/how-to-add-new-device.md` — official extension checklists.
158
+
159
+ ## 11. Changelog
160
+
161
+ - **2026-05-14** — Initial `CONTEXT.md` created. Captures architecture as of `package.json` v1.3.4: 22 supported `DeviceType`s, mixin-based encoder hierarchy, single shared `commandsReadingHelper`, Zod-validated command params, colocated encoder tests + consolidated decoder tests.
162
+ - **2026-05-14** — Added `FanCoilThermostatCommands.getFctOperationalMode` (cmdId `0x53`) in `src/encoders/FanCoilThermostatCommands.ts`. Added a `DeviceType.FanCoilThermostat` branch to case `'53'` in `src/decoders/commandsReadingHelper.ts` that decodes the byte as `fctOperationalMode` (raw int, 0=Vent / 1=Heat / 2=Cool) while leaving the default `targetTemperatureStep` decoding intact for other devices. Encoder + decoder tests added (`FanCoilThermostatCommands.test.ts`, `payloadDecoders.test.ts`). Reinforces the existing pattern of guarding shared response cmdIds by `deviceType` (gotcha §9).
163
+ - **2026-05-19** — Audited `VickiCommands` against the official Vicki cheat-sheet (`docs.mclimate.eu/.../command-cheat-sheet`). Only one documented GET was missing: `0x52` _GET Target temperature with resolution 0.1°C_. Added `VickiCommands.getTargetTemperaturePrecisely()` returning `BaseCommand('GetTargetTemperaturePrecisely', 0x52)`, a matching no-param Zod schema entry in `VickiCommandSchemas`, and an encoder test. Decoder already handles case `'52'` as `targetTemperatureFloat` (2-byte / 10) for all devices, so no `commandsReadingHelper` change needed. All other documented Vicki GETs (incl. `0x14`/`0x15` via `ChildLockCommands`/`TemperatureCommonCommands` mixins and `0x12`/`0x19`/`0x1b`/`0x1d`/`0xa4` via `GeneralCommands`) are already present.
164
+ - **2026-05-19** — Completed Vicki SET audit. Two documented SETs were missing: `0x33` _Set LoRaWAN AppEUI & AppKey_ (≥4.1) and `0x57` _SET target temperature in Fahrenheit_ (≥4.4). Added `setAppEuiAndAppKey({ appEui: hex16, appKey: hex32 })` and `setTargetTemperatureFahrenheit({ targetTemperature: 41–86 })` to `VickiCommands.ts`, matching Zod schemas (`appEui`/`appKey` are hex-string-typed with regex + length), type exports, and 4 new tests (encode + zod-fail per command). All other documented Vicki SETs were already present (incl. `0x4e`/`0x4f` valve openness, `0x59`/`0x5b`/`0x5d`/`0x5f`/`0x61`/`0x63`/`0x65`/`0x67`/`0x69`/`0x6b`/`0x6d` heating-schedule/time/setback/etc.). `0x58` _Additional notifications_ and `0xa6` _External crystal not working_ are uplink-only — out of scope.
165
+ - **2026-05-19** — HT-Sensor D2D protocol additions (per internal _HT new commands (1).odt_). **Encoder** (`HTSensorCommands.ts`): added `setD2dCommunicationState({ enabled: boolean })` (`0xa9`), `getD2dCommunicationState()` (`0xaa`), `setD2dCommunicationPeriod({ period: 1–8 min })` (`0xab`), `getD2dCommunicationPeriod()` (`0xac`). **Decoder** (`commandsReadingHelper.ts`): added `HTSensor`-guarded branches for cases `'aa'` → `d2dCommunicationState: boolean` and `'ac'` → `d2dCommunicationPeriod: number`. **Schemas** (`schemas.ts`): 4 new entries in `HTSensorCommandSchemas` + 2 type exports. 9 new tests (6 encoder + 3 decoder). 324/324 passing.\n- **2026-05-19** — Vicki keep-alive bit-by-bit audit (current docs `/vicki-lorawan-device-communication-protocol/keep-alive`). Only one bit was missing from `vickiPayloadParser`: byte 8 bit 1 → `batteryTooLow`. Pre-4.6 docs label that bit as "Reserved", but current spec exposes it. Added `batteryTooLow: boolean` to `VickiKeepAliveData` type and parser. All 5 existing Vicki keepalive snapshots updated (`batteryTooLow: false` since byte 8 = `0x30`/`0x34` in fixtures). New regression test with byte 8 = `0x32` confirms `batteryTooLow: true`. All other byte 7/8 bits were already covered.\n- **2026-05-19** — Vicki D2D / HT-sensor protocol additions (per internal _Vicki new commands (7).odt_). **Encoder:** added `setD2dNotificationDeviceAppKey({ appKey: hex32 })` (`0x6f` + 16-byte AppKey), `getD2dNotificationDeviceAppKey()` (`0x70`), `requestListenForD2dNotificationDevice()` (`0x71`). Extended `VickiCommandSchemas.setOperationalMode` enum + `VickiEnums.setOperationalMode` to include mode `'03'` (Online automatic with HT-sensor D2D temp). **Decoder:** added Vicki branches to `case '70'` (16-byte AppKey → `d2dNotificationDeviceAppKey` as uppercase hex) and `case '72'` (2-byte temp/10 → `htSensorTemperature`) in `commandsReadingHelper.ts`; other devices' existing handling on those bytes is preserved. **Keep-alive:** `vickiPayloadParser` now exposes `d2dCommunicationReliable` (byte 8 bit 2, previously reserved). `VickiKeepAliveData` type updated. Existing keepalive snapshot tests updated to include the new field (all `false` since byte 8 = `0x30`). 8 new tests added (3 decoder + 5 encoder). 314/314 passing.\n- **2026-05-19** — Thermostat-family audit (WirelessThermostat, FanCoilThermostat, T-Valve) against official cheat-sheets. **WirelessThermostat** (`WirelessThermostatCommands.ts`): added 5 commands — `0x55`/`0x56` `setSensorCompensationTemperature`/`getSensorCompensationTemperature` (sign-byte + abs\*10), `0x5d`/`0x5e` `setTemperatureMeasurementPeriod`/`getTemperatureMeasurementPeriod` (minutes 1–255), and `0xa5` `restartDevice`. **FanCoilThermostat** (`FanCoilThermostatCommands.ts`): added 6 commands — `0x2f` `getTargetTemperature`, `0x3b` `setExtTemperatureSensor1C` (int 1–99°C), `0x3c` `setExtTemperatureSensor` (0.1–99.9°C, 2-byte payload), `0x3e` `getExtTemperatureSensor`, `0x74` `getModeChangedByAutoChangeover`, `0x75` `getPowerModuleCommunicationStatus`. Also fixed two pre-existing `BaseCommand`-name bugs in FCT: the `0x77` get-method emitted name `'SetHeatingCoolingTargetTempRangesUnoccupied'` (now `'Get…'`) and `0x79` emitted `'getFanOffDelayTime'` (now `'GetFanOffDelayTime'`). **T-Valve** (`TValveCommands.ts`): added `0x0b` `deactivateDevice`. Matching Zod schemas + type exports added in `schemas.ts`; 14 new tests added (encode + zod-fail where applicable). **Out of scope** for this batch: `Thermostat` (T-Ring) and `MelissaLorawan` — no public cheat-sheets exist at `docs.mclimate.eu` for these two; their command sets are bespoke (TRing uses 6-byte fixed-format commands, Melissa only has IR recording at `0x09`) and verifying against firmware would require the internal MClimate spec, not the public docs.
@@ -1 +1 @@
1
- {"version":3,"file":"commandsReadingHelper.d.ts","sourceRoot":"","sources":["../../src/decoders/commandsReadingHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAG5D,eAAO,MAAM,qBAAqB,YAAa,MAAM,iBAAiB,MAAM,cAAc,UAAU,mBAqzFnG,CAAA"}
1
+ {"version":3,"file":"commandsReadingHelper.d.ts","sourceRoot":"","sources":["../../src/decoders/commandsReadingHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAG5D,eAAO,MAAM,qBAAqB,YAAa,MAAM,iBAAiB,MAAM,cAAc,UAAU,mBA82FnG,CAAA"}
@@ -1801,8 +1801,15 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
1801
1801
  case '53':
1802
1802
  {
1803
1803
  try {
1804
- command_len = 1;
1805
- const data = { targetTemperatureStep: parseInt(commands[i + 1], 16) / 10 };
1804
+ let data;
1805
+ if (deviceType === types_1.DeviceType.FanCoilThermostat) {
1806
+ command_len = 1;
1807
+ data = { fctOperationalMode: parseInt(commands[i + 1], 16) };
1808
+ }
1809
+ else {
1810
+ command_len = 1;
1811
+ data = { targetTemperatureStep: parseInt(commands[i + 1], 16) / 10 };
1812
+ }
1806
1813
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
1807
1814
  }
1808
1815
  catch (e) {
@@ -2299,6 +2306,15 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
2299
2306
  command_len = 2;
2300
2307
  data = { overheatingRecoveryTime: (parseInt(commands[i + 1], 16) << 8) | parseInt(commands[i + 2], 16) };
2301
2308
  }
2309
+ else if (deviceType === types_1.DeviceType.Vicki) {
2310
+ command_len = 16;
2311
+ data = {
2312
+ d2dNotificationDeviceAppKey: commands
2313
+ .slice(i + 1, i + 17)
2314
+ .join('')
2315
+ .toUpperCase(),
2316
+ };
2317
+ }
2302
2318
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2303
2319
  }
2304
2320
  catch (e) {
@@ -2349,6 +2365,12 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
2349
2365
  command_len = 1;
2350
2366
  data = { overcurrentRecoveryTemp: parseInt(commands[i + 1], 16) };
2351
2367
  }
2368
+ else if (deviceType === types_1.DeviceType.Vicki) {
2369
+ command_len = 2;
2370
+ data = {
2371
+ htSensorTemperature: ((parseInt(commands[i + 1], 16) << 8) | parseInt(commands[i + 2], 16)) / 10,
2372
+ };
2373
+ }
2352
2374
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2353
2375
  }
2354
2376
  catch (e) {
@@ -3001,6 +3023,46 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
3001
3023
  }
3002
3024
  }
3003
3025
  break;
3026
+ case 'aa':
3027
+ {
3028
+ try {
3029
+ if (deviceType === types_1.DeviceType.HTSensor) {
3030
+ command_len = 1;
3031
+ const data = { d2dCommunicationState: parseInt(commands[i + 1], 16) === 1 };
3032
+ Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
3033
+ }
3034
+ }
3035
+ catch (e) {
3036
+ throw new utils_1.CustomError({
3037
+ message: `Failed to process command 'aa'`,
3038
+ hexData,
3039
+ command,
3040
+ deviceType,
3041
+ originalError: e,
3042
+ });
3043
+ }
3044
+ }
3045
+ break;
3046
+ case 'ac':
3047
+ {
3048
+ try {
3049
+ if (deviceType === types_1.DeviceType.HTSensor) {
3050
+ command_len = 1;
3051
+ const data = { d2dCommunicationPeriod: parseInt(commands[i + 1], 16) };
3052
+ Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
3053
+ }
3054
+ }
3055
+ catch (e) {
3056
+ throw new utils_1.CustomError({
3057
+ message: `Failed to process command 'ac'`,
3058
+ hexData,
3059
+ command,
3060
+ deviceType,
3061
+ originalError: e,
3062
+ });
3063
+ }
3064
+ }
3065
+ break;
3004
3066
  default:
3005
3067
  decodeKeepalive(commands, payloadLength, deviceType);
3006
3068
  commands.splice(i, commands.length);