testing
Browse files- .gitattributes copy +35 -0
- .gitignore +18 -0
- Dockerfile +14 -0
- README copy.md +72 -0
- RainFallModel.py +62 -0
- RoofTopCalculation.py +285 -0
- app.py +40 -0
- requirements.txt +0 -0
- vercel.json +15 -0
.gitattributes copy
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.idea/
|
| 2 |
+
.vscode/
|
| 3 |
+
.venv*/
|
| 4 |
+
venv*/
|
| 5 |
+
__pycache__/
|
| 6 |
+
dist/
|
| 7 |
+
.coverage*
|
| 8 |
+
htmlcov/
|
| 9 |
+
.tox/
|
| 10 |
+
docs/_build/
|
| 11 |
+
*.pkl
|
| 12 |
+
*.pyc
|
| 13 |
+
__pycache__/
|
| 14 |
+
venv/
|
| 15 |
+
.env
|
| 16 |
+
instance/
|
| 17 |
+
*.sqlite3
|
| 18 |
+
.vercel
|
Dockerfile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use the official Python 3.10.9 image
|
| 2 |
+
FROM python:3.10.9
|
| 3 |
+
|
| 4 |
+
# Copy the current directory contents into the container at .
|
| 5 |
+
COPY . .
|
| 6 |
+
|
| 7 |
+
# Set the working directory to /
|
| 8 |
+
WORKDIR /
|
| 9 |
+
|
| 10 |
+
# Install requirements.txt
|
| 11 |
+
RUN pip install --no-cache-dir --upgrade -r /requirements.txt
|
| 12 |
+
|
| 13 |
+
# Start the FastAPI app on port 7860, the default port expected by Spaces
|
| 14 |
+
CMD ["python", "app.py"]
|
README copy.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: Rainwater Harvesting Recommendation System
|
| 3 |
+
emoji: 🌧️
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: docker
|
| 7 |
+
pinned: false
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
# Rainwater Harvesting Recommendation System
|
| 11 |
+
|
| 12 |
+
This is a FastAPI-based microservice that provides rainwater harvesting recommendations based on location, roof area, and other parameters.
|
| 13 |
+
|
| 14 |
+
## Features
|
| 15 |
+
|
| 16 |
+
- **Rainfall Prediction**: Uses machine learning to predict rainfall for specific locations and dates
|
| 17 |
+
- **Rooftop Calculation**: Calculates potential rainwater harvesting capacity based on roof area and local conditions
|
| 18 |
+
- **Structure Recommendations**: Suggests appropriate rainwater harvesting structures based on available space and groundwater levels
|
| 19 |
+
- **Cost Analysis**: Provides cost estimates and ROI calculations for rainwater harvesting systems
|
| 20 |
+
|
| 21 |
+
## API Endpoints
|
| 22 |
+
|
| 23 |
+
### POST `/api/roofTopCalculation`
|
| 24 |
+
|
| 25 |
+
Calculate rainwater harvesting parameters for a given location and roof specifications.
|
| 26 |
+
|
| 27 |
+
**Request Body:**
|
| 28 |
+
```json
|
| 29 |
+
{
|
| 30 |
+
"location": "Karur",
|
| 31 |
+
"roof_area": 100,
|
| 32 |
+
"open_space": 50,
|
| 33 |
+
"roof_type": "concrete",
|
| 34 |
+
"dwellers": 4
|
| 35 |
+
}
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
**Response:**
|
| 39 |
+
Returns detailed calculations including:
|
| 40 |
+
- Runoff volume calculations
|
| 41 |
+
- Harvestable water estimates
|
| 42 |
+
- Structure recommendations
|
| 43 |
+
- Cost analysis
|
| 44 |
+
- Feasibility scores
|
| 45 |
+
|
| 46 |
+
## Technology Stack
|
| 47 |
+
|
| 48 |
+
- **FastAPI**: Web framework
|
| 49 |
+
- **Pandas**: Data manipulation
|
| 50 |
+
- **Scikit-learn**: Machine learning predictions
|
| 51 |
+
- **Hugging Face Hub**: Model and data hosting
|
| 52 |
+
|
| 53 |
+
## Installation
|
| 54 |
+
|
| 55 |
+
```bash
|
| 56 |
+
pip install -r requirements.txt
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
## Usage
|
| 60 |
+
|
| 61 |
+
```bash
|
| 62 |
+
python app.py
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
The API will be available at `http://localhost:10000`
|
| 66 |
+
|
| 67 |
+
## Docker
|
| 68 |
+
|
| 69 |
+
```bash
|
| 70 |
+
docker build -t rainwater-harvesting .
|
| 71 |
+
docker run -p 10000:10000 rainwater-harvesting
|
| 72 |
+
```
|
RainFallModel.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
import os
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import numpy as np
|
| 5 |
+
from huggingface_hub import hf_hub_download
|
| 6 |
+
|
| 7 |
+
repo_id = "Navanihk/rainfallPrediction"
|
| 8 |
+
cache_dir = '/tmp/hf_cache'
|
| 9 |
+
os.makedirs(cache_dir, exist_ok=True)
|
| 10 |
+
csv_path = hf_hub_download(repo_id=repo_id, filename="rainFallData.csv", cache_dir=cache_dir,
|
| 11 |
+
|
| 12 |
+
)
|
| 13 |
+
# Load as DataFrame
|
| 14 |
+
df= pd.read_csv(csv_path, sep=";")
|
| 15 |
+
# df= pd.read_csv('./rainFallData.csv',sep=";")
|
| 16 |
+
import calendar
|
| 17 |
+
print(df)
|
| 18 |
+
# Function to remove invalid days for each month
|
| 19 |
+
def valid_day(row):
|
| 20 |
+
year = 2025
|
| 21 |
+
month = row['month']
|
| 22 |
+
day = row['day']
|
| 23 |
+
max_day = calendar.monthrange(year, month)[1] # max days in the month
|
| 24 |
+
return day <= max_day
|
| 25 |
+
def calculate_rainfall():
|
| 26 |
+
# Debug: Print actual column names
|
| 27 |
+
print("Available columns in DataFrame:", df.columns.tolist())
|
| 28 |
+
print("DataFrame shape:", df.shape)
|
| 29 |
+
print("First few rows:")
|
| 30 |
+
print(df.head())
|
| 31 |
+
|
| 32 |
+
# Check if required columns exist
|
| 33 |
+
required_cols = ['state', 'district', 'month']
|
| 34 |
+
missing_cols = [col for col in required_cols if col not in df.columns]
|
| 35 |
+
|
| 36 |
+
if missing_cols:
|
| 37 |
+
print(f"ERROR: Missing columns: {missing_cols}")
|
| 38 |
+
print("Please check the actual column names in your CSV file")
|
| 39 |
+
return None
|
| 40 |
+
|
| 41 |
+
# Melt to long format
|
| 42 |
+
day_cols = [col for col in df.columns if col not in ['state', 'district', 'month']]
|
| 43 |
+
df_long = df.melt(
|
| 44 |
+
id_vars=["state", "district", "month"],
|
| 45 |
+
value_vars=day_cols,
|
| 46 |
+
var_name="day",
|
| 47 |
+
value_name="rainfall"
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
+
# Extract numeric day
|
| 51 |
+
df_long['day'] = df_long['day'].str.extract(r'(\d+)').astype(int)
|
| 52 |
+
|
| 53 |
+
# Keep only valid days
|
| 54 |
+
df_long = df_long[df_long.apply(valid_day, axis=1)]
|
| 55 |
+
|
| 56 |
+
# Create proper date
|
| 57 |
+
df_long['date'] = pd.to_datetime(
|
| 58 |
+
dict(year=2025, month=df_long['month'], day=df_long['day'])
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
df_long = df_long.sort_values(['district', 'date']).reset_index(drop=True)
|
| 62 |
+
return df_long
|
RoofTopCalculation.py
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import math
|
| 2 |
+
import os
|
| 3 |
+
import pickle
|
| 4 |
+
import pandas as pd
|
| 5 |
+
from huggingface_hub import hf_hub_download
|
| 6 |
+
|
| 7 |
+
repo_id = "Navanihk/rainfallPrediction"
|
| 8 |
+
cache_dir = '/tmp/hf_cache'
|
| 9 |
+
os.makedirs(cache_dir, exist_ok=True)
|
| 10 |
+
def predict_rainfall_for_date(df_long, model, district_name, target_date, lags=7):
|
| 11 |
+
"""
|
| 12 |
+
Predict rainfall for a specific district and date.
|
| 13 |
+
|
| 14 |
+
df_long: original dataset (with columns ['district','state','date','rainfall'])
|
| 15 |
+
model: trained LightGBM model
|
| 16 |
+
district_name: name of the district to predict
|
| 17 |
+
target_date: pd.Timestamp or string in 'YYYY-MM-DD'
|
| 18 |
+
lags: number of lag days to use
|
| 19 |
+
"""
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# Ensure target_date is Timestamp
|
| 23 |
+
target_date = pd.Timestamp(target_date)
|
| 24 |
+
|
| 25 |
+
# Get district data up to the day before target_date
|
| 26 |
+
district_data = df_long[(df_long['district']==district_name) &
|
| 27 |
+
(df_long['date'] < target_date)].sort_values('date')
|
| 28 |
+
|
| 29 |
+
# Check if enough data for lags
|
| 30 |
+
if len(district_data) < lags:
|
| 31 |
+
raise ValueError(f"Not enough data to create {lags} lag features for {district_name}")
|
| 32 |
+
|
| 33 |
+
# Get last 'lags' days of rainfall (most recent first)
|
| 34 |
+
lag_values = list(district_data['rainfall'].tail(lags).values[::-1])
|
| 35 |
+
|
| 36 |
+
# Create feature vector: lag + date features
|
| 37 |
+
features = lag_values + [target_date.month, target_date.day, target_date.dayofyear]
|
| 38 |
+
|
| 39 |
+
# Predict
|
| 40 |
+
pred_rain = model.predict([features])[0]
|
| 41 |
+
|
| 42 |
+
return {
|
| 43 |
+
'district': district_name,
|
| 44 |
+
'state': district_data['state'].iloc[0],
|
| 45 |
+
'date': target_date,
|
| 46 |
+
'predicted_rainfall': pred_rain
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def rainFallPrediction(location,RainFallData):
|
| 52 |
+
"""Predict average annual rainfall for a given location using RainFallData"""
|
| 53 |
+
model_path = hf_hub_download(repo_id=repo_id, filename="rainfall.pkl", cache_dir=cache_dir,
|
| 54 |
+
|
| 55 |
+
)
|
| 56 |
+
|
| 57 |
+
# Load the actual model from the downloaded file
|
| 58 |
+
with open(model_path, 'rb') as f:
|
| 59 |
+
model = pickle.load(f)
|
| 60 |
+
|
| 61 |
+
# model = pickle.load(open('rainfall.pkl','rb'))
|
| 62 |
+
date = "2025-01-10"
|
| 63 |
+
print("predict_rainfall_for_date called")
|
| 64 |
+
|
| 65 |
+
pred_result = predict_rainfall_for_date(RainFallData, model, location, date)
|
| 66 |
+
print(pred_result)
|
| 67 |
+
return pred_result['predicted_rainfall'] # Default to Delhi-like rainfall if location not found
|
| 68 |
+
def RooftTopCalculation(input_data,RainFallData):
|
| 69 |
+
"""
|
| 70 |
+
Calculate rainwater harvesting parameters based on input data
|
| 71 |
+
"""
|
| 72 |
+
# Extract input parameters
|
| 73 |
+
location = input_data.get('location', 'Unknown')
|
| 74 |
+
roof_area = input_data.get('roof_area', 0)
|
| 75 |
+
open_space = input_data.get('open_space', 0)
|
| 76 |
+
roof_type = input_data.get('roof_type', 'null')
|
| 77 |
+
dwellers = input_data.get('dwellers', 1)
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
# Default values for calculations (these would typically come from ML models or databases)
|
| 81 |
+
# Using Delhi-like values as defaults
|
| 82 |
+
default_rainfall = rainFallPrediction(location,RainFallData) # mm/year
|
| 83 |
+
default_runoff_coefficient = 0.8 # typical for concrete/tiled roofs
|
| 84 |
+
groundwater_level = 15 # meters below ground level
|
| 85 |
+
soil_type = "Loamy"
|
| 86 |
+
aquifer_type = "Alluvial Aquifer"
|
| 87 |
+
|
| 88 |
+
# Get coordinates (default to Delhi coordinates if location not found)
|
| 89 |
+
coordinates = get_coordinates(location)
|
| 90 |
+
|
| 91 |
+
# Calculate runoff volume (in liters/year)
|
| 92 |
+
runoff_volume = roof_area * default_rainfall * default_runoff_coefficient
|
| 93 |
+
|
| 94 |
+
# Calculate harvestable water (considering losses - typically 15-20% loss)
|
| 95 |
+
loss_factor = 0.15
|
| 96 |
+
harvestable_water = int(runoff_volume * (1 - loss_factor))
|
| 97 |
+
|
| 98 |
+
# Calculate recharge potential (typically 60-70% of harvestable water)
|
| 99 |
+
recharge_potential = int(harvestable_water * 0.65)
|
| 100 |
+
|
| 101 |
+
# Determine structure suggestion based on available space and groundwater level
|
| 102 |
+
structure_suggestion = determine_structure(open_space, groundwater_level, roof_area)
|
| 103 |
+
|
| 104 |
+
# Calculate recommended dimensions
|
| 105 |
+
dimensions = calculate_dimensions(structure_suggestion, harvestable_water)
|
| 106 |
+
|
| 107 |
+
# Calculate capacity
|
| 108 |
+
capacity = dimensions['length'] * dimensions['width'] * dimensions['depth'] * 1000 # in liters
|
| 109 |
+
|
| 110 |
+
# Cost analysis
|
| 111 |
+
estimated_cost = calculate_cost(structure_suggestion, dimensions, roof_area)
|
| 112 |
+
water_saved_value = calculate_water_savings(harvestable_water)
|
| 113 |
+
roi_years = round(estimated_cost / water_saved_value, 1) if water_saved_value > 0 else 0
|
| 114 |
+
|
| 115 |
+
# Feasibility score
|
| 116 |
+
feasibility_score = calculate_feasibility(roof_area, open_space, groundwater_level)
|
| 117 |
+
|
| 118 |
+
# Prepare response
|
| 119 |
+
response = {
|
| 120 |
+
"user": {
|
| 121 |
+
"name": "User", # Default name as not provided in input
|
| 122 |
+
"location": {
|
| 123 |
+
"lat": coordinates[0],
|
| 124 |
+
"lon": coordinates[1],
|
| 125 |
+
"address": location
|
| 126 |
+
},
|
| 127 |
+
"roof_area": roof_area,
|
| 128 |
+
"open_space": open_space,
|
| 129 |
+
"dwellers": dwellers
|
| 130 |
+
},
|
| 131 |
+
"reference_data": {
|
| 132 |
+
"rainfall": f"{default_rainfall} mm/year",
|
| 133 |
+
"aquifer": aquifer_type,
|
| 134 |
+
"groundwater_level": f"{groundwater_level} m bgl",
|
| 135 |
+
"soil_type": soil_type,
|
| 136 |
+
"runoff_coefficient": default_runoff_coefficient
|
| 137 |
+
},
|
| 138 |
+
"calculations": {
|
| 139 |
+
"runoff_volume": f"{int(runoff_volume)} liters/year",
|
| 140 |
+
"harvestable_water": f"{harvestable_water} liters/year",
|
| 141 |
+
"recharge_potential": f"{recharge_potential} liters/year",
|
| 142 |
+
"structure_suggestion": structure_suggestion,
|
| 143 |
+
"recommended_dimensions": dimensions,
|
| 144 |
+
"capacity": f"{int(capacity)} liters"
|
| 145 |
+
},
|
| 146 |
+
"cost_analysis": {
|
| 147 |
+
"estimated_cost": f"₹{estimated_cost:,}",
|
| 148 |
+
"water_saved_value": f"₹{int(water_saved_value):,}/year",
|
| 149 |
+
"roi": f"{roi_years} years"
|
| 150 |
+
},
|
| 151 |
+
"gis_data": {
|
| 152 |
+
"map_coordinates": coordinates,
|
| 153 |
+
"feasibility_score": feasibility_score
|
| 154 |
+
},
|
| 155 |
+
"support": {
|
| 156 |
+
"regional_language": get_regional_language(location),
|
| 157 |
+
"faq_link": "https://cgwb.gov.in/rtrwh-faqs"
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
return response
|
| 162 |
+
|
| 163 |
+
def get_coordinates(location):
|
| 164 |
+
"""Get coordinates for a location (simplified - would use geocoding service in production)"""
|
| 165 |
+
location_coordinates = {
|
| 166 |
+
"karur": [10.9601, 78.0766],
|
| 167 |
+
"new delhi": [28.6139, 77.2090],
|
| 168 |
+
"delhi": [28.6139, 77.2090],
|
| 169 |
+
"mumbai": [19.0760, 72.8777],
|
| 170 |
+
"bangalore": [12.9716, 77.5946],
|
| 171 |
+
"chennai": [13.0827, 80.2707],
|
| 172 |
+
"hyderabad": [17.3850, 78.4867],
|
| 173 |
+
"pune": [18.5204, 73.8567],
|
| 174 |
+
"kolkata": [22.5726, 88.3639],
|
| 175 |
+
"ahmedabad": [23.0225, 72.5714],
|
| 176 |
+
"jaipur": [26.9124, 75.7873]
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
location_lower = location.lower()
|
| 180 |
+
return location_coordinates.get(location_lower, [28.6139, 77.2090]) # Default to Delhi
|
| 181 |
+
|
| 182 |
+
def determine_structure(open_space, groundwater_level, roof_area):
|
| 183 |
+
"""Determine the best rainwater harvesting structure"""
|
| 184 |
+
if open_space >= 100 and groundwater_level > 10:
|
| 185 |
+
return "Recharge Pit"
|
| 186 |
+
elif open_space >= 50 and groundwater_level > 5:
|
| 187 |
+
return "Percolation Tank"
|
| 188 |
+
elif roof_area >= 100:
|
| 189 |
+
return "Storage Tank"
|
| 190 |
+
else:
|
| 191 |
+
return "Rain Barrel"
|
| 192 |
+
|
| 193 |
+
def calculate_dimensions(structure_type, harvestable_water):
|
| 194 |
+
"""Calculate recommended dimensions based on structure type"""
|
| 195 |
+
if structure_type == "Recharge Pit":
|
| 196 |
+
# Calculate based on recharge requirements
|
| 197 |
+
volume_needed = harvestable_water / 1000 # Convert to cubic meters
|
| 198 |
+
depth = min(3, max(2, volume_needed / 4)) # Depth between 2-3m
|
| 199 |
+
area_needed = volume_needed / depth
|
| 200 |
+
side = math.sqrt(area_needed)
|
| 201 |
+
return {
|
| 202 |
+
"length": round(side, 1),
|
| 203 |
+
"width": round(side, 1),
|
| 204 |
+
"depth": round(depth, 1)
|
| 205 |
+
}
|
| 206 |
+
elif structure_type == "Percolation Tank":
|
| 207 |
+
return {"length": 3.0, "width": 3.0, "depth": 2.0}
|
| 208 |
+
elif structure_type == "Storage Tank":
|
| 209 |
+
return {"length": 2.0, "width": 2.0, "depth": 2.5}
|
| 210 |
+
else: # Rain Barrel
|
| 211 |
+
return {"length": 1.0, "width": 1.0, "depth": 1.5}
|
| 212 |
+
|
| 213 |
+
def calculate_cost(structure_type, dimensions, roof_area):
|
| 214 |
+
"""Calculate estimated cost in INR"""
|
| 215 |
+
base_costs = {
|
| 216 |
+
"Recharge Pit": 15000,
|
| 217 |
+
"Percolation Tank": 25000,
|
| 218 |
+
"Storage Tank": 20000,
|
| 219 |
+
"Rain Barrel": 5000
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
base_cost = base_costs.get(structure_type, 15000)
|
| 223 |
+
volume = dimensions['length'] * dimensions['width'] * dimensions['depth']
|
| 224 |
+
|
| 225 |
+
# Additional cost based on volume and roof area
|
| 226 |
+
additional_cost = (volume * 2000) + (roof_area * 50)
|
| 227 |
+
|
| 228 |
+
return int(base_cost + additional_cost)
|
| 229 |
+
|
| 230 |
+
def calculate_water_savings(harvestable_water):
|
| 231 |
+
"""Calculate annual water savings value in INR"""
|
| 232 |
+
# Assuming water cost of ₹12 per 1000 liters
|
| 233 |
+
water_cost_per_1000_liters = 12
|
| 234 |
+
annual_savings = (harvestable_water / 1000) * water_cost_per_1000_liters
|
| 235 |
+
return annual_savings
|
| 236 |
+
|
| 237 |
+
def calculate_feasibility(roof_area, open_space, groundwater_level):
|
| 238 |
+
"""Calculate feasibility score"""
|
| 239 |
+
score = 0
|
| 240 |
+
|
| 241 |
+
if roof_area >= 100:
|
| 242 |
+
score += 30
|
| 243 |
+
elif roof_area >= 50:
|
| 244 |
+
score += 20
|
| 245 |
+
else:
|
| 246 |
+
score += 10
|
| 247 |
+
|
| 248 |
+
if open_space >= 100:
|
| 249 |
+
score += 30
|
| 250 |
+
elif open_space >= 50:
|
| 251 |
+
score += 20
|
| 252 |
+
else:
|
| 253 |
+
score += 10
|
| 254 |
+
|
| 255 |
+
if groundwater_level > 10:
|
| 256 |
+
score += 40
|
| 257 |
+
elif groundwater_level > 5:
|
| 258 |
+
score += 30
|
| 259 |
+
else:
|
| 260 |
+
score += 20
|
| 261 |
+
|
| 262 |
+
if score >= 80:
|
| 263 |
+
return "High"
|
| 264 |
+
elif score >= 60:
|
| 265 |
+
return "Medium"
|
| 266 |
+
else:
|
| 267 |
+
return "Low"
|
| 268 |
+
|
| 269 |
+
def get_regional_language(location):
|
| 270 |
+
"""Get regional language based on location"""
|
| 271 |
+
language_map = {
|
| 272 |
+
"karur": "Tamil",
|
| 273 |
+
"new delhi": "Hindi",
|
| 274 |
+
"delhi": "Hindi",
|
| 275 |
+
"mumbai": "Marathi",
|
| 276 |
+
"bangalore": "Kannada",
|
| 277 |
+
"chennai": "Tamil",
|
| 278 |
+
"hyderabad": "Telugu",
|
| 279 |
+
"pune": "Marathi",
|
| 280 |
+
"kolkata": "Bengali",
|
| 281 |
+
"ahmedabad": "Gujarati",
|
| 282 |
+
"jaipur": "Hindi"
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
return language_map.get(location.lower(), "Hindi")
|
app.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# app.py
|
| 2 |
+
|
| 3 |
+
# from flask import Flask,request,jsonify
|
| 4 |
+
# from flask_cors import CORS
|
| 5 |
+
# app = Flask(__name__)
|
| 6 |
+
# cors = CORS(app, resources={r"*": {"origins": "*"}})
|
| 7 |
+
from fastapi import FastAPI
|
| 8 |
+
import uvicorn
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
# loading the data from the csv file to apandas dataframe
|
| 12 |
+
app = FastAPI()
|
| 13 |
+
from huggingface_hub import login
|
| 14 |
+
|
| 15 |
+
from RoofTopCalculation import RooftTopCalculation
|
| 16 |
+
from RainFallModel import calculate_rainfall
|
| 17 |
+
|
| 18 |
+
import os
|
| 19 |
+
cache_dir = '/tmp/hf_cache'
|
| 20 |
+
os.makedirs(cache_dir, exist_ok=True)
|
| 21 |
+
|
| 22 |
+
@app.post('/api/roofTopCalculation')
|
| 23 |
+
def roof_top_calculation(data: dict):
|
| 24 |
+
RainFallData = calculate_rainfall()
|
| 25 |
+
try:
|
| 26 |
+
if not data:
|
| 27 |
+
return {"error": "No data provided"}, 400
|
| 28 |
+
|
| 29 |
+
# Perform roof top calculation logic
|
| 30 |
+
result = RooftTopCalculation(data,RainFallData)
|
| 31 |
+
return result
|
| 32 |
+
|
| 33 |
+
except Exception as e:
|
| 34 |
+
return {"error": str(e)}, 500
|
| 35 |
+
|
| 36 |
+
# Run the app if the script is executed directly
|
| 37 |
+
# if __name__ == '__main__':
|
| 38 |
+
# app.run(host='0.0.0.0', port=8000, debug=True)
|
| 39 |
+
if __name__ == "__main__":
|
| 40 |
+
uvicorn.run(app, port=10000)
|
requirements.txt
ADDED
|
Binary file (1.32 kB). View file
|
|
|
vercel.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": 2,
|
| 3 |
+
"builds": [
|
| 4 |
+
{
|
| 5 |
+
"src": "./main.py",
|
| 6 |
+
"use": "@vercel/python"
|
| 7 |
+
}
|
| 8 |
+
],
|
| 9 |
+
"routes": [
|
| 10 |
+
{
|
| 11 |
+
"src": "/(.*)",
|
| 12 |
+
"dest": "/"
|
| 13 |
+
}
|
| 14 |
+
]
|
| 15 |
+
}
|