Spaces:
Sleeping
Sleeping
Download lib/potability.ts from dpv007/HydroSense: direct link, hf CLI and curl.
- Browser
- Download file 3.43 kB
-
https://huggingface.co/spaces/dpv007/HydroSense/resolve/main/lib/potability.ts
- Command line
-
hf download hf://spaces/dpv007/HydroSense/lib/potability.ts
-
curl -L -o potability.ts https://huggingface.co/spaces/dpv007/HydroSense/resolve/main/lib/potability.ts
3.43 kB
| const POTABILITY_API = process.env.POTABILITY_API || 'https://dpv007-newclear.hf.space/gradio_api/call/predict_potability'; | |
| /** | |
| * Intelligent Water Quality Index heuristic fallback | |
| * Evaluates standard WHO water quality thresholds | |
| */ | |
| export function calculateFallbackPotability( | |
| ph: number, | |
| hardness: number, | |
| turbidity: number, | |
| temperature: number | |
| ): number { | |
| // pH safe range: 6.5 - 8.5 | |
| let phScore = 1.0; | |
| if (ph < 6.5) phScore = Math.max(0, 1 - (6.5 - ph) / 2.5); | |
| else if (ph > 8.5) phScore = Math.max(0, 1 - (ph - 8.5) / 2.5); | |
| // Turbidity ideal < 5 NTU, acceptable up to 10 NTU | |
| let turbidityScore = 1.0; | |
| if (turbidity > 5) turbidityScore = Math.max(0, 1 - (turbidity - 5) / 10); | |
| // Hardness ideal 60 - 200 mg/L | |
| let hardnessScore = 1.0; | |
| if (hardness < 60) hardnessScore = Math.max(0.2, 1 - (60 - hardness) / 100); | |
| else if (hardness > 200) hardnessScore = Math.max(0.1, 1 - (hardness - 200) / 300); | |
| // Temperature ideal 10 - 25 °C | |
| let tempScore = 1.0; | |
| if (temperature < 10) tempScore = Math.max(0.4, 1 - (10 - temperature) / 20); | |
| else if (temperature > 25) tempScore = Math.max(0.2, 1 - (temperature - 25) / 30); | |
| const potability = (phScore * 0.35) + (turbidityScore * 0.35) + (hardnessScore * 0.2) + (tempScore * 0.1); | |
| return Number(Math.max(0.01, Math.min(0.99, potability)).toFixed(4)); | |
| } | |
| /** | |
| * Predict potability using Hugging Face Gradio ML Model with fallback | |
| */ | |
| export async function predictPotability( | |
| ph: number, | |
| hardness: number, | |
| turbidity: number, | |
| temperature: number | |
| ): Promise<number> { | |
| try { | |
| const postRes = await fetch(POTABILITY_API, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ data: [ph, hardness, turbidity, temperature] }), | |
| signal: AbortSignal.timeout(5000), | |
| }); | |
| if (!postRes.ok) { | |
| return calculateFallbackPotability(ph, hardness, turbidity, temperature); | |
| } | |
| const { event_id } = await postRes.json(); | |
| if (!event_id) { | |
| return calculateFallbackPotability(ph, hardness, turbidity, temperature); | |
| } | |
| const getRes = await fetch(`${POTABILITY_API}/${event_id}`, { | |
| method: 'GET', | |
| signal: AbortSignal.timeout(6000), | |
| }); | |
| if (!getRes.ok) { | |
| return calculateFallbackPotability(ph, hardness, turbidity, temperature); | |
| } | |
| const text = await getRes.text(); | |
| const lines = text.trim().split('\n'); | |
| for (const line of lines) { | |
| if (!line.startsWith('data:')) continue; | |
| const jsonStr = line.replace('data:', '').trim(); | |
| if (!jsonStr) continue; | |
| try { | |
| const json = JSON.parse(jsonStr); | |
| if (Array.isArray(json) && json.length > 0) { | |
| const matchProb = json.map((s: any) => { | |
| if (typeof s !== 'string') return null; | |
| const match = s.match(/(?:^|[^\w-])Potable:\s*([0-9.]+)/i); | |
| return match ? parseFloat(match[1]) : null; | |
| }).filter((v: number | null): v is number => v !== null && !isNaN(v)); | |
| if (matchProb.length > 0) { | |
| const avg = matchProb.reduce((a, b) => a + b, 0) / matchProb.length; | |
| return Number(avg.toFixed(4)); | |
| } | |
| } | |
| } catch { | |
| // ignore parse errors | |
| } | |
| } | |
| return calculateFallbackPotability(ph, hardness, turbidity, temperature); | |
| } catch (err) { | |
| return calculateFallbackPotability(ph, hardness, turbidity, temperature); | |
| } | |
| } | |