jvsveml6070
Version:
Node.js package for the Vishay VEML6070 UVA Light Sensor, written in TypeScript.
341 lines (340 loc) • 12.2 kB
JavaScript
"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;