Skip to main content

Water Flow Monitoring

Real-time monitoring of water flow, consumption tracking, leakage detection, and threshold alerts across multiple locations and categories.


Overview

The Water Flow Monitoring feature provides comprehensive tracking and visualization of water consumption across different categories (Source, Stock, Quality, Ground Water Level) with real-time updates, intelligent alerts, and detailed analytics.

Location: libs/monitoring/

Key Routes:

  • /monitoring/flow/:categoryId - Flow monitoring by category
  • /monitoring/quality - Water quality monitoring
  • /monitoring/stock - Water stock levels
  • /monitoring/groundwater - Ground water level tracking
  • /monitoring/energy - Energy consumption monitoring

Key Features

1. Real-Time Data Monitoring

  • Live Updates: Auto-refresh every interval (configurable via constants.refreshDuration)
  • WebSocket Integration: Real-time data push from Azure Web PubSub
  • Multi-Category Support: Source, Stock, Quality, Ground Water Level, Energy
  • Multi-Unit Tracking: Monitor multiple locations and units simultaneously

2. Time-Based Analysis

Time Selection Options:

  • DAY - Hourly consumption graph (24 hours)
  • WEEK - Daily consumption graph (7 days)
  • MONTH - Daily consumption graph (30 days)
  • YEAR - Monthly consumption graph (12 months)
  • CUSTOM - User-defined date range
WaterFlowEnum.TimeSelection = {
DAY: 'DAY',
WEEK: 'WEEK',
MONTH: 'MONTH',
YEAR: 'YEAR',
CUSTOM: 'CUSTOM',
};

3. Visualization Types

Graph Types:

  • BAR - Bar chart for consumption comparison
  • LINE - Line graph for trend analysis
  • PIE - Pie chart for distribution

View Types:

  • Total Flow - Cumulative consumption
  • Flow Rate - Real-time flow rate (L/min or m³/hr)
WaterFlowEnum.ViewType = {
TOTAL_FLOW: 'total_flow',
FLOW_RATE: 'flow_rate',
};

4. Intelligent Alerts & Status

Unit Status Types:

Leakage Detection

  • Icon: Red leakage indicator
  • Badge: "Leakage Detected"
  • Background: #FFF0F0 (light red)
  • Border Color: #8C0000 (dark red)
  • Detection: AI-powered anomaly detection via stable flow alerts

Threshold Alerts

  • Icon: Orange warning indicator
  • Badge: "Reached Daily Limit"
  • Background: #FFF1ED (light orange)
  • Border Color: Red
  • Trigger: When consumption exceeds configured daily/hourly threshold

Offline Status

  • Icon: Grey offline indicator
  • Badge: "Units Offline"
  • Background: #F5F5F5 (light grey)
  • Border Color: #747474 (grey)
  • Trigger: Device connectivity lost

5. Advanced Filtering

Filter Options:

  • Leakage detected units
  • Threshold crossed units
  • Offline units
  • Online units only
  • All units

Usage:

// Apply filter
flowStore.setUnitFilterConfig({
leakageDetected: true,
thresholdCrossed: false,
offline: false
});

Architecture

Data Flow Pattern

User Interaction (FlowDatePickerComponent)

WaterMonitoringFlowDataProvider (Context)

MonitoringController.getCategoryDataWithOrdering()

MonitoringDataSource.getCategoryDataV2()

API Client → Backend API

Process & Transform Data

Update Context State

Re-render Components (FlowGraphComponent, FlowAccordion)

Key Components

1. WaterMonitoringFlowDataProvider

  • Purpose: Global state management for flow monitoring
  • Location: libs/monitoring/src/dataProvider/WaterMonitoringFlowDataProvider.jsx
  • State Variables:
    • isLoading - Loading state
    • consumptionData - Consumption data with graphs
    • params - Date range and time type parameters
    • labelData - X-axis labels for graphs
    • visibleTimeSelection - Current time filter (DAY/WEEK/MONTH/YEAR)
    • rearrangedSubCategories - User-customized category order

2. MonitoringController

  • Purpose: Business logic layer for data processing
  • Location: libs/monitoring/src/controller/monitoringController.js
  • Key Methods:
    • getCategoryDataWithOrdering() - Fetch and order category data
    • processCategoryData() - Transform API data with leakage detection
    • prepareUnits() - Calculate thresholds and status icons
    • formatFlowGraphData() - Format graph data for charts

3. MonitoringDataSource

  • Purpose: API integration layer
  • Location: libs/monitoring/src/dataSource/monitoring.js
  • Key Methods:
    • getCategoryDataV2() - Fetch category consumption data
    • getLeakageAlertsData() - Fetch leakage alert data
    • getUnitGranularData() - Fetch unit-level granular data
    • getCompareData() - Fetch comparison data for two units

