Skip to content

Team-Starex/HMI_WEB

Repository files navigation

🚗 차량 위험 감지 안전 대응 시스템 (Vehicle Monitoring System)

프로젝트 상태: ✅ 운영 중 (라즈베리파이 CAN 통신 실시간 작동)
최종 수정: 2026년 4월 6일

라즈베리파이에서 CAN 통신으로 수신한 차량 데이터를 Node.js 서버를 통해 React.js 프론트엔드에 실시간 WebSocket 통신으로 표시하는 풀 스택 시스템입니다.

🎯 프로젝트 개요

기술 스택

  • 백엔드: Node.js + Express + Socket.IO
  • 프론트엔드: React 18 + Vite
  • 실시간 통신: WebSocket (Socket.IO)
  • 스타일링: CSS3 + React
  • 테이팅: Jest, React Testing Library
  • 데이터 소스: 라즈베리파이 CAN 통신 (프로토타입 단계)

✨ 주요 기능

📊 실시간 차량 상태 모니터링

기능 설명 상태
속도 계기판 실시간 속도 표시 (0-120 km/h) ✅ 완료
주행 상태 IDLE / DRIVING / STOPPED 상태 표시 ✅ 완료
조향각 디스플레이 실시간 조향각 (-90°~+90°) ✅ 완료
이전값/현재값 추적 변화량 계산 및 이벤트 판단 ✅ 완료
문 잠금 상태 현재 문 잠금/해제 상태 ✅ 완료

🚨 안전 상태 관리 (우선순위 기반)

심각도 동작 상태
FATAL 빨강 배경 펄싱 비상 메시지 ✅ 완료
CRITICAL 주황 배경 위험 메시지 ✅ 완료
WARNING 노랑 배경 경고 메시지 ✅ 완료
NORMAL 초록 배경 정상 메시지 ✅ 완료

⚡ 자동 이벤트 감지

이벤트 감지 조건 상태
출발 시 조향 정렬 속도 0→증가 + 조향각 미정렬 (±5°) ✅ 완료
무응답 경고 10초 이상 데이터 미수신 ✅ 완료
위험 상황 발생 조향각 임계값 초과 ✅ 완료

📱 향상된 UI/UX

기능 설명 상태
원형 속도 계기판 채워지는 애니메이션 효과 ✅ 완료
실시간 토스트 알림 react-toastify 기반 ✅ 완료
토스트 중복 방지 3초 debounce 적용 ✅ 완료
반응형 대시보드 모든 기기에 대응 ✅ 완료
이벤트 로그 발생한 모든 이벤트 기록 ✅ 완료

🚀 빠른 시작

📋 필수 요구사항

  • Node.js 14+ 이상
  • npm 또는 yarn
  • 최신 웹 브라우저

🔧 설치 및 실행

한 번에 모두 시작 (Windows/Mac/Linux)

# Windows
./start-all.bat

# Mac/Linux
./start-all.sh

또는 각각 실행

# 1. 백엔드 설치 및 실행
cd backend
npm install
npm run dev
# 서버 실행: http://192.168.137.158:3002

# 2. 새 터미널에서 프론트엔드 설치 및 실행
cd frontend
npm install
npm run dev
# 프론트엔드 접속: http://192.168.137.158:5173

🌐 접속 주소

라즈베리파이 네트워크에서

http://192.168.137.158:5173

라즈베리파이 직접 연결 모니터에서

http://localhost:5173

⚙️ 환경 변수 설정

frontend/.env.local 파일이 자동 생성되며, 다음 설정으로 백엔드 URL 고정:

VITE_BACKEND_URL=http://192.168.137.158:3002

📡 CAN 통신 상태

현재: 실제 CAN 통신 활성화 (USE_REAL_CAN=true)

  • CAN0 인터페이스에서 데이터 수신 중
  • can_receiver.py로 데이터 파싱
  • 실시간 WebSocket 전송 중

📁 프로젝트 구조

