Умный дом: логика "если темно — включить свет"

Умный дом — это не магия, а набор простых правил: если случилось одно, сделай другое. Самое известное — «стемнело и кто-то вошёл — включи свет».

За дорогими системами умного дома прячется логика, которую ты можешь написать за десять строк: датчики дают условия, программа принимает решения.

Когда слышишь «умный дом», в голове рисуется что-то футуристическое и недосягаемое. На деле же 90% такой «магии» — это правила вида «если-то», которые ты уже умеешь писать. «Если темно и есть движение — включи свет». «Если влажность упала — включи увлажнитель». «Если открыли дверь ночью — пришли уведомление». Дорогие коробки в магазине делают ровно это, просто прячут логику за красивым приложением. Собрав такой сценарий сам, ты понимаешь, что внутри нет ничего волшебного, — и это самое ценное знание из всего курса.

Соберём классический сценарий: свет включается автоматически, когда в комнате темно и есть движение, и выключается, когда движения нет какое-то время. Нам нужны датчик освещённости и датчик движения, оба подключаются как уже знакомые компоненты. Заметь, как переиспользуется всё, что мы изучили раньше: PIR из урока про движение, фоторезистор из урока про датчики. Умный дом — это не новый набор деталей, а новая комбинация уже знакомых.

Как работает под капотом

   [Датчик света] --+
                    |--> [ЛОГИКА умного дома] --> [Реле] --> Лампа
   [Датчик движ.] --+        (правила)

На Pi свет переключают через реле — электронный выключатель, которым управляет GPIO (мощную лампу нельзя питать с пина напрямую). Реле — это, по сути, маленький управляемый рубильник: слабый сигнал 3.3В с пина притягивает внутри катушку, та замыкает контакты, и через них уже течёт «взрослый» ток сетевой лампы. Так пин управляет мощной нагрузкой, не касаясь её напрямую и оставаясь в безопасности. Щелчок, который ты слышишь от реле, — это и есть момент замыкания контактов.

   GPIO 3.3В  ->  катушка реле  ->  замыкает контакт
                                        |
                          220В сеть  -> контакт -> Лампа

Управление реле — пример для платы:

from gpiozero import OutputDevice, MotionSensor, LightSensor

relay = OutputDevice(18)
pir = MotionSensor(23)
light = LightSensor(24)
# дальше — правила в коде

А самое интересное — правила принятия решений — отладим в браузере. Это чистая логика «если/иначе». Попробуй сам ▶

# Логика умного дома: если темно И есть движение -> включить свет
def decide(is_dark, motion, light_on):
    if is_dark and motion:
        return True               # включаем/держим свет
    if not motion:
        return False              # нет движения -> гасим
    return light_on               # иначе оставляем как было

# прогон сценария: (темно?, движение?)
scenario = [
    (False, True),   # день, кто-то вошёл -> свет не нужен
    (True,  True),   # темно и движение -> включить
    (True,  True),   # всё ещё тут -> держим
    (True,  False),  # ушли -> гасим
    (True,  False),  # темно, но пусто -> не включаем
]

light_on = False
for is_dark, motion in scenario:
    light_on = decide(is_dark, motion, light_on)
    print(f"темно={is_dark}, движение={motion} -> свет {'ВКЛ' if light_on else 'выкл'}")

Обрати внимание: днём (светло) свет не включается даже при движении — оба условия должны совпасть. Это и есть мощь логики «И».

Реальная жизнь сложнее одного «если»: если гасить свет в ту же секунду, как PIR перестал видеть движение, лампа будет моргать каждый раз, когда ты замер над книгой. Лекарство — задержка выключения: после пропажи движения держим свет ещё несколько секунд и гасим, только если за это время никто не появился. Отрепетируем эту задержку на чистом Python. Попробуй сам ▶

# Задержка выключения: гасим не сразу, а через delay секунд тишины
events = [(0, True), (1, False), (2, False), (6, False), (10, True), (11, False)]
delay = 4
last_motion = -100
light_on = False

for t, motion in events:
    if motion:
        last_motion = t
        light_on = True
    elif (t - last_motion) >= delay:
        light_on = False
    print(f"t={t:2d}: движение={motion} -> свет {'ВКЛ' if light_on else 'выкл'}")

Частые ошибки

  • Включают мощную лампу с пина. Нужно реле — пин не выдержит ток сетевой лампы.
  • Свет мигает на границе. Если датчик света на грани «темно/светло», добавь гистерезис (порог с запасом).
  • Гаснет мгновенно. Добавь задержку перед выключением, иначе свет погаснет, пока ты стоишь неподвижно.
  • Сам свет лампы влияет на датчик. Если фоторезистор «видит» включённую лампу, он решит, что стало светло, и устроит мигание — разнеси их или учитывай в логике.
  • Лезут к проводке 220В без взрослых. Сетевое напряжение опасно; учебные сценарии лучше отлаживать на светодиоде или реле с низковольтной нагрузкой.

Best practices

  • Выноси правила в отдельную функцию decide() — её легко тестировать без железа.
  • Добавь задержку выключения и гистерезис, чтобы свет не дёргался.
  • Логируй решения, чтобы понимать, почему свет включился.
  • Сначала проверяй сценарий на наборе тестовых ситуаций (как в примерах), и только потом подключай реле.
  • Предусмотри ручной выключатель-«перебивку», чтобы человек всегда мог пересилить автоматику.

Главный вывод этого урока — архитектурный. Мы отделили «измерить» (датчики), «решить» (функция decide) и «сделать» (реле). Благодаря этому разделению логику можно полностью отладить на компьютере без единого провода, а потом смело переносить на Pi. Так устроены не только лампы, но и системы посерьёзнее: термостаты, теплицы, аквариумы с автокормушкой. Освоив этот шаблон, ты получил универсальную отмычку к любому проекту автоматизации.

Итоги. Умный дом — это правила «если условие — действие». Свет включается по совпадению «темно И движение», мощную нагрузку коммутируют через реле, а задержка выключения и гистерезис спасают от мигания. Логику легко отладить на чистом Python, отделив её от железа. Дальше добавим расписание и таймеры.

Проверьте себя
1. При каком условии свет включается в сценарии "если темно — включить"?
AПри любом движении
BТолько когда одновременно темно И есть движение
CКогда светло
DПо расписанию
2. Почему мощную сетевую лампу нельзя включать прямо с пина GPIO?
AПин слишком умный
BПин не выдержит ток и напряжение сетевой лампы — нужно реле как промежуточный выключатель
CЛампа сломает Python
DМожно, без проблем