Rajkhanke007 commited on
Commit
4320de1
·
verified ·
1 Parent(s): 13e006b

Upload 7 files

Browse files
app.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, redirect, url_for, session,jsonify
2
+ import joblib
3
+ import pandas as pd
4
+ import numpy as np
5
+ import requests
6
+ import json
7
+ import plotly.graph_objects as go
8
+
9
+ app = Flask(__name__)
10
+
11
+ # Load the SVM model
12
+ svm_poly_model = joblib.load('svm_poly_model.pkl')
13
+
14
+ # Label encoding mappings for SVM model
15
+ crop_type_mapping = {
16
+ 'BANANA': 0, 'BEAN': 1, 'CABBAGE': 2, 'CITRUS': 3, 'COTTON': 4,
17
+ 'MAIZE': 5, 'MELON': 6, 'MUSTARD': 7, 'ONION': 8, 'OTHER': 9,
18
+ 'POTATO': 10, 'RICE': 11, 'SOYABEAN': 12, 'SUGARCANE': 13,
19
+ 'TOMATO': 14, 'WHEAT': 15
20
+ }
21
+
22
+ soil_type_mapping = {'DRY': 0, 'HUMID': 1, 'WET': 2}
23
+ weather_condition_mapping = {'NORMAL': 0, 'RAINY': 1, 'SUNNY': 2, 'WINDY': 3}
24
+
25
+
26
+ # Fetch weather data from the OpenWeatherMap API
27
+ def get_weather(city):
28
+ api_key = "b3c62ae7f7ad5fc3cb0a7b56cb7cbda6"
29
+ url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"
30
+ try:
31
+ response = requests.get(url)
32
+ response.raise_for_status() # Raise an exception for any HTTP errors
33
+ except requests.exceptions.HTTPError as err:
34
+ return None, None, None, None
35
+
36
+ try:
37
+ data = json.loads(response.text)
38
+ if data['cod'] != 200:
39
+ return None, None, None, None
40
+ except json.JSONDecodeError as err:
41
+ return None, None, None, None
42
+
43
+ # Extract relevant weather information
44
+ weather_description = data['weather'][0]['description']
45
+ temperature = data['main']['temp']
46
+ humidity = data['main']['humidity']
47
+ pressure = data['main']['pressure']
48
+ # Convert temperature from Kelvin to Celsius
49
+ temperature = round(temperature - 273.15, 2)
50
+
51
+ return temperature, humidity, weather_description, pressure
52
+
53
+
54
+ @app.route('/')
55
+ def index():
56
+ return render_template('index.html')
57
+
58
+
59
+ @app.route('/fetch_weather', methods=['GET'])
60
+ def fetch_weather():
61
+ city = request.args.get('city')
62
+ if city:
63
+ temperature, humidity, weather_description, pressure = get_weather(city)
64
+ if temperature is not None:
65
+ return json.dumps({
66
+ 'description': weather_description.capitalize(),
67
+ 'temperature': temperature,
68
+ 'humidity': humidity,
69
+ 'pressure': pressure
70
+ })
71
+ return json.dumps(None) # Return None if weather couldn't be fetched
72
+
73
+
74
+
75
+ @app.route('/predict', methods=['POST'])
76
+ def predict():
77
+ if request.method == 'POST':
78
+ crop_type = request.form['crop_type']
79
+ soil_type = request.form['soil_type']
80
+ city = request.form['city']
81
+ motor_capacity = float(request.form['motor_capacity'])
82
+
83
+ # Get weather data
84
+ temperature, humidity, weather_description, pressure = get_weather(city)
85
+
86
+ # Auto-fill weather condition based on description
87
+ if temperature is None:
88
+ auto_weather_condition = 'NORMAL'
89
+ temperature = 32.0
90
+ else:
91
+ auto_weather_condition = ('SUNNY' if 'clear' in weather_description.lower() else
92
+ 'RAINY' if 'rain' in weather_description.lower() else
93
+ 'WINDY' if 'wind' in weather_description.lower() else
94
+ 'NORMAL')
95
+
96
+ # Encode inputs for the model
97
+ crop_type_encoded = crop_type_mapping[crop_type]
98
+ soil_type_encoded = soil_type_mapping[soil_type]
99
+ weather_condition_encoded = weather_condition_mapping[auto_weather_condition]
100
+
101
+ # Create DataFrame for input
102
+ user_data = pd.DataFrame({
103
+ 'CROP TYPE': [crop_type_encoded],
104
+ 'SOIL TYPE': [soil_type_encoded],
105
+ 'TEMPERATURE': [temperature],
106
+ 'WEATHER CONDITION': [weather_condition_encoded]
107
+ })
108
+
109
+ # Predict water requirement
110
+ water_requirement = svm_poly_model.predict(user_data)[0]
111
+
112
+ # Calculate estimated time duration
113
+ estimated_time_duration = water_requirement / motor_capacity if motor_capacity > 0 else 0
114
+ time_unit = "seconds" if estimated_time_duration < 1 else "minutes"
115
+ estimated_time_duration = estimated_time_duration * 60 if time_unit == "seconds" else estimated_time_duration
116
+
117
+ # Create the gauge charts for water requirement and estimated time
118
+ water_gauge = go.Figure(go.Indicator(
119
+ mode="gauge+number",
120
+ value=water_requirement,
121
+ title={"text": "Water Requirement (m³/sq.m)"},
122
+ gauge={
123
+ "axis": {"range": [None, 100]},
124
+ "bar": {"color": "blue"},
125
+ "steps": [
126
+ {"range": [0, 20], "color": "lightgray"},
127
+ {"range": [20, 50], "color": "yellow"},
128
+ {"range": [50, 100], "color": "green"}
129
+ ]
130
+ }
131
+ ))
132
+
133
+ # Determine gauge axis range based on the time unit
134
+ max_range = 60 if time_unit == "seconds" else 120
135
+
136
+ time_gauge = go.Figure(go.Indicator(
137
+ mode="gauge+number",
138
+ value=round(estimated_time_duration, 2),
139
+ title={"text": f"Estimated Time ({time_unit.capitalize()})"},
140
+ gauge={
141
+ "axis": {"range": [None, max_range]},
142
+ "bar": {"color": "blue"},
143
+ "steps": [
144
+ {"range": [0, max_range * 0.33], "color": "lightgray"},
145
+ {"range": [max_range * 0.33, max_range * 0.66], "color": "yellow"},
146
+ {"range": [max_range * 0.66, max_range], "color": "green"}
147
+ ]
148
+ }
149
+ ))
150
+
151
+ # Send gauge charts to the prediction page
152
+ water_gauge_path = water_gauge.to_html(full_html=False)
153
+ time_gauge_path = time_gauge.to_html(full_html=False)
154
+
155
+ return render_template('predict.html',
156
+ water_requirement=round(water_requirement, 2),
157
+ estimated_time_duration=round(estimated_time_duration, 2),
158
+ time_unit=time_unit,
159
+ weather_info=f"Weather in {city}: {weather_description.capitalize()}<br>"
160
+ f"Temperature: {temperature}°C<br>"
161
+ f"Humidity: {humidity}%<br>"
162
+ f"Pressure: {pressure} hPa<br>",
163
+ water_gauge=water_gauge_path,
164
+ time_gauge=time_gauge_path)
165
+
166
+ return redirect(url_for('index'))
167
+
168
+
169
+ @app.route('/start_motor', methods=['POST'])
170
+ def start_motor():
171
+ estimated_time_duration = float(request.json.get('estimated_time_duration'))
172
+ time_unit = request.json.get('time_unit', 'seconds') # Default unit is seconds
173
+ # Convert time to seconds if it's in minutes
174
+ if estimated_time_duration < 10:
175
+ estimated_time_duration_seconds = estimated_time_duration * 60
176
+ else:
177
+ estimated_time_duration_seconds = estimated_time_duration
178
+
179
+ # Assuming this function will trigger the motor start, we will just send the confirmation
180
+ print(f"Starting motor for {estimated_time_duration_seconds} seconds")
181
+
182
+ # Return a response indicating that the motor has started
183
+ return jsonify({"status": "motor_started", "estimated_time_duration": estimated_time_duration_seconds})
184
+
185
+
186
+ if __name__ == "__main__":
187
+ app.run(debug=True)
requirement.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ gunicorn
2
+ pandas
3
+ numpy
4
+ matplotlib
5
+ joblib==1.4.2
6
+ plotly
7
+ scikit-learn==1.5.2
8
+ flask
9
+ requests
static/alarn_tune.mp3 ADDED
Binary file (229 kB). View file
 
