UNPKG

jvsveml6070

Version:

Node.js package for the Vishay VEML6070 UVA Light Sensor, written in TypeScript.

341 lines (340 loc) 12.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Sensor = void 0; const i2c_bus_1 = require("i2c-bus"); const module_1 = require("./module"); const module_2 = require("./enums/module"); const module_3 = require("./errors/module"); const helpers_1 = require("./helpers"); class Sensor { /** * Creates a new `Sensor` instance. * * @param i2cBusNr - The I2C bus number. Defaults to 1. * @param rSet - The RSET value (in kΩ), which is used to determine the sensor's refresh time. Defaults to 270 kΩ. */ constructor(i2cBusNr = 1, rSet = 270) { this.i2cBusNr = i2cBusNr; this.rSet = rSet; this._commandRegister = new module_1.CommandRegister(); this._state = module_2.SensorState.DISABLED; this._i2cBus = null; this._i2cBusState = module_2.I2CBusState.CLOSED; } /** * Creates a new `Sensor` instance and enables the sensor. * * @param i2cBusNr - The I2C bus number. Defaults to 1. * @param rSet - The RSET value (in kΩ), which is used to determine the sensor's refresh time. Defaults to 270 kΩ. * * @returns A `Promise` that resolves when the sensor has been enabled. */ static initialize(i2cBusNr = 1, rSet = 270) { return new Promise((resolve, reject) => { const sensor = new Sensor(i2cBusNr, rSet); sensor.enable() .then(() => resolve(sensor)) .catch((error) => reject(error)); }); } /** * Retrieves the I2C bus state. * * @returns The `I2CBusState` enumeration value. */ getI2cBusState() { return this._i2cBusState; } /** * Retrieves the sensor's state. * * @returns The `SensorState` enumeration value. */ getState() { return this._state; } /** * Enables the sensor. * * @returns A `Promise` that resolves when the sensor has been initialized. */ enable() { return new Promise((resolve, reject) => { const commandRegister = this._commandRegister.clone(); commandRegister.setShutdownMode(module_2.ShutdownMode.DISABLED); this._checkState(module_2.SensorState.DISABLED) .then(() => this._openI2cBus()) .then(() => this._updateCommandRegister(commandRegister)) .then(() => { this._state = module_2.SensorState.ENABLED; resolve(); }) .catch((error) => { reject(new module_3.SensorError('Failed to enable the sensor.', error)); }); }); } /** * Disables the sensor. * * @returns A `Promise` that resolves when the sensor has been shut down and all resources have been freed up. */ disable() { return new Promise((resolve, reject) => { const commandRegister = this._commandRegister.clone(); commandRegister.setShutdownMode(module_2.ShutdownMode.ENABLED); this._checkState(module_2.SensorState.ENABLED) .then(() => this._updateCommandRegister(commandRegister)) .then(() => this._closeI2cBus()) .then(() => { this._state = module_2.SensorState.DISABLED; resolve(); }) .catch((error) => { reject(new module_3.SensorError('Failed to disable the sensor.', error)); }); }); } /** * Retrieves the shutdown mode. * * @returns The `ShutdownMode` enumeration value. */ getShutdownMode() { return this._commandRegister.getShutdownMode(); } /** * Sets the shutdown mode. * * @param shutdownMode - A `ShutdownMode` enumeration value. * * @returns A `Promise` that resolves when the shutdown mode has been set. */ setShutdownMode(shutdownMode) { const commandRegister = this._commandRegister.clone(); commandRegister.setShutdownMode(shutdownMode); return this._updateCommandRegister(commandRegister); } /** * Retrieves the integration time. * * @returns An `IntegrationTime` instance. */ getIntegrationTime() { return new module_1.IntegrationTime(this._commandRegister.getIntegrationTime()); } /** * Sets the integration time. * * @param integrationTime - An `IntegrationTime` enumeration value. * * @returns A `Promise` that resolves when the integration time has been set. */ setIntegrationTime(integrationTime) { const commandRegister = this._commandRegister.clone(); commandRegister.setIntegrationTime(integrationTime); return this._updateCommandRegister(commandRegister); } /** * Retrieves the refresh time. * * @returns The refresh time in milliseconds. */ getRefreshTime() { const integrationTime = this.getIntegrationTime(); return integrationTime.multiplier * (this.rSet * (125 / 300)); } /** * Retrieves the acknowledge mode. * * @returns The `AcknowledgeMode` enumeration value. */ getAcknowledgeMode() { return this._commandRegister.getAcknowledgeMode(); } /** * Sets the acknowledge mode. * * @param ackMode - An `AcknowledgeMode` enumeration value. * * @returns A `Promise` that resolves when the acknowledge mode has been set. */ setAcknowledgeMode(ackMode) { return this.setAcknowledge(ackMode, undefined); } /** * Retrieves the acknowledge threshold. * * @returns The `AcknowledgeThreshold` enumeration value. */ getAcknowledgeThreshold() { return this._commandRegister.getAcknowledgeThreshold(); } /** * Sets the acknowledge threshold. * * @param ackThreshold - An `AcknowledgeThreshold` enumeration value. * * @returns A `Promise` that resolves when the acknowledge threshold has been set. */ setAcknowledgeThreshold(ackThreshold) { return this.setAcknowledge(undefined, ackThreshold); } /** * Sets the acknowledge mode and/or threshold. * * @param ackMode - An optional `AcknowledgeMode` enumeration value. * @param ackThreshold - An optional `AcknowledgeThreshold` enumeration value. * * @returns A `Promise` that resolves when the acknowledge mode and/or threshold have been set. */ setAcknowledge(ackMode, ackThreshold) { const commandRegister = this._commandRegister.clone(); if (undefined !== ackMode) { commandRegister.setAcknowledgeMode(ackMode); } if (undefined !== ackThreshold) { commandRegister.setAcknowledgeThreshold(ackThreshold); } return this._updateCommandRegister(commandRegister); } /** * Clears the ACK state. * * @param ignoreError - A `boolean` value that determines whether the returned `Promise` resolves even on error. * Defaults to `true` because the Alert Response Address seems to be never valid. This seems to * be an error in the datasheet. * * @returns A `Promise` that resolves when the ACK state has been cleared. */ clearAckState(ignoreError = true) { return new Promise((resolve, reject) => { this._checkI2cBusState(module_2.I2CBusState.OPENED) .then(() => this._i2cBus?.i2cRead(module_2.I2CAddress.AR, 1, Buffer.alloc(1))) .then(() => resolve()) .catch((error) => { if (!ignoreError) { reject(new module_3.SensorError('Failed to clear the ACK state.', error)); } else { resolve(); } }); }); } /** * Reads the value. * * @returns - A `Promise` that resolves when the value has been read. */ read() { return new Promise((resolve, reject) => { this._checkState(module_2.SensorState.ENABLED) .then(() => (0, helpers_1.delay)(this.getRefreshTime())) .then(() => { this._i2cBus?.i2cRead(module_2.I2CAddress.DATA_MSB, 1, Buffer.alloc(1)).then((msb) => { this._i2cBus?.i2cRead(module_2.I2CAddress.DATA_LSB, 1, Buffer.alloc(1)).then((lsb) => { const rawValue = (msb.buffer[0] << 8) | lsb.buffer[0], sensorValue = module_1.SensorValue.fromRawValue(this.rSet, this.getIntegrationTime(), rawValue); resolve(sensorValue); }); }); }) .catch((error) => { reject(new module_3.SensorError('Failed to read value.', error)); }); }); } /** * Checks the I2C bus state. * * @param expectedState - The expected `I2CBusState` enumeration value. * * @returns A `Promise` that resolves when the state is as expected. */ _checkI2cBusState(expectedState) { return new Promise((resolve, reject) => { if (expectedState !== this.getI2cBusState()) { reject(new module_3.I2CError('Invalid bus state.')); } else { resolve(); } }); } /** * Opens the I2C bus. * * @returns A `Promise` that resolves when the I2C bus has been opened. */ _openI2cBus() { return new Promise((resolve, reject) => { this._checkI2cBusState(module_2.I2CBusState.CLOSED) .then(() => (0, i2c_bus_1.openPromisified)(this.i2cBusNr)) .then((i2cBus) => { this._i2cBus = i2cBus; this._i2cBusState = module_2.I2CBusState.OPENED; resolve(); }) .catch((error) => { reject(new module_3.SensorError('Failed to open the I2C bus.', error)); }); }); } /** * Closes the I2C bus. * * @returns A `Promise` that resolves when the I2C bus has been closed. */ _closeI2cBus() { return new Promise((resolve, reject) => { this._checkI2cBusState(module_2.I2CBusState.OPENED) .then(() => this._i2cBus?.close()) .then(() => { this._i2cBus = null; this._i2cBusState = module_2.I2CBusState.CLOSED; resolve(); }) .catch((error) => { reject(new module_3.SensorError('Failed to close the I2C bus.', error)); }); }); } /** * Checks the sensor's state. * * @param expectedState - The expected `SensorState` enumeration value. * * @returns A `Promise` that resolves when the state is as expected. */ _checkState(expectedState) { return new Promise((resolve, reject) => { if (expectedState !== this.getState()) { reject(new module_3.SensorError('Invalid state.')); } else { resolve(); } }); } /** * Updates the sensor's command register. * On success, the internal `CommandRegister` instance is updated. * * @param commandRegister - The `CommandRegister` instance containing the data to write. * * @returns A `Promise` that resolves when the sensor's command register has been updated. */ _updateCommandRegister(commandRegister) { return new Promise((resolve, reject) => { this.clearAckState() .then(() => this._i2cBus?.i2cWrite(module_2.I2CAddress.CMD, 1, commandRegister.toBuffer())) .then(() => { this._commandRegister.writeBits(commandRegister.readBits()); resolve(); }).catch((error) => { reject(new module_3.SensorError('Failed to update the sensor\'s command register.', error)); }); }); } } exports.Sensor = Sensor;