개요
이전에 작성된 포스트(아두이노 연동 시리즈) 는 아두이노 보드의 센서에서 수집한 데이터를 InfluxDB 에 저장한 다음 Grafana 대시보드에서 온습도 데이터를 확인하였다.
별도 스마트 기기가 없어 아두이노 하드웨어와 소프트웨어를 직접 구성해서 데이터를 처리하였다.
SmartThings 가 연동되는 가전이 있는 경우 안드로이드 스마트폰의 SmartThings 앱을 통해 너무나도 편리하게 조작하고 상태를 확인할 수 있으며,
필요하면 루틴을 추가해서 내가 원하는 대로 자동화가 가능하다.
일단 이 글을 처음 작성하는 2025년 4월 초를 기준으로 보면
전력 사용량 및 요금에 대해서는 데이터가 누적해서 저장이 되면서 지난 사용량도 확인이 가능한 반면
온도나 습도에 대해서는 전력 사용량처럼 지난 데이터는 확인이 불가능 하다.
굳이 지나간 온도나 습도를 알아서 뭐하겠어 라고 할 수 있다.
하지만, 굳이 해보고 싶어서 관련 자료를 찾아보고 마지막으로 정착한 환경에 대해 설명해 보고자 한다.
아두이노 연동 시리즈
아두이노 온습도 센서에서 수집된 데이터로 대시보드를 구성하는 과정을 살펴보겠습니다
총 7개의 포스트로 이루어지며 아래 글목록을 보시면 확인이 가능합니다.
- 시스템 개요
- [Mosquitto] MQTT 프로토콜로 데이터를 발행 및 구독하기 위한 MQTT broker 를 구성합니다.
- [Arduino] 아두이노 보드에 온습도 센서를 연결해서 MQTT 프로토콜로 발행하는 코드를 작성합니다.
- (Docker-compose) [Influxdb+Telegraf+Grafana] 대시보드 구성을 위한 시스템은 도커 컴포즈로 일괄 관리합니다.
- [Influxdb] 온습도 데이터를 저장할 데이터베이스를 구성합니다.
- [Telegraf] MQTT broker 의 데이터를 수신해서 Influx DB 에 저장할 Agent 를 구성합니다.
- [Grafana] 데이터베이스에 저장된 데이터를 사용해서 대시보드를 구성합니다.
기기 구성
작은 방에서는 아두이노 보드와 센서가 온도와 습도를 모니터링 했다면
거실에 설치된 에어컨에서는 온도와 습도를 수집하고
드레스룸에 설치된 제습기에서는 습도 데이터를 수집한다.

자료 검색 – 1차
SmartThings 의 경우 API 가 오픈되어 있기 때문에 검색해보면 다양한 언어로 연동이 되는 것을 확인할 수 있다.
참조할 코드가 필요해서 C# 으로 구현된 것을 검색해보면 다음 Github 프로젝트가 검색이 된다.
그리고 위 프로젝트를 사용한 프로젝트 중에 터미널 형태로 구현된 다음 프로젝트를 찾을 수 있다.
SmartThings Terminal 프로젝트의 경우 Fork 해서 token 만 수정해서 실행해 보면 내 디바이스 목록과
디바이스 상태 정보를 조회할 수 있게 잘 구현되어 있다.
2개의 프로젝트 모두 마지막 Commit 이 좀 지난 상태여서 그런지 내 기기의 경우 100% 완벽하게 모두 구현되어 있는 것은 아닌 것 같다.
하지만, 내가 필요한 건 전원 상태와 온도, 습도 데이터이기 때문에 다행히 모두 지원이 되는 것을 확인했다.
자료 검색 – 2차
이미 구현된 코드가 제대로 동작하는 것을 확인했고, 직접 구현 할려다가 C# 언어에 국한하지 않고 좀 더 검색을 해보니
내가 딱 원하던 프로젝트를 발견했다.
Go 언어로 구현된 프로젝트이며 Docker 로도 배포가 되어 있다.
연동 방식을 보면 SmartThings 에서 데이터를 조회해서 InfluxDB 에 저장하는 방식으로 구현되어 있다.
나는 이미 Docker 에 InfluxDB 가 구축되어 있는 상황이라 훨씬 간단하게 처리가 가능하다.
구현
smartthings-influx 프로젝트를 사용해서 기존 Docker Stacks 에 추가해서 완성하기로 한다.
컨테이너 폴더 추가
먼저 smartthings 폴더를 추가한다.