static/images/img.png ADDED
svm_poly_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b60a7814f3e851178e888f92530d7a5dbdeb4a66557f43e0fe7e43d09335a276
3
+ size 124910
templates/index.html ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Irrigation Water Requirement Prediction</title>
7
+ <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ background-color: #f0fff0; /* Very light green */
11
+ }
12
+ .container {
13
+ border: 1px solid #28a745; /* Green border */
14
+ padding: 20px;
15
+ margin: 40px auto;
16
+ background-color: white;
17
+ border-radius: 10px;
18
+ }
19
+ /* Add these styles */
20
+ #weather_info {
21
+ background-color: #f8f9fa; /* Light grey background */
22
+ border: 2px solid #000000; /* Dark black border */
23
+ padding: 15px; /* Padding for spacing inside the box */
24
+ border-radius: 5px; /* Optional: Rounded corners */
25
+ }
26
+ h1 {
27
+ color: #28a745; /* Bold green heading */
28
+ text-align: center;
29
+ font-weight: bold;
30
+ }
31
+ .input-container {
32
+ display: flex;
33
+ justify-content: space-between;
34
+ height: 100%; /* Ensure both sides are the same height */
35
+ }
36
+ .left-input {
37
+ width: 53%;
38
+ border-right: 2px solid #28a745;
39
+ padding-right: 20px;
40
+ }
41
+ .right-image {
42
+ width: 45%;
43
+ display: flex;
44
+ justify-content: center;
45
+ align-items: center;
46
+ height: 200%; /* Ensure full height */
47
+ margin-top: 50px;
48
+ }
49
+ .right-image img {
50
+ width: 100%;
51
+ height: 100%; /* Match the height of the left container */
52
+ object-fit: contain; /* Ensure the image scales well */
53
+ }
54
+ .form-control {
55
+ border-color: #28a745; /* Green border */
56
+ background-color: #f0fff0; /* Light green shading */
57
+ }
58
+ .btn-green {
59
+ background-color: #28a745;
60
+ color: white;
61
+ font-weight: bold;
62
+ width: 100%;
63
+ margin-top: 10px;
64
+ }
65
+ </style>
66
+ </head>
67
+ <body>
68
+
69
+ <div class="container">
70
+ <h1>Irrigation Water Requirement Prediction</h1>
71
+ <form action="/predict" method="POST">
72
+ <div class="input-container">
73
+ <div class="left-input">
74
+ <!-- Crop Type Input -->
75
+ <div class="form-group">
76
+ <label for="crop_type">Crop Type</label>
77
+ <select class="form-control" id="crop_type" name="crop_type" required>
78
+ <option value="BANANA">Banana</option>
79
+ <option value="BEAN">BEAN</option>
80
+ <option value="CABBAGE">CABBAGE</option>
81
+ <option value="CITRUS">CITRUS</option>
82
+ <option value="COTTON">COTTON</option>
83
+ <option value="MAIZE">MAIZE</option>
84
+ <option value="MELON">MELON</option>
85
+ <option value="MUSTARD">MUSTARD</option>
86
+ <option value="ONION">ONION</option>
87
+ <option value="OTHER">OTHER</option>
88
+ <option value="POTATO">POTATO</option>
89
+ <option value="RICE">RICE</option>
90
+ <option value="SOYABEAN">SOYABEAN</option>
91
+ <option value="SUGARCANE">SUGARCANE</option>
92
+ <option value="TOMATO">TOMATO</option>
93
+ <option value="WHEAT">WHEAT</option>
94
+ <!-- Add other options as needed -->
95
+ </select>
96
+ </div>
97
+
98
+ <!-- Soil Type Input -->
99
+ <div class="form-group">
100
+ <label for="soil_type">Soil Type</label>
101
+ <select class="form-control" id="soil_type" name="soil_type" required>
102
+ <option value="DRY">Dry</option>
103
+ <option value="HUMID">Humid</option>
104
+ <option value="WET">Wet</option>
105
+ </select>
106
+ </div>
107
+
108
+ <!-- City Input and Fetch Weather Button -->
109
+ <div class="form-group">
110
+ <label for="city">City</label>
111
+ <input type="text" class="form-control" id="city" name="city" placeholder="Enter city for weather" required>
112
+ </div>
113
+ <button type="button" class="btn btn-green" onclick="fetchWeather()">Fetch Weather Data</button>
114
+ <!-- Weather Info will be inserted below when fetched -->
115
+ <div id="weather_info" class="mt-3" style="display: none;">
116
+ <p><strong>Weather Info:</strong></p>
117
+ <div id="weather_data"></div>
118
+ </div>
119
+ <!-- Motor Capacity Input -->
120
+ <div class="form-group mt-3">
121
+ <label for="motor_capacity">Motor Capacity (liters/sec)</label>
122
+ <input type="text" class="form-control" id="motor_capacity" name="motor_capacity" required>
123
+ </div>
124
+
125
+ <!-- Predict Button -->
126
+ <button type="submit" class="btn btn-green">Predict Water Requirement</button>
127
+ </div>
128
+
129
+ <div class="right-image">
130
+ <img src="/static/images/img.png" alt="Decorative Image">
131
+ </div>
132
+ </div>
133
+ </form>
134
+ </div>
135
+
136
+ <script>
137
+ function fetchWeather() {
138
+ const city = document.getElementById('city').value;
139
+ if (city) {
140
+ fetch(`/fetch_weather?city=${city}`)
141
+ .then(response => response.json())
142
+ .then(data => {
143
+ if (data) {
144
+ document.getElementById('weather_data').innerHTML = `
145
+ Weather: ${data.description}<br>
146
+ Temperature: ${data.temperature}°C<br>
147
+ Humidity: ${data.humidity}%<br>
148
+ Pressure: ${data.pressure} hPa
149
+ `;
150
+ document.getElementById('weather_info').style.display = 'block'; // Show the weather info box
151
+ } else {
152
+ document.getElementById('weather_data').innerHTML = 'Weather data not available';
153
+ document.getElementById('weather_info').style.display = 'block';
154
+ }
155
+ })
156
+ .catch(error => {
157
+ console.error('Error fetching weather:', error);
158
+ document.getElementById('weather_data').innerHTML = 'Error fetching weather data';
159
+ document.getElementById('weather_info').style.display = 'block';
160
+ });
161
+ }
162
+ }
163
+ </script>
164
+
165
+
166
+ </body>
167
+ </html>
templates/predict.html ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Prediction Results</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <style>
9
+ .container {
10
+ margin-top: 20px;
11
+ padding: 20px;
12
+ border: 1px solid #ddd;
13
+ border-radius: 10px;
14
+ }
15
+ h1 {
16
+ color: green;
17
+ font-weight: bold;
18
+ }
19
+ .result-container {
20
+ padding: 20px;
21
+ margin-top: 20px;
22
+ }
23
+ .result-container .row {
24
+ justify-content: center;
25
+ }
26
+ .form-control {
27
+ height: 45px;
28
+ font-size: 18px;
29
+ text-align: center;
30
+ font-weight: bold; /* Bold text */
31
+ color: black; /* Black text */
32
+ border: 2px solid #28a745; /* Green border */
33
+ }
34
+ .result {
35
+ text-align: center;
36
+ }
37
+ .gauge-container {
38
+ margin-top: 20px;
39
+ }
40
+ .gauge-container h5 {
41
+ margin-bottom: 10px;
42
+ }
43
+ .btn-green {
44
+ background-color: green;
45
+ color: white;
46
+ }
47
+
48
+ /* New styles below */
49
+ .info-text {
50
+ font-size: 24px; /* Increased font size */
51
+ font-weight: bold;
52
+ color: black;
53
+ margin-top: 40px;
54
+ text-align: center; /* Center-aligned */
55
+ }
56
+ .camera-container {
57
+ margin-top: 20px;
58
+ text-align: center;
59
+ display: none; /* Hidden by default, shown after button click */
60
+ }
61
+ .timer {
62
+ font-size: 36px; /* Increased size */
63
+ color: white; /* White text */
64
+ background-color: green; /* Green background */
65
+ font-weight: bold; /* Bold font */
66
+ padding: 20px;
67
+ border-radius: 5px;
68
+ display: inline-block;
69
+ }
70
+ video {
71
+ width: 100%;
72
+ height: auto;
73
+ border: 1px solid #ddd;
74
+ }
75
+ .btn-start {
76
+ margin-top: 20px;
77
+ background-color: green;
78
+ color: white;
79
+ font-size: 18px;
80
+ padding: 10px 20px;
81
+ }
82
+ .alert-message {
83
+ font-size: 36px; /* Increased size for alert message */
84
+ color: red;
85
+ font-weight: bold;
86
+ margin-top: 20px;
87
+ text-align: center;
88
+ }
89
+ </style>
90
+ </head>
91
+ <body>
92
+ <div class="container">
93
+ <h1 class="text-center">Water Requirement Prediction Results</h1>
94
+ <div class="result-container row">
95
+ <div class="col-md-6">
96
+ <div class="form-group">
97
+ <label for="water_requirement">Water Requirement Prediction (m³/sq.m):</label>
98
+ <input type="text" class="form-control" id="water_requirement" value="{{ water_requirement }}" readonly>
99
+ </div>
100
+ <div class="gauge-container">
101
+ <h5>Water Requirement Gauge:</h5>
102
+ {{ water_gauge|safe }}
103
+ </div>
104
+ </div>
105
+
106
+ <div class="col-md-6">
107
+ <div class="form-group">
108
+ <label for="estimated_time">Estimated Time Duration (seconds) for which motor should be On:</label>
109
+ <input type="text" class="form-control" id="estimated_time" value="{{ estimated_time_duration }} {{ time_unit }}" readonly>
110
+ </div>
111
+ <div class="gauge-container">
112
+ <h5>Estimated Motor On-Time Gauge:</h5>
113
+ {{ time_gauge|safe }}
114
+ </div>
115
+ </div>
116
+ </div>
117
+
118
+ <!-- New section below -->
119
+ <div class="info-text">
120
+ Want to automatically inspect your irrigation process using AI-driven Irrigation Monitoring?
121
+ <br><strong>Press "Start Motor" button</strong>
122
+ <br>Then click the green <strong>Start</strong> button below.
123
+ </div>
124
+
125
+ <!-- "Start Motor" Button -->
126
+ <div class="text-center">
127
+ <button id="startMotor" class="btn btn-start">Start Motor</button>
128
+ </div>
129
+
130
+ <div class="camera-container">
131
+ <video id="videoElement" autoplay></video>
132
+ <div class="timer" id="timer"></div>
133
+ </div>
134
+
135
+ <div class="alert-message" id="alertMessage"></div>
136
+ </div>
137
+
138
+ <script>
139
+ // Access camera and start video stream
140
+ navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
141
+ .then(function(stream) {
142
+ document.getElementById('videoElement').srcObject = stream;
143
+ })
144
+ .catch(function(err) {
145
+ console.log("Error: " + err);
146
+ });
147
+
148
+ document.getElementById('startMotor').addEventListener('click', function() {
149
+ let estimatedTime = {{ estimated_time_duration }};
150
+ if (estimatedTime < 10) {
151
+ estimatedTime = estimatedTime * 60; // Convert minutes to seconds
152
+ }
153
+ let timeUnit = "{{ time_unit }}";
154
+
155
+ // Show the camera container after the button is clicked
156
+ document.querySelector('.camera-container').style.display = 'block';
157
+
158
+ // Start the timer
159
+ let timer = document.getElementById('timer');
160
+ let timeRemaining = parseInt(estimatedTime, 10); // Convert to integer
161
+ let countdown = setInterval(function() {
162
+ let seconds = timeRemaining;
163
+ timer.textContent = seconds + "s";
164
+ if (timeRemaining <= 0) {
165
+ clearInterval(countdown);
166
+ // Play beep sound
167
+ let beep = new Audio('/static/alarn_tune.mp3');
168
+ beep.play();
169
+
170
+ // Display alert message
171
+ document.getElementById('alertMessage').textContent = "Stop Irrigation!";
172
+ }
173
+ timeRemaining--;
174
+ }, 1000);
175
+
176
+ fetch('/start_motor', {
177
+ method: 'POST',
178
+ headers: {
179
+ 'Content-Type': 'application/json',
180
+ },
181
+ body: JSON.stringify({ estimated_time_duration: estimated_time_duration_seconds })
182
+ });
183
+ });
184
+ </script>
185
+ </body>
186
+ </html>