project1/
├── backend/
│   ├── server.js                      # 메인 서버 파일 (Socket.IO)
│   ├── constants.js                   # 상수 정의
│   ├── can_receiver.py                # Python CAN 수신기 (향후)
│   ├── package.json
│   ├── package-lock.json
│   ├── README.md
│   │
│   ├── src/
│   │   ├── handlers/
│   │   │   └── socketHandlers.js      # WebSocket 이벤트 핸들러
│   │   ├── routes/
│   │   │   └── api.js                 # REST API 엔드포인트
│   │   ├── services/
│   │   │   ├── vehicleStateService.js # 차량 상태 관리
│   │   │   ├── emergencyService.js    # 비상상황 관리
│   │   │   ├── safetyService.js       # 안전 상태 판단
│   │   │   ├── canDataService.js      # CAN 데이터 처리
│   │   │   └── eventService.js        # 이벤트 처리
│   │   └── utils/
│   │       ├── eventTimers.js         # 타이머 관리
│   │       └── testDataSimulator.js   # 테스트 데이터 생성
│   │
│   └── __tests__/
│       └── vehicleState.test.js       # 단위 테스트
│
├── frontend/
│   ├── src/
│   │   ├── App.jsx                    # 메인 앱 컴포넌트
│   │   ├── App.css
│   │   ├── main.jsx                   # React 진입점
│   │   │
│   │   ├── components/
│   │   │   ├── common/
│   │   │   │   ├── Header.jsx         # 헤더
│   │   │   │   ├── Header.css
│   │   │   │   ├── AlertPanel.jsx     # 안전 상태 패널
│   │   │   │   └── AlertPanel.css
│   │   │   ├── features/
│   │   │   │   ├── Dashboard.jsx      # 메인 대시보드
│   │   │   │   ├── Dashboard.css
│   │   │   │   ├── SpeedGauge.jsx     # 속도 계기판
│   │   │   │   ├── SpeedGauge.css
│   │   │   │   ├── SteeringDisplay.jsx # 조향각 표시
│   │   │   │   ├── SteeringDisplay.css
│   │   │   │   ├── DoorLock.jsx       # 문 잠금 상태
│   │   │   │   ├── DoorLock.css
│   │   │   │   ├── EmergencyPanel.jsx # 비상상황 관제
│   │   │   │   ├── EmergencyPanel.css
│   │   │   │   ├── EventLog.jsx       # 이벤트 로그
│   │   │   │   ├── EventLog.css
│   │   │   │   ├── UserInfoModal.jsx  # 사용자 정보 모달
│   │   │   │   └── UserInfoModal.css
│   │   │   ├── CanTestControl.jsx     # 테스트 컨트롤 패널
│   │   │   └── CanTestControl.css
│   │   │
│   │   ├── contexts/
│   │   │   ├── VehicleStateContext.jsx # 차량 상태 전역 상태
│   │   │   └── UserContext.jsx        # 사용자 정보 전역 상태
│   │   │
│   │   ├── hooks/
│   │   │   ├── useVehicleState.js     # WebSocket 수신 & 상태관리
│   │   │   └── useStartupEventDetection.js # 출발 이벤트 감지
│   │   │
│   │   ├── services/
│   │   │   ├── socketService.js       # Socket.IO 클라이언트
│   │   │   └── vehicleApi.js          # REST API 호출
│   │   │
│   │   ├── utils/
│   │   │   ├── constants.js           # 프론트엔드 상수
│   │   │   └── toastDeduplication.js  # 토스트 중복 방지
│   │   │
│   │   └── __tests__/
│   │       ├── components.test.js
│   │       ├── useVehicleState.test.js
│   │       └── useStartupEventDetection.test.js
│   │
│   ├── index.html                     # HTML 진입점
│   ├── vite.config.js
│   ├── package.json
│   ├── package-lock.json
│   └── README.md
│
├── start-all.sh                       # Linux/Mac 한 번에 시작
├── start-all.bat                      # Windows 한 번에 시작
├── IMPLEMENTATION_GUIDE.md            # 구현 가이드
├── RASPBERRY_PI_SETUP.md              # 라즈베리파이 설정 가이드
└── README.md                          # 이 파일

🔌 WebSocket 이벤트 명세

📡 서버 → 클라이언트

vehicle-state - 차량 상태 업데이트 (100ms 주기)

{
  speed: 45,                    // km/h (0-120)
  steeringAngle: 15,           // degree (-90~+90)
  doorLocked: true,
  safetyStatus: "NORMAL",      // NORMAL | WARNING | CRITICAL | FATAL
  dataVersion: 12345,
  timestamp: 1680336000000
}

emergency-alert - 새로운 비상상황 발생

{
  id: "alert-001",
  severity: "CRITICAL",        // INFO | WARNING | CRITICAL | FATAL
  message: "충돌 감지됨",
  timestamp: 1680336000000
}

emergency-resolved - 비상상황 해제

{
  alertId: "alert-001",
  timestamp: 1680336000000
}

📤 클라이언트 → 서버

update-vehicle-data - 차량 데이터 업데이트

{
  speed: 45,
  steeringAngle: 15,
  doorLocked: true
}

add-emergency - 비상상황 추가 (테스트용)

{
  severity: "CRITICAL",
  message: "테스트 충돌"
}

resolve-emergency - 특정 비상상황 해제

{
  alertId: "alert-001";
}

clear-all-emergencies - 모든 비상상황 해제

{
}

🧪 테스트

프로토타입 테스트

프론트엔드의 "테스트 컨트롤" 패널에서 다음을 테스트할 수 있습니다:

버튼 동작 심각도
🚨 충돌 알림 충돌 이벤트 시뮬레이션 CRITICAL
⚠️ 과열 경고 과열 이벤트 시뮬레이션 WARNING
ℹ️ 타이어 압력 타이어 압력 이벤트 시뮬레이션 INFO
✕ 모두 해제 모든 비상상황 제거 -

