Skip to content

Commit

Permalink
feat: support dynamic connection flag for the homekit accessory
Browse files Browse the repository at this point in the history
- add flag as qrcode command line option
- update tests
- update README

- fix #1
  • Loading branch information
SimonGolms committed Feb 28, 2022
1 parent 112aad2 commit 6cc949c
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 29 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Options:
--version Show version number [boolean]
--help Show help [boolean]
-c, --category Category of the HomeKit accessory, required for generating a QR Code [choices: "airConditioner", "airport", "airPurifier", "appleTv", "bridge", "dehumidifier", "door", "doorLock", "fan", "faucet", "garage", "heater", "humidifier", "ipCamera", "lightbulb", "other", "outlet", "programmableSwitch", "rangeExtender", "securitySystem", "sensor", "showerHead", "speaker", "sprinkler", "switch", "targetController", "television", "thermostat", "videoDoorBell", "window", "windowCovering"] [default: "airConditioner"]
-f, --flag Flag how to connect to the HomeKit accessory. [required] [choices: "ble", "ip", "wac"] [default: "ip"]
-f, --flag Flag how to connect to the HomeKit accessory. (1 = NFC; 2 = IP; 4 = BLE; 8 = Wireless Accessory Configuration (WAC)/Apples MFi) [number] [default: 2]
-n, --name Name of the generated file [string] [default: "homekit-qrcode"]
-o, --output Format of the generated file [required] [choices: "svg", "png"] [default: "svg"]
-p, --pairingCode 8 digits pairing code [string] [required]
Expand All @@ -43,8 +43,8 @@ Examples:
# Generate a QR code for a HomeKit switch as switch.png with an image zoom factor of 10
npx homekit-code qrcode --category=switch --pairingCode=84131633 --setupId=3QYT --name=switch --output=png --zoom=10
# Generate a QR code for a Bluetooth Low Energy (BLE) HomeKit switch
npx homekit-code qrcode -c switch -f ble -p 84131633 -s 3QYT
# Generate a QR code for a IP (2) + WAC (8) HomeKit switch
npx homekit-code qrcode -c switch -f 10 -p 84131633 -s 3QYT
```

### Output
Expand Down
3 changes: 1 addition & 2 deletions src/commands/qrcode/qrcode.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { CATEGORIES } from '../../config/categories';
import { FLAGS } from '../../config/flags';
import { CreateQrCode } from '../../types';
import { writeFile } from '../../utils/file';
import { composeQrCode, composeSetupUri } from './qrcode.utils';

export const createQrCode = async ({ category, flag, name, output, pairingCode, setupId, ...rest }: CreateQrCode) => {
const setupUri = composeSetupUri({
categoryId: CATEGORIES[category],
flag: FLAGS[flag],
flag,
password: pairingCode,
setupId,
});
Expand Down
13 changes: 5 additions & 8 deletions src/commands/qrcode/qrcode.utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
import { CATEGORIES } from '../../config/categories';
import { FLAGS } from '../../config/flags';
import { composeQrCode, composeSetupUri } from './qrcode.utils';

describe('composeSetupUri', () => {
test('get Setup Uri for category, password', () => {
expect.assertions(1);
expect(composeSetupUri({ categoryId: CATEGORIES.switch, password: '84131633', setupId: '' })).toBe('X-HM://0081YCYEP');
expect(composeSetupUri({ categoryId: CATEGORIES.switch, flag: 2, password: '84131633', setupId: '' })).toBe('X-HM://0081YCYEP');
});

test('get Setup Uri for category, password and setupId', () => {
expect.assertions(1);
expect(composeSetupUri({ categoryId: CATEGORIES.switch, password: '84131633', setupId: '3QYT' })).toBe('X-HM://0081YCYEP3QYT');
expect(composeSetupUri({ categoryId: CATEGORIES.switch, flag: 2, password: '84131633', setupId: '3QYT' })).toBe('X-HM://0081YCYEP3QYT');
});

test('get Setup Uri for category, flag, password and setupId', () => {
expect.assertions(1);
expect(composeSetupUri({ categoryId: CATEGORIES.switch, flag: FLAGS.ble, password: '84131633', setupId: '3QYT' })).toBe(
'X-HM://0086E6GJ53QYT',
);
expect(composeSetupUri({ categoryId: CATEGORIES.switch, flag: 4, password: '84131633', setupId: '3QYT' })).toBe('X-HM://0086E6GJ53QYT');
});
});

describe('composeQrCode', () => {
test('get QR code for switch', async () => {
expect.assertions(1);
const setupUri = composeSetupUri({ categoryId: CATEGORIES.switch, password: '84131633', setupId: '3QYT' });
const setupUri = composeSetupUri({ categoryId: CATEGORIES.switch, flag: 2, password: '84131633', setupId: '3QYT' });
const qrCode = await composeQrCode({ pairingCode: '84131633', setupUri });

expect(qrCode).toBe(`<?xml version="1.0" encoding="utf-8"?>
Expand Down Expand Up @@ -62,7 +59,7 @@ describe('composeQrCode', () => {

test('get QR code for ble switch', async () => {
expect.assertions(1);
const setupUri = composeSetupUri({ categoryId: CATEGORIES.switch, flag: FLAGS.ble, password: '84131633', setupId: '3QYT' });
const setupUri = composeSetupUri({ categoryId: CATEGORIES.switch, flag: 4, password: '84131633', setupId: '3QYT' });
const qrCode = await composeQrCode({ pairingCode: '84131633', setupUri });

expect(qrCode).toBe(`<?xml version="1.0" encoding="utf-8"?>
Expand Down
2 changes: 1 addition & 1 deletion src/commands/qrcode/qrcode.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const composeQrCode = async ({ pairingCode, setupUri }: ComposeQrCode) =>
};

// KUDOS: https://github.com/maximkulkin/esp-homekit/blob/0f3ef2ac2872ffe64dfe4e5d929420af327d48a5/tools/gen_qrcode#L18
export const composeSetupUri = ({ categoryId, flag = 2, password, reserved = 0, setupId, version = 0 }: ComposeSetupUri) => {
export const composeSetupUri = ({ categoryId, flag, password, reserved = 0, setupId, version = 0 }: ComposeSetupUri) => {
let payload: bigint | number = 0;
payload = payload | (version & 0x7);

Expand Down
7 changes: 2 additions & 5 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { CATEGORIES } from '../config/categories';
import { FLAGS } from '../config/flags';
import { OUTPUT_FORMATS } from '../config/output';

export type Category = keyof typeof CATEGORIES;

export type Flag = keyof typeof FLAGS;

export type OutputFormat = typeof OUTPUT_FORMATS[number];

export type CreateFileBuffer = CreateImage & {
Expand All @@ -27,14 +24,14 @@ export type CreateTag = Omit<WriteFile, 'svg'> & {

export type CreateQrCode = Omit<WriteFile, 'svg'> & {
category: Category;
flag: Flag;
flag: number;
pairingCode: string;
setupId: string;
};

export type ComposeSetupUri = {
categoryId: number;
flag?: number; // 2 = IP; 4 = BLE; 8 = Wireless Accessory Configuration (WAC) / Apple's MFi
flag: number;
password: string;
reserved?: number;
setupId: string;
Expand Down
16 changes: 6 additions & 10 deletions src/yargs.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import yargs from 'yargs/yargs';
import { CATEGORIES } from './config/categories';
import { FLAGS } from './config/flags';
import { OUTPUT_FORMATS } from './config/output';
import { Category, Flag, OutputFormat } from './types';
import { Category, OutputFormat } from './types';
import { isPairingCode } from './utils/number';

export const argv = yargs(process.argv.slice(2))
Expand All @@ -21,10 +20,10 @@ export const argv = yargs(process.argv.slice(2))
},
flag: {
alias: 'f',
choices: Object.keys(FLAGS),
default: 'ip' as Flag,
demandOption: true,
describe: 'Flag how to connect to the HomeKit accessory.',
default: 2,
describe:
'Flag how to connect to the HomeKit accessory. (1 = NFC; 2 = IP; 4 = BLE; 8 = Wireless Accessory Configuration (WAC)/Apples MFi)',
type: 'number',
},
name: {
alias: 'n',
Expand Down Expand Up @@ -63,10 +62,7 @@ export const argv = yargs(process.argv.slice(2))
'npx homekit-code qrcode --category=switch --pairingCode=84131633 --setupId=3QYT --name=switch --output=png --zoom=10',
'Generate a QR code for a HomeKit switch as switch.png with an image zoom factor of 10',
)
.example(
'npx homekit-code qrcode -c=switch -f=ble -p=84131633 -s=3QYT',
'Generate a QR code for a Bluetooth Low Energy (BLE) HomeKit switch',
);
.example('npx homekit-code qrcode -c switch -f 10 -p 84131633 -s 3QYT', 'Generate a QR code for a IP (2) + WAC (8) HomeKit switch');
})
.command('tag', 'Generate a scannable HomeKit tag label', (yargsCmd) => {
return yargsCmd
Expand Down

0 comments on commit 6cc949c

Please sign in to comment.