homebridge-philips-hue-sync-box
Version:
Homebridge plugin for the Philips Hue Sync Box.
67 lines • 2.38 kB
JavaScript
import originalFetch from 'node-fetch';
import fetch_retry from 'fetch-retry';
import * as https from 'node:https';
import AsyncLock from 'async-lock';
const fetch = fetch_retry(originalFetch, {
retries: 3,
retryDelay: attempt => {
return Math.pow(2, attempt) * 1000; // 1000, 2000, 4000
},
});
export class SyncBoxClient {
log;
config;
LOCK_KEY = 'sync-box';
LOCK_OPTIONS = {
timeout: 10000,
maxExecutionTime: 15000,
};
lock;
constructor(log, config) {
this.log = log;
this.config = config;
this.lock = new AsyncLock();
}
async getState() {
return await this.lock
.acquire(this.LOCK_KEY, async () => await this.sendRequest('GET', ''), this.LOCK_OPTIONS)
.catch(e => {
this.log.error('Sync box is offline', e);
return null;
});
}
async updateExecution(execution) {
return await this.lock
.acquire(this.LOCK_KEY, async () => await this.sendRequest('PUT', 'execution', execution), this.LOCK_OPTIONS)
.catch(e => {
this.log.error('Error updating execution:', e);
});
}
async updateHue(hue) {
return await this.lock
.acquire(this.LOCK_KEY, async () => await this.sendRequest('PUT', 'hue', hue), this.LOCK_OPTIONS)
.catch(e => {
this.log.error('Error updating hue:', e);
});
}
async sendRequest(method, path, body) {
const url = `https://${this.config.syncBoxIpAddress}/api/v1/${path}`;
const options = {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.config.syncBoxApiAccessToken}`,
},
method,
body: body ? JSON.stringify(body) : null,
agent: new https.Agent({ rejectUnauthorized: false, keepAlive: true }),
};
this.log.debug('Request to Sync Box:', url, JSON.stringify(options));
const res = await fetch(url, options);
if (!res.ok) {
this.log.error(`Error: ${res.status} - ${res.statusText}. ${JSON.stringify(await res.json())}`);
throw new Error(`Error: ${res.status} - ${res.statusText}`);
}
return method === 'GET' ? (await res.json()) : null;
}
}
//# sourceMappingURL=client.js.map