Car
차량 상태 조회, TCP 명령 전송, 모니터링, 데이터 사용량 표시를 제공하는 PHP 기반 차량 서비스입니다.
프로젝트 성격
Car는 차량 모뎀/게이트웨이에서 받은 상태를 수집해 DB에 저장하고, 웹 화면과 API에서 최신 상태와 명령 실행 결과를 제공하는 내부 차량 관리 서비스입니다.
모뎀에서 제공되는 값의 한계가 있으므로 도어 잠김, 경계, 시동, 공조 상태는 여러 필드를 조합해 해석합니다. 통신사 사용량은 DB 수집값과 T world 기준 보정값을 함께 사용합니다.
주요 기능
- 차량 상태 수집과 저장
- 차량 상태 API
- 허용된 차량 명령 TCP 전송
- monitor 화면과 AJAX 상태 갱신
- monitor 화면 WakeLock, 언어, 테마 토글
- 모바일 폭에 맞춘 사용량 2줄 배치, 로그 가로 스크롤, 시간 문구 축약
- 사용량/요금 표시와 보정 metadata
- 4.95초 UI timeout과 60초 사용량 정산 분리
- TCP 실패 reason과 마지막 수신 지연 표시
- 수집 공백을 반영한 차량 상태 경과 시간 표시
- 도어/경계/시동/공조 상태 해석
- 실시간 차량 도어/트렁크 열림 표시
- service worker와 PWA icon 제공
주요 API
api.php?action=status: 차량 상태 조회api.php?action=command: 차량 명령 전송monitor.php?mode=ajax: monitor 상태 AJAXmonitor.php?mode=usage: 데이터 사용량 AJAX
Monitor 경과 시간
monitor.php?mode=ajax의 meta.state_duration은 현재 시동 상태가 연속으로 유지된 시간입니다. 화면의 시동 카드 문장은 이 값을 사용해 시동 켜짐/꺼짐 경과를 표시합니다.
meta.engine_state_duration도 같은 기준의 값을 함께 내려주어 내부 확인과 호환성을 유지합니다.
상태 기록 섹션의 경과는 각 로그가 기록된 시각부터 현재까지 흐른 시간입니다. 각 행의 age_seconds는 서버 현재시각과 로그 timestamp의 차이로 계산해 내려주며, 화면 갱신마다 상단 조회 주기 경과처럼 계속 증가합니다.
모바일처럼 폭이 좁은 화면에서는 조회 경과와 시동 유지 시간이 한 줄로 유지되도록 초, 필요 시 분 단위를 생략해 표시합니다. 사용량 지표는 3열 2줄로 카드 안에 배치하고, 상태 기록 테이블은 카드 내부 좌우 스크롤로 분리해 전체 페이지 레이아웃이 밀리지 않게 합니다.
실시간 차량 그림의 도어/트렁크 열림 표시선은 열림 애니메이션 중에도 차량 기준 위치를 유지합니다. 트렁크 표시선은 중앙 정렬 기준을 유지한 상태에서 확대되어 PC와 모바일 모두에서 차체 하단과 맞도록 표시됩니다.
Monitor 화면 제어
헤더 우측 컨트롤은 WakeLock, 언어, 테마 순서입니다. WakeLock은 Screen Wake Lock API를 지원하는 브라우저에서 화면 꺼짐을 방지하며, 활성 상태는 초록색 아이콘 버튼으로 표시합니다. 사용자의 선택은 localStorage에 저장하고, 새로고침이나 탭 복귀 후에는 브라우저 정책에 맞춰 다시 획득을 시도합니다.
구성
api.php: 차량 상태/제어 APImonitor.php: 모니터링 화면과 AJAX 응답common.php: 외부 secret 로드와 공통 DB/API 함수collector_se.php: 상태 수집 CLI/crontcp_worker.php: TCP 큐 처리와 늦은 사용량 정산 workercar-tcp-worker.service: systemd service 예시sw.js: service workerassets/: 아이콘과 정적 자산
데이터/저장소
- Car DB tables: 차량 상태, 로그, 차트용 기록, TCP 요청 큐
- 사용량 수집값과 월별 보정 기준
/home/seo/secret/car.php: TCP, DB, token, 허용 IP 설정
처리 흐름
collector_se.php가 차량 상태를 수집해 DB에 저장합니다.monitor.php는 상태 AJAX와 사용량 AJAX를 분리해 갱신합니다.- 제어 요청은 token/IP 정책을 검증합니다.
- 명령 코드를 허용 목록과 대조합니다.
- 요청을
car_tcp_request_queue에 저장합니다. car-tcp-worker.service가 큐를 처리하며 TCP 게이트웨이로 전송합니다.- API는 큐 상태를 4.95초까지만 기다린 뒤 결과 또는 timeout을 반환합니다.
TCP timeout과 사용량 정산
차량 명령 성공/실패 판단은 UI 안정성을 위해 TCP_TOTAL_TIMEOUT 기본값인 4.95초를 사용합니다. 이 시간 안에 정상 응답이 없으면 API는 기존처럼 실패를 반환하므로 자동화와 UI는 즉시 재시도 여부를 판단할 수 있습니다.
단, 실제 모뎀이 4.95초 이후에 늦게 응답할 수 있으므로 사용량 기록은 별도로 정산합니다. API는 요청을 DB 큐에 넣고 4.95초까지만 기다립니다. car-tcp-worker.service는 해당 요청의 TCP 연결을 직접 열고, UI timeout 이후에도 같은 소켓을 최대 TCP_USAGE_SETTLEMENT_TIMEOUT 기본 60초까지 더 관찰합니다.
- 60초 안에 정상 응답이 완성되면
late_response_after_ui_timeout으로 송신량과 수신량을 함께 기록합니다. - 60초까지 응답이 없으면
late_total_timeout_60s_sent_only로 송신 패킷만 사용량에 반영합니다. - 60초 안에 일부 데이터만 오고 정상 포맷이 아니면
late_invalid_or_partial_response로 실제 수신된 바이트까지 기록합니다. - 늦은 정상 응답이 차량 상태 포맷이면 상태 DB에도 저장합니다.
이 구조에서 request_id는 UI 응답과 늦은 사용량 정산 기록을 연결하는 기준입니다. 즉 명령 재시도 로직은 4.95초 기준을 유지하고, 데이터 사용량은 최대 60초까지 늦은 수신 패킷을 반영합니다.
systemd worker
설치 파일은 car-tcp-worker.service입니다.
cp /var/www/seoul/car/car-tcp-worker.service /etc/systemd/system/car-tcp-worker.service
systemctl daemon-reload
systemctl enable --now car-tcp-worker.service
systemctl status car-tcp-worker.service
큐 테이블은 코드에서 자동 생성합니다. Worker가 중지되면 API 요청은 큐에 쌓이지만 4.95초 안에 처리되지 않아 실패로 반환될 수 있습니다. 안전을 위해 worker가 뒤늦게 오래된 queued 요청을 발견하면 실제 TCP 송신 없이 queue_expired_before_send로 만료 처리합니다.
Worker 교체나 예외 종료로 processing, ui_timeout_pending 상태가 남으면 다음 claim 전에 stale queue를 복구합니다. 전송 전이면 expired_before_send, 이미 TCP payload를 보낸 상태면 settled_sent_only로 정산해 사용량 누락을 막습니다.
주요 함수/모듈
common.php: secret 로드와 공통 DB/API 함수api.php: 상태 조회와 명령 전송monitor.php: 화면 렌더링과 AJAX 응답collector_se.php: 상태 수집과 중복 실행 방지tcp_worker.php: TCP 요청 큐 처리와 60초 사용량 정산
보안
- 차량 API는 API token 또는 허용 IP 정책을 사용합니다.
- 차량 제어 명령은 허용된 명령 코드로 제한합니다.
- Secret 파일은 저장소 밖에서 제한된 권한으로 유지합니다.
- 실제 제어 명령은 최신 상태 조회와 명령 검증 이후에만 전송합니다.
운영 체크포인트
- 차량 TCP 실패 reason과 마지막 수신 지연을 확인합니다.
- 명령별 rate limit과 감사 로그를 유지합니다.
- 통신사 기준 데이터 사용량 보정값을 주기적으로 확인합니다. 2026-06-26 01:10 T world 실측 102.4MB(104,834KB) 기준 2026-06 보정값은 통신사 누적 107,350,016 bytes, 로컬 보정 전 누적 54,104,011 bytes, 배율 1.984142입니다.
- 직전 배율 1.984648 기준 현재값은 107,377,429 bytes로 계산되어 T world보다 27,413 bytes(약 0.026MB) 높았고, 새 배율은 직전보다 0.000507 낮아졌습니다.
- 데이터 사용량 집계는 성공 응답 평균을 SQL로 먼저 구하고, 월간/일간 행은 PHP에서 한 줄씩 스트리밍 처리합니다. 기존 보정 조건은 유지하면서
fetchAll()메모리 사용을 제거해 PHP-FPMmemory_limit=128M에서도 동작하도록 합니다. - 4.95초 timeout 직후에는 사용량 기록이 즉시 생기지 않을 수 있으며, 최대 60초 뒤 늦은 정산 행이 추가될 수 있습니다.
systemctl status car-tcp-worker.service와journalctl -u car-tcp-worker.service로 worker 상태를 확인합니다.