모니터링 설정 파일 작성
smartthings-influx-compose.yaml 파일을 다음과 같이 작성해서 해당 폴더에 저장한다.
온도와 습도, switch(전원상태)를 10분 단위로 측정해서 InfluxDB 의 지정된 Bucket 에 저장하는 설정이다.
일단 모든 권한을 추가해서 새로 생성하였다.
[[InfluxDBUrl] 도 기존 환경에 맞춰서 수정해야 한다.
apitoken: [[SmartThingsToken]]
monitor:
- temperatureMeasurement
- relativeHumidityMeasurement
smartthings:
capabilities:
- name: switch
time: wall
period: 600 # 10분 단위
database:
type: influxdbv2
url: [[InfluxDBUrl]
token: [[InfluxDBToken]]
org: Telegraf
bucket: SmartThings
valuemap:
switch:
off: 0
on: 1
해당 Bucket 의 Read, Write 권한을 가지는 토큰을 생성한다.

컨테이너 서비스 추가 및 시작
Docker Stacks 루트 폴더의 docker-compose.yaml 파일에 다음과 같이 smartthings 서비스를 추가해 주었다.
마찬가지로 [[SmartThingsToken]] 부분을 치환해 준다.
해당 컨테이너를 시작한 다음 데이터가 저장되기를 기다려준다.
period(10분) 설정을 고려해야 한다.
smartthings:
image: eargollo/smartthings-influx:latest
container_name: smartthings
environment:
- APITOKEN=[[SmartThingsToken]]
volumes:
- ./smartthings/smartthings-influx-compose.yaml:/.smartthings-influx.yaml
command: monitor
depends_on:
- influxdb
데이터 확인
InfluxDB 의 Data Explorer 메뉴에서 다음과 같이 조회가 가능하다.
일단 InfluxDB 에 제대로 저장이 되는 것을 먼저 확인했다.

Grafana 대시보드 구현
이미 구현된 대시보드의 같은 Chart 에서 동시에 확인하기 위해 기존 패널에 Chart Series 만 추가해 주었다.
온도
다음과 같이 에어컨 온도 쿼리를 추가해 주었다.
from(bucket: "SmartThings")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "temperature")
|> filter(fn: (r) => r["device"] == "에어컨")
|> filter(fn: (r) => r["capability"] == "temperatureMeasurement")
|> filter(fn: (r) => r["_field"] == "value")
|> toFloat()
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> yield(name: "mean")
다음과 같이 온도를 동시에 확인이 가능하다.

습도
에어컨 습도 쿼리는 다음과 같다
from(bucket: "SmartThings")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "humidity")
|> filter(fn: (r) => r["device"] == "에어컨")
|> filter(fn: (r) => r["capability"] == "relativeHumidityMeasurement")
|> filter(fn: (r) => r["_field"] == "value")
|> toFloat()
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> yield(name: "mean")
제습기 습도 쿼리는 다음과 같다.
from(bucket: "SmartThings")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "humidity")
|> filter(fn: (r) => r["device"] == "제습기")
|> filter(fn: (r) => r["capability"] == "relativeHumidityMeasurement")
|> filter(fn: (r) => r["_field"] == "value")
|> toFloat()
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> yield(name: "mean")
다음과 같이 습도를 동시에 확인이 가능하다.

대시보드
대시보드의 UI 는 매번 바뀌지만 현재 상태는 다음과 같다.
필요한 데이터만 선별해서 위치별로 현재 상태 및 과거 기록까지 확인이 가능하다.

0 Comments