Smartthings 공휴일 Edge 스위치 만들기

1. 개요

Smartthings는 2022년 10월 16일 16시(KST)부터 Groovy로 작성된 DTH와 스마트앱 지원이 종료된다고 공지되었다.
이에 현재 사용중인 다수 기기들과 스마트앱을 Edge Driver로 전환할 필요가 생겼다.
그 중 구글캘린더와 연동해서 부엉이님이 만드신 스마트앱을 대체해보았다.

My Day-off : https://blog.weekendproject.net/243

2. 준비물

라즈베리파이, NAS 등 개인 서버

3. MQTT Broker 설치

먼저 MQTT Broker와 파이썬용 MQTT 모듈을 설치한다.

$ sudo apt install mosquitto mosquitto-clients python3 python3-pip
$ pip3 install paho-mqtt

그리고 정상적으로 동작하는지 확인한다.

pi@raspberrypi:~ $ sudo systemctl enable mosquitto
Synchronizing state of mosquitto.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable mosquitto
pi@raspberrypi:~ $ sudo systemctl status mosquitto
● mosquitto.service - Mosquitto MQTT Broker
     Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2023-01-25 10:19:30 GMT; 23s ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
   Main PID: 1688 (mosquitto)
      Tasks: 1 (limit: 779)
        CPU: 78ms
     CGroup: /system.slice/mosquitto.service
             └─1688 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Jan 25 10:19:30 raspberrypi systemd[1]: Starting Mosquitto MQTT Broker...
Jan 25 10:19:30 raspberrypi systemd[1]: Started Mosquitto MQTT Broker.
pi@raspberrypi:~ $ 

그리고 Mosquitto 설정 파일(/etc/mosquitto/mosquitto.conf)에 아래 내용을 추가한다.

allow_anonymous true
bind_address 0.0.0.0

4. MQTTDevices

MQTTDevices : https://github.com/toddaustin07/MQTTDevices
Smartthings Edge Driver : https://bestow-regional.api.smartthings.com/invite/Q1jP7BqnNNlL

MQTTDevices Edge 드라이버로 MQTT 가상 스위치를 생성할 수 있으며 공휴일 여부를 체크해 스위치를 On/Off 하는 코드를 작성할 계획이다.

해당 Edge 드라이버 설치후 설정에서 위에서 설치한 MQTT Broker IP를 입력하자.
그리고 토픽은 "dayoff"로 명명할 계획이다.

5. 공공데이터포털

공공데이터포털 : https://www.data.go.kr/index.do

위 Edge 드라이버로 장치를 생성했다면 공휴일 여부를 알려줄 코드를 작성할 차례다.
나는 '공공데이터포털'을 활용해 매년 달라지는 대체공휴일이나 선거일들을 등을 받아오도록 하였다.
먼저 공공데이터포털에 가입하고 아래 링크에서 '활용신청' 버튼을 눌러 인증키를 받자.

한국천문연구원_특일 정보(xml) : https://www.data.go.kr/data/15012690/openapi.do

6. 서버 스크립트 작성

이제 서버 스크립트를 작성할 차례다. python으로 작성했고 다음과 같은 과정으로 휴일 여부를 체크했다.

오늘 날짜 확인 -> 토,일요일 체크 -> 공공데이터포털에서 해당 월 공휴일 날짜 추출 -> 공휴일 여부 체크

필요한 python 모듈들은 다음과 같다.

pip install requests
pip install BeautifulSoup4
pip install lxml
import requests
import datetime
from bs4 import BeautifulSoup
import urllib.parse as urlparse
import sys
import paho.mqtt.client as mqtt

def mqtt_pub(msg): 
    broker_address = 'localhost'
    broker_port = 1883
    client = mqtt.Client('Hello')
    print("[+] Connect to broker")
    client.connect(host=broker_address, port=broker_port)
    client.publish('dayoff', msg)

today = datetime.datetime.now().date()
year = today.strftime('%Y')
month = today.strftime('%m')
day = today.strftime('%d')
week = today.strftime('%w')
compare_today = today.strftime('%Y%m%d')

# 토, 일요일 여부 확인
if week == '0' or week == '6':
    mqtt_pub('on')
    sys.exit()

# 일반 인증키(Encoding)
serviceKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

# 공휴일 정보 조회
url = 'http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService'
operation = 'getRestDeInfo'
params = {
    'solYear':year,
    'solMonth':month
}
params = urlparse.urlencode(params)
req = url + '/' + operation + '?' + params + '&' + 'serviceKey' + '=' + serviceKey
get_data = requests.get(req)

if True == get_data.ok:
    soup = BeautifulSoup(get_data.content, 'xml')
    item = soup.findAll('item')
    #print(item)
    for x in item:
        #print(x.dateName.string, x.isHoliday.string, x.locdate.string)
        # 공휴일 여부 확인
        if compare_today == x.locdate.string:
            mqtt_pub('on')
            sys.exit()

mqtt_pub('off')

7. python 스크립트 스케쥴러 등록

마지막으로 작성한 스크립트가 주기적으로 동작하면서 스위치에 공휴일 여부 상태값을 반영시켜줘야 한다.
나는 라즈베리파이에서 구동중으로 crontab에 아래와 같이 등록해 1시간 단위로 업데이트 하도록 하였다.
참고로 crontab은 root 권한이 아닌 user 권한으로 등록해야 라이브러리를 불러오는데 문제가 없다.

1 * * * * /usr/bin/python3 /home/pi/dayoff/dayoff.py

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다