UNPKG

node-anemometer

Version:

Measuring the wind speed with an anemometer

174 lines (173 loc) 7.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WindSpeedUnits = exports.WindSpeed = exports.scanBus = exports.calcFactor = exports.Anemometer = void 0; const dynamic_1 = require("set-interval-async/dynamic"); const constants_1 = require("./utils/constants"); const History_1 = require("./utils/History"); const PCF8583_1 = require("./utils/PCF8583"); const utilities_1 = require("./utils/utilities"); /** * Represents an Anemometer device for measuring wind speed using a PCF8583 real-time clock module. * This class allows you to read wind speed data, calculate wind speed values, and maintain a history * of pulse counts to determine wind speed over time. */ class Anemometer { calc; opts; chip; history; readInterval = null; /** * Creates an instance of the Anemometer class, which interfaces with a PCF8583 module. * * @param calc A function that calculates WindSpeed based on pulse count and time. * @param opts Optional configuration options for the Anemometer. */ constructor(calc, opts = {}) { this.calc = calc; this.opts = opts; this.chip = new PCF8583_1.PCF8583(this.opts.address ?? constants_1.I2CADDR, this.opts.bus ?? 1); this.history = new History_1.History(this.opts.history?.expirationTime, this.opts.history?.maxElements); } /** * Indicator of whether a connection has been established and the data is being read.. * * @readonly * @returns `true` if the connection is ready; otherwise, `false`. */ get isReady() { return this.readInterval !== null; } /* * ========================================== * Private functions * ========================================== */ /** * Resets the PCF8583 chip to its default values and initializes it for event counting mode. * * @returns A promise that resolves when the chip is successfully reset and initialized. */ async resetChip() { if (this.chip.isOpen) { await this.chip.close(); } await this.chip.open(); await this.chip.reset(); await this.chip.setMode(constants_1.PCF8583Mode.COUNTER); await this.chip.start(); this.history.push(0); } /** * Clears the read interval if it is set. * * @returns A promise that resolves when the read interval is cleared. */ async clearReadInterval() { if (this.readInterval !== null) { await (0, dynamic_1.clearIntervalAsync)(this.readInterval); this.readInterval = null; } } /* * ========================================== * Public functions * ========================================== */ /** * Opens the i2c connection and start the reading data. * * @returns A promise that resolves when the connection is successfully opened. */ async open() { await this.resetChip(); await this.clearReadInterval(); this.readInterval = (0, dynamic_1.setIntervalAsync)(async () => { let count = null; for (let i = 0; i < (this.opts.retries ?? 3); i++) { count = await (0, utilities_1.runSave)(this.chip.getCount(), null, this.opts.readFailed); if (count !== null) { break; } await (0, utilities_1.sleep)(100 * i); } if (count === null) { return await (0, utilities_1.runSave)(this.resetChip()); } this.history.clean(); this.history.push(count); if (count > 900000) { await this.chip.setCount(0); this.history.push(0); } }, this.opts.readInterval ?? 1000); } /** * Closes the i2c connection and stops the reading process. * * @returns A promise that resolves when the connection is successfully closed. */ async close() { await this.clearReadInterval(); if (this.chip.isOpen) { await this.chip.stop(); await this.chip.close(); } } /** * Calculates the average wind speed of the past x seconds. * * @deprecated Use `.getAverageWindSpeed()` instead of `.getData()` * @param time The offset for which to retrieve wind speed data. * @returns The average WindSpeed data for the specified time. */ getData(time) { if (time <= 0 || time > this.history.expirationTime) { throw new Error(`The given time is not in range. Value is only valid between 1 and ${this.history.expirationTime}!`); } const data = this.history.get({ recentSeconds: time }); const { pulses, timeSpan } = (0, utilities_1.getTotalPulses)(data); return this.calc(pulses, timeSpan); } /** * Retrieves data records based on the specified conditions. * * @param conditions The conditions to filter and retrieve the data records. * @returns An copied array of data records. Each record includes a value and a timestamp. */ getHistoryData(conditions) { return this.history.get(conditions); } /** * Calculates the average wind speed over a specified time period. * The average wind speed is computed from the total pulses and the time span of the data records. * * @param conditions Optional time conditions to filter the data. * @returns The average wind speed calculated from the data records. */ getAverageWindSpeed(conditions = {}) { const data = this.history.get(conditions); const { pulses, timeSpan } = (0, utilities_1.getTotalPulses)(data); return this.calc(pulses, timeSpan); } /** * Finds the peak wind gust within a specified time period. * The peak wind gust is determined by finding the largest increase in pulse values and the corresponding time span. * * @param conditions Optional time conditions to filter the data. * @returns The peak wind gust calculated from the data records. */ getPeakWindGust(conditions = {}) { const data = this.history.get(conditions); const { step, timeSpan } = (0, utilities_1.getMaxIncreaseRate)(data); return this.calc(step, timeSpan); } } exports.Anemometer = Anemometer; // Provide legacy support exports.default = Anemometer; var utilities_2 = require("./utils/utilities"); Object.defineProperty(exports, "calcFactor", { enumerable: true, get: function () { return utilities_2.calcFactor; } }); Object.defineProperty(exports, "scanBus", { enumerable: true, get: function () { return utilities_2.scanBus; } }); Object.defineProperty(exports, "WindSpeed", { enumerable: true, get: function () { return utilities_2.WindSpeed; } }); Object.defineProperty(exports, "WindSpeedUnits", { enumerable: true, get: function () { return utilities_2.WindSpeedUnits; } });