Skip to main content

Water Quality Monitoring

Monitor water quality parameters in real-time with threshold-based alerts, visual range indicators, and 7-day trend analysis across multiple units and locations.


Overview

The Water Quality Monitoring feature tracks multiple water quality parameters (pH, TDS, Turbidity, Temperature, etc.) with configurable min/max thresholds, visual sliders showing current values, and line graphs displaying 7-day trends.

Location: libs/monitoring/src/pages/quality/

Route: /monitoring/quality/:categoryId

Permission Required: WATER_MONITORING


Key Features

1. Multi-Parameter Monitoring

Track multiple quality parameters simultaneously per unit:

Common Parameters:

  • pH - Acidity/Alkalinity level
  • TDS - Total Dissolved Solids (ppm)
  • Turbidity - Water cloudiness (NTU)
  • Temperature - Water temperature (°C)
  • Conductivity - Electrical conductivity (µS/cm)
  • DO - Dissolved Oxygen (mg/L)
  • COD - Chemical Oxygen Demand (mg/L)
  • BOD - Biological Oxygen Demand (mg/L)

2. Threshold-Based Alerts

Each parameter has configurable threshold ranges:

unit.meta = {
params: ['pH', 'TDS', 'Turbidity'],
paramsEnabled: ['pH', 'TDS'], // Only enabled params are displayed
min: {
pH: 0,
TDS: 0,
Turbidity: 0
},
max: {
pH: 14,
TDS: 1000,
Turbidity: 100
},
lowThreshold: {
pH: 6.5,
TDS: 100,
Turbidity: 5
},
highThreshold: {
pH: 8.5,
TDS: 500,
Turbidity: 10
}
};

Color Coding:

  • Green - Within acceptable range (between low and high thresholds)
  • Red - Outside acceptable range (below low or above high threshold)

3. Visual Range Slider

Interactive slider visualization showing:

  • Min Value - Absolute minimum
  • Low Threshold - Lower acceptable limit
  • Current Value - Current reading (as black vertical line)
  • High Threshold - Upper acceptable limit
  • Max Value - Absolute maximum

Color Gradient:

  • Red zone: Min → Low Threshold
  • Green zone: Low Threshold → High Threshold
  • Red zone: High Threshold → Max

4. 7-Day Trend Graph

Line chart showing parameter trends over the past 7 days:

Features:

  • Reference lines for min, max, low threshold, high threshold
  • Color-coded dots:
    • Green - Values within acceptable range
    • Red - Values outside acceptable range
  • Hover tooltip showing exact value and date
  • X-axis: Daily labels (DD MMM format)
  • Y-axis: Parameter value range

5. Online/Offline Status

Each unit displays:

  • Online: Green "Online" badge
  • Offline: Last update timestamp and reduced opacity

Architecture

Data Flow

QualityPage Component

QualityScreenDataProvider (Context)

MonitoringStore.getCategoryData()

MonitoringController.getCategoryData()

MonitoringDataSource.getCategoryData()

API Client → Backend

Update Context State

Re-render Quality Components

Key Components

1. QualityScreenDataProvider

  • Purpose: State management for quality monitoring
  • Location: libs/monitoring/src/dataProvider/QualityScreenDataProvider.jsx
  • State Variables:
    • qualityData - Quality parameter data with units and graphs
    • params - Query parameters (date, category, type)

Example Context Value:

{
qualityData: {
data: {
subCategories: [
{
displayName: 'Inlet Water',
units: [
{
unitId: 'UNIT_1',
displayName: 'Inlet Point 1',
online: true,
value1: { pH: 7.2, TDS: 350, Turbidity: 5 },
lastUpdatedAt: '25/02/2026 10:30 AM',
meta: {
params: ['pH', 'TDS', 'Turbidity'],
paramsEnabled: ['pH', 'TDS'],
min: { pH: 0, TDS: 0, Turbidity: 0 },
max: { pH: 14, TDS: 1000, Turbidity: 100 },
lowThreshold: { pH: 6.5, TDS: 100, Turbidity: 5 },
highThreshold: { pH: 8.5, TDS: 500, Turbidity: 10 }
},
graph1: [
{ x: '19/02/2026', y: { pH: 7.1, TDS: 340 } },
{ x: '20/02/2026', y: { pH: 7.3, TDS: 360 } },
// ... 7 days of data
]
}
]
}
]
}
},
setParams: (params) => {}
}