자동화 테스트

백엔드 테스트

cd backend
npm test

프론트엔드 테스트

cd frontend
npm test

🛠️ REST API 엔드포인트

메서드 경로 설명
GET /api/vehicle-state 현재 차량 상태 조회
GET /api/emergencies 현재 비상상황 목록 조회
POST /api/emergencies 비상상황 구독

📲 라즈베리파이 CAN 통신 연결

Python 클라이언트 예제 -> (실제 파일은 backend폴더 내에 존재함)

import socketio
import python_can
import json

# Socket.IO 클라이언트 생성
sio = socketio.Client()

# CAN 버스 초기화
bus = python_can.interface.Bus(channel='can0', bustype='socketcan')

@sio.event
def connect():
    print("서버에 연결되었습니다")

def read_can_data():
    """CAN 버스에서 데이터 읽기"""
    while True:
        msg = bus.recv(timeout=1)
        if msg:
            # CAN 데이터 파싱
            data = parse_can_message(msg)
            # 서버로 전송
            sio.emit('update-vehicle-data', data)

def parse_can_message(msg):
    """CAN 메시지 파싱"""
    return {
        'speed': msg.data[0],
        'steeringAngle': msg.data[1],
        'doorLocked': bool(msg.data[2])
    }

if __name__ == "__main__":
    sio.connect('http://localhost:3001')
    read_can_data()

라즈베리파이 설정

자세한 설정 방법은 RASPBERRY_PI_SETUP.md를 참고하세요.


🔄 데이터 흐름

라즈베리파이 (또는 테스트 시뮬레이터)
    ↓
  CAN 버스
    ↓
Node.js 서버
    ├→ 데이터 검증/변환
    ├→ 안전 상태 판단
    ├→ 이벤트 생성
    └→ WebSocket 브로드캐스트
    ↓
React 프론트엔드
    ├→ 실시간 차량 상태 표시
    ├→ 알림 표시
    └→ 이벤트 로그 업데이트

📋 환경 변수 (선택)

백엔드 (.env)

PORT=3001
CLIENT_URL=http://localhost:5173
NODE_ENV=development

💡 주요 성능 최적화

  • WebSocket 주기적 업데이트: 100ms 주기 (200ms 수신 debounce)
  • 토스트 중복 방지: 동일 메시지 3초 내 표시 제한
  • 이벤트 우선순위: FATAL > CRITICAL > WARNING > NORMAL
  • 상태 버전 추적: 오래된 데이터 무시
  • 타이머 효율화: 이벤트별 개별 타이머 관리

🐛 문제 해결

포트가 이미 사용 중인 경우 ->(start.sh 실행스크립트에 전부 반영되어 있습니다.)

# Windows
netstat -ano | findstr :3001
taskkill /PID <PID> /F

# Mac/Linux
lsof -i :3001
kill -9 <PID>

WebSocket 연결 안 됨

  • 방화벽 확인
  • 백엔드 서버가 정상 실행 중인지 확인
  • 브라우저 개발자 도구의 Network 탭 확인

데이터가 업데이트 안 됨

  • 백엔드 로그 확인: npm run dev 출력
  • 프론트엔드 콘솔 오류 확인
  • Socket.IO 연결 상태 확인

📚 참고 문서


📄 라이선스

MIT import time from can import Bus

sio = socketio.Client()

@sio.event def connect(): print('Connected to server')

CAN 버스 초기화

bus = Bus(interface='socketcan', channel='can0', bitrate=500000)

def send_vehicle_data(): while True: for msg in bus: # CAN 메시지 파싱 vehicle_data = { 'speed': msg.data[0], 'doorLocked': msg.data[1] == 1, 'emergencies': [] } sio.emit('update-vehicle-data', vehicle_data)


## 📝 환경 변수

### 백엔드 (.env)

PORT=3001 CLIENT_URL=http://localhost:5173


### 프론트엔드 (.env.local)

VITE_SERVER_URL=http://localhost:3001


## 🎨 UI/UX 특징

- 다크 테마 (시각적 편의성)
- 사이버펑크 스타일 인터페이스
- 심각도별 색상 코딩
  - 🔴 Critical (위험)
  - 🟠 Warning (경고)
  - 🔵 Info (정보)
- 애니메이션 효과 (실시간 상태 피드백)
- 반응형 레이아웃

## 📚 참고 자료

- [Socket.IO 문서](https://socket.io/docs/)
- [React.js 공식 문서](https://react.dev/)
- [Express.js 가이드](https://expressjs.com/)
- [Vite 문서](https://vitejs.dev/)

## 📄 라이선스

MIT License

About

차량 상태 및 위험 관제 기능 서버 (Front/Back)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors