irtxrx 0.0.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.
- package/README.md +127 -0
- package/dist/cjs/decode.d.ts +184 -0
- package/dist/cjs/decode.d.ts.map +1 -0
- package/dist/cjs/decode.js +431 -0
- package/dist/cjs/decode.js.map +1 -0
- package/dist/cjs/encode.d.ts +76 -0
- package/dist/cjs/encode.d.ts.map +1 -0
- package/dist/cjs/encode.js +185 -0
- package/dist/cjs/encode.js.map +1 -0
- package/dist/cjs/index.d.ts +34 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +99 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/protocols/coolix.d.ts +98 -0
- package/dist/cjs/protocols/coolix.d.ts.map +1 -0
- package/dist/cjs/protocols/coolix.js +331 -0
- package/dist/cjs/protocols/coolix.js.map +1 -0
- package/dist/cjs/protocols/daikin.d.ts +47 -0
- package/dist/cjs/protocols/daikin.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin.js +353 -0
- package/dist/cjs/protocols/daikin.js.map +1 -0
- package/dist/cjs/protocols/daikin128.d.ts +60 -0
- package/dist/cjs/protocols/daikin128.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin128.js +267 -0
- package/dist/cjs/protocols/daikin128.js.map +1 -0
- package/dist/cjs/protocols/daikin152.d.ts +47 -0
- package/dist/cjs/protocols/daikin152.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin152.js +256 -0
- package/dist/cjs/protocols/daikin152.js.map +1 -0
- package/dist/cjs/protocols/daikin160.d.ts +37 -0
- package/dist/cjs/protocols/daikin160.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin160.js +176 -0
- package/dist/cjs/protocols/daikin160.js.map +1 -0
- package/dist/cjs/protocols/daikin176.d.ts +44 -0
- package/dist/cjs/protocols/daikin176.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin176.js +215 -0
- package/dist/cjs/protocols/daikin176.js.map +1 -0
- package/dist/cjs/protocols/daikin2.d.ts +46 -0
- package/dist/cjs/protocols/daikin2.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin2.js +337 -0
- package/dist/cjs/protocols/daikin2.js.map +1 -0
- package/dist/cjs/protocols/daikin216.d.ts +30 -0
- package/dist/cjs/protocols/daikin216.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin216.js +167 -0
- package/dist/cjs/protocols/daikin216.js.map +1 -0
- package/dist/cjs/protocols/daikin312.d.ts +45 -0
- package/dist/cjs/protocols/daikin312.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin312.js +345 -0
- package/dist/cjs/protocols/daikin312.js.map +1 -0
- package/dist/cjs/protocols/daikin64.d.ts +79 -0
- package/dist/cjs/protocols/daikin64.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin64.js +260 -0
- package/dist/cjs/protocols/daikin64.js.map +1 -0
- package/dist/cjs/protocols/daikin_common.d.ts +28 -0
- package/dist/cjs/protocols/daikin_common.d.ts.map +1 -0
- package/dist/cjs/protocols/daikin_common.js +41 -0
- package/dist/cjs/protocols/daikin_common.js.map +1 -0
- package/dist/cjs/protocols/nec.d.ts +50 -0
- package/dist/cjs/protocols/nec.d.ts.map +1 -0
- package/dist/cjs/protocols/nec.js +180 -0
- package/dist/cjs/protocols/nec.js.map +1 -0
- package/dist/decode.d.ts +67 -0
- package/dist/decode.d.ts.map +1 -0
- package/dist/decode.js +242 -0
- package/dist/decode.js.map +1 -0
- package/dist/encode.d.ts +76 -0
- package/dist/encode.d.ts.map +1 -0
- package/dist/encode.js +174 -0
- package/dist/encode.js.map +1 -0
- package/dist/esm/decode.d.ts +184 -0
- package/dist/esm/decode.d.ts.map +1 -0
- package/dist/esm/decode.js +420 -0
- package/dist/esm/decode.js.map +1 -0
- package/dist/esm/encode.d.ts +76 -0
- package/dist/esm/encode.d.ts.map +1 -0
- package/dist/esm/encode.js +174 -0
- package/dist/esm/encode.js.map +1 -0
- package/dist/esm/index.d.ts +34 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/protocols/coolix.d.ts +98 -0
- package/dist/esm/protocols/coolix.d.ts.map +1 -0
- package/dist/esm/protocols/coolix.js +322 -0
- package/dist/esm/protocols/coolix.js.map +1 -0
- package/dist/esm/protocols/daikin.d.ts +47 -0
- package/dist/esm/protocols/daikin.d.ts.map +1 -0
- package/dist/esm/protocols/daikin.js +344 -0
- package/dist/esm/protocols/daikin.js.map +1 -0
- package/dist/esm/protocols/daikin128.d.ts +60 -0
- package/dist/esm/protocols/daikin128.d.ts.map +1 -0
- package/dist/esm/protocols/daikin128.js +260 -0
- package/dist/esm/protocols/daikin128.js.map +1 -0
- package/dist/esm/protocols/daikin152.d.ts +47 -0
- package/dist/esm/protocols/daikin152.d.ts.map +1 -0
- package/dist/esm/protocols/daikin152.js +247 -0
- package/dist/esm/protocols/daikin152.js.map +1 -0
- package/dist/esm/protocols/daikin160.d.ts +37 -0
- package/dist/esm/protocols/daikin160.d.ts.map +1 -0
- package/dist/esm/protocols/daikin160.js +167 -0
- package/dist/esm/protocols/daikin160.js.map +1 -0
- package/dist/esm/protocols/daikin176.d.ts +44 -0
- package/dist/esm/protocols/daikin176.d.ts.map +1 -0
- package/dist/esm/protocols/daikin176.js +208 -0
- package/dist/esm/protocols/daikin176.js.map +1 -0
- package/dist/esm/protocols/daikin2.d.ts +46 -0
- package/dist/esm/protocols/daikin2.d.ts.map +1 -0
- package/dist/esm/protocols/daikin2.js +328 -0
- package/dist/esm/protocols/daikin2.js.map +1 -0
- package/dist/esm/protocols/daikin216.d.ts +30 -0
- package/dist/esm/protocols/daikin216.d.ts.map +1 -0
- package/dist/esm/protocols/daikin216.js +158 -0
- package/dist/esm/protocols/daikin216.js.map +1 -0
- package/dist/esm/protocols/daikin312.d.ts +45 -0
- package/dist/esm/protocols/daikin312.d.ts.map +1 -0
- package/dist/esm/protocols/daikin312.js +336 -0
- package/dist/esm/protocols/daikin312.js.map +1 -0
- package/dist/esm/protocols/daikin64.d.ts +79 -0
- package/dist/esm/protocols/daikin64.d.ts.map +1 -0
- package/dist/esm/protocols/daikin64.js +253 -0
- package/dist/esm/protocols/daikin64.js.map +1 -0
- package/dist/esm/protocols/daikin_common.d.ts +28 -0
- package/dist/esm/protocols/daikin_common.d.ts.map +1 -0
- package/dist/esm/protocols/daikin_common.js +38 -0
- package/dist/esm/protocols/daikin_common.js.map +1 -0
- package/dist/esm/protocols/nec.d.ts +50 -0
- package/dist/esm/protocols/nec.d.ts.map +1 -0
- package/dist/esm/protocols/nec.js +175 -0
- package/dist/esm/protocols/nec.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/protocols/daikin.d.ts +47 -0
- package/dist/protocols/daikin.d.ts.map +1 -0
- package/dist/protocols/daikin.js +343 -0
- package/dist/protocols/daikin.js.map +1 -0
- package/dist/protocols/daikin128.d.ts +60 -0
- package/dist/protocols/daikin128.d.ts.map +1 -0
- package/dist/protocols/daikin128.js +259 -0
- package/dist/protocols/daikin128.js.map +1 -0
- package/dist/protocols/daikin152.d.ts +47 -0
- package/dist/protocols/daikin152.d.ts.map +1 -0
- package/dist/protocols/daikin152.js +246 -0
- package/dist/protocols/daikin152.js.map +1 -0
- package/dist/protocols/daikin160.d.ts +37 -0
- package/dist/protocols/daikin160.d.ts.map +1 -0
- package/dist/protocols/daikin160.js +166 -0
- package/dist/protocols/daikin160.js.map +1 -0
- package/dist/protocols/daikin176.d.ts +44 -0
- package/dist/protocols/daikin176.d.ts.map +1 -0
- package/dist/protocols/daikin176.js +207 -0
- package/dist/protocols/daikin176.js.map +1 -0
- package/dist/protocols/daikin2.d.ts +46 -0
- package/dist/protocols/daikin2.d.ts.map +1 -0
- package/dist/protocols/daikin2.js +326 -0
- package/dist/protocols/daikin2.js.map +1 -0
- package/dist/protocols/daikin216.d.ts +30 -0
- package/dist/protocols/daikin216.d.ts.map +1 -0
- package/dist/protocols/daikin216.js +157 -0
- package/dist/protocols/daikin216.js.map +1 -0
- package/dist/protocols/daikin312.d.ts +45 -0
- package/dist/protocols/daikin312.d.ts.map +1 -0
- package/dist/protocols/daikin312.js +334 -0
- package/dist/protocols/daikin312.js.map +1 -0
- package/dist/protocols/daikin64.d.ts +79 -0
- package/dist/protocols/daikin64.d.ts.map +1 -0
- package/dist/protocols/daikin64.js +251 -0
- package/dist/protocols/daikin64.js.map +1 -0
- package/dist/protocols/daikin_common.d.ts +28 -0
- package/dist/protocols/daikin_common.d.ts.map +1 -0
- package/dist/protocols/daikin_common.js +38 -0
- package/dist/protocols/daikin_common.js.map +1 -0
- package/dist/protocols/nec.d.ts +50 -0
- package/dist/protocols/nec.d.ts.map +1 -0
- package/dist/protocols/nec.js +175 -0
- package/dist/protocols/nec.js.map +1 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# irtxrx
|
|
2
|
+
|
|
3
|
+
TypeScript library for encoding and decoding raw IR remote control frames. Converts between appliance state (temperature, mode, fan speed) and raw timing arrays that IR blaster hardware can transmit.
|
|
4
|
+
|
|
5
|
+
Zero runtime dependencies. Dual ESM/CJS. Correctness verified against the [IRremoteESP8266](https://github.com/crankyoldgit/IRremoteESP8266) C++ library.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
npm install irtxrx
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Encode (TX)
|
|
14
|
+
|
|
15
|
+
Build raw IR timing arrays from appliance state:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { sendDaikin152, DaikinMode, DaikinFan } from "irtxrx";
|
|
19
|
+
|
|
20
|
+
const timings = sendDaikin152({
|
|
21
|
+
power: true,
|
|
22
|
+
temp: 24,
|
|
23
|
+
mode: DaikinMode.Cool,
|
|
24
|
+
fan: DaikinFan.Auto,
|
|
25
|
+
swingVertical: true,
|
|
26
|
+
});
|
|
27
|
+
// → [3492, 1718, 433, 1529, 433, 433, ...] (mark/space durations in µs)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { sendCoolix, CoolixMode, CoolixFan } from "irtxrx";
|
|
32
|
+
|
|
33
|
+
const timings = sendCoolix({ temp: 22, mode: CoolixMode.Heat, fan: CoolixFan.Max });
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { sendNEC, encodeNEC } from "irtxrx";
|
|
38
|
+
|
|
39
|
+
const timings = sendNEC(encodeNEC(0x01, 0x02));
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Decode (RX)
|
|
43
|
+
|
|
44
|
+
Identify the protocol and extract state from raw timings captured by hardware:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { decode } from "irtxrx";
|
|
48
|
+
|
|
49
|
+
// Blind decode — identifies the protocol automatically
|
|
50
|
+
const result = decode(timings);
|
|
51
|
+
// → { protocol: "daikin152", brand: "daikin", type: "ac",
|
|
52
|
+
// state: { power: true, temp: 24, mode: 3, fan: 10, ... },
|
|
53
|
+
// confidence: "checksum_valid" }
|
|
54
|
+
|
|
55
|
+
// With protocol hint — faster, tolerates missing headers
|
|
56
|
+
const result = decode(timings, { protocol: "coolix" });
|
|
57
|
+
|
|
58
|
+
// Filter by brand or type
|
|
59
|
+
const result = decode(timings, { brand: "daikin" });
|
|
60
|
+
const result = decode(timings, { type: "ac" });
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The decoded `state` is the same type accepted by the encoder, so roundtrips are lossless:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const state = decode(timings, { protocol: "daikin152" })!.state;
|
|
67
|
+
const timings2 = sendDaikin152(state);
|
|
68
|
+
// timings2 produces identical raw bytes
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Handling hardware captures
|
|
72
|
+
|
|
73
|
+
Real IR captures from photodiode hardware often arrive with the first frame's header missing (the sensor wakes from sleep on the initial pulse). The decoder handles this automatically:
|
|
74
|
+
|
|
75
|
+
- **Blind decode** uses a 3-tier strategy: header match, repeat frame scan, then headerless brute force with checksum validation
|
|
76
|
+
- **Protocol-hinted decode** skips straight to headerless decoding since the checksum/parity check is sufficient
|
|
77
|
+
|
|
78
|
+
### Command-based protocols
|
|
79
|
+
|
|
80
|
+
Some protocols (Coolix) use fixed codes for toggle features like swing, turbo, and power off. These decode as `state: null` with a `raw` code:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { decode, CoolixCommand } from "irtxrx";
|
|
84
|
+
|
|
85
|
+
const result = decode(timings, { protocol: "coolix" });
|
|
86
|
+
if (result?.state === null) {
|
|
87
|
+
// It's a command frame
|
|
88
|
+
if (result.raw === CoolixCommand.Off) { /* power off */ }
|
|
89
|
+
if (result.raw === CoolixCommand.Swing) { /* toggle swing */ }
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Supported protocols
|
|
94
|
+
|
|
95
|
+
| Protocol | Bits | Brand | Type | Features |
|
|
96
|
+
|----------|------|-------|------|----------|
|
|
97
|
+
| NEC | 32 | NEC | Simple | Address + command, repeat detection |
|
|
98
|
+
| Coolix | 24 | Coolix | AC | Temp, mode, fan, zone follow, toggle commands |
|
|
99
|
+
| Daikin64 | 64 | Daikin | AC | Temp, mode, fan, swing, sleep, timers |
|
|
100
|
+
| Daikin128 | 128 | Daikin | AC | BCD temps, nibble checksums, timers |
|
|
101
|
+
| Daikin152 | 152 | Daikin | AC | Quiet, powerful, econo, comfort, sensor |
|
|
102
|
+
| Daikin160 | 160 | Daikin | AC | 5 discrete swing positions |
|
|
103
|
+
| Daikin176 | 176 | Daikin | AC | Unique mode values, horizontal swing |
|
|
104
|
+
| Daikin216 | 216 | Daikin | AC | Vertical + horizontal swing, powerful |
|
|
105
|
+
| DaikinESP | 280 | Daikin | AC | Most features: 0.5°C, timers, mold, comfort |
|
|
106
|
+
| Daikin2 | 312 | Daikin | AC | Eye, purify, fresh air, light, beep |
|
|
107
|
+
| Daikin312 | 312 | Daikin | AC | 0.5°C, eye auto, purify |
|
|
108
|
+
|
|
109
|
+
## Development
|
|
110
|
+
|
|
111
|
+
Requires [Bun](https://bun.sh) and a C++ compiler (for cross-validation tests).
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
bun install
|
|
115
|
+
bun test # Run tests (compiles C++ runner on first run)
|
|
116
|
+
bun run build # Build ESM + CJS to dist/
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The vendored IRremoteESP8266 submodule is used only for testing:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
git submodule update --init
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
MIT
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core IR decoding engine.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the decoding logic of IRremoteESP8266's IRrecv, but operates
|
|
5
|
+
* on plain timing arrays (in microseconds) instead of hardware capture buffers.
|
|
6
|
+
*/
|
|
7
|
+
/** Default percentage tolerance for timing matches (±25%). */
|
|
8
|
+
export declare const kTolerance = 25;
|
|
9
|
+
/**
|
|
10
|
+
* Default mark excess in microseconds.
|
|
11
|
+
* Compensates for sensor lag: marks are captured too long, spaces too short.
|
|
12
|
+
* Set to 0 for ideal timings (encoder output); increase for real hardware.
|
|
13
|
+
*/
|
|
14
|
+
export declare const kMarkExcess = 0;
|
|
15
|
+
/** Check if a measured timing is within tolerance of a desired value. */
|
|
16
|
+
export declare function matchTiming(measured: number, desired: number, tolerance?: number, delta?: number): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Match a mark (IR ON) timing.
|
|
19
|
+
* Adds excess to desired to compensate for marks being captured too long.
|
|
20
|
+
*/
|
|
21
|
+
export declare function matchMark(measured: number, desired: number, tolerance?: number, excess?: number): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Match a space (IR OFF) timing.
|
|
24
|
+
* Subtracts excess from desired to compensate for spaces being too short.
|
|
25
|
+
*/
|
|
26
|
+
export declare function matchSpace(measured: number, desired: number, tolerance?: number, excess?: number): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Match a timing that should be at least as long as desired.
|
|
29
|
+
* Used for trailing gaps which can be arbitrarily long.
|
|
30
|
+
*/
|
|
31
|
+
export declare function matchAtLeast(measured: number, desired: number, tolerance?: number, delta?: number): boolean;
|
|
32
|
+
export interface MatchDataResult {
|
|
33
|
+
success: boolean;
|
|
34
|
+
data: bigint;
|
|
35
|
+
used: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Decode `nbits` of data from mark/space pairs in a timing array.
|
|
39
|
+
*
|
|
40
|
+
* Inverse of `encodeData`. Matches IRremoteESP8266 `IRrecv::matchData`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function matchData(timings: number[], offset: number, nbits: number, oneMark: number, oneSpace: number, zeroMark: number, zeroSpace: number, tolerance?: number, excess?: number, msbFirst?: boolean, expectLastSpace?: boolean): MatchDataResult;
|
|
43
|
+
export interface MatchGenericResult {
|
|
44
|
+
data: bigint;
|
|
45
|
+
used: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Generic IR frame decoder for protocols with ≤ 64 data bits.
|
|
49
|
+
*
|
|
50
|
+
* Inverse of `sendGeneric`. Matches IRremoteESP8266 `IRrecv::matchGeneric`.
|
|
51
|
+
*
|
|
52
|
+
* @returns Decoded data and entries consumed, or null on mismatch.
|
|
53
|
+
*/
|
|
54
|
+
export declare function matchGeneric(timings: number[], offset: number, remaining: number, nbits: number, headerMark: number, headerSpace: number, oneMark: number, oneSpace: number, zeroMark: number, zeroSpace: number, footerMark: number, footerSpace: number, atLeast?: boolean, tolerance?: number, excess?: number, msbFirst?: boolean, headerOptional?: boolean): MatchGenericResult | null;
|
|
55
|
+
export interface MatchGenericBytesResult {
|
|
56
|
+
data: Uint8Array;
|
|
57
|
+
used: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Generic IR frame decoder for byte-array protocols (AC protocols).
|
|
61
|
+
*
|
|
62
|
+
* Inverse of `sendGenericBytes`. Decodes each byte individually (8 bits).
|
|
63
|
+
*
|
|
64
|
+
* @returns Decoded byte array and entries consumed, or null on mismatch.
|
|
65
|
+
*/
|
|
66
|
+
export declare function matchGenericBytes(timings: number[], offset: number, remaining: number, nbytes: number, headerMark: number, headerSpace: number, oneMark: number, oneSpace: number, zeroMark: number, zeroSpace: number, footerMark: number, footerSpace: number, atLeast?: boolean, tolerance?: number, excess?: number, msbFirst?: boolean, headerOptional?: boolean): MatchGenericBytesResult | null;
|
|
67
|
+
import type { NECDecodeResult } from "./protocols/nec.js";
|
|
68
|
+
import type { Daikin64State } from "./protocols/daikin64.js";
|
|
69
|
+
import type { Daikin128State } from "./protocols/daikin128.js";
|
|
70
|
+
import type { Daikin152State } from "./protocols/daikin152.js";
|
|
71
|
+
import type { Daikin160State } from "./protocols/daikin160.js";
|
|
72
|
+
import type { Daikin176State } from "./protocols/daikin176.js";
|
|
73
|
+
import type { Daikin216State } from "./protocols/daikin216.js";
|
|
74
|
+
import type { DaikinESPState } from "./protocols/daikin.js";
|
|
75
|
+
import type { Daikin2State } from "./protocols/daikin2.js";
|
|
76
|
+
import type { Daikin312State } from "./protocols/daikin312.js";
|
|
77
|
+
import type { CoolixState } from "./protocols/coolix.js";
|
|
78
|
+
/** All supported protocol names. */
|
|
79
|
+
export type ProtocolName = "nec" | "daikin64" | "daikin128" | "daikin152" | "daikin160" | "daikin176" | "daikin216" | "daikin" | "daikin2" | "daikin312" | "coolix";
|
|
80
|
+
/** Brand groupings for hint-based filtering. */
|
|
81
|
+
export type BrandName = "nec" | "daikin" | "coolix";
|
|
82
|
+
/** Protocol type groupings. */
|
|
83
|
+
export type ProtocolType = "ac" | "simple";
|
|
84
|
+
/** Discriminated union of all possible decode results. */
|
|
85
|
+
export type DecodeResult = {
|
|
86
|
+
protocol: "nec";
|
|
87
|
+
brand: "nec";
|
|
88
|
+
type: "simple";
|
|
89
|
+
state: NECDecodeResult;
|
|
90
|
+
confidence: "timing_match";
|
|
91
|
+
} | {
|
|
92
|
+
protocol: "daikin64";
|
|
93
|
+
brand: "daikin";
|
|
94
|
+
type: "ac";
|
|
95
|
+
state: Daikin64State;
|
|
96
|
+
confidence: "checksum_valid";
|
|
97
|
+
} | {
|
|
98
|
+
protocol: "daikin128";
|
|
99
|
+
brand: "daikin";
|
|
100
|
+
type: "ac";
|
|
101
|
+
state: Daikin128State;
|
|
102
|
+
confidence: "checksum_valid";
|
|
103
|
+
} | {
|
|
104
|
+
protocol: "daikin152";
|
|
105
|
+
brand: "daikin";
|
|
106
|
+
type: "ac";
|
|
107
|
+
state: Daikin152State;
|
|
108
|
+
confidence: "checksum_valid";
|
|
109
|
+
} | {
|
|
110
|
+
protocol: "daikin160";
|
|
111
|
+
brand: "daikin";
|
|
112
|
+
type: "ac";
|
|
113
|
+
state: Daikin160State;
|
|
114
|
+
confidence: "checksum_valid";
|
|
115
|
+
} | {
|
|
116
|
+
protocol: "daikin176";
|
|
117
|
+
brand: "daikin";
|
|
118
|
+
type: "ac";
|
|
119
|
+
state: Daikin176State;
|
|
120
|
+
confidence: "checksum_valid";
|
|
121
|
+
} | {
|
|
122
|
+
protocol: "daikin216";
|
|
123
|
+
brand: "daikin";
|
|
124
|
+
type: "ac";
|
|
125
|
+
state: Daikin216State;
|
|
126
|
+
confidence: "checksum_valid";
|
|
127
|
+
} | {
|
|
128
|
+
protocol: "daikin";
|
|
129
|
+
brand: "daikin";
|
|
130
|
+
type: "ac";
|
|
131
|
+
state: DaikinESPState;
|
|
132
|
+
confidence: "checksum_valid";
|
|
133
|
+
} | {
|
|
134
|
+
protocol: "daikin2";
|
|
135
|
+
brand: "daikin";
|
|
136
|
+
type: "ac";
|
|
137
|
+
state: Daikin2State;
|
|
138
|
+
confidence: "checksum_valid";
|
|
139
|
+
} | {
|
|
140
|
+
protocol: "daikin312";
|
|
141
|
+
brand: "daikin";
|
|
142
|
+
type: "ac";
|
|
143
|
+
state: Daikin312State;
|
|
144
|
+
confidence: "checksum_valid";
|
|
145
|
+
} | {
|
|
146
|
+
protocol: "coolix";
|
|
147
|
+
brand: "coolix";
|
|
148
|
+
type: "ac";
|
|
149
|
+
state: CoolixState;
|
|
150
|
+
confidence: "checksum_valid";
|
|
151
|
+
} | {
|
|
152
|
+
protocol: "coolix";
|
|
153
|
+
brand: "coolix";
|
|
154
|
+
type: "ac";
|
|
155
|
+
state: null;
|
|
156
|
+
raw: number;
|
|
157
|
+
confidence: "checksum_valid";
|
|
158
|
+
};
|
|
159
|
+
export interface DecodeOptions {
|
|
160
|
+
/** Try only this specific protocol. */
|
|
161
|
+
protocol?: ProtocolName;
|
|
162
|
+
/** Try only protocols from this brand. */
|
|
163
|
+
brand?: BrandName;
|
|
164
|
+
/** Try only protocols of this type. */
|
|
165
|
+
type?: ProtocolType;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Unified IR decode dispatcher.
|
|
169
|
+
*
|
|
170
|
+
* Uses a 3-tier strategy to handle real-world hardware captures where
|
|
171
|
+
* headers may be missing:
|
|
172
|
+
*
|
|
173
|
+
* 1. **Header match at offset 0** — fastest path, handles intact captures.
|
|
174
|
+
* 2. **Find repeat frame** — scan for inter-frame gaps, try after each gap
|
|
175
|
+
* with header required. Handles missing first-frame headers.
|
|
176
|
+
* 3. **Brute force, header optional** — try at offset 0 relying solely on
|
|
177
|
+
* checksum/parity validation. Handles single-frame headerless captures.
|
|
178
|
+
*
|
|
179
|
+
* @param timings Raw mark/space timing array in microseconds.
|
|
180
|
+
* @param options Optional hints to narrow the search.
|
|
181
|
+
* @returns The first matching protocol's decode result, or null.
|
|
182
|
+
*/
|
|
183
|
+
export declare function decode(timings: number[], options?: DecodeOptions): DecodeResult | null;
|
|
184
|
+
//# sourceMappingURL=decode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/decode.ts"],"names":[],"mappings":"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"}
|