2. QualityPage

  • Purpose: Main quality monitoring page
  • Location: libs/monitoring/src/pages/quality/QualityPage.jsx
  • Features:
    • Displays all subcategories and units
    • Renders parameter sliders and trend graphs
    • Shows online/offline status

3. BuildUnitsView

  • Purpose: Render individual unit quality panels
  • Features:
    • Unit name and online status
    • Category heading (Parameter, Range, 7 Days Trend)
    • Parameter rows with slider + graph

4. CustomTooltip

  • Purpose: Graph tooltip for trend line chart
  • Shows: Parameter value with unit on hover

5. CustomizedDot

  • Purpose: Custom dots for line chart
  • Logic:
    • Green dot if value within thresholds
    • Red dot if value outside thresholds
    • No dot if value is null/undefined

API Integration

Get Category Data

GET /categoryData
Params: {
category: 'QUALITY_CATEGORY',
type: 'HOUR',
date1: '25/02/2026'
}

Response: {
siUnit: {
pH: '',
TDS: 'ppm',
Turbidity: 'NTU',
Temperature: '°C'
},
subCategories: [
{
id: 'SUB_CAT_1',
displayName: 'Inlet Water',
units: [
{
unitId: 'UNIT_1',
displayName: 'Inlet Point 1',
online: true,
value1: {
pH: 7.2,
TDS: 350,
Turbidity: 5,
Temperature: 25
},
lastUpdatedAt: '25/02/2026 10:30 AM',
meta: {
params: ['pH', 'TDS', 'Turbidity', 'Temperature'],
paramsEnabled: ['pH', 'TDS', 'Turbidity'],
min: { pH: 0, TDS: 0, Turbidity: 0, Temperature: 0 },
max: { pH: 14, TDS: 1000, Turbidity: 100, Temperature: 50 },
lowThreshold: { pH: 6.5, TDS: 100, Turbidity: 5, Temperature: 10 },
highThreshold: { pH: 8.5, TDS: 500, Turbidity: 10, Temperature: 35 }
},
graph1: [
{ x: '19/02/2026', y: { pH: 7.1, TDS: 340, Turbidity: 5 } },
{ x: '20/02/2026', y: { pH: 7.3, TDS: 360, Turbidity: 6 } },
{ x: '21/02/2026', y: { pH: 7.0, TDS: 330, Turbidity: 5 } },
{ x: '22/02/2026', y: { pH: 7.2, TDS: 350, Turbidity: 7 } },
{ x: '23/02/2026', y: { pH: 7.4, TDS: 370, Turbidity: 6 } },
{ x: '24/02/2026', y: { pH: 7.1, TDS: 345, Turbidity: 5 } },
{ x: '25/02/2026', y: { pH: 7.2, TDS: 350, Turbidity: 5 } }
]
}
]
}
]
}

Usage Examples

1. Initialize Quality Monitoring

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

function QualityApp() {
const { categoryId } = useParams();

return (
<QualityScreenDataProvider categoryId={categoryId}>
<QualityContent />
</QualityScreenDataProvider>
);
}

2. Access Quality Data

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

function QualityWidget() {
const qualityStore = useContext(QualityDataContext);
const { qualityData } = qualityStore;

return (
<div>
{qualityData?.data?.subCategories?.map(category => (
<div key={category.id}>
<h3>{category.displayName}</h3>
{category.units.map(unit => (
<div key={unit.unitId}>
<h4>{unit.displayName}</h4>
<p>pH: {unit.value1?.pH}</p>
<p>TDS: {unit.value1?.TDS} ppm</p>
<p>Status: {unit.online ? 'Online' : 'Offline'}</p>
</div>
))}
</div>
))}
</div>
);
}

3. Check Parameter Thresholds

function checkParameterStatus(unit, param) {
const value = unit.value1?.[param];
const lowThreshold = unit.meta.lowThreshold[param];
const highThreshold = unit.meta.highThreshold[param];

if (!value) return 'NO_DATA';

if (value < lowThreshold || value > highThreshold) {
return 'OUT_OF_RANGE'; // Red
}

return 'NORMAL'; // Green
}

// Usage
const status = checkParameterStatus(unit, 'pH');
const color = status === 'NORMAL' ? 'green' : 'red';

4. Filter Enabled Parameters

function getEnabledParameters(unit) {
// Use paramsEnabled if available, otherwise use params
const enabledParams = unit.meta.paramsEnabled ?? unit.meta.params;

return enabledParams.map(param => ({
name: param,
currentValue: unit.value1?.[param],
min: unit.meta.min[param],
max: unit.meta.max[param],
lowThreshold: unit.meta.lowThreshold[param],
highThreshold: unit.meta.highThreshold[param],
siUnit: categoryData.siUnit?.[param]
}));
}

