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(); //check wether a serie exists const hasSeries = measurements .type("flow") .variant("measured") .exists(); // true if any position exists const hasUpstreamValues = measurements .type("flow") .variant("measured") .exists({ position: "upstream", requireValues: true }); // Passing everything explicitly const hasPercent = measurements.exists({ type: "volume", variant: "percent", position: "atEquipment", }); 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(2); // new helper const prevPrevSample = stats.getLaggedValue(3); // 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 };