4. FlowGraphComponent

  • Purpose: Render consumption graphs for units and categories
  • Location: libs/monitoring/src/pages/flow/flowCategoryPage/components/FlowGraphComponent.jsx
  • Features:
    • Interactive bar/line charts
    • Threshold visualization
    • Click-to-drill-down
    • Export functionality

5. FlowAccordion

  • Purpose: Collapsible category sections with unit listings
  • Location: libs/monitoring/src/pages/flow/flowCategoryPage/BuildFlowPageLayout.jsx
  • Features:
    • Expand/collapse subcategories
    • Display total consumption per category
    • Show unit count per category
    • Filter units by status

API Endpoints

Get Category Data V2

GET /categoryDataV2
Params: {
category: 'SOURCE_CATEGORY',
type: 'DAY',
date1: '25/02/2026',
date2: '25/02/2026'
}
Response: {
siUnit: 'kL',
total: 1234.56,
subCategories: [
{
id: 'SUB_CAT_1',
displayName: 'Borewell',
total: 567.89,
units: [
{
unitId: 'UNIT_1',
displayName: 'Borewell 1',
value: 123.45,
online: true,
graph: [...],
meta: {
threshold: 100,
alertsConfig: {...}
}
}
]
}
]
}

Get Leakage Alerts Data

GET /getLeakageAlertsData
Params: {
unitId: 'UNIT_1,UNIT_2',
startDate: '25/02/2026',
endDate: '25/02/2026'
}
Response: {
leakageDetected: [
{
unitId: 'UNIT_1',
alertType: 'stable_flow_alert',
detectedAt: '2026-02-25T10:30:00Z',
duration: 120 // minutes
}
]
}

Get Unit Granular Data

GET /granular/unit
Params: {
unitId: 'UNIT_1',
date1: '25/02/2026',
date2: '25/02/2026',
type: 'DAY'
}
Response: {
graph: [
{ x: '00:00', y: 12.5, threshold: 10 },
{ x: '01:00', y: 8.3, threshold: 10 }
]
}

Usage Examples

1. Initialize Flow Monitoring

import { WaterMonitoringFlowDataProvider } from '@aquagen-mf-webapp/monitoring';

function App() {
return (
<WaterMonitoringFlowDataProvider>
<FlowMonitoringPage />
</WaterMonitoringFlowDataProvider>
);
}

2. Access Flow Data in Component

import { useContext } from 'react';
import { WaterMonitoringFlowDataContext } from '@aquagen-mf-webapp/monitoring';

function FlowComponent() {
const flowStore = useContext(WaterMonitoringFlowDataContext);

const {
consumptionData,
isLoading,
params,
setParams
} = flowStore;

if (isLoading) return <Loader />;

return (
<div>
<h2>Total: {consumptionData?.data?.total} {consumptionData?.siUnit}</h2>
{consumptionData?.data?.subCategories?.map(sub => (
<div key={sub.id}>
<h3>{sub.displayName}: {sub.total} kL</h3>
</div>
))}
</div>
);
}

3. Change Time Period

import { WaterFlowEnum } from '@aquagen-mf-webapp/monitoring';

function DateSelector() {
const flowStore = useContext(WaterMonitoringFlowDataContext);

const handleTimeChange = (type) => {
const today = moment().format('DD/MM/YYYY');
flowStore.setParams({
type: type,
date1: today,
date2: today
});
};

return (
<button onClick={() => handleTimeChange(WaterFlowEnum.TimeSelection.WEEK)}>
View Weekly Data
</button>
);
}

4. Filter Units by Status

function UnitFilter() {
const flowStore = useContext(FlowScreenDataContext);

const showOnlyLeakage = () => {
flowStore.setUnitFilterConfig({
leakageDetected: true
});
};

const showAll = () => {
flowStore.setUnitFilterConfig({
leakageDetected: false,
thresholdCrossed: false,
offline: false
});
};

return (
<div>
<button onClick={showOnlyLeakage}>Show Leakage Units</button>
<button onClick={showAll}>Show All Units</button>
</div>
);
}

Leakage Detection

How It Works

  1. Alert Configuration: Each unit has meta.alertsConfig.alertEnabled.stable_flow flag
  2. Detection: Backend monitors for unusual stable flow patterns indicating leakage
  3. Data Fetching: getLeakageAlertsData() API returns detected leakages
  4. Unit Update: LeakageDetectionHelper.updateUnitsWithLeakageData() marks affected units
  5. Visual Indicator: Red border, leakage icon, and badge displayed on unit card

Example Leakage Configuration:

unit.meta = {
alertsConfig: {
alertEnabled: {
stable_flow: true // Enable leakage detection
}
},
leakageEnabled: true
};

Leakage Status Icons

