Role & Tech Stack
나의 역할: 기획, 프론트엔드, 백엔드, 디바이스 연동, 자동화 구조, 배포 구조 설계
기술 스택: React 18, Vite, FastAPI, Python, SmartThings API, Xiaomi MIoT, python-miio, JWT, PWA, Nginx Proxy Manager
1. 기획 배경
집 안의 조명, 블라인드, 선풍기, 공기청정기처럼 제조사와 앱이 다른 IoT 기기를 가족이 한 화면에서 제어할 수 있도록 만들었습니다. 특정 제조사 앱에 의존하기보다, 실제 집에서 쓰는 기기들을 모바일 웹 중심으로 묶고 자동화까지 실행하는 것이 목표였습니다.
2. 핵심 기능
- 디바이스 제어: Xiaomi 선풍기, SmartThings 조명·스위치·블라인드 제어
- 자동화: 매일 특정 시간에 실행되는 Time trigger, 메인 씬 버튼으로 실행되는 Button trigger, 디바이스별 세부 액션 조합
- 계정: JWT 기반 다중 사용자 구조와 사용자별 디바이스·자동화·카드 정렬 저장
- SmartThings OAuth-In: 사용자가 본인 SmartThings 계정을 연결하고 토큰 갱신·만료 처리를 수행하는 구조
- UX: 모바일 우선 PWA UI, Pull-to-refresh, 카드 재배열, 위치 저장
- 날씨 위젯: 실시간 날씨와 시간별·일별 예보를 홈 화면에 표시
3. 시스템 구조
프론트엔드는 React 18과 Vite 기반의 단일 SPA로 구성했고, 백엔드는 FastAPI와 Python으로 구현했습니다. 디바이스 통신은 Xiaomi 기기의 경우 `python-miio` 로컬 통신을 사용했고, SmartThings 기기는 REST API와 OAuth 흐름을 통해 연동했습니다.
백그라운드에서는 FastAPI lifespan 기반으로 자동화 스케줄러가 실행되며, 사용자의 디바이스 설정과 자동화 정보는 JSON 상태 파일로 저장했습니다. 배포 환경에서는 HTTPS 리버스 프록시와 접근 제한 구조를 고려했습니다.
4. 나의 핵심 기여
- 모바일 우선 홈 화면, 디바이스 카드, 자동화 목록, 설정 화면 등 주요 UI 흐름 구성
- SmartThings와 Xiaomi처럼 다른 통신 방식을 공통 디바이스 action 구조로 정리
- 명령 실행, 상태 조회, 자동화 실행이 같은 백엔드 경로를 사용하도록 구조화
- 사용자별 카드 정렬, 디바이스 설정, 자동화 설정 저장 구조 구현
- LLM 자연어 명령을 디바이스 제어와 자동화 생성 흐름으로 연결하는 실험
5. 문제 해결
제조사별 기기 제어 방식 차이
SmartThings는 클라우드 API 중심이고 Xiaomi는 로컬 통신 중심이라 명령 방식이 달랐습니다. 백엔드에서 기기별 구현을 분리하고, 화면과 자동화는 공통 action 형태만 사용하도록 정리했습니다.
가족용 서비스의 접근 범위
외부 공개 서비스가 아니라 가족이 사용하는 사설 서비스이기 때문에, 인증과 접근 제한, HTTPS 프록시, 토큰 저장 범위를 함께 고려했습니다.
6. 회고
HomeIOT를 만들면서 실제 사용자가 반복적으로 쓰는 서비스에서는 버튼 하나의 위치, 새로고침 방식, 상태 표시 지연 같은 작은 부분도 중요하다는 것을 느꼈습니다. 또한 제조사별 API를 직접 다루며, 확장 가능한 추상화와 운영 중 장애 메시지 설계의 필요성을 배웠습니다.