Skip to content
Snippets Groups Projects
Commit 59b0b12c authored by Sebastian Ebert's avatar Sebastian Ebert
Browse files

updated webapp

parent 239369c3
Branches main
No related tags found
No related merge requests found
from flask import Flask, render_template, request, jsonify from flask import Flask, render_template, request, jsonify
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
# Flask app initialization
app = Flask(__name__) app = Flask(__name__)
# MQTT Configuration # MQTT Configuration
BROKER = "localhost" # Replace with your broker BROKER = "localhost" # Change if using a remote broker
PUBLISH_TOPIC = "colors/publish" PORT = 1883
LOG_TOPIC = "colors/log"
mqtt_client = mqtt.Client() mqtt_client = mqtt.Client()
# On connect, subscribe to the log topic # Connect to MQTT broker
def on_connect(client, userdata, flags, rc): mqtt_client.connect(BROKER, PORT, 60)
print(f"Connected to MQTT Broker with result code {rc}")
mqtt_client.subscribe(LOG_TOPIC)
# On receiving a message, print it
log_messages = []
def on_message(client, userdata, msg):
global log_messages
message = msg.payload.decode()
log_messages.append(message)
# Assign MQTT event handlers
mqtt_client.on_connect = on_connect
mqtt_client.on_message = on_message
# Connect to the broker
mqtt_client.connect(BROKER, 1884, 60)
mqtt_client.loop_start() mqtt_client.loop_start()
# Route for the main page
@app.route('/') @app.route('/')
def index(): def index():
# List of colors to display as buttons return render_template('index.html')
colors = ["red", "blue", "green"]
return render_template('index.html', colors=colors)
# Route to handle button press
@app.route('/publish', methods=['POST']) @app.route('/publish', methods=['POST'])
def publish(): def publish():
color = request.json.get("color") data = request.json
if color: topic = data.get("topic")
topic = f"/{color}" # Each color gets its own topic message = data.get("message")
mqtt_client.publish(topic, color)
return jsonify({"status": "success", "topic": topic, "color": color}) if topic and message in ["true", "false"]:
return jsonify({"status": "error"}), 400 mqtt_client.publish(topic, message)
return jsonify({"status": "success", "topic": topic, "message": message})
# Route to fetch log messages return jsonify({"status": "error", "message": "Invalid input"}), 400
@app.route('/logs', methods=['GET'])
def get_logs():
return jsonify(log_messages)
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=True)
......
...@@ -3,137 +3,122 @@ ...@@ -3,137 +3,122 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Selector</title> <title>MQTT Publisher</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<style> <style>
body { body {
font-family: 'Inter', sans-serif; font-family: Arial, sans-serif;
background-color: #f4f7fc;
margin: 0; margin: 0;
padding: 0; padding: 20px;
background-color: #f4f4f9;
color: #333;
} }
header {
background-color: #4a90e2; h1 {
color: white;
padding: 15px 20px;
text-align: center; text-align: center;
font-size: 24px; color: #333;
font-weight: 600;
} }
main {
max-width: 800px; .container {
margin: 20px auto; max-width: 500px;
margin: 0 auto;
background-color: white;
padding: 20px; padding: 20px;
background: white; border-radius: 8px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
border-radius: 10px;
} }
h1 {
font-size: 28px; label {
margin-bottom: 20px; font-size: 16px;
color: #4a90e2; margin-bottom: 8px;
display: block;
color: #555;
} }
.buttons-container {
display: flex; select {
flex-wrap: wrap; width: 100%;
justify-content: center; padding: 10px;
gap: 15px; margin-bottom: 20px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #fafafa;
} }
.color-button {
display: inline-block; button {
width: 120px; width: 100%;
height: 120px; padding: 12px;
background-color: #4CAF50;
color: white;
font-size: 16px;
border: none; border: none;
border-radius: 10px; border-radius: 5px;
cursor: pointer; cursor: pointer;
font-size: 18px; transition: background-color 0.3s;
font-weight: 600;
color: white;
text-transform: capitalize;
transition: transform 0.2s, box-shadow 0.2s;
} }
.color-button:hover {
transform: translateY(-3px); button:hover {
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2); background-color: #45a049;
} }
#log-container {
margin-top: 30px; .form-group {
margin-bottom: 20px;
} }
#log-container h2 {
font-size: 22px; .form-group:last-child {
margin-bottom: 15px; margin-bottom: 0;
} }
.log-item {
padding: 10px 15px; .message {
margin-bottom: 10px; font-size: 18px;
background-color: #f9f9f9; text-align: center;
border-left: 4px solid #4a90e2; margin-top: 20px;
border-radius: 5px;
font-size: 14px;
color: #555;
} }
</style> </style>
<script>
async function sendMessage() {
const topic = document.getElementById("topic").value;
const message = document.getElementById("message").value;
const response = await fetch('/publish', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ topic, message })
});
const result = await response.json();
alert(result.status === "success" ? "Message Sent!" : "Error Sending Message");
}
</script>
</head> </head>
<body> <body>
<header>Selector</header> <h1>MQTT Publisher</h1>
<main>
<h1>Select a Color</h1> <div class="container">
<div class="buttons-container"> <div class="form-group">
{% for color in colors %} <label for="topic">Topic:</label>
<button <select id="topic">
class="color-button" <option value="Red">Red</option>
style="background-color: {{ color }};" <option value="Green">Green</option>
onclick="sendColor('{{ color }}')"> <option value="Blue">Blue</option>
{{ color }} <option value="PickSuccess">PickSuccess</option>
</button> <option value="PlaceSuccess">PlaceSuccess</option>
{% endfor %} <option value="PickFail">PickFail</option>
</div> <option value="PlaceFail">PlaceFail</option>
<div id="log-container"> <option value="Stop">Stop</option>
<h2>Logs</h2> <option value="Sensor">Sensor</option>
<div id="logs"> </select>
<!-- Logs will be dynamically updated -->
</div>
</div> </div>
</main>
<script> <div class="form-group">
// Function to send color to the server <label for="message">Message:</label>
async function sendColor(color) { <select id="message">
try { <option value="true">true</option>
const response = await fetch('/publish', { <option value="false">false</option>
method: 'POST', </select>
headers: { </div>
'Content-Type': 'application/json',
},
body: JSON.stringify({ color: color }),
});
const result = await response.json();
if (result.status === "success") {
alert(`Color "${result.color}" sent successfully!`);
} else {
alert("Error sending color.");
}
} catch (error) {
console.error("Error:", error);
}
}
// Function to fetch logs <button onclick="sendMessage()">Publish</button>
async function fetchLogs() { </div>
try {
const response = await fetch('/logs');
const logs = await response.json();
const logsContainer = document.getElementById("logs");
logsContainer.innerHTML = logs.map(log => `<div class="log-item">${log}</div>`).join("");
} catch (error) {
console.error("Error fetching logs:", error);
}
}
// Fetch logs every 2 seconds
setInterval(fetchLogs, 2000);
</script>
</body> </body>
</html> </html>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment