homebridge-prometheus-exporter/src/discovery/hap_node_js_client.ts

70 lines
2.1 KiB
TypeScript
Raw Normal View History

2022-11-07 20:49:11 +01:00
import type { HapDiscover } from './api'
import { HAPNodeJSClient } from 'hap-node-client'
2022-11-06 13:50:39 +01:00
2022-11-07 20:49:11 +01:00
import { Device, DeviceBoundary } from '../boundaries'
import { Array, Unknown } from 'runtypes'
import { Logger } from 'homebridge'
2022-11-06 13:50:39 +01:00
const MaybeDevices = Array(Unknown)
2022-11-07 19:30:55 +01:00
type HapConfig = {
debug: boolean
refresh: number
timeout: number
reqTimeout: number
pin: string
}
type HapClient = typeof HAPNodeJSClient
type ResolveFunc = (devices: Device[]) => void
type RejectFunc = (error: unknown) => void
2022-11-07 20:49:11 +01:00
const clientMap: Record<string, HapClient> = {}
const promiseMap: Record<string, [ResolveFunc, RejectFunc]> = {}
2022-11-07 19:30:55 +01:00
function startDiscovery(logger: Logger, config: HapConfig, resolve: ResolveFunc, reject: RejectFunc) {
const key = JSON.stringify(config)
if (!clientMap[key]) {
logger.debug('Creating new HAP client')
const client = new HAPNodeJSClient(config)
client.on('Ready', (deviceData: unknown) => {
try {
const devices: Device[] = []
for (const device of MaybeDevices.check(deviceData)) {
try {
devices.push(DeviceBoundary.check(device))
} catch (e) {
2022-11-07 20:49:11 +01:00
logger.error('Boundary check for device data failed %o %s', e, JSON.stringify(device, null, 4))
2022-11-07 19:30:55 +01:00
}
}
if (promiseMap[key]) promiseMap[key][0](devices)
} catch (e) {
if (promiseMap[key]) promiseMap[key][1](e)
}
})
clientMap[key] = client
} else {
logger.debug('Reusing existing HAP client')
}
promiseMap[key] = [resolve, reject]
}
2022-11-07 20:49:11 +01:00
export const discover: HapDiscover = ({ pin, refreshInterval, discoveryTimeout, requestTimeout, logger, debug }) => {
2022-11-06 13:50:39 +01:00
return new Promise((resolve, reject) => {
2022-11-07 19:30:55 +01:00
startDiscovery(
logger,
{
2022-11-06 13:50:39 +01:00
debug: debug,
refresh: refreshInterval,
timeout: discoveryTimeout,
reqTimeout: requestTimeout,
pin,
2022-11-07 19:30:55 +01:00
},
resolve,
2022-11-07 20:49:11 +01:00
reject,
2022-11-07 19:30:55 +01:00
)
2022-11-06 13:50:39 +01:00
})
}