UNPKG

@chrispyduck/homie-sensors

Version:

Sensor library intended for ues with homie-device

327 lines 16 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var ArrisSurfboardStatus_1; Object.defineProperty(exports, "__esModule", { value: true }); const homie_device_1 = require("@chrispyduck/homie-device"); const ISensor_1 = require("../ISensor"); const lodash_1 = require("lodash"); const jsdom_1 = __importDefault(require("jsdom")); const events_1 = require("events"); let ArrisSurfboardStatus = ArrisSurfboardStatus_1 = class ArrisSurfboardStatus extends events_1.EventEmitter { constructor(config) { super(); this.homieRegistration = null; this.read = async () => { var _a, _b, _c, _d; const dom = await jsdom_1.default.JSDOM.fromURL(this.config.url); const tables = dom.window.document.querySelectorAll("table"); if (tables.length !== 3) throw new Error(`Expected 3 tables but found ${tables.length}`); const metrics = { startupProcedureStatus: this.extractSummary(tables[0].getElementsByTagName("tr")), downstreamChannels: this.extractDownstreamChannels(tables[1].getElementsByTagName("tr")), upstreamChannels: this.extractUpstreamChannels(tables[2].getElementsByTagName("tr")), }; if (this.homieRegistration) { this.homieRegistration.state.connectivityState.publishValue((_a = metrics.startupProcedureStatus.connectivityState) !== null && _a !== void 0 ? _a : "Unknown"); this.homieRegistration.state.configurationFile.publishValue((_b = metrics.startupProcedureStatus.configurationFileStatus) !== null && _b !== void 0 ? _b : "Unknown"); this.homieRegistration.state.bootState.publishValue((_c = metrics.startupProcedureStatus.bootState) !== null && _c !== void 0 ? _c : "Unknown"); this.homieRegistration.state.net.publishValue(metrics.startupProcedureStatus.networkAccess === "Allowed"); this.homieRegistration.state.security.publishValue((_d = metrics.startupProcedureStatus.securityStatus) !== null && _d !== void 0 ? _d : "Unknown"); for (let i = 0; i < metrics.downstreamChannels.length; i++) { this.homieRegistration.downstreamChannels.id.publishValue(metrics.downstreamChannels[i].id, i); this.homieRegistration.downstreamChannels.lockStatus.publishValue(metrics.downstreamChannels[i].lockStatus, i); this.homieRegistration.downstreamChannels.frequency.publishValue(metrics.downstreamChannels[i].frequency, i); this.homieRegistration.downstreamChannels.modulation.publishValue(metrics.downstreamChannels[i].modulation, i); this.homieRegistration.downstreamChannels.power.publishValue(metrics.downstreamChannels[i].power, i); this.homieRegistration.downstreamChannels.snr.publishValue(metrics.downstreamChannels[i].snr, i); this.homieRegistration.downstreamChannels.correctedFrames.publishValue(metrics.downstreamChannels[i].corrected, i); this.homieRegistration.downstreamChannels.uncorrectableFrames.publishValue(metrics.downstreamChannels[i].uncorrectable); } for (let i = 0; i < metrics.upstreamChannels.length; i++) { this.homieRegistration.upstreamChannels.id.publishValue(metrics.upstreamChannels[i].id, i); this.homieRegistration.upstreamChannels.lockStatus.publishValue(metrics.upstreamChannels[i].lockStatus, i); this.homieRegistration.upstreamChannels.frequency.publishValue(metrics.upstreamChannels[i].frequency, i); this.homieRegistration.upstreamChannels.width.publishValue(metrics.upstreamChannels[i].width, i); this.homieRegistration.upstreamChannels.channelType.publishValue(metrics.upstreamChannels[i].channelType, i); this.homieRegistration.upstreamChannels.power.publishValue(metrics.upstreamChannels[i].power, i); } } return metrics; }; this.extractSummary = (rows) => { const result = {}; for (let i = 2; i < rows.length; i++) { const caption = rows[i].children[0].innerHTML; const status = rows[i].children[1].innerHTML; const comment = rows[i].children[2].innerHTML; switch (caption) { case "Acquire Downstream Channel": { result.downstreamChannelFrequency = Number.parseInt(status) / 1000 / 1000; result.downstreamChannelStatus = comment; break; } case "Connectivity State": { result.connectivityState = status; break; } case "Boot State": { result.bootState = status; break; } case "Configuration File": { result.configurationFileStatus = status; break; } case "Security": { result.securityStatus = status; break; } case "DOCSIS Network Access Enabled": { result.networkAccess = status; break; } } } return result; }; this.extractDownstreamChannels = (rows) => { const result = []; for (let i = 2; i < rows.length; i++) { const channelID = Number.parseInt(rows[i].children[0].innerHTML); if (channelID > 0) { const cellValues = Array .from(rows[i].children) .map(cell => cell.innerHTML); const channel = { id: channelID, lockStatus: cellValues[1], modulation: cellValues[2], frequency: Number.parseInt(cellValues[3]) / 1000 / 1000, power: Number.parseFloat(cellValues[4]), snr: Number.parseFloat(cellValues[5]), corrected: Number.parseInt(cellValues[6]), uncorrectable: Number.parseInt(cellValues[7]), }; result.push(channel); } } return result.sort((a, b) => a.id - b.id); }; this.extractUpstreamChannels = (rows) => { const result = []; for (let i = 2; i < rows.length; i++) { const channelNum = Number.parseInt(rows[i].children[0].innerHTML); if (channelNum > 0) { const cellValues = Array .from(rows[i].children) .map(cell => cell.innerHTML); const channel = { id: Number.parseInt(cellValues[1]), lockStatus: cellValues[2], channelType: cellValues[3], frequency: Number.parseInt(cellValues[4]) / 1000 / 1000, width: Number.parseFloat(cellValues[5]) / 1000 / 1000, power: Number.parseFloat(cellValues[6]), }; result.push(channel); } } return result.sort((a, b) => a.id - b.id); }; this.config = lodash_1.merge({}, ArrisSurfboardStatus_1.DefaultConfiguration, config); } register(device) { const stateNode = device.node(Object.assign(Object.assign({}, this.config.node), { name: `${this.config.node.name}-state`, friendlyName: `${this.config.node.friendlyName} - State`, isRange: false })); const state = { node: stateNode, connectivityState: stateNode.addProperty({ name: "connectivity", friendlyName: "Connectivity State", dataType: homie_device_1.PropertyDataType.string, settable: false, retained: true, }), bootState: stateNode.addProperty({ name: "bootState", friendlyName: "Boot State", dataType: homie_device_1.PropertyDataType.string, settable: false, retained: true, }), configurationFile: stateNode.addProperty({ name: "configurationFile", friendlyName: "Configuration File Status", dataType: homie_device_1.PropertyDataType.string, settable: false, retained: true, }), security: stateNode.addProperty({ name: "security", friendlyName: "Security State", dataType: homie_device_1.PropertyDataType.string, settable: false, retained: true, }), net: stateNode.addProperty({ name: "net", friendlyName: "DOCSIS Network Access Enabled", dataType: homie_device_1.PropertyDataType.boolean, settable: false, retained: true, }), }; const downstreamNode = device.node(Object.assign(Object.assign({}, this.config.node), { name: `${this.config.node.name}-downstream`, friendlyName: `${this.config.node.friendlyName} - Downstream`, isRange: true, startRange: 0, endRange: this.config.downstreamChannels - 1 })); const downstreamChannels = { node: downstreamNode, id: downstreamNode.addProperty({ name: "id", friendlyName: "Channel ID", dataType: homie_device_1.PropertyDataType.integer, settable: false, retained: true }), lockStatus: downstreamNode.addProperty({ name: "lockStatus", friendlyName: "Lock Status", dataType: homie_device_1.PropertyDataType.enum, format: "Locked,Not Locked", settable: false, retained: true }), modulation: downstreamNode.addProperty({ name: "modulation", friendlyName: "Modulation", dataType: homie_device_1.PropertyDataType.string, settable: false, retained: true }), frequency: downstreamNode.addProperty({ name: "frequency", friendlyName: "Frequency", dataType: homie_device_1.PropertyDataType.float, unit: "MHz", settable: false, retained: true }), power: downstreamNode.addProperty({ name: "power", friendlyName: "Power", dataType: homie_device_1.PropertyDataType.float, unit: "dBmV", settable: false, retained: true }), snr: downstreamNode.addProperty({ name: "snr", friendlyName: "Signal to Noise Ratio", dataType: homie_device_1.PropertyDataType.float, unit: "dB", settable: false, retained: true }), correctedFrames: downstreamNode.addProperty({ name: "correctedFrames", friendlyName: "Corrected Frames", dataType: homie_device_1.PropertyDataType.integer, settable: false, retained: true }), uncorrectableFrames: downstreamNode.addProperty({ name: "uncorrectableFrames", friendlyName: "Uncorrectable Frames", dataType: homie_device_1.PropertyDataType.integer, settable: false, retained: true }), }; const upstreamNode = device.node(Object.assign(Object.assign({}, this.config.node), { name: `${this.config.node.name}-upstream`, friendlyName: `${this.config.node.friendlyName} - Upstream`, isRange: true, startRange: 0, endRange: this.config.upstreamChannels - 1 })); const upstreamChannels = { node: upstreamNode, id: upstreamNode.addProperty({ name: "id", friendlyName: "Channel ID", dataType: homie_device_1.PropertyDataType.integer, settable: false, retained: true }), lockStatus: upstreamNode.addProperty({ name: "lockStatus", friendlyName: "Lock Status", dataType: homie_device_1.PropertyDataType.enum, format: "Locked,Not Locked", settable: false, retained: true }), channelType: upstreamNode.addProperty({ name: "usChannelType", friendlyName: "US Channel Type", dataType: homie_device_1.PropertyDataType.string, settable: false, retained: true }), frequency: upstreamNode.addProperty({ name: "frequency", friendlyName: "Frequency", dataType: homie_device_1.PropertyDataType.float, unit: "MHz", settable: false, retained: true }), width: upstreamNode.addProperty({ name: "width", friendlyName: "Width", dataType: homie_device_1.PropertyDataType.float, unit: "Hz", settable: false, retained: true }), power: upstreamNode.addProperty({ name: "power", friendlyName: "Power", dataType: homie_device_1.PropertyDataType.float, unit: "dBmV", settable: false, retained: true }), }; this.homieRegistration = { state, downstreamChannels, upstreamChannels, }; } init() { return Promise.resolve(); } }; ArrisSurfboardStatus.DefaultConfiguration = { type: "net", netType: "arris-surfboard-scraper", node: { name: "arris-surfboard", friendlyName: "Arris Surfboard Cable Modem", type: "Cable Modem", isRange: false, }, downstreamChannels: 33, upstreamChannels: 3, url: "http://192.168.100.1", }; ArrisSurfboardStatus = ArrisSurfboardStatus_1 = __decorate([ ISensor_1.staticImplements(), __metadata("design:paramtypes", [Object]) ], ArrisSurfboardStatus); exports.default = ArrisSurfboardStatus; //# sourceMappingURL=ArrisSurfboard.js.map