Skip to main content
Summary

센서 하나가 집 전체의 규칙이 될 때

지금까지 라즈베리 파이는 LED를 켜고, 버튼을 읽고, 센서값을 저장하고, 웹 화면에 보여 주었다. 이제 한 단계 더 나아가 보자. IoT는 Internet of Things, 즉 사물인터넷이다. 어렵게 들리지만 핵심은 단순하다. 센서와 장치가 네트워크로 메시지를 주고받고, 그 메시지에 따라 자동으로 움직이는 구조다.

비유하면 집 안에 작은 메신저 방을 만드는 것이다. 온도 센서는 "거실 온도 29도"라고 말하고, 조명 장치는 "켜라"라는 메시지를 듣고 반응한다. 사람은 매번 터미널을 열지 않아도 된다. 규칙만 잘 만들어 두면 라즈베리 파이가 계속 듣고, 판단하고, 실행한다.

이번 장에서는 라즈베리 파이를 작은 스마트홈 허브처럼 사용한다. 목표는 세 가지다.

  • 온도값을 MQTT 메시지로 보내기

  • Node-RED에서 자동화 흐름 만들기

  • Home Assistant와 연결할 수 있는 구조 이해하기

주의: 릴레이로 220V 가전제품을 직접 제어하는 실습은 초보 단계에서 권장하지 않는다. 이 장에서는 LED, USB 팬, 저전압 DC 장치처럼 안전한 부품을 기준으로 설명한다.

IoT와 스마트홈으로 확장하기AI 생성 이미지

MQTT: 말하는 장치와 듣는 장치 사이의 우체국

MQTT는 IoT에서 자주 쓰는 가벼운 메시지 통신 방식이다. 구조는 세 가지로 이해하면 된다.

  • 브로커: 메시지를 받아서 필요한 장치에 전달하는 중간 서버

  • 발행: 어떤 주제로 메시지를 보내는 동작

  • 구독: 어떤 주제의 메시지를 듣겠다고 등록하는 동작

예를 들어 온도 센서가 home/livingroom/temperature라는 주제로 28.5를 발행한다. LED 제어 프로그램이나 대시보드는 이 주제를 구독하고 있다가 새 값을 받는다. MQTT는 이처럼 브로커를 중심으로 발행자와 구독자를 분리해 여러 장치가 느슨하게 연결되도록 만든다.1

먼저 라즈베리 파이에 MQTT 브로커인 Mosquitto를 설치한다.

sudo apt update
sudo apt install -y mosquitto mosquitto-clients
sudo systemctl enable --now mosquitto
sudo systemctl status mosquitto

상태 확인 화면에 active (running)이 보이면 브로커가 실행 중이다. q를 눌러 빠져나온다.

이제 터미널을 두 개 연다. 첫 번째 터미널에서는 메시지를 구독한다.

mosquitto_sub -h localhost -t home/livingroom/temperature

두 번째 터미널에서는 같은 주제로 메시지를 발행한다.

mosquitto_pub -h localhost -t home/livingroom/temperature -m "24.8"

첫 번째 터미널에 24.8이 나타나면 성공이다. 여기서는 같은 라즈베리 파이 안에서 테스트했기 때문에 브로커 주소로 localhost를 사용했다. 구조 자체는 네트워크 전체로 확장할 수 있지만, 최신 Mosquitto는 보안을 위해 기본 설정에서 로컬 접속만 허용하는 경우가 많다.2 즉 다른 라즈베리 파이, 노트북, 스마트홈 서버에서 이 브로커에 접속하려면 별도의 리스너 설정과 사용자 인증을 추가해야 한다.

처음 실습할 때는 지금처럼 localhost로 충분하다. 같은 집 안 네트워크의 다른 장치까지 연결하고 싶다면, 그때는 Mosquitto 설정 파일에 내부망용 리스너와 비밀번호 파일을 만들고 방화벽 범위를 확인한다. 아무 설정 없이 인터넷에 1883 포트를 열어 두는 방식은 피해야 한다.

주제 이름은 처음부터 규칙 있게 짓는 것이 좋다.

home/livingroom/temperature
home/livingroom/humidity
home/livingroom/led/set
home/bedroom/motion
home/kitchen/fan/set

home/공간/장치또는값/동작처럼 정하면 나중에 장치가 늘어나도 헷갈리지 않는다. 특히 값을 알려 주는 주제와 명령을 받는 주제를 구분해 두면 편하다. 예를 들어 온도는 temperature, LED 명령은 led/set처럼 나누는 식이다.

