역할

SCI는 삼성 SmartThings와 LH 스마트홈을 잇는 C2C(Cloud-to-Cloud) 커넥터임. 삼성 배포 @homeiot/partnersdk 기반 SmartApp 샘플을 LH용으로 고친 Node.js 서버임. 전체 그림은 공개노트/개발/시스템 구성.

  • SmartThings → LH: 입주민이 SmartThings 앱에서 제어하면 SCI가 공개노트/개발/모듈/PIW 연계 서버/api/eum/devices/*를 호출함
  • LH → SmartThings: 기기 상태가 바뀌면 PIW가 SCI의 /api/sci/partner로 이벤트를 보내고 SCI가 SmartThings API로 전달함
  • SmartApp 라이프사이클: SmartThings 클라우드가 SCI의 /api/sci로 INSTALL/UPDATE/UNINSTALL/이벤트 등을 보냄
  • SmartThings 앱 홈의 대시보드 카드(공지·주차·택배 등), 알림 항목 관리도 담당함(현재 대부분 미사용, 아래 참고)

기술 스택

항목
런타임Node.js, TypeScript(tsc -blib/)
프로세스 매니저pm2, pm2-logrotate(300MB, 60개 보관)
웹 프레임워크express
핵심 SDK@homeiot/partnersdk(삼성 비공개 npm), @smartthings/core-sdk, @smartthings/smartapp
저장소Redis(관계형 DB 없음)
포트dev/prod 8088, local 8080. API base path /api/sci
로그/app/logs/was/nodejs-sci/sci.log, sci-error.log

기동은 PROXY_HOST=[내부프록시] PROXY_PORT=13128을 앞에 붙여 squid 프록시를 태움(내부망 → 외부 SmartThings 호출용). npm installnpm run patch 필수(SDK 파일을 node_modules에 덮어씀).

PARTNER_CLIENTID=sseOAW의 tb_ptnr_m.ptnr_id와 같은 값이고, PARTNER_AUTHURL/PARTNER_REFRESHURL이 OAW의 /api/uma/authorize, /api/uma/token을 가리킴.

HTTP 엔드포인트 (전부 POST)

경로호출자하는 일
/api/sciSmartThings 클라우드SmartApp 라이프사이클 전부
/api/sci/partnerPIW, MAW(입주민 앱)본문에 events/commands/subscriptions로 분기. 셋 다 아니면 401
/api/sci/misc-command운영자운영 명령(로그레벨 변경, 토큰 강제 갱신, Redis/DB 점검 등). 고정 헤더 키로 인증

/api/sci/partner가 PIW의 sqi.partner.sse.api-event.uri(http://localhost:8088/api/sci/partner)가 가리키는 그 엔드포인트임.

입주민 앱(MAW)이 부를 때

  • 엔드포인트가 언제나 /api/sci/partner 하나임. 기기 목록 조회인지 제어인지는 본문의 commands[]로만 갈림. 로그에서 경로만 보면 무슨 요청인지 알 수 없으니 본문을 같이 볼 것
  • 인증 토큰은 MAW가 발급하지 않고 Redis에 삼성 커넥터가 심어 준 값을 읽어 씀. 값이 없으면 MAW 쪽에서 데이터 없음으로 끝남
  • 삼성 연동 해제 시 MAW가 알림 발송 성공 뒤 10초를 고정으로 기다린 다음 스마트앱 제거를 호출함(삼성 가이드 요구). 앱에서는 10초 이상 로딩으로 보이며 정상 동작임. 공개노트/개발/모듈/MAW 앱 API 서버

SmartApp 라이프사이클 핵심 흐름

  • INSTALL: 개인정보 동의 저장(실패 시 설치 전체 중단) → LH 기기 목록 조회해 SmartThings에 디바이스 생성 → SmartThings 토큰 갱신 스케줄 등록(월 2회). 콜백 등록(registerCallbackToPartnerWithIds)은 return true만 하고 실제 호출은 미구현임(“OAW가 액세스토큰을 저장하지 않아 구현 불가”라는 주석 있음)
  • 기기 제어(SmartThings → LH): LH 현재 상태 먼저 조회 → 이미 그 상태면 LH 호출 생략(중복 제어 방지) → 다르면 PIW에 명령 전송. 승강기는 2초 뒤 standby 이벤트를 따로 쏨(PARTNER_ELEVATOR_LAGGING_EVENT)
  • 기기 상태 이벤트 수신(LH → SmartThings): Redis PartnerDevice:{기기ID}로 이 기기가 속한 설치 건을 찾아 각각 전달. SmartThings 토큰이 INVALID면 조용히 버림 — 입주민이 커넥터를 다시 연결해야 함
  • 대시보드 카드: 공지·주차·택배 등 10개 항목. 현재 저장소 설정은 전부 off. 카드용 API 경로(/notice/title 등)가 PIW에는 없어 LH에서 미사용으로 추정

기기 타입 ↔ SmartThings capability 매핑

SCI 타입LH typeSmartThings 명령LH 속성
HNLIGHTlighton/offpower
HNDIMLIGHTlight(dimming)on/off, setLevelpower, dimming
HNHEATthermostaton/off, setHeatingSetpointpower, setTemperature
HNGASgasopen/closelock(on=열림, off=잠김)
HNVENTventilatoron/off, setFanSpeedpower, auto, speed
HNELEVATORelevatorcall(PIW /eum/devices/elevator/sse)
HNAWAYoutingon/offset
HNSECURITYpreventionon/offset

값 변환

  • 디밍: LH 15단계 ↔ SmartThings 0100%(1→20, 2→40, 3→60, 4→80, 5→100)
  • 환기: auto=onfan_speed=0, auto=off+speed=1~3→그 값. SmartThings에서 켜기 명령은 power=on+auto=off+speed=1 세 개를 함께 보냄
  • 가스: LH lock=off가 잠김(close), SmartThings valve=closed

단지별 구성

하나의 SCI 프로세스가 여러 단지를 각각 다른 SmartApp으로 서비스함. 단지마다 삼성에 별도 SmartApp을 만들고 id-list.json(운영)/id-list-dev.json(개발)에 appId/clientId/clientSecret/단지명을 등록함. 신규 단지 삼성 연동 절차: (1) 삼성에서 SmartApp 생성 → (2) id-list.json에 등록 → (3) 재배포.

운영 등록 현황(코드 시점): LH과천포레드림, LH인천검단37단지 2곳. prod의 ST_APP_LIST가 플레이스홀더라 다중 앱 모드가 꺼져 있고 단일 앱만 씀 — 실제 운영 상태 확인 필요(아래 참조).

온보딩 (PARTNER_ONBOARD_TYPE)

LH는 타입 1을 씀: “아파트 앱을 먼저 설치하고 계정을 만든 뒤 진행”임. 즉 입주민은 홈즈 앱 계정이 있어야 SmartThings 연동 가능. “SmartThings에서 LH 로그인이 안 된다” 문의는 대부분 홈즈 앱 계정이 승인 대기(RDY)이거나 없는 경우임.

스케줄

이름주기하는 일
SmartThingsRefreshToken월 2회 새벽 3시(설치 시각 기반)SmartThings access 토큰 갱신
SmartThingsDailyMonitorScheduler5분마다(이름은 Daily)전력계량기 관련, LH는 미사용 프로필이라 실질 동작 없음
PartnerRefreshToken등록된 스케줄 없음아래 확인 필요 참조

데이터

관계형 DB 없음. 모든 상태는 Redis.

내용
SmartThings:{installedAppId}SmartThings 쪽 authToken/refreshToken
Partner:{installedAppId}LH 쪽 accessToken/refreshToken + PartnerDeviceId:{LH기기ID} 매핑
PartnerDevice:{LH기기ID}이 기기를 쓰는 installedAppId 목록(역방향)

Partner:{installedAppId}accessToken이 PIW가 삼성 이벤트 발송 시 읽는 그 값임(공개노트/개발/모듈/PIW 연계 서버 참고).

알려진 이슈

  • 콜백 등록 미구현으로 입주민 퇴거 시 SmartThings 연동 자동 해제가 동작하지 않을 가능성 있음.
  • PartnerRefreshToken 갱신 스케줄이 등록되지 않음. LH refresh 토큰(2주 만료) 대응이 401 시 자동 갱신 경로에만 의존하는 것으로 추정됨.
  • /api/sci/partner인증이 없음(본문 형태로만 분기). PIW가 localhost:8088로만 호출하는 구조라 외부 노출이 없어야 함.
  • 환경 파일에 SmartThings·LH clientSecret이 평문으로 커밋되어 있음.
  • PIW의 Redis는 Sentinel(3노드)인데 SCI는 단독 노드 설정으로 되어 있어 같은 Redis인지 확인 필요(다르면 삼성 이벤트에 토큰이 안 붙음).

확인 필요

확인 필요

  • PIW가 읽는 Redis와 SCI가 쓰는 Redis가 같은 인스턴스인지.
  • PartnerRefreshToken 스케줄 미등록이 의도인지.
  • 입주민 퇴거 시 SmartThings 연동 해제 절차(콜백 미구현 관련).
  • 대시보드 카드용 API(/notice/title 등)를 제공하는 서버(MAW로 추정) 및 카드 전체 off가 의도인지.
  • 운영에 등록된 단지가 2곳뿐인지, 이후 추가된 단지가 실제 반영되었는지.
  • 승강기 lagging 이벤트(SCI, 2초 뒤 standby)와 PIW의 승강기 이벤트 2회 발송(1초 called, 20초 standby)이 중복되는지.

관련

공개노트/개발/시스템 구성 공개노트/개발/모듈/PIW 연계 서버 공개노트/개발/모듈/APW 연계 서버 공개노트/기능/승강기 호출 공개노트/기능/홈넷 서버 연동