coffee/return

This commit is contained in:
derlole
2025-05-09 10:50:40 +00:00
parent a02ed0fe08
commit 416d30ae1c
10 changed files with 149 additions and 82 deletions

View File

@@ -1,63 +0,0 @@
import urequests
import json
import socket
import network
import time
import ubinascii
from umqtt.simple import MQTTClient
import machine
host = "lires.de"
# one time dns resolve, damit der arme ESP und nicht wegkocht.
def resolve_ip(hostname):
try:
print(f"🌐 Resolvieren von '{hostname}' ...")
addr_info = socket.getaddrinfo(hostname, 80)
ip = addr_info[0][4][0]
print(f"🔎 IP-Adresse gefunden: {ip}")
return ip
except Exception as e:
print("❌ Fehler beim Resolvieren:", e)
return None
ip = resolve_ip(host)
if ip is None:
print("❌ Fehler: IP-Adresse konnte nicht aufgelöst werden.")
raise SystemExit(1)
MQTT_BROKER = ip
MQTT_TOPIC = b'iot/testdata'
#callback
def mqtt_callback(topic, msg):
print("Neue Nachricht:", msg.decode())
#send data to the server on the given url
def main():
client_id = ubinascii.hexlify(machine.unique_id())
client = MQTTClient(client_id, MQTT_BROKER)
client.set_callback(mqtt_callback)
client.connect()
client.subscribe(MQTT_TOPIC)
print("Warte auf Nachrichten...")
try:
while True:
client.wait_msg() # blockiert, bis Nachricht ankommt
finally:
client.disconnect()
main()
while True:
{
}

BIN
db/coffee.db Normal file

Binary file not shown.

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Dieses Skript erstellt eine SQLite-Datenbank mit einer Tabelle für Befehle.
import os
import sqlite3
db_folder = "db"
db_filename = "coffee.db"
db_path = os.path.join(db_folder, db_filename)
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Tabelle erstellen mit entsprechenden Atributen
cursor.execute("""
CREATE TABLE IF NOT EXISTS commands (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user TEXT NOT NULL,
status TEXT NOT NULL,
tstamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
""")
conn.commit()
conn.close()
print(f"[DB]Datenbank erstellt unter: {db_path}")

View File

