Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -3,6 +3,7 @@ import paho.mqtt.client as mqtt
|
|
3 |
import threading
|
4 |
import time
|
5 |
import json
|
|
|
6 |
from datetime import datetime
|
7 |
|
8 |
app = Flask(__name__)
|
@@ -17,26 +18,58 @@ CLIENT_ID = "Flask_Web_Client"
|
|
17 |
|
18 |
# Global variables
|
19 |
relay_state = False
|
20 |
-
connection_status = "
|
21 |
last_message_time = None
|
22 |
message_log = []
|
|
|
23 |
|
24 |
# MQTT Client Setup
|
25 |
mqtt_client = mqtt.Client(CLIENT_ID)
|
26 |
mqtt_client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
def on_connect(client, userdata, flags, rc):
|
30 |
-
global connection_status
|
31 |
if rc == 0:
|
32 |
connection_status = "Connected"
|
|
|
33 |
print("Connected to MQTT broker")
|
34 |
client.subscribe(MQTT_TOPIC)
|
35 |
# Subscribe to status topic to get relay state updates
|
36 |
client.subscribe(f"{MQTT_TOPIC}/status")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
else:
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
def on_message(client, userdata, msg):
|
42 |
global relay_state, last_message_time, message_log
|
@@ -69,9 +102,29 @@ def on_message(client, userdata, msg):
|
|
69 |
print(f"Error processing message: {e}")
|
70 |
|
71 |
def on_disconnect(client, userdata, rc):
|
72 |
-
global connection_status
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
|
76 |
# Set MQTT callbacks
|
77 |
mqtt_client.on_connect = on_connect
|
@@ -79,11 +132,35 @@ mqtt_client.on_message = on_message
|
|
79 |
mqtt_client.on_disconnect = on_disconnect
|
80 |
|
81 |
def connect_mqtt():
|
|
|
82 |
try:
|
|
|
|
|
|
|
|
|
83 |
mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60)
|
84 |
mqtt_client.loop_start()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
except Exception as e:
|
|
|
|
|
86 |
print(f"Error connecting to MQTT broker: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
# Routes
|
89 |
@app.route('/')
|
@@ -95,10 +172,40 @@ def get_status():
|
|
95 |
return jsonify({
|
96 |
'relay_state': relay_state,
|
97 |
'connection_status': connection_status,
|
|
|
98 |
'last_message_time': last_message_time.strftime("%Y-%m-%d %H:%M:%S") if last_message_time else "Never",
|
99 |
-
'message_log': message_log
|
100 |
})
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
@app.route('/api/toggle', methods=['POST'])
|
103 |
def toggle_relay():
|
104 |
global relay_state
|
@@ -152,6 +259,11 @@ if __name__ == '__main__':
|
|
152 |
mqtt_thread.start()
|
153 |
|
154 |
# Wait a moment for MQTT to connect
|
155 |
-
time.sleep(
|
|
|
|
|
|
|
|
|
|
|
156 |
|
157 |
app.run(debug=True, host='0.0.0.0', port=5000)
|
|
|
3 |
import threading
|
4 |
import time
|
5 |
import json
|
6 |
+
import ssl
|
7 |
from datetime import datetime
|
8 |
|
9 |
app = Flask(__name__)
|
|
|
18 |
|
19 |
# Global variables
|
20 |
relay_state = False
|
21 |
+
connection_status = "Connecting..."
|
22 |
last_message_time = None
|
23 |
message_log = []
|
24 |
+
connection_error = None
|
25 |
|
26 |
# MQTT Client Setup
|
27 |
mqtt_client = mqtt.Client(CLIENT_ID)
|
28 |
mqtt_client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
|
29 |
+
|
30 |
+
# Configure TLS with less strict verification (similar to ESP8266's setInsecure)
|
31 |
+
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
|
32 |
+
context.check_hostname = False
|
33 |
+
context.verify_mode = ssl.CERT_NONE
|
34 |
+
mqtt_client.tls_set_context(context)
|
35 |
|
36 |
def on_connect(client, userdata, flags, rc):
|
37 |
+
global connection_status, connection_error
|
38 |
if rc == 0:
|
39 |
connection_status = "Connected"
|
40 |
+
connection_error = None
|
41 |
print("Connected to MQTT broker")
|
42 |
client.subscribe(MQTT_TOPIC)
|
43 |
# Subscribe to status topic to get relay state updates
|
44 |
client.subscribe(f"{MQTT_TOPIC}/status")
|
45 |
+
|
46 |
+
# Add connection success to log
|
47 |
+
log_entry = {
|
48 |
+
'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
49 |
+
'topic': 'system',
|
50 |
+
'message': 'Connected to MQTT broker'
|
51 |
+
}
|
52 |
+
message_log.append(log_entry)
|
53 |
+
|
54 |
else:
|
55 |
+
error_messages = {
|
56 |
+
1: "Connection refused - incorrect protocol version",
|
57 |
+
2: "Connection refused - invalid client identifier",
|
58 |
+
3: "Connection refused - server unavailable",
|
59 |
+
4: "Connection refused - bad username or password",
|
60 |
+
5: "Connection refused - not authorised"
|
61 |
+
}
|
62 |
+
connection_error = error_messages.get(rc, f"Unknown error code: {rc}")
|
63 |
+
connection_status = f"Failed: {connection_error}"
|
64 |
+
print(f"Failed to connect to MQTT broker: {connection_error}")
|
65 |
+
|
66 |
+
# Add connection failure to log
|
67 |
+
log_entry = {
|
68 |
+
'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
69 |
+
'topic': 'system',
|
70 |
+
'message': f'Connection failed: {connection_error}'
|
71 |
+
}
|
72 |
+
message_log.append(log_entry)
|
73 |
|
74 |
def on_message(client, userdata, msg):
|
75 |
global relay_state, last_message_time, message_log
|
|
|
102 |
print(f"Error processing message: {e}")
|
103 |
|
104 |
def on_disconnect(client, userdata, rc):
|
105 |
+
global connection_status, connection_error
|
106 |
+
if rc != 0:
|
107 |
+
connection_status = "Disconnected unexpectedly"
|
108 |
+
connection_error = f"Unexpected disconnection (code: {rc})"
|
109 |
+
print(f"Unexpected disconnection from MQTT broker: {rc}")
|
110 |
+
|
111 |
+
# Add disconnection to log
|
112 |
+
log_entry = {
|
113 |
+
'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
114 |
+
'topic': 'system',
|
115 |
+
'message': f'Disconnected unexpectedly (code: {rc})'
|
116 |
+
}
|
117 |
+
message_log.append(log_entry)
|
118 |
+
|
119 |
+
# Try to reconnect
|
120 |
+
try:
|
121 |
+
time.sleep(5) # Wait 5 seconds before reconnecting
|
122 |
+
client.reconnect()
|
123 |
+
except Exception as e:
|
124 |
+
print(f"Reconnection failed: {e}")
|
125 |
+
else:
|
126 |
+
connection_status = "Disconnected"
|
127 |
+
print("Disconnected from MQTT broker")
|
128 |
|
129 |
# Set MQTT callbacks
|
130 |
mqtt_client.on_connect = on_connect
|
|
|
132 |
mqtt_client.on_disconnect = on_disconnect
|
133 |
|
134 |
def connect_mqtt():
|
135 |
+
global connection_status, connection_error
|
136 |
try:
|
137 |
+
print("Attempting to connect to MQTT broker...")
|
138 |
+
connection_status = "Connecting..."
|
139 |
+
|
140 |
+
# Set keepalive and connect
|
141 |
mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60)
|
142 |
mqtt_client.loop_start()
|
143 |
+
|
144 |
+
# Wait for connection result
|
145 |
+
time.sleep(5)
|
146 |
+
|
147 |
+
if connection_status == "Connecting...":
|
148 |
+
connection_status = "Connection timeout"
|
149 |
+
connection_error = "Connection attempt timed out"
|
150 |
+
print("Connection attempt timed out")
|
151 |
+
|
152 |
except Exception as e:
|
153 |
+
connection_error = str(e)
|
154 |
+
connection_status = f"Connection error: {str(e)}"
|
155 |
print(f"Error connecting to MQTT broker: {e}")
|
156 |
+
|
157 |
+
# Add connection error to log
|
158 |
+
log_entry = {
|
159 |
+
'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
160 |
+
'topic': 'system',
|
161 |
+
'message': f'Connection error: {str(e)}'
|
162 |
+
}
|
163 |
+
message_log.append(log_entry)
|
164 |
|
165 |
# Routes
|
166 |
@app.route('/')
|
|
|
172 |
return jsonify({
|
173 |
'relay_state': relay_state,
|
174 |
'connection_status': connection_status,
|
175 |
+
'connection_error': connection_error,
|
176 |
'last_message_time': last_message_time.strftime("%Y-%m-%d %H:%M:%S") if last_message_time else "Never",
|
177 |
+
'message_log': message_log[-10:] # Only last 10 messages
|
178 |
})
|
179 |
|
180 |
+
@app.route('/api/reconnect', methods=['POST'])
|
181 |
+
def reconnect_mqtt():
|
182 |
+
global connection_status, connection_error
|
183 |
+
|
184 |
+
try:
|
185 |
+
if mqtt_client.is_connected():
|
186 |
+
mqtt_client.disconnect()
|
187 |
+
|
188 |
+
time.sleep(2) # Wait before reconnecting
|
189 |
+
|
190 |
+
connection_status = "Reconnecting..."
|
191 |
+
connection_error = None
|
192 |
+
|
193 |
+
# Reconnect
|
194 |
+
mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60)
|
195 |
+
|
196 |
+
return jsonify({
|
197 |
+
'success': True,
|
198 |
+
'message': 'Reconnection initiated'
|
199 |
+
})
|
200 |
+
|
201 |
+
except Exception as e:
|
202 |
+
connection_error = str(e)
|
203 |
+
connection_status = f"Reconnection failed: {str(e)}"
|
204 |
+
return jsonify({
|
205 |
+
'success': False,
|
206 |
+
'error': str(e)
|
207 |
+
})
|
208 |
+
|
209 |
@app.route('/api/toggle', methods=['POST'])
|
210 |
def toggle_relay():
|
211 |
global relay_state
|
|
|
259 |
mqtt_thread.start()
|
260 |
|
261 |
# Wait a moment for MQTT to connect
|
262 |
+
time.sleep(3)
|
263 |
+
|
264 |
+
print(f"Starting Flask server...")
|
265 |
+
print(f"MQTT Status: {connection_status}")
|
266 |
+
if connection_error:
|
267 |
+
print(f"MQTT Error: {connection_error}")
|
268 |
|
269 |
app.run(debug=True, host='0.0.0.0', port=5000)
|