B-Saver
IoT를 이용한 에너지 절감 시스템

사례 요약
고객사
DWK Partners (자사 솔루션)
분야
건물 에너지 관리, IoT 공간 제어
기간
2025년 4월 ~ 현재 (운영 중)
고민
기기 제어와 전력 사용량이 서로 다른 시스템에 있어, 둘을 대조하는 일이 사람의 몫으로 남았습니다
활용 기능
공간 단위 기기 제어, 시나리오 자동화, QR 임시 접근, 전력 사용량 분석, 알림 센터
성과
IoT 기기 200대 이상을 단일 대시보드에서 제어, 제어 이력과 사용량 변화를 같은 화면에서 확인
1. 서비스 소개
B-Saver는 당사가 직접 개발해 운영하는 건물 에너지 절감 솔루션입니다.
- 제품군: 건물용 B-Saver, 별도 용도의 F-Saver를 같은 기반에서 개발
- 제공 형태: 클라우드 SaaS 대시보드 + 현장 키오스크·모바일 앱
- 제어 범위: 조명·스위치·냉난방 등 IoT 기기 200대 이상
- 운영 현황: 2025년 4월 개발 착수 후 현재까지 운영과 기능 추가를 진행
2. 도입 배경
건물의 에너지 비용을 줄이려면 두 가지를 동시에 알아야 합니다. 지금 어떤 공간에서 어떤 기기가 켜져 있는지, 그리고 그 결과로 전기를 얼마나 쓰고 있는지입니다. 그런데 현장에서는 이 두 정보가 따로 놉니다. 기기 제어는 제조사별 앱으로, 전력 사용량은 한국전력 고지서나 별도 계측 시스템으로 확인합니다. 중간에서 둘을 이어 붙이는 일은 관리자의 몫으로 남습니다.
확인은 가능하지만, 아무도 하지 않는다
문제는 이 연결이 사람의 기억에 의존한다는 점입니다. "지난주에 회의실 냉방을 계속 틀어둔 날이 있었는데 그날 전력이 얼마나 튀었더라" 같은 질문에 답하려면, 제어 기록과 사용량 데이터를 각각 찾아 시간을 맞춰 대조해야 합니다. 대부분의 현장에서는 이 작업을 하지 않습니다. 시간이 오래 걸리고, 해봤자 다음 달에 또 같은 일을 반복해야 하기 때문입니다. 결국 에너지 절감은 "여름에는 냉방 온도를 26도로" 같은 지침 수준에 머무릅니다.
두 정보를 한 시스템에 두기
B-Saver는 이 간극을 없애기 위해 만든 자체 솔루션입니다. 2025년 4월에 개발을 시작해 현재까지 운영과 기능 추가를 이어가고 있으며, 200대가 넘는 IoT 기기를 제어하고 있습니다. 기기 제어와 전력 데이터를 같은 시스템 안에 두면, 앞의 질문은 대조 작업이 아니라 화면 조회로 바뀝니다.
자체 솔루션으로 개발한 이유도 여기에 있습니다. 시중의 에너지 관리 시스템은 계측에 집중하고, 스마트홈 플랫폼은 제어에 집중합니다. 둘을 함께 다루려면 두 시스템을 사서 붙여야 하는데, 그 접점은 결국 직접 만들어야 합니다. 그렇다면 처음부터 하나의 시스템으로 설계하는 편이 낫다고 판단했습니다. 현재는 건물용 B-Saver와 다른 용도의 F-Saver를 같은 기반 위에서 함께 개발하고 있습니다.
목표는 처음부터 명확했습니다. 관리자가 앱을 여러 개 오갈 필요 없이, 건물에서 층으로, 층에서 공간으로 내려가며 제어와 분석을 끝내는 것입니다. 여기에 한 가지 조건을 더 붙였습니다. 건물마다 설치된 기기의 제조사와 종류가 다르기 때문에, 특정 제조사에 묶이지 않는 구조여야 한다는 것입니다.
한 줄 요약 기기 제어와 전력 사용량을 같은 시스템에 두면, 원인 확인이 대조 작업이 아니라 화면 조회가 됩니다.
3. 활용 기능
Home Assistant(오픈소스 IoT 허브)를 제어 계층으로 두고, 그 위에 SaaS 형태의 관리 대시보드를 올렸습니다. Home Assistant는 수천 종의 기기를 표준화된 엔티티로 다루기 때문에, 조명 제조사가 바뀌어도 상위 시스템은 같은 방식으로 제어할 수 있습니다. B-Saver는 이 엔티티를 건물·층·공간이라는 운영 단위에 매핑하는 역할을 맡습니다.
왜 공간 단위인가
초기 설계에서 가장 오래 고민한 지점은 제어의 기준 단위였습니다. 기기 목록을 펼쳐 놓고 하나씩 켜고 끄는 방식이 만들기는 쉽습니다. 하지만 건물 관리자가 실제로 내리는 지시는 "3층 회의실 정리해 주세요"이지 "조명 12번, 14번 꺼 주세요"가 아닙니다. 기기를 기준으로 화면을 만들면 관리자가 머릿속에서 공간을 기기 목록으로 번역해야 하고, 기기가 늘어날수록 그 번역이 어려워집니다.
그래서 공간을 기준으로 삼고 기기를 그 아래에 두었습니다. 화면에서 먼저 보이는 것은 공간이고, 기기는 공간을 열었을 때 나타납니다. 이 선택 덕분에 기기가 200대를 넘어도 관리자가 보는 목록의 길이는 공간 수만큼만 늘어납니다.
공간 중심의 데이터 모델
시스템의 중심은 기기가 아니라 공간입니다. 건물(Building) 아래 층(Floor)이 있고, 층 아래 공간(Space)이 있습니다. 공간에는 타입(사무실·회의실·공용공간), 면적, 수용 인원 같은 정보와 함께 현재 상태가 붙습니다. 청소 중인지, 입실했는지, 회의 중인지를 상태로 관리하기 때문에 관리자는 제어 버튼을 누르기 전에 지금 그 공간에서 무슨 일이 벌어지고 있는지 먼저 확인할 수 있습니다.
기기(Device)와 센서(Sensor)는 공간에 배치됩니다. 기기는 Home Assistant의 엔티티 ID로 등록하고, 별칭과 설명, 펌웨어 정보, 온라인 상태와 마지막 통신 시각을 함께 관리합니다. 센서는 온도·습도·조도·모션 등을 다루며, 공간에 매핑하지 않고 미할당 상태로 둘 수도 있습니다. 설치는 끝났지만 아직 어느 공간에 속할지 정하지 않은 장비를 위한 여지입니다. 센서 값은 시계열로 쌓입니다.
제품군과 모노레포 구성
저장소는 모노레포로 구성했습니다. 건물용 B-Saver와 다른 용도의 F-Saver, 그리고 관리자 애플리케이션이 같은 저장소 안의 별도 앱으로 존재하고, 공용 UI 컴포넌트와 gRPC 통신 코어, HVAC 제어 계약을 패키지로 분리했습니다. 제품이 늘어도 제어 프로토콜과 UI 규칙은 한 곳에서 관리합니다.
현장 운영을 위한 키오스크와 모바일 앱은 별도 저장소로 두었습니다. 관리자 웹, 키오스크 웹, 안드로이드 네이티브 앱이 공통 데이터베이스 패키지를 공유하는 구조이며, 결제 단말(VAN) 연동 모듈을 포함합니다. 결제 단말은 응답이 늦거나 중간에 끊기는 상황이 잦아, 폴링 방식과 예외 처리를 따로 정리한 기술 문서를 두고 관리하고 있습니다.
운영 화면 구성
화면은 관리자의 일과를 따라 배치했습니다. 로그인하면 먼저 대시보드가 열립니다. 전체 공간과 활성 공간, 온라인 기기와 센서 개수가 카드로 요약되고, 기기 유형별 분포와 최근 제어한 기기 목록이 이어집니다. 여기서 이상한 숫자가 보이면 바로 해당 화면으로 이동합니다.
공간 제어 화면은 건물·층·공간 트리와 공간 카드로 구성했습니다. 카드를 누르면 상세 모달이 열리고, 그 안에서 기기와 센서 목록을 확인하며 시나리오를 실행합니다. 기기 관리 화면에서는 엔티티 등록과 배치, 별칭 수정을 처리하고, 설정 화면에서는 빌딩·공간 정보와 API 키, 계기 설정, 구독과 보안, 알림 설정을 다룹니다.
에너지 분석 화면은 계기 데이터를 기준으로 월별·일별 사용량을 보여 줍니다. 제어 이력 화면과 알림 화면은 각각 로그와 알림을 시간순으로 나열하고, 자동화 화면에서는 시나리오 목록과 실행 현황을 관리합니다. 마지막으로 QR 토큰으로 접근하는 경량 제어 페이지가 별도 경로에 있습니다. 이 페이지는 로그인 없이 열리기 때문에 나머지 화면과 완전히 분리해 두었습니다.
전력 데이터 연동
전력 데이터는 한국전력 계기 정보와 연동했습니다. 빌딩에 계기 설정을 붙이면 고객명, 주소, 계약전력, 검침일 같은 정보가 함께 관리되고, 여기에 외부 API 키를 연결해 사용량을 가져옵니다. 월별 요금은 기본요금, 전력량요금, 청구요금, 할인요금, 부하대별 사용량으로 나눠 저장합니다. 일별 데이터는 하루를 15분 단위 96개 구간으로 나눈 배열로 저장하기 때문에, "회의실 사용이 몰리는 시간대에 전력 피크가 생기는지" 같은 질문에 데이터로 답할 수 있습니다.
API로 가져올 수 없는 과거 데이터는 CSV와 엑셀 파일 업로드로 채웁니다. 시스템 도입 이전 기간의 사용량을 넣어야 비교 대상이 생기기 때문에, 초기 셋업에서 실제로 자주 쓰이는 기능입니다.
주요 기능
공간 단위 기기 제어
건물·층·공간 계층을 따라 내려가며 기기를 제어합니다. 공간 카드에는 현재 상태와 연결된 기기·센서가 함께 표시되고, 카드를 열면 상세 모달에서 개별 기기를 조작하거나 공간 상태를 바꿀 수 있습니다. 필터 패널로 특정 조건의 공간만 추려 볼 수 있어, 층 전체를 훑지 않고도 조치가 필요한 공간을 찾습니다. 기기마다 온라인 여부와 마지막 통신 시각을 표시하기 때문에, 명령이 실패했을 때 그 원인이 통신 문제인지 설정 문제인지 구분할 수 있습니다.
시나리오 자동화
여러 기기 제어를 하나의 시나리오로 묶어 버튼 한 번으로 실행합니다. 시나리오는 공간 전용으로 만들 수도 있고 전역으로 둘 수도 있으며, 아이콘과 색상, 목표 상태를 지정합니다. 시나리오 안의 각 동작에는 순서와 지연 시간을 줄 수 있어, "조명을 끈 뒤 3초 후 냉방을 절전 모드로 전환" 같은 절차를 그대로 옮길 수 있습니다. 기기에 따라 명령을 연속으로 보내면 뒤 명령이 씹히는 경우가 있어, 지연 실행은 선택 기능이 아니라 필수 기능에 가깝습니다.
제어 이력과 통계
모든 제어는 로그로 남습니다. 누가 실행했는지, 수동인지 자동인지, 성공했는지 실패했는지를 기록하고 통계 API로 집계합니다. 이 로그는 두 가지 용도로 쓰입니다. 하나는 문제가 생겼을 때 원인을 추적하는 것이고, 다른 하나는 자동화가 실제로 얼마나 기여했는지 확인하는 것입니다. 대시보드에는 자동화 효과와 평균 제어 횟수가 카드로 표시됩니다.
QR 기반 임시 접근 권한
객실 투숙객이나 외부 협력사처럼 계정을 만들 수 없는 사용자를 위해 QR 접근 기능을 넣었습니다. 공간별로 AES-256으로 암호화한 6자리 코드를 발급하고, 그 코드로 들어온 사용자는 허용된 시나리오만 실행할 수 있습니다. 실행 가능한 시나리오 목록을 공간이 아니라 접근 권한에 붙였기 때문에, 같은 공간이라도 발급 대상에 따라 권한 범위를 다르게 줄 수 있습니다. 만료 시간을 지정하면 정해진 기간이 지난 뒤 자동으로 권한이 사라지고, 접근 화면은 전체 대시보드가 아니라 버튼 몇 개만 있는 경량 페이지로 제공합니다.
전력 사용량 분석
계기 설정과 연결된 빌딩의 월별 요금과 일별 사용량을 조회하고 동기화합니다. 대시보드에서는 월별 추이와 15분 구간 사용량을 차트로 확인하며, 부하대별 사용량을 구분해 보여 줍니다. 요금 항목을 세분해 저장하기 때문에 청구액 변화가 사용량 증가 때문인지 요금제 변경 때문인지 구분할 수 있습니다.
알림 센터
시스템·기기·보안·과금 등 알림 종류를 구분하고, 이메일·푸시·SMS·웹 채널별로 발송 이력을 남깁니다. 사용자마다 받을 알림 종류와 채널을 따로 설정할 수 있어, 시설 담당자와 회계 담당자가 서로 다른 알림만 받도록 구성할 수 있습니다. 발송 이력을 별도로 저장하기 때문에 "알림이 안 왔다"는 문의가 들어왔을 때 발송 자체가 없었는지, 발송은 됐지만 전달에 실패했는지 확인할 수 있습니다.
인증과 API 토큰
이메일·비밀번호 기반 로그인에 더해, 세션과 로그인 이력을 별도 테이블로 관리합니다. 사용자는 자신의 세션 목록을 확인하고 전체 로그아웃을 실행할 수 있습니다. 데몬이나 백엔드 서비스가 API를 호출할 때는 사람 계정이 아니라 별도로 발급한 API 토큰을 쓰고, 이 토큰은 JWT로 검증합니다. 사람이 쓰는 인증과 기계가 쓰는 인증을 분리해 두면, 담당자가 바뀌어 계정을 정리할 때 연동이 함께 끊기는 사고를 막을 수 있습니다.
현장 장비와 관리 도구의 분리
같은 시스템이라도 관리자가 사무실에서 쓰는 화면과 현장에 설치된 장비의 화면은 요구 조건이 다릅니다. 관리 화면은 정보 밀도가 높아야 하고, 현장 장비는 누구나 안내 없이 쓸 수 있어야 합니다. 그래서 관리자 웹과 키오스크, 모바일 앱을 각각의 애플리케이션으로 나누되 데이터베이스 패키지는 공유하도록 구성했습니다. 화면은 용도에 맞게 따로 만들고, 데이터 구조는 한 곳에서 관리합니다.
핵심 설계 제어의 기준 단위를 기기가 아니라 공간으로 잡았습니다. 기기가 200대를 넘어도 관리자가 보는 목록은 공간 수만큼만 늘어납니다.
4. 성과
IoT 기기 200대 이상을 단일 대시보드에서 제어하고 있습니다. 기기 제어와 전력 데이터를 같은 화면에 놓으면서, 제어 이력과 사용량 변화를 함께 확인할 수 있는 운영 환경을 만들었습니다. 도입 전에는 두 시스템을 오가며 대조해야 했던 작업이 화면 조회로 바뀌었습니다.
QR 접근 기능으로 계정 발급 없이도 외부 사용자에게 제한된 제어 권한을 줄 수 있게 되어, 숙박·공유오피스처럼 이용자가 자주 바뀌는 공간에도 적용 가능한 구조가 되었습니다. 발급과 만료가 자동으로 처리되므로 운영자가 권한을 회수하는 일을 잊어도 문제가 생기지 않습니다.
제품군을 모노레포로 묶고 제어 규약을 패키지로 분리한 덕분에, 새로운 제품을 추가할 때 처음부터 만들지 않고 기존 제어 계층과 UI를 재사용합니다. 건물용 B-Saver와 F-Saver가 같은 기반을 공유하는 것도 이 구조 덕분입니다.
운영 측면에서는 제어 로그와 알림 발송 이력을 남긴 것이 실제로 가장 자주 쓰입니다. "명령이 안 먹었다", "알림이 안 왔다" 같은 문의는 기록이 없으면 재현부터 해야 하지만, 기록이 있으면 조회 한 번으로 끝납니다. 기능을 추가할 때마다 그 기능의 실행 결과를 어디에 남길지 함께 정한 것이 운영 부담을 줄였습니다.
2025년 4월 이후 현재까지 운영과 기능 개선을 이어가고 있으며, 현장에서 나온 요구사항을 반영해 제어 대상과 분석 항목을 계속 넓히고 있습니다.
5. 기술 구성
Web
Next.js 15 App Router와 React 19, TypeScript로 구성했습니다. UI는 Tailwind CSS와 shadcn/ui 컴포넌트를 사용하고, 차트는 Recharts로 그립니다. 다크·라이트 테마 전환을 지원하며, PWA로 구성해 현장 태블릿에서 앱처럼 설치해 쓸 수 있습니다. 한국어와 영어 UI를 함께 제공합니다.
Backend
Next.js API Routes 위에 인증과 도메인 API를 올렸습니다. 사용자 인증은 NextAuth.js, 기계 간 통신은 API 토큰 + JWT로 나눴습니다. 데이터베이스는 Prisma ORM과 PostgreSQL을 사용하고, API 입력값은 Zod로 런타임 검증합니다. 코드 포매팅과 린트는 Biome 하나로 통일해 설정 파일 수를 줄였습니다.
IoT
Home Assistant 엔티티를 기기 제어의 공통 인터페이스로 사용합니다. 제품군 사이의 HVAC 제어 규칙은 별도 계약 패키지로 분리하고, 서비스 간 통신에는 gRPC 코어 패키지를 씁니다. 기기 제어처럼 지연에 민감한 호출을 REST가 아닌 gRPC로 두면, 요청·응답 형식을 코드로 고정할 수 있어 서비스가 늘어도 규약이 흐트러지지 않습니다.
Kiosk / Mobile
pnpm과 Turborepo 기반 모노레포로 관리자 웹, 키오스크 웹, React Native 안드로이드 앱을 함께 둡니다. 세 앱이 같은 데이터베이스 패키지를 공유하므로 스키마 변경이 한 번에 반영됩니다. 결제 단말(VAN) 연동 모듈을 포함합니다.
기술 선택의 기준
기술을 고를 때 기준은 하나였습니다. 현장에서 장애가 났을 때 원인을 빨리 찾을 수 있는가입니다. 제어 명령은 웹에서 출발해 허브를 거쳐 기기까지 가는데, 중간 어느 지점에서 끊겨도 사용자에게는 "안 된다"로만 보입니다. 그래서 각 구간의 경계를 코드로 고정하는 쪽을 택했습니다. 서비스 간 호출은 gRPC로 형식을 강제하고, API 입력은 Zod로 검증해 잘못된 값이 안쪽까지 들어가지 않게 막았습니다. 기기 제어 규칙은 별도 계약 패키지에 모아, 제품이 달라도 같은 규약을 따르게 했습니다. 이렇게 해두면 장애 원인을 "어느 구간에서 형식이 깨졌는지"로 좁힐 수 있습니다.
구현하면서 다룬 문제
제조사마다 다른 기기 응답 속도. 같은 조명이라도 제조사에 따라 명령 반영까지 걸리는 시간이 다릅니다. 시나리오를 만들 때 지연 시간을 사람이 지정할 수 있게 한 것은 이 차이를 코드로 흡수하기 어려웠기 때문입니다. 현장에서 값을 조정해 맞추는 편이 훨씬 빠릅니다.
제어 실패를 조용히 넘기지 않기. 제어 명령은 네트워크, 허브, 기기 어느 단계에서든 실패할 수 있습니다. 실패를 무시하면 화면은 켜졌다고 표시하는데 실제 기기는 꺼져 있는 상태가 됩니다. 모든 제어를 성공·실패까지 기록하고, 기기의 마지막 통신 시각을 함께 보여 주는 이유입니다.
결제 단말 연동. 키오스크의 VAN 결제는 응답이 늦거나 중간에 끊기는 경우가 잦습니다. 폴링 주기와 타임아웃, 재시도 조건을 정리해 별도 문서로 관리하고 있습니다. 하드웨어와 붙는 기능은 코드보다 운영 규칙이 먼저 정리돼야 안정적으로 돌아갑니다.
공간 상태와 실제 상황의 차이. 시스템에 기록된 공간 상태와 현장의 실제 상황이 어긋나는 경우가 있습니다. 상태를 자동으로만 갱신하면 예외 상황을 반영하지 못하고, 수동으로만 두면 갱신이 밀립니다. 센서 값과 수동 변경을 함께 쓰되 마지막 변경 시각을 표시해, 관리자가 그 값을 얼마나 신뢰할지 판단하도록 했습니다.
6. 프로젝트 정보
| 항목 | 내용 |
|---|---|
| 사업명 | 에너지 절감 솔루션(B-Saver / F-Saver) 개발 |
| 담당 범위 | 기획, 웹·키오스크·앱 개발, 운영 |
| 적용 기술 | Next.js, React, TypeScript, Prisma, PostgreSQL, Home Assistant, gRPC, React Native |
비슷한 프로젝트를 준비 중이신가요?
요구사항과 일정만 알려주시면 적합한 구성과 예상 범위를 정리해 드립니다.
댓글 0
첫 번째 댓글을 남겨보세요.