@@ -4,19 +4,14 @@
import os
import sqlite3
# Ordner und Pfad definieren
db_folder = "db"
db_filename = "commands.db"
db_path = os.path.join(db_folder, db_filename)
# Ordner erstellen, falls nicht vorhanden
os.makedirs(db_folder, exist_ok=True)
# Verbindung zur SQLite-Datenbank
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Tabelle erstellen
# Tabelle erstellen mit entsprechenden Atributen
cursor.execute("""
CREATE TABLE IF NOT EXISTS commands (
id INTEGER PRIMARY KEY AUTOINCREMENT,

View File

@@ -1,8 +1,9 @@
{
"state": "idle",
"state": "OFF",
"connected": false,
"ready": false,
"peding_command": false,
"error": false,
"berror": false,
"error": "",
"lastConnectionProof": "2025-05-06 20:56:49.436343+00:00"
}

View File

@@ -57,7 +57,6 @@ def on_message(client, userdata, msg):
print(f"[MQTT] Unbekanntes Topic: {msg.topic}")
return
# MQTT-Thread
def mqtt_thread():
client = mqtt.Client()
@@ -100,15 +99,22 @@ def clear_commands_db():
import os
import sqlite3
db_path = os.path.join(os.path.dirname(__file__), "db", "commands.db")
db_path_command = os.path.join(os.path.dirname(__file__), "db", "commands.db")
db_path_coffee = os.path.join(os.path.dirname(__file__), "db", "coffee.db")
if os.path.exists(db_path):
conn = sqlite3.connect(db_path)
if os.path.exists(db_path_command):
conn = sqlite3.connect(db_path_command)
cursor = conn.cursor()
cursor.execute("DELETE FROM commands")
conn.commit()
conn.close()
print("[DB] commands-Tabelle geleert.")
conn = sqlite3.connect(db_path_coffee)
cursor = conn.cursor()
cursor.execute("DELETE FROM coffee")
conn.commit()
conn.close()
print("[DB] coffee-Tabelle geleert.")
else:
print("[DB] Keine Datenbank gefunden nichts geleert.")

View File

@@ -21,7 +21,24 @@ gebId("ip_global").innerText = esp_conn_infos.ip_global
gebId("ip_local").innerText = esp_conn_infos.ip_local
gebId("valid_connection").innerText = esp_conn_infos.connection_valid
gebId("last_seen").innerText = esp_conn_infos.last_seen
machienReady = gebId("machine-ready-butt")
makeCoffee = gebId("make-coffee-butt")
if(machine.status == "OFF"){
gebId("machine-status").innerText = "AUS";
gebId("machine-status-butt").classList.add("initBackRed");
}
if(machine.berror){
gebId("machine-error-butt").classList.add("initBackRed");
gebId("machiene-error-text").innerText = machine.error;
}
if(machine.ready && machine.state == "ON" && !machine.berror && esp_conn_infos.connection_valid){
makeCoffee.classList.remove("deniePress");
}
if(machine.ready){
machienReady.classList.remove("initBackRed");
machienReady.classList.add("initBackGreen");
gebId("machiene-ready-text").innerText = "Bereit";
}
if (esp_conn_infos.connection_valid) {
gebId("validButt").classList.add("deniePress");
gebId("machine-status-butt").classList.remove("deniePress");
@@ -34,7 +51,33 @@ if (water.fill < 20) {
if (beans.fill < 20) {
gebId("beans-fill").parentElement.classList.add("blink-orange");
}
//all there given if generated html manipulations are not else-ed because the else condition is always in the dafult.
//If later information is changed and should manipulate the html, it will come through socketio.js
switch (machine.state) {
case "ON":
gebId("machine-status").innerText = "AN";
gebId("machine-status-butt").classList.remove("blink-orange");
gebId("machine-status-butt").classList.remove("initBackRed");
gebId("machine-status-butt").classList.add("initBackGreen");
break;
case "PENDING":
gebId("machine-status").innerText = "WARTEN";
gebId("machine-status-butt").classList.add("blink-orange");
gebId("machine-status-butt").classList.remove("initBackRed");
gebId("machine-status-butt").classList.remove("initBackGreen");
break;
case "OFF":
gebId("machine-status").innerText = "AUS";
gebId("machine-status-butt").classList.remove("blink-orange");
gebId("machine-status-butt").classList.add("initBackRed");
gebId("machine-status-butt").classList.remove("initBackGreen");
break;
default:
gebId("machine-status").innerText = "UNBEKANNT";
gebId("machine-status-butt").classList.add("initBackRed");
}
// All there
function toggleMachine() {
if (gebId("machine-status-butt").classList.contains("deniePress")){
return;

View File

@@ -15,6 +15,30 @@ socket.on('static_data', (data) => {
gebId("ip_local").innerText = data.esp_conn_infos.ip_local
gebId("valid_connection").innerText = data.esp_conn_infos.connection_valid
gebId("last_seen").innerText = data.esp_conn_infos.last_seen
switch (data.machine.state) {
case "ON":
gebId("machine-status").innerText = "AN";
gebId("machine-status-butt").classList.remove("blink-orange");
gebId("machine-status-butt").classList.remove("initBackRed");
gebId("machine-status-butt").classList.add("initBackGreen");
break;
case "PENDING":
gebId("machine-status").innerText = "WARTEN";
gebId("machine-status-butt").classList.add("blink-orange");
gebId("machine-status-butt").classList.remove("initBackRed");
gebId("machine-status-butt").classList.remove("initBackGreen");
break;
case "OFF":
gebId("machine-status").innerText = "AUS";
gebId("machine-status-butt").classList.remove("blink-orange");
gebId("machine-status-butt").classList.add("initBackRed");
gebId("machine-status-butt").classList.remove("initBackGreen");
break;
default:
gebId("machine-status").innerText = "UNBEKANNT";
gebId("machine-status-butt").classList.add("initBackRed");
}
if (data.water.fill < 20) {
gebId("water-fill").parentElement.classList.add("blink-orange");
}else {
@@ -34,4 +58,28 @@ socket.on('static_data', (data) => {
gebId("infoMain").classList.add("blink-orange");
gebId("machine-status-butt").classList.add("deniePress");
}
if(data.machine.berror){
gebId("machine-error-butt").classList.add("initBackRed");
gebId("machiene-error-text").innerText = machine.error;
}
else {
gebId("machine-error-butt").classList.remove("initBackRed");
gebId("machiene-error-text").innerText = "";
}
machienReady = gebId("machine-ready-butt")
makeCoffee = gebId("make-coffee-butt")
if(data.machine.ready && data.machine.state == "ON" && !data.machine.berror && data.esp_conn_infos.connection_valid){
makeCoffee.classList.remove("deniePress");
}else {
makeCoffee.classList.add("deniePress");
}
if(data.machine.ready){
machienReady.classList.add("initBackRed");
machienReady.classList.remove("initBackGreen");
gebId("machiene-ready-text").innerText = "Bereit";
}else {
machienReady.classList.remove("initBackRed");
machienReady.classList.add("initBackGreen");
gebId("machiene-ready-text").innerText = "Nicht bereit";
}
});

View File

@@ -226,6 +226,12 @@ background-color: red;
.initBackRed:Hover{
background-color: rgb(252, 47, 47);
}
.initBackGreen {
background-color: green;
}
.initBackGreen:hover {
background-color: rgb(0, 151, 0);
}
.deniePress:hover{
cursor: not-allowed;
}
@@ -252,6 +258,10 @@ background-color: red;
.validButt:hover.deniePress{
background-color: green !important;
}
.initBackGreen:hover.deniePress {
background-color: green !important;
cursor: not-allowed;
}
.deniePress:hover{
cursor: not-allowed;
}

View File

@@ -44,22 +44,22 @@
</div>
</div>
<div class="button-grid">
<div class="grid-button deniePress">
<div class="grid-button deniePress" id="make-coffee-butt">
<div class="top-left-text">Kaffeeee</div>
<div class="center-number">Kaffee Machen</div>
</div>
<div class="grid-button initBackRed deniePress" id="machine-status-butt" onclick="toggleMachine()">
<div class="grid-button deniePress" id="machine-status-butt" onclick="toggleMachine()">
<div class="top-left-text">Maschine</div>
<div class="center-number" id="machine-status">AUS</div>
</div>
<div class="grid-button deniePress">
<div class="grid-button deniePress initBackRed" id="machine-ready-butt">
<div class="top-left-text">Maschine</div>
<div class="center-number">Nicht Bereit</div>
<div class="center-number" id="machiene-ready-text">Nicht Bereit</div>
</div>
<div class="grid-button deniePress">
<div class="grid-button deniePress" id="machine-error-butt">
<div class="top-left-text">Fehler</div>
<div class="center-number">Wasser leer?</div>
<div class="center-number" id="machiene-error-text">Keiner</div>
</div>
<div class="grid-button defaultGray">
<div class="top-left-text">Wasser</div>