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 stateconsumptionData- Consumption data with graphsparams- Date range and time type parameterslabelData- X-axis labels for graphsvisibleTimeSelection- 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 dataprocessCategoryData()- Transform API data with leakage detectionprepareUnits()- Calculate thresholds and status iconsformatFlowGraphData()- Format graph data for charts
3. MonitoringDataSource
- Purpose: API integration layer
- Location:
libs/monitoring/src/dataSource/monitoring.js - Key Methods:
getCategoryDataV2()- Fetch category consumption datagetLeakageAlertsData()- Fetch leakage alert datagetUnitGranularData()- Fetch unit-level granular datagetCompareData()- 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
- Alert Configuration: Each unit has
meta.alertsConfig.alertEnabled.stable_flowflag - Detection: Backend monitors for unusual stable flow patterns indicating leakage
- Data Fetching:
getLeakageAlertsData()API returns detected leakages - Unit Update:
LeakageDetectionHelper.updateUnitsWithLeakageData()marks affected units - 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
Related Documentation
- Routes - Application routing for monitoring pages
- Permissions - WATER_MONITORING permission required
- API & Services - API client configuration
- State Management - Context pattern usage
Last Updated: February 2026
Module Location: libs/monitoring/