UNPKG

inventoresed

Version:

Z-Wave driver written entirely in JavaScript/TypeScript

81 lines (76 loc) 2.33 kB
import { formatId } from "@zwave-js/shared"; import { isObject } from "alcalzone-shared/typeguards"; import axios from "axios"; import * as crypto from "crypto"; import type { Driver } from "../driver/Driver"; const apiToken = "ef58278d935ccb26307800279458484d"; const statisticsUrl = `https://stats.zwave-js.io/statistics`; export interface AppInfo { driverVersion: string; applicationName: string; applicationVersion: string; nodeVersion: string; os: NodeJS.Platform; arch: string; } export async function compileStatistics( driver: Driver, appInfo: AppInfo, ): Promise<Record<string, any>> { const salt = await driver.getUUID(); return { // Salt and hash the homeId, so it cannot easily be tracked // It is no state secret, but since we're collecting it, make sure it is anonymous id: crypto .createHash("sha256") .update(driver.controller.homeId!.toString(16)) .update(salt) .digest("hex"), ...appInfo, devices: [...driver.controller.nodes.values()].map((node) => ({ manufacturerId: node.manufacturerId != undefined ? formatId(node.manufacturerId) : "", productType: node.productType != undefined ? formatId(node.productType) : "", productId: node.productId != undefined ? formatId(node.productId) : "", firmwareVersion: node.firmwareVersion ?? "", })), }; } /** * Sends the statistics to the statistics backend. Returns: * - `true` when sending succeeded * - The number of seconds to wait before trying again when hitting the rate limiter * - `false` for any other errors */ export async function sendStatistics( statistics: Record<string, any>, ): Promise<boolean | number> { try { const { data } = await axios.post( statisticsUrl, { data: [statistics] }, { headers: { "x-api-token": apiToken } }, ); if (isObject(data) && typeof data.success === "boolean") { return data.success; } return false; } catch (e: any) { if (isObject(e.response) && e.response.status === 429) { // We've hit the rate limiter. Figure out when we may try again. if ( isObject(e.response.headers) && "retry-after" in e.response.headers ) { const retryAfter = parseInt(e.response.headers["retry-after"]); if (Number.isInteger(retryAfter)) return retryAfter; } } // didn't work, try again later return false; } }