파이썬으로 온도값 발행하기

실제 온습도 센서를 연결해도 되지만, 여기서는 먼저 임의의 온도값으로 흐름을 확인한다. 앞에서 만든 센서 함수와 같은 자리에 실제 DHT22 코드나 다른 센서 코드를 넣으면 된다.

작업 폴더를 만든다.

mkdir -p ~/iot-smart-home
cd ~/iot-smart-home
python -m venv .venv
source .venv/bin/activate
pip install paho-mqtt gpiozero

temperature_publisher.py 파일을 만든다.

nano temperature_publisher.py

다음 코드를 입력한다.

import json
import random
import time
from datetime import datetime
from paho.mqtt import client as mqtt

BROKER = "localhost"
TOPIC = "home/livingroom/temperature"

client = mqtt.Client(callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
client.connect(BROKER, 1883, 60)
client.loop_start()

try:
    while True:
        value = round(random.uniform(22.0, 31.0), 1)
        payload = {
            "value": value,
            "unit": "C",
            "time": datetime.now().isoformat(timespec="seconds")
        }
        client.publish(TOPIC, json.dumps(payload), retain=True)
        print("published:", payload)
        time.sleep(5)
except KeyboardInterrupt:
    print("stopped")
finally:
    client.loop_stop()
    client.disconnect()

실행한다.

python temperature_publisher.py

다른 터미널에서 확인한다.

mosquitto_sub -h localhost -t home/livingroom/temperature

다음처럼 JSON 형태의 메시지가 보이면 된다.

{"value": 27.4, "unit": "C", "time": "2026-07-15T14:20:10"}

JSON은 여러 값을 이름과 함께 담는 표기 방식이다. 온도 숫자만 보내는 것보다 단위와 시간을 함께 보내면 Node-RED나 Home Assistant에서 처리하기 쉽다. 위 코드의 retain=True는 브로커가 마지막 메시지를 기억하게 하는 옵션이다. 새로 접속한 대시보드나 자동화 도구가 다음 측정까지 빈 화면으로 기다리지 않고 최근 값을 바로 받을 수 있어 센서값에 자주 사용한다.

MQTT로 LED 제어하기

이번에는 반대 방향이다. 라즈베리 파이가 명령을 듣고 LED를 켠다. 회로는 GPIO와 전자회로 첫걸음에서 사용한 기본 LED 회로와 같다.

준비물은 다음과 같다.

  • LED 1개

  • 330Ω 저항 1개

  • 점퍼선

  • 브레드보드

연결은 다음 순서로 한다.

  1. GPIO17 → 330Ω 저항

  2. 저항 → LED 긴 다리

  3. LED 짧은 다리 → GND

주의: LED에는 반드시 저항을 함께 연결한다. GPIO 핀에는 5V를 직접 넣지 않는다.

led_subscriber.py 파일을 만든다.

nano led_subscriber.py

다음 코드를 입력한다.

from gpiozero import LED
from paho.mqtt import client as mqtt

BROKER = "localhost"
TOPIC = "home/livingroom/led/set"

led = LED(17)


def on_connect(client, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    client.subscribe(TOPIC)


def on_message(client, userdata, msg):
    command = msg.payload.decode().strip().lower()
    print("received:", command)

    if command == "on":
        led.on()
    elif command == "off":
        led.off()
    else:
        print("use on or off")


client = mqtt.Client(callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, 60)

try:
    client.loop_forever()
except KeyboardInterrupt:
    led.off()
    client.disconnect()

실행한다.

python led_subscriber.py

다른 터미널에서 LED 켜기 명령을 보낸다.

mosquitto_pub -h localhost -t home/livingroom/led/set -m "on"

LED를 끄려면 다음처럼 보낸다.

mosquitto_pub -h localhost -t home/livingroom/led/set -m "off"

이제 중요한 구조가 완성되었다. 센서는 값을 발행하고, 장치는 명령을 구독한다. 대시보드, 자동화 도구, 다른 라즈베리 파이는 같은 주제를 통해 이 흐름에 끼어들 수 있다. 단, 다른 장치에서 접속할 때는 앞에서 말한 것처럼 브로커의 네트워크 접근 설정과 인증을 먼저 정리해야 한다.

Node-RED로 자동화 흐름 만들기

Node-RED는 코드를 길게 쓰지 않고 상자와 선을 연결해 자동화 흐름을 만드는 도구다. 각 상자를 노드라고 부른다. MQTT 입력 노드는 메시지를 구독하고, MQTT 출력 노드는 메시지를 발행한다. Node-RED에서는 센서값을 받아 조건을 검사한 뒤 다시 장치 제어 메시지를 보내는 흐름을 시각적으로 만들 수 있다.3

라즈베리 파이에 Node-RED를 설치한다.

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
sudo systemctl enable nodered.service
sudo systemctl start nodered.service

상태를 확인한다.

sudo systemctl status nodered.service

브라우저에서 다음 주소를 연다.

http://라즈베리파이IP주소:1880

예를 들어 라즈베리 파이 주소가 192.168.0.25라면 다음과 같다.

http://192.168.0.25:1880

이 주소는 Node-RED 편집 화면이다. 처음 실습할 때는 같은 집 안 Wi-Fi에서만 접속한다고 생각하자. 외부 인터넷에 바로 공개하기 전에 반드시 인증 설정을 해야 한다.

이제 다음 흐름을 만든다.

  1. mqtt in 노드 추가

    • Server: localhost:1883

    • Topic: home/livingroom/temperature

  2. json 노드 추가

    • 문자열 메시지를 JSON 객체로 바꾼다.

  3. switch 노드 추가

    • 조건: msg.payload.value가 28 이상

  4. change 노드 추가

    • msg.payload를 on으로 설정

  5. mqtt out 노드 추가

    • Topic: home/livingroom/led/set

  6. 필요하면 반대 조건 흐름을 하나 더 만들어 off를 보낸다.

오른쪽 위의 Deploy를 누른다. 앞에서 만든 temperature_publisher.py와 led_subscriber.py를 실행해 둔 상태라면, 온도값이 28도 이상일 때 LED가 켜진다.

다만 여기서 한 가지를 생각해 볼 필요가 있다. 위 흐름은 28도 이상일 때 on을 보내지만, 온도가 다시 낮아졌을 때 자동으로 끄는 흐름은 아직 없다. LED를 완전히 자동화하려면 msg.payload.value가 27 이하일 때 off를 보내는 반대 흐름도 함께 만드는 것이 좋다. 켜는 기준과 끄는 기준을 28도와 27도처럼 조금 다르게 두면, 온도가 28도 근처에서 오르내릴 때 LED가 너무 자주 깜박이는 일을 줄일 수 있다.

이 흐름은 매우 단순하지만 스마트홈 자동화의 기본형이다.

센서값 수신 → 조건 판단 → 장치 명령 발행

여기에 시간 조건, 버튼 입력, 움직임 감지, 카메라 감지 결과를 붙이면 더 현실적인 규칙이 된다.

Home Assistant와 연결하는 방향

Home Assistant는 여러 스마트홈 장치를 한곳에 모아 보여 주고 자동화하는 허브 소프트웨어다. 라즈베리 파이를 Home Assistant 전용 장비로 사용할 수도 있고, 다른 장치에서 실행 중인 Home Assistant가 라즈베리 파이의 MQTT 메시지를 받아 가게 만들 수도 있다.

처음에는 다음 두 가지 방향 중 하나를 고르면 된다.

  • 전용 스마트홈 허브: 별도의 라즈베리 파이에 Home Assistant OS를 설치한다.

  • 학습용 라즈베리 파이 유지: 지금 쓰는 Raspberry Pi OS에서 MQTT와 파이썬 코드를 실행하고, Home Assistant는 다른 장치나 별도 서버에서 연결한다.

Home Assistant 환경에서는 Mosquitto broker를 애드온으로 설치하고, Node-RED도 커뮤니티 애드온 등을 통해 함께 구성하는 방식이 널리 쓰인다.4 이 경우 MQTT가 센서, Node-RED, Home Assistant 사이의 공통 메시지 통로가 된다.

예를 들어 다음과 같이 역할을 나눌 수 있다.

  • 라즈베리 파이: 온도, 습도, 움직임, 카메라 감지 결과 발행

  • MQTT 브로커: 메시지 전달

  • Home Assistant: 대시보드 표시, 자동화 규칙 관리

  • Node-RED: 복잡한 조건 흐름 처리

  • LED, 팬, 조명 장치: 명령 주제 구독 후 동작

처음부터 모든 것을 Home Assistant에 넣으려고 하지 않아도 된다. 파이썬으로 센서값을 발행하고, Node-RED로 규칙을 만들고, 나중에 Home Assistant가 같은 MQTT 주제를 읽게 하면 된다.

외부 접속은 편리함보다 안전이 먼저다

스마트홈을 만들면 밖에서도 집 안 상태를 보고 싶어진다. 하지만 라즈베리 파이를 인터넷에 바로 노출하는 것은 위험하다. 특히 Node-RED 편집 화면, MQTT 브로커, Flask 개발 서버를 아무 인증 없이 공개하면 다른 사람이 장치를 제어하거나 설정을 바꿀 수 있다. Node-RED는 외부에 공개하기 전에 편집기 인증과 HTTP 노드 인증을 설정해야 한다.5

외부 접속 방식은 다음처럼 구분한다.

방식특징초보자 권장도
같은 집 안 Wi-Fi 접속내부망에서만 접근높음
포트 포워딩공유기에서 외부 요청을 라즈베리 파이로 직접 전달낮음
VPN내 기기만 집 안 네트워크에 들어온 것처럼 접속높음
클라우드 연동외부 서비스가 중간에서 연결중간
터널·리버스 프록시공개 HTTPS 주소를 만들어 내부 서비스에 연결설정 후 사용

초보자에게 가장 안전한 순서는 다음과 같다.

  1. 먼저 내부망에서만 동작하게 만든다.

  2. 비밀번호와 업데이트를 적용한다.

  3. 외부 접속이 필요하면 VPN을 먼저 검토한다.

  4. 포트 포워딩은 꼭 필요한 경우에만 사용한다.

  5. 공개 서비스에는 HTTPS, 강한 비밀번호, 접근 제한을 적용한다.

MQTT도 마찬가지다. 내부망에서는 보통 1883 포트를 사용하지만, 인터넷을 거쳐 MQTT 메시지를 보내야 한다면 TLS 암호화를 사용하는 8883 포트, 계정 인증, 접근 권한 설정을 고려해야 한다. 단순히 공유기에서 1883 포트를 열어 두는 방식은 피한다.

여러 장치를 하나의 규칙으로 묶기

이제 작은 사례를 설계해 보자. 목표는 "거실이 덥고 사람이 있으면 환기를 켜고, 밤에는 조명도 약하게 켠다"이다.

사용할 MQTT 주제는 다음과 같다.

home/livingroom/temperature
home/livingroom/humidity
home/livingroom/motion
home/livingroom/fan/set
home/livingroom/light/set
home/notify/message

규칙은 이렇게 만들 수 있다.

  1. 온도가 28도 이상이다.

  2. 습도가 70% 이상이거나 움직임이 감지된다.

  3. 조건을 만족하면 home/livingroom/fan/set에 on을 보낸다.

  4. 저녁 시간이라면 home/livingroom/light/set에 dim을 보낸다.

  5. 동시에 home/notify/message에 "거실 환기 시작"을 보낸다.

Node-RED에서는 이 규칙을 mqtt in, json, switch, function, mqtt out 노드로 구성할 수 있다. Home Assistant에서는 같은 조건을 자동화 규칙으로 만들 수 있다. 파이썬으로 직접 구현할 수도 있다.

중요한 것은 도구가 아니라 흐름이다.

측정한다 → 메시지로 보낸다 → 조건을 판단한다 → 장치를 움직인다 → 결과를 확인한다

이 흐름이 익숙해지면 라즈베리 파이는 단순한 실습용 컴퓨터가 아니라 집 안의 작은 자동화 관리자처럼 동작한다. 다음 장에서는 이런 프로그램들이 재부팅 후에도 계속 실행되도록 서비스로 등록하고, 로그와 보안을 관리하는 방법을 다룬다.

참고

1MQTT Setup | Set up Home Assistant with a Raspberry Pi | Adafruit Learning System

2Migrating from 1.x to 2.0 | Eclipse Mosquitto

3Working with MQTT in Node-RED: Complete Guide

4Node Red | Set up Home Assistant with a Raspberry Pi | Adafruit Learning System

5Self-Hosting Node-RED: Complete Guide to Installation, Security, and Remote Access

책 목록

라즈베리 파이 학습: 설치부터 GPIO, 웹 서버, IoT 프로젝트까지

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기