import network
import machine
import time
import ujson
# --- Настройка пинов ---
pir = machine.Pin(15, machine.Pin.IN)
led = machine.Pin(13, machine.Pin.OUT)
btn = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_UP)
# --- Переменные логики ---
motion_detected = False
last_motion_time = 0
led_state = False
btn_last = 1
# --- STATE ---
STATE = {
"DEVICE_ID": "LED-01",
"MODE": "NIGHT_AUTO",
"INPUT_LEVEL": 0,
"OUTPUT_LEVEL": 0,
"BRIGHTNESS": 5,
"COLOR": "warm_white",
"timer_duration": 40,
"IP": "offline"
}
MODES = ["NIGHT_AUTO", "DAY_AUTO", "MANUAL"]
# --- Wi-Fi ---
def connect_wifi():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("Wokwi-GUEST", "")
print("Подключение к Wi-Fi...")
timeout = 10
while not wlan.isconnected() and timeout > 0:
time.sleep(1)
timeout -= 1
print(".")
if wlan.isconnected():
ip = wlan.ifconfig()[0]
print("Wi-Fi подключён. IP:", ip)
STATE["IP"] = ip
else:
print("Wi-Fi недоступен (симулятор). Работа в офлайн-режиме.")
STATE["IP"] = "offline"
connect_wifi()
# --- Отправка состояния на сервер (имитация) ---
def send_state_to_server():
payload = ujson.dumps({
"device_id": STATE["DEVICE_ID"],
"mode": STATE["MODE"],
"input_value": STATE["INPUT_LEVEL"],
"output_value": STATE["OUTPUT_LEVEL"],
"brightness": STATE["BRIGHTNESS"],
"color": STATE["COLOR"]
})
print("[HTTP->SERVER] POST /api/update_state.php")
print("[PAYLOAD]", payload)
# --- Получение команды с сервера (имитация) ---
def get_command_from_server():
print("[HTTP->SERVER] GET /api/get_state.php?device_id=LED-01")
simulated_response = ujson.dumps({
"mode": STATE["MODE"],
"brightness": STATE["BRIGHTNESS"],
"color": STATE["COLOR"],
"output_value": STATE["OUTPUT_LEVEL"]
})
print("[SERVER->HTTP] Ответ:", simulated_response)
response = ujson.loads(simulated_response)
return response.get("mode", None)
# --- Применить режим ---
def apply_mode(mode):
if mode == "NIGHT_AUTO":
STATE["BRIGHTNESS"] = 5
STATE["COLOR"] = "warm_white"
STATE["timer_duration"] = 40
elif mode == "DAY_AUTO":
STATE["BRIGHTNESS"] = 30
STATE["COLOR"] = "neutral_white"
STATE["timer_duration"] = 15
elif mode == "MANUAL":
STATE["BRIGHTNESS"] = 100
STATE["COLOR"] = "custom"
STATE["timer_duration"] = 0
STATE["OUTPUT_LEVEL"] = 1
print("[РЕЖИМ ПРИМЕНЁН]", mode)
print_state()
# --- Вывод STATE ---
def print_state():
print(ujson.dumps(STATE))
# --- Смена режима кнопкой ---
def switch_mode():
current = STATE["MODE"]
if current in MODES:
idx = MODES.index(current)
next_mode = MODES[(idx + 1) % len(MODES)]
else:
next_mode = "NIGHT_AUTO"
apply_mode(next_mode)
STATE["MODE"] = next_mode
print("[MODE CHANGE] -> " + next_mode)
send_state_to_server()
print("========================================")
print("DEVICE BOOTED")
print("PIR GPIO 15, LED GPIO 13, BTN GPIO 14")
print("Current mode: " + STATE["MODE"])
print("Initial STATE:")
print_state()
print("Waiting for motion...")
print("========================================")
last_sync = time.time()
while True:
current_pir = pir.value()
btn_now = btn.value()
# --- Проверка команд с сервера каждые 5 секунд ---
now = time.time()
if now - last_sync >= 5:
last_sync = now
server_mode = get_command_from_server()
if server_mode and server_mode != STATE["MODE"]:
print("[КОМАНДА] Сервер требует режим:", server_mode)
STATE["MODE"] = server_mode
apply_mode(STATE["MODE"])
send_state_to_server()
# --- Кнопка ---
if btn_now == 0 and btn_last == 1:
motion_detected = False
led.value(0)
led_state = False
STATE["INPUT_LEVEL"] = 0
STATE["OUTPUT_LEVEL"] = 0
switch_mode()
btn_last = btn_now
mode = STATE["MODE"]
# --- FSM ---
if mode == "NIGHT_AUTO" or mode == "DAY_AUTO":
if current_pir == 1 and motion_detected == False:
motion_detected = True
last_motion_time = time.time()
led.value(1)
led_state = True
STATE["INPUT_LEVEL"] = 1
STATE["OUTPUT_LEVEL"] = 1
print("[MOTION STARTED] LED ON")
print_state()
send_state_to_server()
if current_pir == 1 and motion_detected == True:
last_motion_time = time.time()
if current_pir == 0 and motion_detected == True:
motion_detected = False
STATE["INPUT_LEVEL"] = 0
print("[MOTION STOPPED] Timer started")
print_state()
if motion_detected == False and led_state == True:
elapsed = time.time() - last_motion_time
if elapsed > STATE["timer_duration"]:
led.value(0)
led_state = False
STATE["OUTPUT_LEVEL"] = 0
print("[TIMER EXPIRED] LED OFF")
print_state()
send_state_to_server()
elif mode == "MANUAL":
if led_state == False:
led.value(1)
led_state = True
STATE["OUTPUT_LEVEL"] = 1
print("[MANUAL] LED forced ON")
print_state()
send_state_to_server()
else:
print("[ERROR] Unknown mode, fallback NIGHT_AUTO")
STATE["MODE"] = "NIGHT_AUTO"
apply_mode("NIGHT_AUTO")
print_state()
time.sleep(0.1)