changed the folder and added index.js
This commit is contained in:
187
src/measurements/Measurement.js
Normal file
187
src/measurements/Measurement.js
Normal file
@@ -0,0 +1,187 @@
|
||||
// Add unit conversion support
|
||||
const convertModule = require('../../../convert/dependencies/index');
|
||||
|
||||
class Measurement {
|
||||
constructor(type, variant, position, windowSize) {
|
||||
this.type = type; // e.g. 'pressure', 'flow', etc.
|
||||
this.variant = variant; // e.g. 'predicted' or 'measured', etc..
|
||||
this.position = position; // Downstream or upstream of parent object
|
||||
this.windowSize = windowSize; // Rolling window size
|
||||
|
||||
// Place all data inside an array
|
||||
this.values = []; // Array to store all values
|
||||
this.timestamps = []; // Array to store all timestamps
|
||||
|
||||
// Unit tracking
|
||||
this.unit = null; // Current unit of measurement
|
||||
|
||||
// For tracking differences if this is a calculated difference measurement
|
||||
this.isDifference = false;
|
||||
this.sourcePositions = [];
|
||||
}
|
||||
|
||||
// -- Updater methods --
|
||||
setType(type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
setVariant(variant) {
|
||||
this.variant = variant;
|
||||
return this;
|
||||
}
|
||||
|
||||
setPosition(position) {
|
||||
this.position = position;
|
||||
return this;
|
||||
}
|
||||
|
||||
setValue(value, timestamp = Date.now()) {
|
||||
/*
|
||||
if (value === undefined || value === null) {
|
||||
value = null ;
|
||||
//throw new Error('Value cannot be null or undefined');
|
||||
}
|
||||
*/
|
||||
|
||||
//shift the oldest value
|
||||
if(this.values.length >= this.windowSize){
|
||||
this.values.shift();
|
||||
this.timestamps.shift();
|
||||
}
|
||||
|
||||
//push the new value
|
||||
this.values.push(value);
|
||||
this.timestamps.push(timestamp);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
setUnit(unit) {
|
||||
this.unit = unit;
|
||||
return this;
|
||||
}
|
||||
|
||||
// -- Getter methods --
|
||||
getCurrentValue() {
|
||||
if (this.values.length === 0) return null;
|
||||
return this.values[this.values.length - 1];
|
||||
}
|
||||
|
||||
getAverage() {
|
||||
if (this.values.length === 0) return null;
|
||||
const sum = this.values.reduce((acc, val) => acc + val, 0);
|
||||
return sum / this.values.length;
|
||||
}
|
||||
|
||||
getMin() {
|
||||
if (this.values.length === 0) return null;
|
||||
return Math.min(...this.values);
|
||||
}
|
||||
|
||||
getMax() {
|
||||
if (this.values.length === 0) return null;
|
||||
return Math.max(...this.values);
|
||||
}
|
||||
|
||||
getAllValues() {
|
||||
return {
|
||||
values: [...this.values],
|
||||
timestamps: [...this.timestamps],
|
||||
unit: this.unit
|
||||
};
|
||||
}
|
||||
|
||||
// -- Position-based methods --
|
||||
|
||||
// Create a new measurement that is the difference between two positions
|
||||
static createDifference(upstreamMeasurement, downstreamMeasurement) {
|
||||
console.log('hello:');
|
||||
if (upstreamMeasurement.type !== downstreamMeasurement.type ||
|
||||
upstreamMeasurement.variant !== downstreamMeasurement.variant) {
|
||||
throw new Error('Cannot calculate difference between different measurement types or variants');
|
||||
}
|
||||
|
||||
// Ensure units match
|
||||
let downstream = downstreamMeasurement;
|
||||
if (upstreamMeasurement.unit && downstream.unit &&
|
||||
upstreamMeasurement.unit !== downstream.unit) {
|
||||
downstream = downstream.convertTo(upstreamMeasurement.unit);
|
||||
}
|
||||
|
||||
// Create a new difference measurement
|
||||
const diffMeasurement = new Measurement(
|
||||
upstreamMeasurement.type,
|
||||
upstreamMeasurement.variant,
|
||||
'difference',
|
||||
Math.min(upstreamMeasurement.windowSize, downstream.windowSize)
|
||||
);
|
||||
|
||||
// Mark as a difference measurement and keep track of sources
|
||||
diffMeasurement.isDifference = true;
|
||||
diffMeasurement.sourcePositions = ['upstream', 'downstream'];
|
||||
|
||||
// Calculate all differences where timestamps match
|
||||
const upValues = upstreamMeasurement.getAllValues();
|
||||
const downValues = downstream.getAllValues();
|
||||
|
||||
// Match timestamps and calculate differences
|
||||
for (let i = 0; i < upValues.timestamps.length; i++) {
|
||||
const upTimestamp = upValues.timestamps[i];
|
||||
const downIndex = downValues.timestamps.indexOf(upTimestamp);
|
||||
|
||||
if (downIndex !== -1) {
|
||||
|
||||
const diff = upValues.values[i] - downValues.values[downIndex];
|
||||
diffMeasurement.setValue(diff, upTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
diffMeasurement.setUnit(upstreamMeasurement.unit);
|
||||
|
||||
return diffMeasurement;
|
||||
}
|
||||
|
||||
// -- Additional getter methods --
|
||||
getLatestTimestamp() {
|
||||
if (this.timestamps.length === 0) return null;
|
||||
return this.timestamps[this.timestamps.length - 1];
|
||||
}
|
||||
|
||||
getValueAtTimestamp(timestamp) {
|
||||
const index = this.timestamps.indexOf(timestamp);
|
||||
if (index === -1) return null;
|
||||
return this.values[index];
|
||||
}
|
||||
|
||||
// -- Unit conversion methods --
|
||||
convertTo(targetUnit) {
|
||||
if (!this.unit) {
|
||||
throw new Error('Current unit not set, cannot convert');
|
||||
}
|
||||
|
||||
try {
|
||||
const convertedValues = this.values.map(value =>
|
||||
convertModule.convert(value).from(this.unit).to(targetUnit)
|
||||
);
|
||||
|
||||
const newMeasurement = new Measurement(
|
||||
this.type,
|
||||
this.variant,
|
||||
this.position,
|
||||
this.windowSize
|
||||
);
|
||||
|
||||
// Copy values and timestamps
|
||||
newMeasurement.values = convertedValues;
|
||||
newMeasurement.timestamps = [...this.timestamps];
|
||||
newMeasurement.unit = targetUnit;
|
||||
|
||||
return newMeasurement;
|
||||
} catch (error) {
|
||||
throw new Error(`Unit conversion failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Measurement;
|
||||
Reference in New Issue
Block a user