WaterFlowEnum.UnitStatus.LEAKAGE_DETECTED = {
icon: leakageDetectedIcon,
alt: 'Leakage Detected',
badgeLabel: 'Leakage Detected',
unitCardText: 'Leakage has been detected in this unit',
backgroundColor: '#FFF0F0',
borderColor: '#8C0000',
textColor: '#8C0000',
tooltip: {
single: { prefix: 'Leakage has been detected in ', suffix: '' },
multiple: ' are detected with leakage',
scroll: (count) => `Leakage detected in ${count} units`,
animation: 'scrollLeakage'
}
};

Threshold Management

Threshold Types

  • Daily Threshold: Maximum consumption per day (kL)
  • Hourly Threshold: Maximum consumption per hour (kL)

Threshold Resolution Logic

// Resolve threshold based on time type
const activeThreshold = WaterFlowUtils.resolveThresholdForType(
params, // { type: 'DAY', date1: '...', date2: '...' }
unit.meta // { threshold: 100, hourlyThreshold: 10 }
);

// Returns:
// - hourlyThreshold for DAY type
// - threshold for WEEK/MONTH/YEAR types

Threshold Status

// Check if unit exceeded threshold
const isAboveThreshold = WaterFlowUtils.isAboveThreshold(
{ safeValue: unit.value },
params.type
);

// Visual indicator when threshold crossed
WaterFlowEnum.UnitStatus.THRESHOLD_DETECTED = {
badgeLabel: 'Reached Daily Limit',
backgroundColor: '#FFF1ED',
borderColor: '#FF0000',
textColor: '#FF0000'
};

Customization Features

1. Reorder Subcategories

Users can drag-and-drop to reorder subcategories. Order is persisted in localStorage.

// Update category order
flowStore.setRearrangedSubCategories([
{ id: 'SUB_CAT_2', displayName: 'Borewell' },
{ id: 'SUB_CAT_1', displayName: 'Municipal' }
]);

// Stored in localStorage using user-specific key
WaterMonitoringFlowHelper.writeRearrangedSubCategories(newOrder);

2. Persistent Date Selection

Last selected date range and time type are saved and restored on next visit.

// Save selection
WaterMonitoringFlowHelper.writeSelection(
WaterFlowEnum.TimeSelection.WEEK,
{ type: 'CUSTOM', date1: '...' date2: '...' }
);

// Read selection on mount
const stored = WaterMonitoringFlowHelper.readSelection();

Performance Optimization

1. Auto-Refresh Strategy

useEffect(() => {
// Initial load with loader
init(true);

// Subsequent refreshes without loader
const interval = setInterval(() => {
init(false); // Background refresh
}, constants.refreshDuration);

return () => clearInterval(interval);
}, [params]);

2. Conditional Loading

// Show loader only on user-initiated changes
async function init(showLoader = false) {
if (showLoader) setIsLoading(true);

try {
const data = await fetchData();
setConsumptionData(data);
} finally {
if (showLoader) setIsLoading(false);
}
}

3. Memoized Filtering

// Filter units only when filter config changes
useEffect(() => {
setFilteredUnits(
WaterFlowHelper.filterUnits(
subCategoryData.units,
flowStore.unitFilterConfig
)
);
}, [flowStore.unitFilterConfig]);

Analytics Integration

Track user interactions for insights:

import { AnalyticsService } from '@aquagen-mf-webapp/shared/services';
import { AnalyticEvents } from '@aquagen-mf-webapp/shared/enums';

// Page view
AnalyticsService.sendEvent(AnalyticEvents.PAGE_VIEW, {}, true);

// Date change
AnalyticsService.sendEvent(AnalyticEvents.FLOW_DATE_CHANGE, {
params: { type: 'WEEK', date1: '...' }
});

// Filter applied
AnalyticsService.sendEvent(AnalyticEvents.FLOW_FILTER_APPLY, {
filter: 'leakageDetected'
});

Best Practices

1. Always Use Context Providers

Wrap components with WaterMonitoringFlowDataProvider to access flow data:

<WaterMonitoringFlowDataProvider>
<YourFlowComponent />
</WaterMonitoringFlowDataProvider>

2. Handle Loading States

const { isLoading, consumptionData } = useContext(WaterMonitoringFlowDataContext);

if (isLoading) return <Loader />;
if (!consumptionData) return <NoData />;

3. Use Enums for Constants

// Good
params.type = WaterFlowEnum.TimeSelection.DAY;

// Bad
params.type = 'DAY'; // Magic string

4. Follow Data Flow Pattern

Component → Context → Controller → DataSource → API

Never call API directly from components.


Troubleshooting

Units Not Showing

Cause: Filter config hiding units Solution: Reset filters

flowStore.setUnitFilterConfig({
leakageDetected: false,
thresholdCrossed: false,
offline: false
});

Leakage Not Detected

Cause: Alert not enabled for unit Solution: Enable stable flow alert in unit configuration

unit.meta.alertsConfig.alertEnabled.stable_flow = true;

Graph Not Updating

Cause: Auto-refresh interval not running Solution: Check constants.refreshDuration is set correctly



Last Updated: February 2026 Module Location: libs/monitoring/