diff --git a/.github/workflows/update_static.yml b/.github/workflows/update_static.yml new file mode 100644 index 0000000..d4f91d2 --- /dev/null +++ b/.github/workflows/update_static.yml @@ -0,0 +1,30 @@ +name: Update Static Files + +on: + schedule: + - cron: '0 */6 * * *' # Runs every 6 hours + workflow_dispatch: # Allows manual triggering + +jobs: + update_static: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Generate static files + env: + OPENWEATHERMAP_API_KEY: ${{ secrets.OPENWEATHERMAP_API_KEY || '' }} + run: | + python generate_static.py + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build \ No newline at end of file diff --git a/README.md b/README.md index eee3c5c..82d175d 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,20 @@ This Weather Monitoring System is a Python-based application that fetches real-t - Web dashboard for real-time weather visualization - Machine learning-based weather prediction for the next 24 hours - ### Web Dashboard + ### Web Dashboard The web dashboard provides a user-friendly interface to view current weather data, forecasts, and predictions for all monitored cities. - ### Machine Learning Weather Prediction + ### Machine Learning Weather Prediction Trained machine learning models for 24-hour weather prediction are stored in the `models/` directory. + ### Hosted Dashboard + + You can view a static version of the weather dashboard online: + + https://aryanbv.github.io/weather_monitoring_system/ + + Note: This static version is updated periodically and may not reflect real-time data. For the most up-to-date information, please run the application locally as described in the Usage section. + ### Weather Monitoring System To view the real-time weather dashboard: diff --git a/app.py b/app.py index e82c345..056cfbb 100644 --- a/app.py +++ b/app.py @@ -26,18 +26,25 @@ def dashboard(): predictor.load_model() except FileNotFoundError: historical_data = db_handler.get_historical_weather_data(city) - predictor.train_model(historical_data) - + if historical_data: + predictor.train_model(historical_data) + else: + continue # Skip prediction if no historical data + next_day = datetime.now() + timedelta(days=1) - prediction = predictor.predict( - next_day.hour, - next_day.weekday(), - next_day.month, - latest_data[city]['humidity'], - latest_data[city]['wind_speed'], - latest_data[city]['weather_condition'] - ) - predictions[city] = round(prediction, 1) + try: + prediction = predictor.predict( + next_day.hour, + next_day.weekday(), + next_day.month, + latest_data[city]['humidity'], + latest_data[city]['wind_speed'], + latest_data[city]['weather_condition'] + ) + predictions[city] = round(prediction, 1) + except ValueError as e: + print(f"Prediction error for {city}: {str(e)}") + predictions[city] = "N/A" return render_template('dashboard.html', latest_data=latest_data, predictions=predictions) diff --git a/models/Bangalore_label_encoder.joblib b/models/Bangalore_label_encoder.joblib new file mode 100644 index 0000000..b517b15 Binary files /dev/null and b/models/Bangalore_label_encoder.joblib differ diff --git a/models/Chennai_label_encoder.joblib b/models/Chennai_label_encoder.joblib new file mode 100644 index 0000000..4e5ca3a Binary files /dev/null and b/models/Chennai_label_encoder.joblib differ diff --git a/models/Delhi_label_encoder.joblib b/models/Delhi_label_encoder.joblib new file mode 100644 index 0000000..48149da Binary files /dev/null and b/models/Delhi_label_encoder.joblib differ diff --git a/models/Hyderabad_label_encoder.joblib b/models/Hyderabad_label_encoder.joblib new file mode 100644 index 0000000..9725ddd Binary files /dev/null and b/models/Hyderabad_label_encoder.joblib differ diff --git a/models/Kolkata_label_encoder.joblib b/models/Kolkata_label_encoder.joblib new file mode 100644 index 0000000..48149da Binary files /dev/null and b/models/Kolkata_label_encoder.joblib differ diff --git a/models/Mumbai_label_encoder.joblib b/models/Mumbai_label_encoder.joblib new file mode 100644 index 0000000..2a83ad0 Binary files /dev/null and b/models/Mumbai_label_encoder.joblib differ diff --git a/src/database/__pycache__/db_handler.cpython-312.pyc b/src/database/__pycache__/db_handler.cpython-312.pyc index 54451fb..dd71bf7 100644 Binary files a/src/database/__pycache__/db_handler.cpython-312.pyc and b/src/database/__pycache__/db_handler.cpython-312.pyc differ diff --git a/src/ml/__pycache__/weather_predictor.cpython-312.pyc b/src/ml/__pycache__/weather_predictor.cpython-312.pyc index a37cf08..e259a63 100644 Binary files a/src/ml/__pycache__/weather_predictor.cpython-312.pyc and b/src/ml/__pycache__/weather_predictor.cpython-312.pyc differ diff --git a/src/ml/weather_predictor.py b/src/ml/weather_predictor.py index c444051..729a085 100644 --- a/src/ml/weather_predictor.py +++ b/src/ml/weather_predictor.py @@ -11,6 +11,8 @@ def __init__(self, city): self.model = None self.le = LabelEncoder() self.model_path = f'models/{city}_weather_model.joblib' + self.le_path = f'models/{city}_label_encoder.joblib' + self.is_fitted = False def prepare_data(self, data): df = pd.DataFrame(data) @@ -18,7 +20,8 @@ def prepare_data(self, data): df['hour'] = df['timestamp'].dt.hour df['day_of_week'] = df['timestamp'].dt.dayofweek df['month'] = df['timestamp'].dt.month - df['weather_condition'] = self.le.fit_transform(df['weather_condition']) + self.le.fit(df['weather_condition']) + df['weather_condition'] = self.le.transform(df['weather_condition']) return df def train_model(self, data): @@ -29,11 +32,20 @@ def train_model(self, data): self.model = RandomForestRegressor(n_estimators=100, random_state=42) self.model.fit(X_train, y_train) self.save_model() + self.is_fitted = True def predict(self, hour, day_of_week, month, humidity, wind_speed, weather_condition): - if self.model is None: + if not self.is_fitted: self.load_model() - weather_condition_encoded = self.le.transform([weather_condition])[0] + try: + weather_condition_encoded = self.le.transform([weather_condition])[0] + except ValueError: + # If the weather condition is not in the encoder, use a default value + weather_condition_encoded = -1 + + if self.model is None: + raise ValueError("Model not trained or loaded. Please train the model first.") + prediction = self.model.predict([[hour, day_of_week, month, humidity, wind_speed, weather_condition_encoded]]) return prediction[0] @@ -41,9 +53,12 @@ def save_model(self): if not os.path.exists('models'): os.makedirs('models') joblib.dump(self.model, self.model_path) + joblib.dump(self.le, self.le_path) def load_model(self): - if os.path.exists(self.model_path): + if os.path.exists(self.model_path) and os.path.exists(self.le_path): self.model = joblib.load(self.model_path) + self.le = joblib.load(self.le_path) + self.is_fitted = True else: raise FileNotFoundError(f"No trained model found for {self.city}") \ No newline at end of file diff --git a/update_github.sh b/update_github.sh new file mode 100644 index 0000000..233fad5 --- /dev/null +++ b/update_github.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Update main branch +git checkout main +git add . +git commit -m "Update main branch with latest changes" +git push origin main + +# Update gh-pages branch +git checkout gh-pages +git merge main +python generate_static.py +git add . +git commit -m "Update static files for GitHub Pages" +git push origin gh-pages + +# Switch back to main branch +git checkout main + +echo "GitHub repository and Pages site updated successfully!" \ No newline at end of file