Slider Visualization Logic

Color Gradient Calculation

// Calculate percentage positions for color zones
const total = max - min;
const minPV = lowThreshold - min;
const minP = (minPV / total) * 100; // Red zone end %

const maxPV = highThreshold - min;
const maxP = (maxPV / total) * 100; // Green zone end %

// Create gradient
const gradient = `linear-gradient(to right,
red 0%,
red ${minP}%,
green ${minP}%,
green ${maxP}%,
red ${maxP}%,
red 100%
)`;

Marks Configuration

const marks = [
{ value: min, label: min },
{ value: lowThreshold, label: lowThreshold },
{ value: highThreshold, label: highThreshold },
{ value: max, label: max }
];

Graph Visualization

Line Chart with Reference Lines

<LineChart data={labels}>
<YAxis min={min} max={max} hide domain={[min, max]} />
<XAxis dataKey="label" />
<Tooltip content={<CustomTooltip siUnit={siUnit} />} />

{/* Reference Lines */}
<ReferenceLine y={min} stroke="#B0B0B0" strokeWidth={1} />
<ReferenceLine y={lowThreshold} stroke="#CBCBCB" strokeWidth={1} strokeDasharray="3 3" />
<ReferenceLine y={highThreshold} stroke="#CBCBCB" strokeWidth={1} strokeDasharray="3 3" />
<ReferenceLine y={max} stroke="#CBCBCB" strokeWidth={1} strokeDasharray="3 3" />

{/* Data Line */}
<Line
type="monotone"
dataKey="value"
stroke="black"
dot={<CustomizedDot />}
/>
</LineChart>

Custom Dot Component

const CustomizedDot = (props) => {
const { cx, cy, value } = props;

if (!value) return <span></span>; // No data

const isOutOfRange = value < lowThreshold || value > highThreshold;
const color = isOutOfRange ? 'red' : 'green';

return (
<svg x={cx - 5} y={cy - 5} width={8} height={10} fill={color} viewBox="0 0 1024 1024">
<circle cx="512" cy="512" r="450" />
</svg>
);
};

Auto-Refresh

Quality data auto-refreshes at configured intervals:

useEffect(() => {
init(); // Initial load

const interval = setInterval(() => {
init(); // Background refresh
}, constants.refreshDuration);

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

Default Refresh Interval: Configured in constants.refreshDuration (typically 30-60 seconds)


Responsive Layout

The quality monitoring page adapts to different screen sizes:

Desktop (lg+):

  • Three-column layout: Parameter | Range Slider | 7-Day Graph
  • Category heading visible
  • Horizontal dividers between sections

Mobile (xs-md):

  • Stacked vertical layout
  • Horizontal dividers between sections
  • Last update timestamp moved to bottom

Best Practices

1. Use Enabled Parameters

Always check paramsEnabled before rendering:

const enabledParams = unit.meta.paramsEnabled ?? unit.meta.params;

2. Handle Null Values

Check for null/undefined values in graphs:

const labels = unit.graph1.map(g => ({
label: DateFormatter.customFormatter(g.x, 'DD/MM/YYYY', 'DD MMM'),
value: g.y?.[param]?.toFixed(2) ?? 0,
showTooltip: g.y?.[param] !== undefined && g.y?.[param] !== null
}));

3. Color Code for Quick Status

Use consistent color coding:

  • Green = Normal/Good
  • Red = Alert/Out of Range
  • Grey = Offline/No Data

4. Show Unit Information

Always display SI units for parameters:

`${value} ${categoryData.siUnit?.[param] || ''}`

Troubleshooting

Parameters Not Showing

Cause: Parameter not in paramsEnabled array Solution: Check backend configuration or use params as fallback

const enabledParams = unit.meta.paramsEnabled ?? unit.meta.params;

Graph Not Rendering

Cause: Missing or null values in graph1 data Solution: Filter out null values and set showTooltip: false

showTooltip: g.y?.[param] !== undefined && g.y?.[param] !== null

Thresholds Not Matching Colors

Cause: Gradient calculation error Solution: Verify min, max, lowThreshold, highThreshold are numeric and in correct order


Analytics Integration

Quality monitoring tracks page views:

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

useEffect(() => {
AnalyticsService.sendEvent(AnalyticEvents.PAGE_VIEW, {}, true);
}, []);


Last Updated: February 2026 Module Location: libs/monitoring/src/pages/quality/