@homebridge/hap-client 1.10.0-beta.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.
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HapMonitor = void 0;
4
+ const node_events_1 = require("node:events");
5
+ const eventedHttpClient_1 = require("./eventedHttpClient");
6
+ class HapMonitor extends node_events_1.EventEmitter {
7
+ pin;
8
+ evInstances;
9
+ services;
10
+ logger;
11
+ debug;
12
+ constructor(logger, debug, pin, services) {
13
+ super();
14
+ this.logger = logger;
15
+ this.debug = debug;
16
+ this.pin = pin;
17
+ this.services = services;
18
+ this.evInstances = [];
19
+ this.parseServices();
20
+ this.start();
21
+ }
22
+ start() {
23
+ for (const instance of this.evInstances) {
24
+ instance.socket = (0, eventedHttpClient_1.createConnection)(instance, this.pin, { characteristics: instance.evCharacteristics });
25
+ this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Connected`);
26
+ instance.socket.on('data', (data) => {
27
+ const message = (0, eventedHttpClient_1.parseMessage)(data);
28
+ if (message.statusCode === 401) {
29
+ if (this.logger) {
30
+ this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] ` +
31
+ `${message.statusCode} ${message.statusMessage} - make sure Homebridge pin for this instance is set to ${this.pin}.`);
32
+ }
33
+ }
34
+ if (message.protocol === 'EVENT') {
35
+ try {
36
+ const body = JSON.parse(message.body);
37
+ if (body.characteristics && body.characteristics.length) {
38
+ this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] ` +
39
+ `Got Event: ${JSON.stringify(body.characteristics)}`);
40
+ const response = body.characteristics.map((c) => {
41
+ const services = this.services.filter(x => x.aid === c.aid && x.instance.username === instance.username);
42
+ const service = services.find(x => x.serviceCharacteristics.find(y => y.iid === c.iid));
43
+ if (service) {
44
+ const characteristic = service.serviceCharacteristics.find(x => x.iid === c.iid);
45
+ if (characteristic) {
46
+ characteristic.value = c.value;
47
+ service.values[characteristic.type] = c.value;
48
+ return service;
49
+ }
50
+ }
51
+ });
52
+ this.emit('service-update', response.filter(x => x));
53
+ }
54
+ }
55
+ catch (e) {
56
+ }
57
+ }
58
+ });
59
+ }
60
+ }
61
+ finish() {
62
+ for (const instance of this.evInstances) {
63
+ if (instance.socket) {
64
+ try {
65
+ instance.socket.destroy();
66
+ this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Disconnected`);
67
+ }
68
+ catch (e) {
69
+ }
70
+ }
71
+ }
72
+ }
73
+ parseServices() {
74
+ for (const service of this.services) {
75
+ const evCharacteristics = service.serviceCharacteristics.filter(x => x.perms.includes('ev'));
76
+ if (evCharacteristics.length) {
77
+ if (!this.evInstances.find(x => x.username === service.instance.username)) {
78
+ const newInstance = Object.assign({}, service.instance);
79
+ newInstance.evCharacteristics = [];
80
+ this.evInstances.push(newInstance);
81
+ }
82
+ const instance = this.evInstances.find(x => x.username === service.instance.username);
83
+ for (const evCharacteristic of evCharacteristics) {
84
+ if (!instance.evCharacteristics.find(x => x.aid === service.aid && x.iid === evCharacteristic.iid)) {
85
+ instance.evCharacteristics.push({ aid: service.aid, iid: evCharacteristic.iid, ev: true });
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ exports.HapMonitor = HapMonitor;
93
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../src/monitor.ts"],"names":[],"mappings":"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"}
package/dist/uuid.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function isValid(UUID: string): boolean;
2
+ export declare function toLongFormUUID(uuid: string, base?: string): string;
package/dist/uuid.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toLongFormUUID = exports.isValid = void 0;
4
+ const VALID_UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
5
+ function isValid(UUID) {
6
+ return VALID_UUID_REGEX.test(UUID);
7
+ }
8
+ exports.isValid = isValid;
9
+ const VALID_SHORT_REGEX = /^[0-9a-f]{1,8}$/i;
10
+ function toLongFormUUID(uuid, base = '-0000-1000-8000-0026BB765291') {
11
+ if (isValid(uuid)) {
12
+ return uuid.toUpperCase();
13
+ }
14
+ if (!VALID_SHORT_REGEX.test(uuid)) {
15
+ throw new TypeError('uuid was not a valid UUID or short form UUID');
16
+ }
17
+ if (!isValid('00000000' + base)) {
18
+ throw new TypeError('base was not a valid base UUID');
19
+ }
20
+ return (('00000000' + uuid).substr(-8) + base).toUpperCase();
21
+ }
22
+ exports.toLongFormUUID = toLongFormUUID;
23
+ //# sourceMappingURL=uuid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../src/uuid.ts"],"names":[],"mappings":";;;AAEA,MAAM,gBAAgB,GAAG,iEAAiE,CAAC;AAE3F,SAAgB,OAAO,CAAC,IAAY;IAClC,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAFD,0BAEC;AACD,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAE7C,SAAgB,cAAc,CAAC,IAAY,EAAE,IAAI,GAAG,8BAA8B;IAChF,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;AAC/D,CAAC;AAZD,wCAYC"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@homebridge/hap-client",
3
+ "version": "1.10.0-beta.0",
4
+ "description": "A client for HAP-NodeJS.",
5
+ "main": "./dist/index.js",
6
+ "scripts": {
7
+ "check": "npm install && npm outdated",
8
+ "lint": "eslint src/**.ts",
9
+ "build": "tsc",
10
+ "gen": "ts-node -P tsconfig.gen.json scripts/gen-hap-types.ts",
11
+ "prepublishOnly": "npm run lint && npm run build",
12
+ "clean": "rimraf ./dist",
13
+ "test": "eslint src/**.ts"
14
+ },
15
+ "types": "./dist/index.d.ts",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/homebridge/hap-client.git"
19
+ },
20
+ "keywords": [
21
+ "hap",
22
+ "homebridge",
23
+ "api"
24
+ ],
25
+ "author": {
26
+ "name": "oznu",
27
+ "email": "dev@oz.nu"
28
+ },
29
+ "contributors": [
30
+ {
31
+ "name": "homebridge",
32
+ "url": "https://github.com/homebridge"
33
+ }
34
+ ],
35
+ "license": "GPL-3.0",
36
+ "bugs": {
37
+ "url": "https://github.com/homebridge/hap-client/issues/"
38
+ },
39
+ "homepage": "https://github.com/homebridge/hap-client/blob/latest#readme",
40
+ "dependencies": {
41
+ "axios": "^1.6.8",
42
+ "bonjour-service": "^1.2.1",
43
+ "decamelize": "^6.0.0",
44
+ "inflection": "^3.0.0",
45
+ "source-map-support": "^0.5.21"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^20.12.2",
49
+ "@types/source-map-support": "^0.5.10",
50
+ "@typescript-eslint/eslint-plugin": "^7.4.0",
51
+ "@typescript-eslint/parser": "^7.4.0",
52
+ "eslint": "^8.57.0",
53
+ "eslint-plugin-jest": "^27.9.0",
54
+ "hap-nodejs": "^0.11.2",
55
+ "ts-node": "^10.9.2",
56
+ "typescript": "^5.4.3"
57
+ }
58
+ }
@@ -0,0 +1,62 @@
1
+ import { writeFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+
4
+ import { Characteristic, Service, Categories } from 'hap-nodejs';
5
+
6
+ /** Generate Service Types */
7
+
8
+ let Services = [
9
+ 'export const Services = {',
10
+ ] as any;
11
+
12
+ const uuidMap = new Map();
13
+
14
+ for (const [name, value] of Object.entries(Service)) {
15
+ if (value.UUID) {
16
+ if (!uuidMap.has(value.UUID)) {
17
+ // If the UUID does not exist, add a new entry
18
+ Services.push(` '${value.UUID}': '${name}',`);
19
+ uuidMap.set(value.UUID, Services.length - 1);
20
+ }
21
+ Services.push(` '${name}': '${value.UUID}',`);
22
+ }
23
+ }
24
+
25
+ Services.push(`};\n\n`);
26
+ Services = Services.join('\n');
27
+
28
+ /** Generate Characteristic Types */
29
+
30
+ let Characteristics = [
31
+ 'export const Characteristics = {',
32
+ ] as any;
33
+
34
+ for (const [name, value] of Object.entries(Characteristic)) {
35
+ if (value.UUID) {
36
+ Characteristics.push(` '${value.UUID}': '${name}',`);
37
+ Characteristics.push(` '${name}': '${value.UUID}',`);
38
+ }
39
+ }
40
+
41
+ Characteristics.push(`};\n\n`);
42
+ Characteristics = Characteristics.join('\n');
43
+
44
+ /** Generate Category Types */
45
+
46
+ let Category = [
47
+ 'export const Categories = {',
48
+ ] as any;
49
+
50
+ // @ts-ignore
51
+ for (const [name, value] of Object.entries(Categories)) {
52
+ if (typeof value === 'number') {
53
+ Category.push(` '${name}': ${value},`);
54
+ }
55
+ }
56
+
57
+ Category.push(`};\n`);
58
+ Category = Category.join('\n');
59
+
60
+ const out = `/* This file is automatically generated */\n\n` + Services + Characteristics + Category;
61
+
62
+ writeFileSync(resolve(__dirname, '../src/hap-types.ts'), out, 'utf8');
@@ -0,0 +1,9 @@
1
+ import { HapClient } from '../src'
2
+
3
+ const client = new HapClient({
4
+ pin: '000-00-000',
5
+ logger: console,
6
+ config: {
7
+ debug: true
8
+ }
9
+ });