UNPKG

inventoresed

Version:

Z-Wave driver written entirely in JavaScript/TypeScript

101 lines (94 loc) 3.18 kB
import * as Sentry from "@sentry/node"; import { AssociationGroupInfoCC, ConfigurationCC } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import type { ZWaveApplicationHost } from "@zwave-js/host"; import { formatId } from "@zwave-js/shared"; import { isObject } from "alcalzone-shared/typeguards"; import axios from "axios"; import type { ZWaveNode } from "../node/Node"; const missingDeviceConfigCache = new Set<string>(); export async function reportMissingDeviceConfig( applHost: ZWaveApplicationHost, node: ZWaveNode & { manufacturerId: number; productType: number; productId: number; firmwareVersion: string; }, ): Promise<void> { const configFingerprint = `${formatId(node.manufacturerId)}:${formatId( node.productType, )}:${formatId(node.productId)}:${node.firmwareVersion}`; // We used to get a LOT of false positives, so we should check with our device // database whether this config file is actually unknown // If we tried to report this file earlier, we can skip the report if (missingDeviceConfigCache.has(configFingerprint)) return; // Otherwise ask our device DB if it exists try { const { data } = await axios.get( `https://devices.zwave-js.io/public_api/getdeviceinfo/${configFingerprint.replace( /:/g, "/", )}`, ); if ( isObject(data) && typeof data.deviceFound === "boolean" && data.deviceFound ) { // This is a false positive - remember it missingDeviceConfigCache.add(configFingerprint); return; } } catch (e) { // didn't work, try again next time return; } const message = `Missing device config: ${configFingerprint}`; const deviceInfo: Record<string, any> = { supportsConfigCCV3: node.getCCVersion(CommandClasses.Configuration) >= 3, supportsAGI: node.supportsCC( CommandClasses["Association Group Information"], ), supportsZWavePlus: node.supportsCC(CommandClasses["Z-Wave Plus Info"]), }; try { if (deviceInfo.supportsConfigCCV3) { // Try to collect all info about config params we can get const instance = node.createCCInstanceUnsafe(ConfigurationCC)!; deviceInfo.parameters = instance.getQueriedParamInfos(applHost); } if (deviceInfo.supportsAGI) { // Try to collect all info about association groups we can get const associationGroupCount = AssociationGroupInfoCC[ "getAssociationGroupCountCached" ](applHost, node); const names: string[] = []; for (let group = 1; group <= associationGroupCount; group++) { names.push( AssociationGroupInfoCC.getGroupNameCached( applHost, node, group, ) ?? "", ); } deviceInfo.associationGroups = names; } if (deviceInfo.supportsZWavePlus) { deviceInfo.zWavePlusVersion = node.zwavePlusVersion; } } catch { // Don't fail on the last meters :) } Sentry.captureMessage(message, (scope) => { scope.clearBreadcrumbs(); // Group by device config, otherwise Sentry groups by "Unknown device config", which is nonsense scope.setFingerprint([configFingerprint]); scope.setExtras(deviceInfo); return scope; }); // Remember that we reported the config missingDeviceConfigCache.add(configFingerprint); }