garage_door/main.py
2026-05-30 20:16:43 -05:00

238 lines
7.1 KiB
Python

import network
import socket
import time
import machine
import config
from machine import Pin
relay1 = Pin(config.RELAY1_PIN, Pin.OUT)
relay2 = Pin(config.RELAY2_PIN, Pin.OUT)
door_sensor1 = Pin(config.DOOR1_SENSOR_PIN, Pin.IN, Pin.PULL_UP)
door_sensor2 = Pin(config.DOOR2_SENSOR_PIN, Pin.IN, Pin.PULL_UP)
relay1.value(config.RELAY_OFF)
relay2.value(config.RELAY_OFF)
last_press_time = {"door1": 0, "door2": 0}
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(config.WIFI_SSID, config.WIFI_PASSWORD)
max_retries = 30
while not wlan.isconnected() and max_retries > 0:
time.sleep(1)
max_retries -= 1
if wlan.isconnected():
wlan.ifconfig((config.STATIC_IP, config.SUBNET, config.GATEWAY, config.DNS))
ip_address = config.STATIC_IP
else:
ip_address = None
def toggle_door(door_num):
current_time = int(time.time())
door_key = f"door{door_num}"
if current_time - last_press_time[door_key] < config.PRESS_COOLDOWN:
return False
last_press_time[door_key] = current_time
if door_num == 1:
relay1.value(config.RELAY_ON)
else:
relay2.value(config.RELAY_ON)
time.sleep(0.5)
if door_num == 1:
relay1.value(config.RELAY_OFF)
else:
relay2.value(config.RELAY_OFF)
return True
def get_door_status(door_num):
if door_num == 1:
sensor = door_sensor1
else:
sensor = door_sensor2
return "open" if sensor.value() == config.DOOR_OPEN else "closed"
def get_html(status1, status2, msg="", client_ip=""):
return (
"""<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Garage Door Control</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; padding: 30px; background-color: #f5f5f5; }
.door-section { background: white; padding: 20px; margin: 20px auto; max-width: 400px; border-radius: 10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
.status { font-size: 20px; margin: 15px; padding: 15px; border-radius: 8px; }
.open { background-color: #90EE90; }
.closed { background-color: #FFB6C1; }
button { font-size: 18px; padding: 15px 30px; cursor: pointer; background-color: #4CAF50; color: white; border: none; border-radius: 5px; }
button:hover { background-color: #45a049; }
button:disabled { background-color: #cccccc; cursor: not-allowed; }
.ip { margin-top: 30px; color: #666; }
.message { color: #ff6600; font-size: 16px; margin: 10px; }
.log-section {
background: white;
padding: 20px;
margin: 30px auto;
max-width: 600px;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
height: 250px;
display: flex;
flex-direction: column;
}
.log-section h2 { margin-top: 0; }
.log-box {
flex: 1;
width: 100%;
font-family: monospace;
font-size: 12px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
resize: none;
background-color: #1e1e1e;
color: #00ff00;
box-sizing: border-box;
overflow-y: scroll;
text-align: left;
}
.log-entry { margin: 2px 0; }
</style>
</head>
<body>
<h1>Garage Door Control</h1>
<div class="door-section">
<h2>Door 1</h2>
<div class="status """
+ status1
+ """">
Door is """
+ status1.upper()
+ """
</div>
<form method="POST">
<button type="submit" name="action" value="toggle1">Toggle Door 1</button>
</form>
</div>
<div class="door-section">
<h2>Door 2</h2>
<div class="status """
+ status2
+ """">
Door is """
+ status2.upper()
+ """
</div>
<form method="POST">
<button type="submit" name="action" value="toggle2">Toggle Door 2</button>
</form>
</div>
"""
+ ('<div class="message">' + msg + "</div>" if msg else "")
+ """
<div class="log-section">
<h2>Activity Log</h2>
<textarea id="logBox" class="log-box" readonly></textarea>
</div>
<div class="ip">IP: """
+ (ip_address or "Not connected")
+ """</div>
<script>
var clientIP = \""""
+ client_ip
+ """\";
function loadLog() {
var log = localStorage.getItem('garageDoorLog') || '';
document.getElementById('logBox').value = log;
document.getElementById('logBox').scrollTop = document.getElementById('logBox').scrollHeight;
}
function addLogEntry(door, ip) {
var now = new Date();
var timestamp = now.toLocaleString();
var entry = '[' + timestamp + '] Door ' + door + ' toggled from ' + ip + '\\n';
var log = localStorage.getItem('garageDoorLog') || '';
log = entry + log;
var lines = log.split('\\n').filter(function(line) { return line.trim(); });
if (lines.length > 100) {
log = lines.slice(0, 100).join('\\n') + '\\n';
}
localStorage.setItem('garageDoorLog', log);
loadLog();
}
loadLog();
document.querySelectorAll('form').forEach(function(form) {
form.addEventListener('submit', function() {
var action = form.querySelector('button').value;
var doorNum = action.replace('toggle', '');
addLogEntry(doorNum, clientIP);
});
});
</script>
</body>
</html>"""
)
def web_server():
addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(1)
while True:
try:
cl, addr = s.accept()
client_ip = addr[0]
request = cl.recv(1024)
request_str = request.decode("utf-8")
message = ""
if "POST" in request_str:
if "toggle1" in request_str:
if toggle_door(1):
message = ""
else:
message = "Please wait before pressing again"
elif "toggle2" in request_str:
if toggle_door(2):
message = ""
else:
message = "Please wait before pressing again"
status1 = get_door_status(1)
status2 = get_door_status(2)
response = get_html(status1, status2, message, client_ip)
cl.send("HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n")
cl.send(response)
cl.close()
except Exception as e:
pass
if __name__ == "__main__":
if ip_address:
print("Connected, IP:", ip_address)
web_server()
else:
print("Failed to connect to WiFi")