가족 사진 액자형 IoT 디바이스, 낙상 감지, 건강 데이터, 음성 메시지를 연결한 헬스케어 AIoT 돌봄 서비스
EEUM은 독거 중인 피부양자와 떨어져 지내는 가족을 연결하기 위한 헬스케어 AIoT 서비스입니다. 평상시에는 가족 사진과 메시지를 보여주는 액자형 디바이스로 동작하고, 위험 상황이 감지되면 보호자 앱과 서버, IoT 장치가 함께 대응 흐름을 만듭니다.
- 2026.01 - 2026.02
- 낙상, 무응답, 심박 이상과 같은 위험 상황은 발생 직후 발견과 공유가 어렵습니다.
- 기존 알림 중심 서비스는 위험 감지 이후 누가 확인했고 어떤 조치를 했는지 남기기 어렵습니다.
- 피부양자가 감시 대상처럼 느끼지 않도록, 일상 공간에 자연스럽게 놓이는 디바이스 경험이 필요했습니다.
- 카메라, PIR 센서, 웨어러블 데이터를 활용해 위험 상황을 감지하고 보호자에게 전달합니다.
- 가족 그룹, 일정, 복약, 메시지, 앨범을 한 흐름으로 묶어 돌봄 정보를 공유합니다.
- 라즈베리파이 디바이스가 서버와 동기화되며 사진 슬라이드, 음성 안내, 위험 알림을 수행하도록 구성합니다.
| 기능 | 설명 |
|---|---|
| 낙상 감지 | Jetson/Edge 앱에서 YOLO Pose 기반 관절 정보를 분석하고 낙상 이벤트를 서버로 전송합니다. |
| 보호자 알림 | 낙상, IoT 이벤트, 건강 측정 요청을 Firebase FCM과 앱 알림으로 전달합니다. |
| 가족 앨범 | 보호자가 업로드한 사진을 S3에 저장하고 라즈베리파이 디바이스와 동기화합니다. |
| 음성 메시지 | 가족 메시지를 RunPod 기반 TTS 작업으로 생성하고 디바이스에서 재생할 수 있게 동기화합니다. |
| 건강 데이터 연동 | Android 앱에서 Samsung Health 데이터를 수집해 심박수와 건강 지표를 서버에 저장합니다. |
| 일정·복약 관리 | 방문 일정, 생일, 복약 정보를 관리하고 디바이스로 일정 알림을 전송합니다. |
- 보호자가 앱에서 가족 그룹, 일정, 앨범, 음성 메시지를 등록합니다.
- 서버는 데이터 변경 로그를 남기고 IoT 장치에 동기화 알림을 보냅니다.
- 라즈베리파이는 필요한 앨범·음성 데이터를 내려받아 액자 화면과 음성 안내에 반영합니다.
- 엣지 앱이 낙상 의심 상황을 감지하면 서버에 이벤트를 전송합니다.
- 서버는 건강 데이터 요청, 보호자 FCM 알림, 낙상 기록 저장을 수행합니다.
eeum/
├── backend/ # Spring Boot API 서버
│ └── src/main/java/org/ssafy/eeum/
│ ├── domain/ # auth, family, health, iot, message, schedule, voice 등 도메인
│ └── global/ # security, jwt, redis, mqtt, s3, fcm, exception 설정
├── frontend/ # Vue 3 웹 프론트엔드
│ └── src/
│ ├── views/ # 화면 단위 페이지
│ ├── components/ # 공통 UI 컴포넌트
│ ├── stores/ # Pinia 상태 관리
│ └── services/ # Axios API 모듈
├── mobile/ # Android 앱 및 Wear OS 모듈
│ ├── app/ # WebView 기반 Android 앱, FCM, Samsung Health 연동
│ └── wear/ # Wear OS 심박 측정 서비스
├── IoT/ # 라즈베리파이, ESP32, 디바이스용 프론트엔드
│ ├── apps/rpi5/ # FastAPI 게이트웨이
│ └── apps/esp32-pir-sender/# PIR 센서 펌웨어
├── edge_app/ # Jetson 낙상 감지 앱
│ └── app/ # 카메라, YOLO 추론, 서버 통신, 스트리밍
├── ai/ # 음성 메시지 관련 AI 서버 코드
├── load-test/ # nGrinder/k6 형태의 부하 테스트 스크립트
└── docs/ # 프로젝트 개요, 시나리오, 화면 이미지
- 백엔드는
auth,family,health,iot,message,schedule,voice도메인으로 나누어 API와 비즈니스 로직의 경계를 분리했습니다. - IoT 장치용 API는
/api/iot/device계열로 분리해 보호자 앱 API와 디바이스 초기화·동기화 흐름을 구분했습니다. - 전역 설정은
global패키지에서 Security, JWT, Redis, MQTT, S3, Firebase, 예외 처리를 담당하도록 모았습니다.
- 라즈베리파이 장치는 서버 데이터를 매번 직접 화면에 렌더링하지 않고, 앨범·음성·멤버 정보를 로컬 DB와 파일로 동기화합니다.
- 서버는 데이터 변경 시
IotSyncService를 통해 변경 종류를 알리고, 장치는 필요한 데이터만 다시 가져갈 수 있습니다. - 사진과 음성 파일은 S3 경로를 기준으로 관리해 서버 API와 디바이스 저장소 사이의 파일 전달 책임을 분리했습니다.
- 메시지 등록과 TTS 생성은 분리되어 있으며,
MessageTtsAsyncService가 비동기로 음성 생성 후 메시지에 결과를 연결합니다. - RunPod 작업이 즉시 끝나지 않는 경우
VoiceTask를 메시지와 연결해 후속 웹훅 처리 흐름을 유지합니다. - 음성 파일 생성 이후에는
VoiceLog와 IoT 동기화 알림을 남겨 디바이스가 새 음성을 가져갈 수 있게 했습니다.
| 기술 | 선택 이유 |
|---|---|
| Spring Boot | 가족, 일정, 건강, IoT 등 도메인이 많은 API 서버를 계층적으로 구성하기 위해 사용했습니다. |
| Redis | 일정 월별 조회 결과와 인증·토큰성 데이터를 빠르게 다루기 위해 도입했습니다. |
| MQTT | 서버와 라즈베리파이 장치 간 이벤트성 명령을 가볍게 전달하기 위해 사용했습니다. |
| FastAPI | 라즈베리파이와 엣지 앱에서 Python 기반 장치 제어·추론 코드를 API로 묶기 적합했습니다. |
| S3 Presigned URL | 이미지, 음성, 낙상 영상 파일 업로드를 서버 부하와 분리하기 위해 사용했습니다. |
| FCM | 보호자 앱에 위험 알림과 건강 측정 요청을 전달하기 위해 사용했습니다. |
- Problem
- 초기 HTTP IP 스트리밍 방식은 동일 네트워크에서만 동작해 외부 네트워크 접속에 한계가 있었습니다.
- HTTPS 배포 환경에서는 HTTP 영상 스트림이 Mixed Content 정책에 의해 차단되었습니다.
- Action
- IoT 기기와 보호자 앱이 직접 연결되는 구조 대신 서버가 중계하는 WebSocket 릴레이 구조로 재설계했습니다.
- 서비스 특성이 양방향 통화가 아닌 단방향 모니터링이라는 점을 고려해 WebRTC 대신 WebSocket 기반 바이너리 이미지 전송 방식을 적용했습니다.
- Result
- 별도 포트포워딩 없이 LTE/5G 등 외부 네트워크에서도 실시간 영상을 확인할 수 있게 되었습니다.
- WSS 적용을 통해 HTTPS 환경에서도 안정적으로 실시간 스트리밍을 제공할 수 있게 되었습니다.
- Problem
- 낙상 감지 시 서버가 사용자 앱에 즉시 심박수 측정 명령을 전달해야 했습니다.
- WebSocket 상시 연결 방식은 모바일 백그라운드 상태에서 연결이 끊기거나 배터리 소모가 커질 수 있었습니다.
- Action
- 상시 연결 방식 대신 심박수 측정이 필요한 순간에만 FCM으로 앱을 깨우는 Wake-up 트리거 구조를 적용했습니다.
- 측정 완료 데이터는 HTTP POST로 서버에 전달하고 연결을 종료하는 Stateless 비동기 구조로 전환했습니다.
- Result
- 불필요한 TCP 세션 유지를 제거해 스마트폰 대기 전력 소모를 줄일 수 있었습니다.
- FCM 기반 명령 전달로 백그라운드 환경에서도 측정 명령을 전달할 수 있게 되었습니다.
- 동시 접속 세션 유지 부담을 줄여 서버 리소스 사용량을 낮출 수 있었습니다.
- 로컬에서 동작하는 기능도 실제 서비스 환경에서는 네트워크, HTTPS, OS 정책 같은 제약을 만날 수 있다는 점을 배웠습니다.
- 기능 구현뿐 아니라 사용자가 접속하는 네트워크 환경과 배포 보안 정책까지 고려해 구조를 설계해야 한다는 것을 경험했습니다.
- 기술 수준보다 서비스 목적에 맞는 선택이 더 중요하다는 점을 깨달았고, 단방향 모니터링이라는 요구에 맞춰 WebRTC 대신 WebSocket 릴레이를 선택했습니다.
- 초기에는 모바일 백그라운드 제약과 배터리 소모를 충분히 고려하지 못했습니다.
- HTTPS 배포 환경에서 Mixed Content 문제가 발생하기 전까지 로컬 네트워크 기준의 스트리밍 구조에 머물러 있었습니다.
- FCM 도달률, 스트리밍 지연 시간, 네트워크 단절 상황을 사전에 지표로 관리하지 못했습니다.
- OS 백그라운드 정책, 네트워크 단절, FCM 도달률, 스트리밍 지연 시간을 사전에 검토하고 측정 지표로 관리합니다.
- 외부 네트워크와 HTTPS 환경을 기준으로 통합 테스트 시나리오를 보강합니다.
- 앞으로도 사용자 상황과 운영 환경을 기준으로 기술을 선택하는 개발자가 되는 것을 목표로 합니다.
