this repo has no description
1import { question } from "@topcli/prompts";
2import type { Applet } from "../Applet.js";
3import { DATA_LENGTH_BITS_TO_SONY_PROTOCOL_VARIATION } from "../util/sony.ts";
4import { extractBits } from "../util/bit-manipulation.ts";
5import { createStringPromptValidator } from "../util/prompts.ts";
6import {
7 parseUnfoldedHex,
8 UNFOLDED_CIRCLE_PROTOCOL_SONY,
9} from "../util/unfolded-circle.ts";
10
11const sonyUnfoldedHexValidator = createStringPromptValidator((input) => {
12 const parsed = parseUnfoldedHex(input);
13
14 if (parsed == undefined) {
15 return {
16 isValid: false,
17 error: `${input} does not match this format: {protocolNum};{hexData};{dataLengthBits};{repeatCount}`,
18 };
19 }
20
21 if (parsed.protocolNum != UNFOLDED_CIRCLE_PROTOCOL_SONY) {
22 return {
23 isValid: false,
24 error: `The provided code has a protocol number that does not match the value for Sony (${UNFOLDED_CIRCLE_PROTOCOL_SONY})`,
25 };
26 }
27
28 if (
29 !DATA_LENGTH_BITS_TO_SONY_PROTOCOL_VARIATION.has(parsed.dataLengthBits)
30 ) {
31 return {
32 isValid: false,
33 error: `The provided code has data with a number of bits other than 12, 15, or 20.`,
34 };
35 }
36
37 if (parsed.dataLengthBits === 20) {
38 return {
39 isValid: false,
40 error: `The 20-bit Sony IR protocol is not currently supported.`,
41 };
42 }
43
44 return { isValid: true };
45});
46
47export const UnfoldedHexToSonyApplet: Applet = {
48 name: "Convert Unfolded Circle 'hex' IR code to Sony SIRC message",
49 runFunc: async (): Promise<undefined> => {
50 const unfoldedHex = await question(
51 "Enter an Unfolded Circle IR hex code",
52 { validators: [sonyUnfoldedHexValidator] },
53 );
54 // The exclamation points are OK because we're checking these things in sonyUnfoldedHexValidator.
55 // We can stop re-parsing if https://github.com/TopCli/prompts/issues/149 gets implemented.
56 const parsedUnfoldedHex = parseUnfoldedHex(unfoldedHex)!;
57 const { commandLengthBits, deviceTypeLengthBits, extensionLengthBits } =
58 DATA_LENGTH_BITS_TO_SONY_PROTOCOL_VARIATION.get(
59 parsedUnfoldedHex.dataLengthBits,
60 )!;
61
62 // We have to reverse the bits because SIRC transmits values LSB-first
63 // The device type is also referred to as the "address"
64 const deviceType = extractBits({
65 input: parsedUnfoldedHex.data,
66 leastSignificantBit: 0,
67 extractedNumLengthBits: deviceTypeLengthBits,
68 reverseResultBits: true,
69 });
70 const command = extractBits({
71 input: parsedUnfoldedHex.data,
72 leastSignificantBit: deviceTypeLengthBits,
73 extractedNumLengthBits: commandLengthBits,
74 reverseResultBits: true,
75 });
76 const extension = extractBits({
77 input: parsedUnfoldedHex.data,
78 leastSignificantBit: deviceTypeLengthBits + commandLengthBits,
79 extractedNumLengthBits: extensionLengthBits,
80 reverseResultBits: true,
81 });
82
83 console.log(`Device type: ${deviceType}`);
84 console.log(`Command: ${command}`);
85 console.log(`Extension: ${extension}`);
86 },
87};