현대 블루링크 대시보드를 만들었다 — 차량 상태 모니터링 + 정비 예측 + EV 분석
투싼을 타면서 블루링크 앱을 쓰다가 문득 든 생각이 있었다. “현대자동차가 Developers API를 공개해놨으니 Claude를 이용하면 내 차량 정보를 한 눈에 확인할 수 있는 dashboard를 만들 수 있지 않을까?”

무엇을 만들었나
Streamlit 기반 차량 관리 대시보드다. 현대 Developers API에서 차량 데이터를 가져와서 건강 점수 계산, 정비 시기 예측, EV 분석, 자동 이메일 알림까지 처리한다.
주요 기능은 다음과 같다:
- 차량 대시보드 : 경고등 7종(엔진오일, 브레이크오일, 타이어 공기압, 워셔액, 스마트키, 램프, 주유) 실시간 조회. 가중치 기반 건강 점수 100점 만점으로 계산. 70점 이하면 자동 이메일 경고
- 정비 시기 예측 : 오도미터를 일별 수집해서 일평균 주행 거리를 계산하고, 각 정비 항목(엔진오일 15,000km, 에어필터 30,000km 등)의 교체 예상일을 타임라인 차트로 시각화. D-7/3/1에 이메일 알림
- EV 분석 : SOC/DTE 수집, 충전 이벤트 자동 감지(SOC +5% 이상 증가 구간), 구간 전비(km/%SOC) 역산, 카탈로그 대비 배터리 열화율 추정, 계절별 DTE 분포 비교
- 자동 알림 : APScheduler로 매주 월요일 09:00 주간 리포트, 매일 09:00 BlueLink 서비스 만료 체크(D-30/7/1)
- 설정 페이지 : Streamlit 안에서 OAuth2 재인증, 계정 연결 해제, 차량 목록/계약 정보 확인, DB 초기화. 비밀번호 재확인 게이트와 민감정보 마스킹 적용
기술적으로 신경 쓴 부분
OAuth2 인증
현대 API는 OAuth 2.0 기반이라고 나와있다. 계정 API(prd 서버)와 데이터 API(dev 서버)가 분리되어 있어서 URL을 잘못 쓰면 인증은 되는데 데이터 호출이 안 되는 상황이 생겼다. AUTH_BASE_URL과 DATA_BASE_URL을 명확히 분리해서 코드를 작성해달라고 요청했고, API 래퍼에서 용도별로 다른 base URL을 사용하도록 설계됐다.
Refresh Token은 Fernet 대칭 암호화 후 디스크에 저장하고, Access Token은 세션 메모리에만 유지한다. 만료 5분 전에 자동 갱신되도록 해서 사용 중 토큰 만료로 끊기는 일이 없게 했다.
초기에는 터미널에서 python init_auth.py를 실행해야 했는데 그 부분이 너무 번거롭게 느껴져서 설정 페이지에서 OAuth 콜백 서버를 백그라운드로 띄우고 인증 코드를 파일로 전달하는 방식으로 Streamlit 안에서 재인증까지 가능하게 만들었다.
사이드바 통합
Streamlit 멀티페이지 앱의 고질적인 문제 — 자동 생성되는 기본 네비게이션과 커스텀 사이드바가 중복되는 것 — 를 CSS로 기본 메뉴를 숨기고, 공통 render_sidebar() 함수로 모든 페이지에 동일한 사이드바를 렌더링하는 방식으로 해결했다. 프로필 카드, 상태 배지, 카테고리별 페이지 링크, 새로고침/README 버튼이 어느 페이지에서든 동일하게 표시된다.
보안
설정 페이지는 민감 정보(계정 정보, 토큰 상태, SMTP 설정)를 다루기 때문에 비밀번호 재확인 게이트를 넣었다. auth_config.yaml의 bcrypt 해시와 대조해서 5분간 유효하게 했다. 이름, 이메일, 전화번호, 차량 ID, 만료일, SMTP 주소 등은 기본적으로 마스킹(홍**, te***@gmail.com, *******5678)되어 있고 “실제 정보 표시” 체크박스를 눌러야 원본이 보인다. DB 초기화는 DELETE 텍스트 입력 + 비밀번호 이중 확인을 거쳐야 실행된다.
AI를 어떻게 활용했나
이번에도 Claude를 코드 작성과 설계 전반에 활용했다.
처음 구상은 단순했다. “경고등 7개 보여주고 점수 매기는 대시보드” 정도. 그런데 Claude와 대화하면서 점점 범위가 넓어졌다. “정비 시기도 예측할 수 있지 않나?”, “EV 충전 패턴을 분석하면 배터리 열화를 추정할 수 있겠다”, “주간 리포트를 자동으로 보내면 어떨까” — 이런 식으로 기능이 하나씩 붙었다.
코드 리뷰도 맡겼다. 처음 Claude로 짠 bluelink_client.py에서 AUTH/DATA 서버 URL이 하드코딩되어 있던 것, 경고등 파싱이 실제 API 응답 형식({"status": bool})과 맞지 않던 것, EV 필터링이 fuelType 키를 쓰고 있었는데 실제 API 응답은 carType이었던 것 — 이런 버그들을 API 문서와 대조하면서 잡아냈다.
보안 관련 피드백도 유용했다. “Settings 페이지에 민감 정보가 그대로 노출된다”는 지적에서 비밀번호 게이트 → 마스킹 → DB 초기화 이중 확인까지 단계적으로 강화했다. 사이드바 중복 문제도 목업을 먼저 보여준 뒤 구현 방향을 확인하고 진행하는 방식이 효과적이었다.
결과적으로 3,100줄 규모의 코드가 나왔는데, 처음부터 혼자 설계했으면 이 정도 구조를 잡기 어려웠을 것 같다.
이런 식으로 하니깐 결과물은 빨리 나오는데 내 코딩 실력은 전혀 늘질 않는 것 같다. 남이 짜준 코드라도 이해할 수 있는 수준이 되려면 코딩 공부도 같이 병행해야될 것 같다.
앞으로
현재 버전은 로컬 단일 사용자 전용이다. 로컬 파일 기반이라 여러 사람이 쓸 수 없다. 다음 단계로 Next.js + FastAPI 웹앱으로 전환해서 다중 사용자 서비스로 확장할 수 있는지 알아보는 중이다.
일단 지금 버전으로 한동안 써보면서 실제로 유용한 기능과 그렇지 않은 기능을 구분해볼 생각이다.
Enjoy Reading This Article?
Here are some more articles you might like to read next: