node-anemometer
Version:
Measuring the wind speed with an anemometer
174 lines (173 loc) • 7.02 kB
JavaScript
"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; } });