Files
generalFunctions/src/measurements/examples.js

360 lines
11 KiB
JavaScript

const { MeasurementContainer } = require('./index');
console.log('=== MEASUREMENT CONTAINER EXAMPLES ===\n');
console.log('This guide shows how to use the MeasurementContainer for storing,');
console.log('retrieving, and converting measurement data with automatic unit handling.\n');
// ====================================
// BASIC SETUP EXAMPLES
// ====================================
console.log('--- Example 1: Basic Setup & Distance ---');
// Create a basic container
const basicContainer = new MeasurementContainer({ windowSize: 20 });
// Subscribe to events to monitor changes
basicContainer.emitter.on('flow.predicted.upstream', (data) => {
console.log(`📡 Event: Flow predicted upstream = ${data.value} ${data.unit || ''} (distance=${data.distance ?? 'n/a'}m)`);
});
// Subscribe to all measured flow events using wildcard
basicContainer.emitter.on('flow.measured.*', (data) => {
console.log(`📡 Event: Flow measured ${data.position} = ${data.value} ${data.unit || ''} (distance=${data.distance ?? 'n/a'}m)`);
});
// Basic value setting with distance
console.log('\nSetting pressure values with distances:');
basicContainer
.type('pressure')
.variant('measured')
.position('upstream')
.distance(1.5)
.value(100)
.unit('psi');
basicContainer
.type('pressure')
.variant('measured')
.position('downstream')
.distance(5.2)
.value(95)
.unit('psi');
// Distance persists - no need to set it again for same position
basicContainer
.type('pressure')
.variant('measured')
.position('downstream')
.value(90); // distance 5.2 is automatically reused
console.log('✅ Basic setup complete\n');
// Retrieve and display the distance
const upstreamPressure = basicContainer
.type('pressure')
.variant('measured')
.position('upstream')
.get();
console.log(`Retrieved upstream pressure: ${upstreamPressure.getCurrentValue()} ${upstreamPressure.unit}`);
console.log(`Distance from parent: ${upstreamPressure.distance ?? 'not set'} m\n`);
// ====================================
// AUTO-CONVERSION SETUP
// ====================================
console.log('--- Example 2: Auto-Conversion Setup ---');
const autoContainer = new MeasurementContainer({
autoConvert: true,
windowSize: 50,
defaultUnits: {
pressure: 'bar',
flow: 'l/min',
power: 'kW',
temperature: 'C'
},
preferredUnits: {
pressure: 'psi'
}
});
// Values automatically convert to preferred units
console.log('Adding pressure with auto-conversion:');
autoContainer
.type('pressure')
.variant('measured')
.position('upstream')
.distance(0.5)
.value(1.5, Date.now(), 'bar'); // Input: 1.5 bar → Auto-stored as ~21.76 psi
const converted = autoContainer
.type('pressure')
.variant('measured')
.position('upstream')
.get();
console.log(`Stored as: ${converted.getCurrentValue()} ${converted.unit} (distance=${converted.distance}m)`);
console.log('✅ Auto-conversion complete\n');
// ====================================
// UNIT CONVERSION ON RETRIEVAL
// ====================================
console.log('--- Example 3: Unit Conversion on Retrieval ---');
autoContainer
.type('flow')
.variant('predicted')
.position('upstream')
.distance(2.4)
.value(100, Date.now(), 'l/min');
const flowMeasurement = autoContainer
.type('flow')
.variant('predicted')
.position('upstream')
.get();
console.log(`Flow in l/min: ${flowMeasurement.getCurrentValue('l/min')}`);
console.log(`Flow in m³/h: ${flowMeasurement.getCurrentValue('m3/h').toFixed(2)}`);
console.log(`Flow in gal/min: ${flowMeasurement.getCurrentValue('gal/min').toFixed(2)}`);
console.log(`Distance: ${flowMeasurement.distance}m\n`);
// ====================================
// SMART UNIT SELECTION
// ====================================
console.log('--- Example 4: Smart Unit Selection ---');
autoContainer
.type('pressure')
.variant('test')
.position('sensor')
.distance(0.2)
.value(0.001, Date.now(), 'bar');
const bestUnit = autoContainer
.type('pressure')
.variant('test')
.position('sensor')
.getBestUnit();
if (bestUnit) {
console.log(`Best unit: ${bestUnit.val.toFixed(2)} ${bestUnit.unit}`);
}
const availableUnits = autoContainer.getAvailableUnits('pressure');
console.log(`Available units: ${availableUnits.slice(0, 5).join(', ')}...\n`);
// ====================================
// BASIC RETRIEVAL
// ====================================
console.log('--- Example 5: Basic Value Retrieval ---');
const upstreamVal = basicContainer
.type('pressure')
.variant('measured')
.position('upstream')
.getCurrentValue();
const upstreamData = basicContainer
.type('pressure')
.variant('measured')
.position('upstream')
.get();
console.log(`Upstream: ${upstreamVal} ${upstreamData.unit} at ${upstreamData.distance}m`);
const downstreamVal = basicContainer
.type('pressure')
.variant('measured')
.position('downstream')
.getCurrentValue();
const downstreamData = basicContainer
.type('pressure')
.variant('measured')
.position('downstream')
.get();
console.log(`Downstream: ${downstreamVal} ${downstreamData.unit} at ${downstreamData.distance}m\n`);
// ====================================
// CALCULATIONS & STATISTICS
// ====================================
console.log('--- Example 6: Calculations & Statistics ---');
basicContainer
.type('flow')
.variant('predicted')
.position('upstream')
.distance(3.0)
.value(200)
.unit('gpm');
basicContainer
.type('flow')
.variant('predicted')
.position('downstream')
.distance(8.5)
.value(195)
.unit('gpm');
const flowAvg = basicContainer
.type('flow')
.variant('predicted')
.position('upstream')
.getAverage();
console.log(`Average upstream flow: ${flowAvg.toFixed(1)} gpm`);
const pressureDiff = basicContainer
.type('pressure')
.variant('measured')
.difference();
console.log(`Pressure difference: ${pressureDiff.value} ${pressureDiff.unit}\n`);
//reversable difference
const deltaP = basicContainer.type("pressure").variant("measured").difference(); // defaults to downstream - upstream
const netFlow = basicContainer.type("flow").variant("measured").difference({ from: "upstream", to: "downstream" });
// ====================================
// ADVANCED STATISTICS & HISTORY
// ====================================
console.log('--- Example 7: Advanced Statistics & History ---');
basicContainer
.type('flow')
.variant('measured')
.position('upstream')
.distance(3.0)
.value(210)
.value(215)
.value(205)
.value(220)
.value(200)
.unit('m3/h');
const stats = basicContainer
.type('flow')
.variant('measured')
.position('upstream');
const statsData = stats.get();
console.log('Flow Statistics:');
console.log(` Current: ${stats.getCurrentValue()} ${statsData.unit}`);
console.log(` Average: ${stats.getAverage().toFixed(1)} ${statsData.unit}`);
console.log(` Min: ${stats.getMin()} ${statsData.unit}`);
console.log(` Max: ${stats.getMax()} ${statsData.unit}`);
console.log(` Distance: ${statsData.distance}m`);
const allValues = stats.getAllValues();
console.log(` Samples: ${allValues.values.length}`);
console.log(` History: [${allValues.values.join(', ')}]\n`);
console.log('--- Lagged sample comparison ---');
const latest = stats.getCurrentValue(); // existing helper
const prevSample = stats.getLaggedValue(1); // new helper
const prevPrevSample = stats.getLaggedValue(2); // optional
if (prevSample) {
const delta = latest - prevSample.value;
console.log(
`Current vs previous: ${latest} ${statsData.unit} (t=${stats.get().getLatestTimestamp()}) vs ` +
`${prevSample.value} ${prevSample.unit} (t=${prevSample.timestamp})`
);
console.log(`Δ = ${delta.toFixed(2)} ${statsData.unit}`);
}
if (prevPrevSample) {
console.log(
`Previous vs 2-steps-back timestamps: ${new Date(prevSample.timestamp).toISOString()} vs ` +
`${new Date(prevPrevSample.timestamp).toISOString()}`
);
}
// ====================================
// DYNAMIC UNIT MANAGEMENT
// ====================================
console.log('--- Example 8: Dynamic Unit Management ---');
autoContainer.setPreferredUnit('flow', 'm3/h');
console.log('Changed preferred flow unit to m³/h');
autoContainer
.type('flow')
.variant('realtime')
.position('inlet')
.distance(1.2)
.value(150, Date.now(), 'l/min');
const realtimeFlow = autoContainer
.type('flow')
.variant('realtime')
.position('inlet')
.get();
console.log(`Stored as: ${realtimeFlow.getCurrentValue()} ${realtimeFlow.unit}`);
console.log(`Original: ${realtimeFlow.getCurrentValue('l/min').toFixed(1)} l/min`);
console.log(`Distance: ${realtimeFlow.distance}m\n`);
// ====================================
// DATA EXPLORATION
// ====================================
console.log('--- Example 9: Data Exploration ---');
console.log('Available types:', basicContainer.getTypes());
console.log('Pressure variants:', basicContainer.type('pressure').getVariants());
console.log('Measured pressure positions:', basicContainer.type('pressure').variant('measured').getPositions());
console.log('\nData Structure:');
basicContainer.getTypes().forEach(type => {
const variants = basicContainer.type(type).getVariants();
if (variants.length > 0) {
console.log(`${type.toUpperCase()}:`);
variants.forEach(variant => {
const positions = basicContainer.type(type).variant(variant).getPositions();
positions.forEach(position => {
const m = basicContainer.type(type).variant(variant).position(position).get();
if (m && m.values.length > 0) {
console.log(` └─ ${variant}.${position}: ${m.values.length} values, ${m.unit || 'no unit'}, dist=${m.distance ?? 'n/a'}m`);
}
});
});
}
});
console.log('\n✅ All examples complete!\n');
// ====================================
// BEST PRACTICES
// ====================================
console.log('--- Best Practices Summary ---\n');
console.log('SETUP:');
console.log(' • Enable autoConvert for consistent units');
console.log(' • Define defaultUnits for your measurement types');
console.log(' • Set windowSize based on your data retention needs\n');
console.log('STORING DATA:');
console.log(' • Chain methods: type().variant().position().distance().value()');
console.log(' • Set distance once - it persists for that position');
console.log(' • Specify source unit: .value(100, timestamp, "psi")');
console.log(' • Set unit immediately: .value(100).unit("psi")\n');
console.log('RETRIEVING DATA:');
console.log(' • Use .getCurrentValue("unit") for specific units');
console.log(' • Use .getBestUnit() for automatic selection');
console.log(' • Use .difference() for upstream/downstream deltas');
console.log(' • Access .get().distance for physical positioning\n');
console.log('MONITORING:');
console.log(' • Subscribe: .emitter.on("type.variant.position", callback)');
console.log(' • Event data includes: value, unit, timestamp, distance');
console.log(' • Explore data: .getTypes(), .getVariants(), .getPositions()\n');
module.exports = { basicContainer, autoContainer };