Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions H2O-NOVA/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@



---

#### **Project Name**:
**QATRA matters** 💧 - AI-Powered Water Consumption Management

---
![looooogo (1)](https://github.com/user-attachments/assets/163e9365-a86d-4d4d-8af5-921024c72ef8)

#### **Problem**:
Water scarcity 🌍 and inefficient water management are growing concerns, especially in regions like Morocco 🇲🇦. Despite existing efforts, many households and businesses lack tools to effectively track, manage, and reduce water consumption. Overuse, leaks, and wastage are common problems that lead to high bills and environmental strain . There is a need for a comprehensive, user-friendly solution to monitor, forecast, and optimize water usage.

---

#### **Solution**:
**SmartWater** leverages **AI-driven technology** to provide real-time monitoring , predictive forecasting 📊, and personalized alerts to help users optimize water consumption. Our solution empowers individuals , businesses , and government bodies to adopt sustainable water usage practices 🌱, reduce wastage 💦, and ultimately save resources 💰 and costs. The integration of machine learning models, a chatbot 🗣, and OCR technology makes our solution easy to use, efficient, and accessible for everyone.

---
#### **Workflow**:

![Flowchart Building](https://github.com/user-attachments/assets/b2cc6812-3a6b-451c-99dc-75189dae6799)
![Flowchart Building (1)](https://github.com/user-attachments/assets/e2c66b4b-f5da-4e14-bd14-0c5c3ddffc86)


#### **Key Features**:
1. **Real-Time Water Consumption Tracking** 📉:
- Monitors water usage from traditional water meters 💧.
- Provides visualizations of current and historical water consumption data.

2. **AI-Powered Forecasting** 🔮:
- Uses **LSTM (Long Short-Term Memory)** models for predicting future water usage based on historical data 📈.

3. **Threshold Alerts** 🚨:
- Notifies users when their water consumption exceeds a predefined limit .
- Encourages users to take corrective actions and reduce wastage.

4. **Interactive Chatbot** :
- Provides personalized recommendations for reducing water consumption.

5. **Water Bill Integration** 🧾:
- Scans and extracts data from water bills using **OCR** technology to automatically update and compare consumption data.


---

#### **Impact**:
1. **Sustainability** 🌍:
- Promotes responsible water consumption and contributes to long-term environmental sustainability 🌱.

2. **Cost Savings** 💸:
- Helps users reduce water bills by providing insights on where and how to save water .

4. **Local Adaptation** :
- The chatbot will be enhanced with **Moroccan Arabic** 🗣️ to ensure accessibility and engagement for local users, making it easier for Moroccans to adopt sustainable water practices.

5. **Scalability** 📈:
- Our solution can be scaled to address the needs of both urban and rural areas, impacting a wide range of users across Morocco.

---

#### **Technologies Used**:
- **Machine Learning**: **LSTM (Long Short-Term Memory)** for predictive modeling 📉.
- **OCR**: **Tesseract** or **Google Vision API** for water bill scanning 🧾.
- **Web App**: Built using **Streamlit** for real-time dashboards and analytics 📊.
- **Chatbot**: Integrated with **Dialogflow** for natural language interactions 🗣️.

---

#### **Future Improvements**:
- **IoT Integration** : Compatibility with smart water meters for real-time, automated data collection 🧭.
- **Advanced AI Features** : More sophisticated anomaly detection algorithms for leaks or inefficiencies 🏚️.

#### **Links**:
* DEMO:https://www.youtube.com/watch?v=ZPSJRCKDiYc&ab_channel=MeriameBoulaghrous
* PITCH:https://www.youtube.com/watch?v=1HCLl-bTkgU&ab_channel=MeriameBoulaghrous
38 changes: 38 additions & 0 deletions H2O-NOVA/admin/test_water_consumtion_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import requests
import matplotlib.pyplot as plt
from datetime import datetime

# Define the API endpoint
api_url = "https://8791-34-40-149-146.ngrok-free.app/predict"

payload = {
"days_to_predict": 7 # Predict the next 7 days
}

try:
# Send a POST request to the API
response = requests.post(api_url, json=payload)
response.raise_for_status() # Raise an error for bad status codes
data = response.json()

# Extract predictions and timestamps from the response
predictions = data["predictions"]
timestamps = data["timestamps"]

# Convert timestamps to datetime objects
timestamps = [datetime.strptime(ts, "%Y-%m-%d") for ts in timestamps]

# Plot the predictions
plt.figure(figsize=(10, 6))
plt.plot(timestamps, predictions, marker="o", label="Predicted Meter Reading", color="orange")
plt.title("Forecasted Meter Reading")
plt.xlabel("Date")
plt.ylabel("Meter Reading")
plt.xticks(rotation=45)
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()

except requests.exceptions.RequestException as e:
print(f"An error occurred while fetching predictions: {e}")
1 change: 1 addition & 0 deletions H2O-NOVA/admin/water_consumption_forecasting.ipynb

Large diffs are not rendered by default.

Binary file added H2O-NOVA/presentation.pdf
Binary file not shown.
19 changes: 19 additions & 0 deletions H2O-NOVA/user_app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# User App

## Description

Streamlit app to track water consumption

## Installation

1. **Install requirements:**
```bash
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

2. **Run the app:**
```bash
streamlit run app.py
```
95 changes: 95 additions & 0 deletions H2O-NOVA/user_app/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import altair as alt
import pandas as pd
import streamlit as st

THRESHOLD = 10
materials = ['Shower', 'Bathtub', 'Faucet', 'Washing Machine', 'Dishwasher',
'Water Heater', 'Irrigation System', 'Water Filter', 'Other']


df = pd.read_csv("data/user_data.csv")
df_melted = df.drop(columns=["Price"]).melt("Month", var_name="Category", value_name="Liters")

user_name = "John Bob"
current_water_usage = df.iloc[-1]['User Water Usage (liters)']
city_threshold = f"{THRESHOLD} liters"


# App layout
st.set_page_config(layout="wide")
st.title("Water Usage")

# User details
col1, col2 = st.columns(2)
with col1:
st.subheader("User Details")
st.info(f"**First Name:** {user_name.split()[0]}")
st.info(f"**Last Name:** {user_name.split()[1]}")

with col2:
st.subheader("Last month Water Usage")
st.warning(f"**Water Usage:** {current_water_usage} liters")
st.warning(f"**City Threshold:** {city_threshold}")


# Users material
st.subheader("Select Water-Related Materials/Devices")

if "selected_materials" not in st.session_state:
st.session_state.selected_materials = []

# Create checkboxes for each material
cols = st.columns(3)

for i, material in enumerate(materials):
col_idx = i % 3
with cols[col_idx]:
if st.checkbox(material, value=(material in st.session_state.selected_materials)):
# Add to session state if selected
if material not in st.session_state.selected_materials:
st.session_state.selected_materials.append(material)
else:
# Remove from session state if unchecked
if material in st.session_state.selected_materials:
st.session_state.selected_materials.remove(material)

# Plots
col1, col2 = st.columns(2)

st.header("Track your water usage")

chart = (
alt.Chart(df_melted)
.mark_line(point=True)
.encode(
x=alt.X("Month:T", title="Month"),
y=alt.Y("Liters:Q", title="Liters"),
color=alt.Color("Category:N", title="Category"),
tooltip=["Month:T", "Category:N", "Liters:Q"],
)
.properties(
width=800,
height=400,
title="Water Usage Evolution"
)
.interactive()
)

price_chart = (
alt.Chart(df)
.mark_line(color="red", point=True)
.encode(
x=alt.X("Month:T", title="Month"),
y=alt.Y("Price:Q", title="Price (in MAD)"),
tooltip=["Month:T", "Price:Q"],
)
.properties(
width=800,
height=200,
title="Monthly Price Paid (MAD)",
)
.interactive()
)

st.altair_chart(price_chart, use_container_width=True)
st.altair_chart(chart, use_container_width=True)
2 changes: 2 additions & 0 deletions H2O-NOVA/user_app/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DATA_PATH = "data/user_data.csv"
THRESHOLD = 10
13 changes: 13 additions & 0 deletions H2O-NOVA/user_app/data/user_data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Month,User Water Usage (liters),City Threshold (liters),Price
2024-01-31,51,60,190.8
2024-02-29,36,65,175.8
2024-03-31,67,55,202.14
2024-04-30,42,60,173.45
2024-05-31,55,70,193.2
2024-06-30,73,55,205.45
2024-07-31,79,65,210.15
2024-08-31,64,60,200.2
2024-09-30,46,45,177.8
2024-10-31,51,50,190.8
2024-11-30,36,60,175.8
2024-12-31,21,45,144.8
30 changes: 30 additions & 0 deletions H2O-NOVA/user_app/data_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import calendar

import pandas as pd
from constants import DATA_PATH, THRESHOLD


def update_data(price, water_usage, city_threshold=THRESHOLD):
df = pd.read_csv(DATA_PATH)
# Extract the last row's month (assuming the 'Month' column is in YYYY-MM-DD format)
last_row_date = pd.to_datetime(df['Month'].iloc[-1])

# Calculate the next month and handle year change if necessary
next_month = (last_row_date.month % 12) + 1
next_year = last_row_date.year if next_month != 1 else last_row_date.year + 1

_, last_day = calendar.monthrange(next_year, next_month)
next_month_last_day = f"{next_year}-{next_month:02d}-{last_day:02d}"

next_month_data = pd.DataFrame({
'Month': [next_month_last_day],
'User Water Usage (liters)': [water_usage],
'City Threshold (liters)': [city_threshold],
'Price': [price]
})

# Concatenate the new row to the existing DataFrame
df = pd.concat([df, next_month_data], ignore_index=True)
df.to_csv(DATA_PATH, index=False)

return df
65 changes: 65 additions & 0 deletions H2O-NOVA/user_app/extractor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import re

import pytesseract
from PyPDF2 import PdfReader

pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract'


class PpdExtractor:
@staticmethod
def extract(pdf_path, page_number=2):
reader = PdfReader(pdf_path)

assert page_number >= 1 or page_number <= len(reader.pages)

extracted_text = reader.pages[page_number - 1].extract_text()
price_match = re.search(r'Total TTC\s+(\d+,\d+)', extracted_text)
price = None
if price_match:
# Replace the comma with a dot and convert to float
price = float(price_match.group(1).replace(",", "."))

water_consumption = re.findall(r'(\d+)\s+Tranche', extracted_text)
if len(water_consumption) == 0:
water_consumption = 0

elif len(water_consumption) >= 2:
# Take only the first which corresponds to water consumption, other is for electricity
water_consumption = int(water_consumption[0])

return price, water_consumption


class ImageExtractor:
def __init__(self, image):
self.width, self.height = image.size
self.image = image

def extract_water_usage(self, text):
# Extract water usage
try:
water_usage = re.findall(r"\d{2}/\d{2}/\d{4}\s+(\d+)", text.split("N°")[1])[-1]
water_usage = int(water_usage)
except Exception:
water_usage = None

return water_usage

def extract_price(self, text):
# Number that comes after "Sous total TTC"
price = re.search(r"Sous total TTC[:\s]+([\d,]+(?:\.\d{1,2})?)", text)
try:
price = price.group(1)
price = float(price.replace(",", "."))
except Exception:
price = None

return price

def extract(self):
text = pytesseract.image_to_string(self.image)
price = self.extract_price(text)
water_usage = self.extract_water_usage(text)

return price, water_usage
3 changes: 3 additions & 0 deletions H2O-NOVA/user_app/packages.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tesseract-ocr
libtk8.6
poppler-utils
Loading