Smartthings 공휴일 Edge 스위치 만들기

1. 개요

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

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

2. 준비물

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

3. edgebridge

edgebridge : https://github.com/toddaustin07/edgebridge

edgebridge에 대한 설명은 github를 참고하고 라즈베리파이나 NAS 등에 설치하면 된다.
나의 경우 라즈베리파이에 설치후 crontab에 아래와 같이 한줄을 추가하여 구동중이다.

@reboot sleep 10 && /home/pi/edgebridge/edgebridge4pi

4. lantrigger

lantrigger : https://github.com/toddaustin07/lantrigger

lantrigger Edge 드라이버로 가상 스위치를 생성할 수 있으며 외부에서 POST 요청을 통해 가상 스위치의 상태 변경이 가능하다.
나의 경우 lantrigger를 Wifi 공유기 연결시 재실 확인용으로 사용하고자 조금 수정하여 사용중인데 금번 공휴일 스위치 역시 해당 Edge 드라이버를 활용할 예정이다.

내가 수정한 Edge 드라이버는 "http://서버주소:8088/장치이름/in" 으로 POST 요청할 경우 스위치가 켜지고,
"http://서버주소:8088/장치이름/out" 로 POST 요청할 경우 꺼지도록 수정하였다.

Github : https://github.com/byjjoon/lantrigger
Channel : https://bestow-regional.api.smartthings.com/invite/JVMk3QBdgAMG

위 채널에서 Edge 드라이버를 설치하고 장치를 추가한다.
그리고 장치의 설정은 아래와 같이 한다.

User Name : dayoff
Server Address : python 스크립트가 동작하는 서버의 IP
Bridbe Address : edgebridge가 동작중인 서버의 IP:8088

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

def send_post(who, msg):
    #print(who + ' ' + msg)
    url = 'http://192.168.1.100:8088/' + who + '/' + msg
    requests.post(url)

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':
    send_post('dayoff', 'in')
    sys.exit()

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

# 공휴일 정보 조회
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:
            send_post('dayoff', 'in')
            sys.exit()

send_post('dayoff', 'out')

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

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

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

답글 남기기

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