- 설계 스펙 v2.0 (다관점 리뷰 반영: 기절경로 분리, 시점강건 낙상, 인증/RBAC, 평가셋, fps 3티어, 컴플라이언스, 증거 무결성) - P1-A 엣지 감지 코어 구현계획 (16 태스크 TDD) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ne4rU4FToTLHcBUMUvUnT1
36 KiB
작업장 안전관리 AI CCTV — 설계 문서 (Design Spec)
- 문서 버전: 2.0 (다관점 리뷰 반영 개정)
- 작성일: 2026-07-11
- 코드명:
move_detect - 상태: 설계 확정 대기(사용자 리뷰 전)
v2.0 변경 요약: 5개 렌즈(산업안전·엣지CV·운영UX·보안/개인정보·제품/배포) 다관점 리뷰 결과 반영. 핵심: (1) 기절 감지를 낙상 경로에서 분리(자세무관 부동 워치독 + 트랙소실 유령사고), (2) 시점/노이즈 강건 낙상(OR로직·공간바인딩·지터스무딩), (3) 대시보드 인증/RBAC 및 ingest/저장 하드닝, (4) 라벨 평가셋 + 드릴 커미셔닝 게이트, (5) fps 3티어 폴백, (6) PIPA·노사협의회 컴플라이언스 제품 내장, (7) 증거 무결성(계층 보존·legal-hold·audit). 사용자 결정: 호스팅 = Cafe24 유지(내부 하드닝) · v1+끼임 body-part(P2) · 라이브뷰 폐기(스냅샷 절대) · 컴플라이언스 제품 소유.
1. 개념 (Concept)
Raspberry Pi 5 + AI HAT+ (Hailo-8, 26 TOPS)가 작업장 카메라 영상을 **실시간 자세추정(pose estimation)**으로 분석해, 넘어짐·미동/기절·위험구역 침입(+끼임) 사고를 판단하고, 사고 순간 스냅샷과 함께 Cafe24 PHP 관제 대시보드로 즉시 경보하는 엣지 AI CCTV. 감지에 그치지 않고 응답(에스컬레이션·119)·측정(정확도)·합법(컴플라이언스)·증거보존까지 책임지는 안전관리 제품.
핵심 철학:
- 무거운 AI 판단은 전부 엣지(Pi)에서. 클라우드는 얇게 — 수신·저장·표시·발송·대응관리.
- 영상 스트림/라이브뷰를 절대 내보내지 않는다. 개인정보·대역폭 이유로 사고 순간 정지 스냅샷만 (라이브뷰·클립 없음, 사용자 결정).
- 오탐(FP)은 안전 시스템에서 치명적. 자세추정으로 앉음/숙임/의도적 눕기와 실제 낙상을 구분한다.
- 미탐(FN)은 더 치명적. 가장 위험한 케이스(좌위 실신·가림 붕괴)에서 경보가 나가도록 설계한다.
- 감지≠안전. 응답자에게 닿고, 정확도를 측정·튜닝하고, 법적 증거로 남아야 안전이 완성된다.
2. 범위 (Scope)
2.1 목표 (In scope)
- 사고 감지: 넘어짐, 넘어짐 후 장시간 미동(기절 의심), 자세무관 장시간 부동, 위험구역 침입(2단계), 끼임 body-part 침입(P2).
- 1대의 Pi가 2~4대 카메라(CSI + USB UVC 혼합) 동시 처리, fps 3티어 폴백으로 우아한 저하.
- 사고 시 스냅샷 1~3장(사고 前/中/後, 링버퍼) + 메타데이터를 Cafe24 PHP로 HTTPS POST(HMAC+nonce).
- PHP 관제 대시보드: 인증/RBAC, 실시간 사고 목록·상세, 대응 에스컬레이션, 위험구역 설정, 감도 다이얼, 장비/플릿 상태, 이력·통계, 오탐 피드백.
- 대응 계층: 확인 SLA·에스컬레이션 사다리·온콜 라우팅·119 안내 카드.
- 컴플라이언스 모듈(제품 소유): 노사협의회 협의 기록, PIPA 안내판/처리방침 메타, DPIA 체크리스트 게이트, 데이터주체 조회/삭제 도구, 배경인물 얼굴블러 default-ON.
- 증거: 계층형 보존 + legal-hold(실사고 3~5년), 위변조방지 audit 로그, 서버 신뢰 타임스탬프.
- (선택) 위급 시 SMS(기존
leak_sms게이트 재사용), 현장 GPIO 경보(경광등/부저).
2.2 비목표 (Out of scope, YAGNI)
- 라이브뷰·영상클립·상시 녹화·클라우드 스트리밍 — 절대 미포함(사용자 결정, no-streaming 원칙 고수).
- 얼굴 인식/개인 식별 — 미포함. (단 배경인물 탐지-후-블러는 최소화 요건으로 포함; 식별 아님)
- 실외·야간·IR 환경 — 대상은 실내 공장/창고, 주간 조명. (조명꺼짐은
monitoring_degraded로 처리) - 떨어짐(추락)·부딪힘(차량)·밀폐공간 질식·화재/가스 — v1 미포함, 외부센서/별도클래스 필요 → P4 범위 결정(§16).
- 기계 비상정지(E-stop) 능동 개입 — 안전PLC 인증·책임 이슈로 v1 미포함, 훅만 설계(§16 미결정).
- 시간축 딥러닝 행동인식(ST-GCN) — v1은 자세 휴리스틱. 오탐 과다 시 P4 재검토.
- 대규모 온사이트 다중 Pi 집계 서버 — P4. (단 경량 멀티사이트 플릿 레지스트리는 P2로 포함 — 클라우드가 이미 device_id 키 기반)
2.3 컴플라이언스 (제품 소유 — v1 In scope)
v1.0에서 "운영정책, 범위밖"으로 뺐던 항목을 제품 기능으로 내장한다(사용자 결정, 차별화). 이는 배포의 법적 전제:
- 근로자참여법 §20-14: 감시장비 설치는 노사협의회 필수 협의 사항 → 협의 기록(일자·안건·근로자대표 서명) 관리 기능.
- PIPA §25: 영상정보처리기기 안내판, 운영·관리방침, 목적 제한(근태감시 전용(轉用) 차단), 데이터주체 조회/삭제 권리 도구.
- 낙상/실신 영상은 민감정보 소지 → 최소수집·접근통제·접근로그.
- 배포 전 DPIA 체크리스트 게이트.
3. 요구사항 (Requirements)
3.1 기능 요구사항
| ID | 요구사항 | 단계 |
|---|---|---|
| F1 | 사람이 넘어져 완전히 넘어진 자세(prone)가 > 3초 지속되면 넘어짐 이벤트를 발생시킨다. | P1 |
| F2 | 넘어짐 상태에서 관절 움직임이 임계 미만으로 ≥10초 지속되면 "위급(기절 의심)" 최고등급 경보를 발생시킨다. | P1 |
| F3 | 스스로 일어나면(자세 복원) 넘어짐/미동 경보를 취소·하향한다. | P1 |
| F3b | 낙상 전이 없이도 추적 중인 사람이 자세와 무관하게 관절변위 임계 미만으로 N초(좌위 기본 90~180초, 위험구역 더 짧게) 지속되면 "이상 정지" 저·중등급 확인 경보를 발생시킨다. | P1 |
| F3c | FALLING/FALLEN/NO_MOTION 트랙이 복원 확인 없이 사라지면(가림) 마지막 위치에 공간 "유령사고"를 만들고, T초 내 인근에 트랙 재출현 없으면 상향한다. | P1 |
| F4 | 카메라별 위험구역 폴리곤(2단계: 경고/절대금지)에 사람 발끝이 진입하면 침입 이벤트를 발생시킨다. | P1 |
| F4b | 기계 위험점 구역에 대해 임의 신체 관절점 진입(발목만 아님)으로 끼임 위험을 판정한다. | P2 |
| F5 | 모든 이벤트는 (트랙ID 또는 공간영역) 기준 1회 발생 + 쿨다운으로 반복 폭탄을 방지한다. | P1 |
| F6 | 이벤트 시 스냅샷 1~3장(前/中/後, 링버퍼) + 메타데이터를 Cafe24로 전송한다. | P1 |
| F7 | 관리자는 인증 후 실시간 사고 목록·상세를 보고, 위험구역을 그리고, 감도를 조정하고, 이력·통계를 조회한다. | P1 |
| F8 | 전송 실패 시 로컬 큐잉 후 재전송하여 사고를 유실하지 않는다. | P1 |
| F9 | 미확인 위급 경보는 확인 SLA 초과 시 2·3차 온콜로 자동 에스컬레이션한다. | P3(위급 최소본 P1) |
| F10 | 이벤트 처리결과(실제/오탐/현장처리/드릴/검토요)를 라벨링하고, 온디바이스 키포인트 시계열로 재생·튜닝한다. | P2 |
| F11 | 임계값을 (device, camera, zone)별로 오버라이드하고, 관리자용 감도 프리셋(Conservative↔Aggressive)으로 노출한다. | P2 |
| F12 | 카메라 가림/초점흐림/조명꺼짐/탬퍼를 self-check해 monitoring_degraded를 발생시킨다. |
P2 |
| F13 | 실사고로 분류된 건은 legal-hold로 자동만료에서 제외하고 증거묶음을 내보낸다. | P3 |
| F14 | 컴플라이언스: 노사협의회 기록·안내판메타·DPIA·데이터주체 도구·얼굴블러를 제공한다. | P1 |
| F15 | "현재 프레임 캡처" 명령으로 이벤트 전에도 구역 그리기·커미셔닝·탬퍼 기준 스냅샷을 얻는다. | P1 |
3.2 비기능 요구사항
| ID | 요구사항 |
|---|---|
| NF1 | 낙상 중요 카메라 유효 ≥12~15 fps, 저위험 8~10 fps. fps 티어별 보장. |
| NF2 | 사고 발생→대시보드 표시 지연 ≤ 5초(정상 네트워크). 위급 확인 SLA 별도(§8). |
| NF3 | Pi 소프트웨어 오프라인 설치(모든 .hef·의존성 사전 번들; 폐쇄망). 업데이트는 서명 검증 오프라인 번들. |
| NF4 | 파이프라인 멈춤/카메라 끊김/가림 자동 복구·감지(워치독·재연결·self-check). |
| NF5 | POST는 HTTPS + HMAC + nonce/timestamp(replay 방지) + per-device 키. |
| NF6 | 보관은 계층형 + env 설정(하드코딩 금지): 일상/오탐 이벤트 보존일·실사고 legal-hold 기간 모두 환경변수. 기본값 TBD(법률 확정 시 조정). |
| NF7 | 대시보드 인증 필수(argon2id·세션 하드닝·RBAC·brute-force 잠금). 무인증 접근 0. |
| NF8 | 사고 정확도 목표(낙상 recall, 오탐/카메라/일, 에스컬레이션 지연)를 정의하고 커미셔닝에서 검증. |
| NF9 | 심각도는 색상 단독 금지(텍스트+아이콘+WCAG-AA+색맹안전). 데스크 오디오·모바일 push. |
| NF10 | 사고 시각은 신뢰 시간원(HW RTC + 로컬 NTP) + 서버 received_at 이중기록. |
4. 아키텍처 (Architecture)
2계층: 엣지(Pi) 감지·판단·대응트리거, 클라우드(Cafe24) 수신·인증·표시·대응관리·컴플라이언스.
┌──────────── 엣지: Raspberry Pi 5 + AI HAT+ (Hailo-8 26TOPS, PCIe Gen3, HW RTC) ────────────┐
│ │
│ [CSI캠]─(별프로세스)─┐ ┌─▶ EventEngine (상태머신 × 트랙/공간) │
│ [USB캠 MJPEG]────────┼─▶ Capture ─▶ roundrobin ─▶ │ ├ FallDetector (OR로직, 시점강건) │
│ [USB캠 MJPEG]────────┘ (정규화640) hailonet │ ├ ImmobilityWatchdog (자세무관 부동) │
│ (공유 pose, └streamrouter│ ├ GhostIncident (트랙소실 공간사고) │
│ batch≥N) → Tracker │ └ ZoneIntrusion (발끝/body-part) │
│ (ByteTrack └────────────┬──────────────────────────┤
│ +공간바인딩, │ │
│ 지터스무딩) RingBuffer(前/中/後 프레임) │
│ │ ▼ │ │
│ Snapshotter+FaceBlur Alerter(POST+GPIO) │
│ │ │ │ │
│ LocalQueue◀─재시도─┘ HealthAgent │
│ (암호화) (하트비트/워치독/ │
│ │ 카메라 self-check)│
│ Config(구역·임계값 per-cam/zone, 동기) │
│ Secrets(TPM/keyring, per-device 키) │
└────────────────────────────────┼───────────────────────────────────────┬───────────────────┘
HTTPS POST(이벤트+JPEG, HMAC+nonce) GPIO │
하트비트(fps·온도·스로틀·큐·config버전) ▼
┌──────────────── 클라우드: Cafe24 웹호스팅 (PHP + MySQL) ─────────────────┐ [경광등/부저]
│ [인증/RBAC] ── 세션하드닝 ── 접근로그 │
│ Ingest API(HMAC+nonce검증, 이미지 재인코딩, rate limit) │
│ │ │
│ MySQL ── 스냅샷은 웹루트 밖 저장 → 인증 PHP 프록시로만 서빙 │
│ ├─ 실시간 관제(사고 목록·상세, 심각도 텍스트+아이콘, 데스크오디오) │
│ ├─ 대응(에스컬레이션 사다리·온콜 로스터·119 카드·NEW→CLAIMED→RESOLVED) │
│ ├─ 위험구역 설정(폴리곤 드로잉) + 감도 다이얼(per-cam/zone) │
│ ├─ 장비/플릿(사이트별, config버전, 온도/스로틀, 카메라 degraded) │
│ ├─ 오탐 피드백(처리결과 라벨·재생·튜닝 제안) │
│ ├─ 이력·통계·KPI + 증거묶음 내보내기(legal-hold, 산업재해조사표) │
│ └─ 컴플라이언스(노사협의회 기록·안내판메타·DPIA·데이터주체·블러정책) │
│ audit 로그(append-only 해시체인: 임계값·조회·내보내기·확인) │
│ SMS 발송(위급, leak_sms 재사용) · Config/구역 동기 API(버전확인) │
│ 모바일 PWA + Web Push (high/warning) · SMS(critical 폴백) │
└────────────────────────────────────────────────────────────────────────────┘
4.1 단일 공유모델 원칙 (유지)
모든 카메라가 단일 yolov8s_pose HEF를 공유하고, 사람 박스·발끝/관절(구역·끼임)·관절 기하(낙상)·관절 변위(미동)를 같은 pose 출력에서 파생. 2모델 동시는 컨텍스트스위치 손해라 회피.
5. 엣지 컴포넌트
| 컴포넌트 | 책임 | 신규/변경 |
|---|---|---|
| Capture | CSI=picamera2(카메라당 별 프로세스), USB=v4l2 MJPEG. 640 정규화. "현재프레임 캡처" 명령 지원. | +F15 |
| Inference | 공유 yolov8s_pose HEF. roundrobin→hailonet(batch≥N)→streamrouter. fps 3티어(§10.2). |
+티어 |
| Tracker | ByteTrack/OC-SORT. 공간(IoU) 바인딩으로 ID스위치 시 상태·타이머 승계. per-keypoint One-Euro/Kalman 스무딩. | 변경 |
| EventEngine | 트랙/공간 상태머신 4서브: FallDetector·ImmobilityWatchdog·GhostIncident·ZoneIntrusion(+body-part). | 대폭 |
| RingBuffer | 사전 프레임 링버퍼 → 사고 前/中/後 스냅샷 공급. 온디바이스 키포인트 시계열 기록. | 신규 |
| Snapshotter+FaceBlur | 링버퍼에서 1~3장 JPEG. 배경인물 얼굴 블러 default-ON(피재자 제외 옵션). | +블러 |
| Alerter | 이벤트+스냅샷 POST(HMAC+nonce). 위급 시 GPIO + SMS 트리거. | +nonce |
| LocalQueue | 실패 시 암호화(LUKS) SQLite 큐, 백오프 재전송. | +암호화 |
| Config | 구역·임계값 per-(device,camera,zone) 로컬 관리, 클라우드 동기 + 적용버전 보고. | 변경 |
| Secrets | HMAC/SMS 키를 TPM/keyring, per-device. 평문파일 금지. | 신규 |
| HealthAgent | 하트비트(fps·온도·스로틀·큐깊이·config버전). 프레임정체·카메라끊김 복구. 카메라 가림/초점/조명/탬퍼 self-check → monitoring_degraded. |
대폭 |
6. 이벤트 판정 로직
모든 픽셀 임계는 사람 bbox 높이로 정규화. 단 이는 스케일만 보정 — 렌즈왜곡·마운트유형(탑다운 vs 사각)은 per-camera 캘리브레이션 프로파일로 보완(§16 캘리브 도구). 임계는 실장비 튜닝 전 시작값, per-cam/zone 조정 가능.
6.1 트랙/공간 상태머신 (기절 경로 분리)
┌──────────── ImmobilityWatchdog (자세 무관, 독립) ───────────┐
│ 임의 트랙이 관절변위<임계 N초 지속 → "이상정지" 저·중경보 │
└──────────────────────────────────────────────────────────────┘
STANDING/SITTING ──(급격 수직하강 or 낙상 전이)──▶ FALLING ──(prone >3s)──▶ FALLEN
▲ │ │
│(자세복원, F3) │(복원) │(관절변위<임계 ≥10s)
└──────────────────────────────────────────────┴─────────────────────────┤
▼
NO_MOTION (위급/기절)
[임의 상태에서 트랙 소실(복원확인 없이)] ──▶ GhostIncident(마지막 위치) ──(T초 내 미재출현)──▶ 상향
- 핵심 변경: 위급(기절) 경보는 이제 FALLEN 경로 전용이 아니다. ImmobilityWatchdog가 자세·트랙연속성과 무관하게 병렬로 돈다. 좌위 실신·기대 슬럼프도 잡힘.
- incident 활성 중 baseline freeze: §6.5 재보정이 넘어진 자세를 "정상"으로 재앵커하지 않도록, 임의 incident 상태 동안 정상자세 기준을 동결.
6.2 넘어짐 (Fall) — F1, 시점 강건 (OR 로직)
각도 = 몸통(어깨중심→엉덩이중심) 벡터가 수직축과 이루는 각. 서있음≈0°, 누움≈90°.
FALLING 진입(전이): 몸통각도 ~45° 상향 돌파 AND COM 하강속도·낙차 유의미(10프레임 윈도우, 정규화).
FALLEN 확정 — 직교 단서 OR 결합(정면/후면 낙상 대응):
- 다음 중 하나 이상 확신 + prone > 3초(20프레임 다수결):
- 몸통각도 수직대비 > 70°(측면 낙상), 또는
- bbox 수직크기(높이) 급붕괴(정면/후면 낙상 — 각도·종횡비 안 변해도 키가 확 줄음), 또는
- COM 하강속도 큼 + 바닥권 정지, 또는
- 머리 y > 엉덩이 y 또는 종횡비 W/H > 1.25.
- AND 게이트 폐기 이유: 카메라 향해/등지고 넘어지면 몸통벡터 단축·종횡비 불변 → v1.0의 AND 조합은 한 방향 통째 미탐이었음.
- 관절 신뢰도 게이트: conf<0.5 폐기, 핵심 4관절 필수, 가시 ≥10.
6.3 미동/기절 (No-motion) — F2, F3, F3b
- 낙상 후 미동: FALLEN 진입 시 타이머, 관절변위<임계 ≥10초 → NO_MOTION 위급(대시보드+SMS+부저).
- 자세무관 부동(F3b): ImmobilityWatchdog가 임의 트랙에 대해 변위<임계 지속(좌위 90~180초, 위험구역 더 짧게) → 저·중 확인경보 → 미해소 상향.
- 지터 대응: INT8 pose 관절은 FP보다 노이즈 큼 → per-keypoint 스무딩, 미동 임계 = 측정된 정지지터 + 마진(무한 미발화 방지).
- 움직임 재개 → 취소·하향. 위급 후 쿨다운.
6.4 위험구역 침입 — F4 / 끼임 body-part — F4b(P2)
- 일반 침입(F4): 발목 관절점 point-in-polygon. 경고구역(노랑)/절대금지(주황+옵션 부저). 디바운스 0.5~1초.
- 끼임 body-part(F4b, P2): 기계 위험점 구역은 임의 관절점(손목·팔꿈치 등) 진입으로 판정. 손/팔이 프레스·롤러 위험점에 들어가는 상황 커버. point-in-polygon 소확장.
- 구역은 대시보드에서 스냅샷 위 폴리곤 드로잉. (E-stop 능동개입은 훅만, §16)
6.5 공통 억제 규칙
- (트랙ID 또는 공간영역)당 1회 + 유형별 쿨다운. GhostIncident는 공간영역 기준.
- 저신뢰 검출 판정 제외. incident 활성 중 baseline 동결(§6.1).
7. 클라우드 (Cafe24 PHP + MySQL) — 하드닝
Cafe24 공유호스팅 유지(사용자 결정). 공유호스팅 한계를 인정하되 내부 하드닝 최대로. 스냅샷 웹루트 밖 + 프록시, 인증/RBAC, replay 방지가 필수.
7.1 인증 / 접근제어 (신규, P1)
- 로그인 필수(argon2id, HttpOnly+Secure+SameSite 쿠키, CSRF 토큰, brute-force 잠금, HTTPS/HSTS).
- RBAC: admin(설정·임계값·컴플라이언스) / operator(확인·대응) / viewer(조회). 사이트 스코프.
acknowledged_by는 인증 주체에 바인딩. 모든 조회/내보내기 접근로그(PIPA).
7.2 화면 (Dashboard)
| 화면 | 기능 |
|---|---|
| 실시간 관제 | 이벤트 실시간 목록, 미확인 상단고정, 심각도 = 텍스트(위급/높음/경고)+아이콘+색(색맹안전), 데스크 Web Audio(위급 반복·무음불가). |
| 사고 상세 | 스냅샷 1~3장(前/中/後), 카메라·시각·구역·트랙ID·지속, 처리결과 라벨(실제/오탐/…), 확인처리(인증). |
| 대응 | 확인 SLA 타이머, 에스컬레이션 사다리(2/3차 온콜·음성콜), 온콜 로스터/교대, 119 카드(위치도·주소·게이트코드·AED·응급처치), NEW→CLAIMED→RESOLVED. |
| 위험구역 설정 | 최신/현재캡처 스냅샷 위 폴리곤 드래그, 경고/금지/끼임 지정, Pi 동기. |
| 감도 | (device/camera/zone)별 프리셋 Conservative↔Balanced↔Aggressive + 고급 raw 슬라이더. |
| 장비/플릿 | 사이트별 Pi·카메라 상태, config 적용버전(drift 표시), 온도/스로틀/fps, monitoring_degraded. |
| 오탐 피드백 | 처리결과 라벨 집계, 키포인트 시계열 재생, 임계 튜닝 제안. |
| 이력·통계 | 날짜·구역·유형 이력, KPI(오탐률·MTTA), 히트맵, 증거묶음 내보내기(legal-hold, 산업재해조사표 프리필). |
| 컴플라이언스 | 노사협의회 협의 기록, 안내판/처리방침 메타, DPIA 체크리스트, 데이터주체 조회/삭제, 얼굴블러 정책. |
| 모바일 | PWA 반응형 + Web Push(high/warning), SMS(critical 폴백), 딥링크. |
7.3 데이터 계약 (Ingest API) — 하드닝
POST /api/events (JSON+base64 또는 multipart), 헤더 X-Signature: HMAC-SHA256(nonce+ts+body, per_device_secret), X-Nonce, X-Timestamp.
- replay 방지: nonce 1회성 + timestamp 윈도우 검증.
- 이미지: 서버가 GD/Imagick로 재인코딩(페이로드 제거, 강제 .jpg, 랜덤 UUID 파일명), 웹루트 밖 저장, 인증 PHP 프록시로만 서빙(IDOR 차단).
- SQL: prepared statement + event_type/severity 화이트리스트 enum. 출력 인코딩 + CSP(저장 XSS).
- 남용: per-device rate limit + 크기/inode 쿼터(위조 홍수로 스토리지·대시보드 다운 방지).
{
"device_id": "pi-warehouse-01",
"camera_id": "cam-02",
"event_type": "fall | no_motion | immobility | ghost | zone_warning | zone_restricted | pinch | monitoring_degraded | device_fault",
"severity": "critical | high | warning | info",
"track_id": 42,
"zone_id": "zone-loading-dock",
"occurred_at": "2026-07-11T09:15:32+09:00",
"received_at": "(서버 기록)",
"duration_s": 12.4,
"disposition": "unset | real_emergency | false_alarm | handled_onsite | drill | needs_review",
"is_test": false,
"metrics": { "torso_angle": 78.2, "height_collapse": 0.55, "immobility_s": 10.1 },
"snapshots": ["<jpeg-1>", "<jpeg-2>", "<jpeg-3>"]
}
POST /api/heartbeat — device_id, 카메라별 상태·fps·온도·스로틀·큐깊이·config버전.
GET /api/config?device_id= — 구역·임계값(per-cam/zone) 최신본; Pi가 적용버전 회신.
7.4 DB 스키마(개략)
users(user_id, role, site_scope, password_hash, ...),sites(site_id, name, address)devices(device_id, site_id, name, last_heartbeat, temp, throttle, config_version, status)cameras(camera_id, device_id, name, role[fall_critical|zone|low], last_frame_at)zones(zone_id, camera_id, level[warning|restricted|pinch], polygon_json, updated_at)events(event_id, device_id, camera_id, event_type, severity, track_id, zone_id, occurred_at, received_at, duration_s, disposition, is_test, legal_hold, metrics_json, acknowledged_by, acknowledged_at, lifecycle_state)event_snapshots(snapshot_id, event_id, file_uuid, content_hash, created_at)— 웹루트 밖.thresholds(device_id, camera_id, zone_id, key, value)— per-cam/zone.escalations(event_id, level, recipient, sent_at, delivered, responded_at),oncall(site_id, shift, recipient, priority)audit_log(id, actor, action, target, before, after, ts, prev_hash, hash)— append-only 해시체인.compliance(site_id, nosa_record_json, dpia_json, signage_meta, subject_requests_json)retention_policy(data_class, days, legal_hold_years)
8. 신뢰성 / 대응 / 에러 처리
- 오프라인 큐: 실패 시 암호화 SQLite 저장, 백오프 재전송. 유실 0.
- 하트비트: 30초 주기(fps·온도·스로틀·큐·config버전). 90초 무신호 → "감시 중단" 경보.
- 카메라 재연결 + self-check: 끊김 자동 재오픈; 가림/초점흐림/조명꺼짐/탬퍼 →
monitoring_degraded(다운과 구분). active-hours 스케줄로 off-shift 블라인드는 정상 처리. - 워치독: 프레임 정체 → systemd watchdog 재시작.
- 대응 에스컬레이션(F9): 위급 미확인 SLA 초과 → 2/3차 온콜·음성콜 폴백 → 119 카드 → 지방노동관서 보고 초안. SMS 전송영수증 추적·미전달 재라우팅.
- 경보 이중화: 위급 = 대시보드+SMS+부저+데스크오디오 동시.
- 신뢰 시간: HW RTC + 로컬 NTP; 서버 received_at 병기; skew 플래그.
9. 개인정보 / 보안
9.1 데이터 / 프라이버시
- 클라우드엔 사고 스냅샷만(라이브뷰·영상 없음). 배경인물 얼굴블러 default-ON.
- 계층형 보존(NF6): 일상/오탐 30
90일, 실사고 **legal-hold 35년**(산안법 §164 대응; 정확 값 법률 확정 §16). 자동삭제가 중대재해 증거 파기하지 않도록 legal-hold 우선. - 목적 제한(근태감시 전용 차단), 데이터주체 조회/삭제, 모든 조회/내보내기 접근로그.
9.2 애플리케이션 보안
- 대시보드 인증/RBAC/세션하드닝(§7.1). ingest HMAC+nonce+per-device 키(§7.3).
- 스냅샷 웹루트 밖 + 프록시, 이미지 재인코딩, prepared statement, CSP, rate limit.
- 위변조방지 audit: 임계값·구역·확인·조회·내보내기 전부 append-only 해시체인(누가·언제·전·후). 감도 몰래 낮춰 사고 은폐 탐지.
9.3 엣지 / 공급망
- 큐/스냅샷 파티션 LUKS 암호화, 시크릿 TPM/keyring(평문 금지), 함체 탬퍼 GPIO → 보안이벤트.
- SSH 키전용·root 비활성·egress 방화벽(Cafe24만). TLS 엄격검증 + 인증서 핀닝 fail-closed.
- 모든 vendored 의존성·
.hefSHA256/GPG 검증(빌드+로드시) + SBOM. (참고 fall repo의 Azure 문자열 유출 사례 = 공급망 리스크 근거.)
9.4 시크릿 관리
- HMAC·SMS·DB 키 환경변수/시크릿 매니저. 소스·아티팩트 하드코딩 금지. per-device 키 회전/폐기.
10. 하드웨어 · 모델 · 런타임 (조사 근거)
10.1 모델
- 주 모델
yolov8s_pose(640×640, 17 관절). Hailo-8 pose HEF 라이트. 세 이벤트 전부 여기서 파생. - Hailo HEF 배포 → 런타임 ultralytics(AGPL) 비의존.
10.2 fps 3티어 폴백 (신규, P1 설계 의무)
미검증 pose fps 리스크에 제품적 답. 카메라 role이 NPU 스케줄링 구동:
| 티어 | 처리 | 용도 | 부하 |
|---|---|---|---|
| T1 full-pose | 관절17 → 낙상+미동+구역+끼임 | fall_critical 카메라 | 최대 |
| T2 detection-only | 사람박스+발끝앵커 → 구역+거친 낙상(종횡비)만 | zone 카메라 | 중 |
| T3 motion-occupancy | 움직임/점유만 → 부동·구역 진입만 | low-priority | 최소 |
- PCIe Gen3 강제(
dtparam=pciex1_gen=3),batch-size ≥ N, 640 유지. - 실병목 = Pi CPU(파이프라인당 ~1코어). 후처리 C/GStreamer, Python 콜백 최소.
- 3티어 전부 P1에서 실장비 검증 → 우아한 저하 제품 확보 후 고객약속. 벤치 결과 → cameras-per-Pi·Pis-per-site·BOM·가격 산정.
- 스로틀 텔레메트리: 뜨거운 밀폐 함체 스로틀이 fps 저하 → 온도·스로틀 하트비트로 티어 신뢰.
10.3 카메라 캡처
- CSI: picamera2, 카메라당 별 프로세스. USB: v4l2 MJPEG 필수, 2개 USB3 컨트롤러 분산 + 전원 허브.
10.4 런타임 스택
- hailo-rpi5-examples(MIT) + hailo-apps-infra + GStreamer.
N소스 → hailoroundrobin → 단일 hailonet(공유 pose, batch≥N) → hailostreamrouter → 캠별 추적/룰.
10.5 참조 BOM / 사이트 준비 (P2)
- 카메라 SKU·렌즈/FoV, IP5x+ 방열·필터 함체(동작온도 명시), 마운트/조준 가이드, 전원 허브, 소형 UPS(정전 라이드), 네트워크 업링크/페일오버. "현재프레임 캡처"(F15)로 신규캠 구역 그리기 chicken-egg 해소.
11. 재사용 OSS 및 라이선스
| 용도 | 프로젝트 | 라이선스 | 방식 |
|---|---|---|---|
| 플러밍 뼈대 | hailo-ai/hailo-rpi5-examples | MIT | fork |
| 추적+체류 참조 | Seeed YOLOv11-Hailo-Tracker | MIT | ByteTrack+dwell → 구역/미동 타이머 |
| 구역/끼임 | roboflow/supervision | MIT | PolygonZone 앵커(발끝/임의관절) |
| 구역 드로잉 UI | roboflow/polygonzone | MIT | 참조 |
| 추적기 | ByteTrack / OC-SORT | MIT | 기본/대안 |
| 키포인트 스무딩 | One-Euro filter | 공개 알고리즘 | 자체 구현 |
| 낙상 휴리스틱 | InvictusRex, Y-B-Class 등 | 무라이선스 | 알고리즘만 참고·재구현 |
라이선스 함정: ultralytics(AGPL) 런타임 배제 → Hailo HEF + 자체 로직. 무라이선스 repo = 알고리즘 참고만. (16dina/fall-detection Azure 문자열 유출 블록 복사 금지.)
12. 테스트 / 검증 전략
- 유닛: 상태머신(전이·부동 워치독·유령사고·디바운스·쿨다운·baseline freeze) 합성 시퀀스, 80%+ 코드커버리지.
- 탐지 정확도(NF8, 신규): 라벨 평가셋 구축 — 공개 낙상 코퍼스 + 매트 연출낙상 + 강한 하드네거티브(앉음·깊은 숙임·의도적 눕기·무거운 물건 낙하·2인 겹침) + 정면/후면·가림·기어감·프레임가장자리 케이스. 목표: 낙상 recall, 오탐/카메라/일, 에스컬레이션 지연.
- 커미셔닝 게이트(신규): 드릴 모드로 실장착 카메라별 연출낙상 → pass/fail 리포트.
is_test=true로 실제 119/SMS 억제. go-live 전제 + 중대재해처벌법 due-diligence 증거. - 부하: 4캠 라운드로빈 fps·CPU·온도·지연 실측(티어별).
- E2E: 모의사고 → 스냅샷 → Cafe24 수신(인증/HMAC) → 대시보드 → 에스컬레이션 → (위급) SMS.
- 오프라인: 네트워크 차단 설치·구동(NF3), POST 실패→큐→복구 재전송.
- 보안: 인증/RBAC·replay·IDOR·업로드·SQLi·rate limit 침투 테스트.
13. 단계별 로드맵 (리뷰 반영 재배치)
- P1 (MVP + 안전 필수): 1캠 낙상 + 자세무관 부동(F3b) + 유령사고(F3c) + 스냅샷 POST. 시점강건 낙상(OR)·지터스무딩·baseline freeze. 대시보드 인증/RBAC(F7,NF7) + ingest 하드닝(NF5). 라벨 평가셋 + 드릴 커미셔닝 게이트(NF8). fps 3티어 검증(§10.2). 컴플라이언스 최소본(F14: 노사협의회·안내판·블러·DPIA). 색맹안전 심각도(NF9). "현재프레임 캡처"(F15). 위급 최소 에스컬레이션.
- P2: 멀티캠(2~4) + 끼임 body-part(F4b) + 위험구역 2단계·감도 다이얼(F11) + 오탐 피드백·링버퍼(F10) + 카메라 self-check(F12) + 신뢰시간(NF10) + 경량 멀티사이트 플릿 + 플릿 관측성·물리내구 + BOM/함체/UPS.
- P3: 대응 에스컬레이션 풀(F9) + 증거 무결성·legal-hold·audit(F13) + 엣지 하드닝(LUKS/TPM/탬퍼) + 서명 오프라인 OTA + SMS/GPIO 이중화 + 이력·통계·KPI.
- P4 (선택/범위결정): 떨어짐·부딪힘·밀폐공간(외부센서) · 끼임 E-stop 능동개입 · 행동인식(ST-GCN) · 대규모 다중 Pi 집계 · RTSP 레트로핏 수신.
14. 미해결 리스크 / 실장비 검증 체크리스트
- [최우선] Pi
yolov8s_pose엔드투엔드 fps 미검증. 3티어 전부 실장비 벤치 → 캠 수·BOM 확정. - PCIe Gen3 안정성 — 지속부하·발열 링크 안정.
- 멀티 CSI 불안정 — 카메라당 별프로세스, 장시간 CSI+USB 동시 검증.
- USB UVC 대역폭 — MJPEG, 2 USB3 분산.
- 마운팅 각도별 휴리스틱 오탐 — per-camera 캘리브 + 현장영상 튜닝.
- 저fps 낙상 누락 — 낙상 중요캠 ≥12~15fps, 속도 휴리스틱 발화 확인.
- INT8 pose 정확도/지터 — recall·미동 임계에 영향, 평가셋으로 측정.
- 가림/ID스위치 — 공간바인딩·유령사고 효과 실측.
- Cafe24 공유호스팅 하드닝 한계 — 웹루트밖·프록시·rate limit로 완화, 침투 테스트로 검증.
- 폐쇄망 패키징 —
.hef·휠·PHP 의존성 번들, 차단 설치 검증, HailoRT↔Compiler 버전 정렬. - 열/스로틀 — 함체 방열 검증, 스로틀 텔레메트리.
- SD 마모 — SSD/NVMe 부팅 + WAL로 "유실0" 보전.
15. 설정 파라미터 레퍼런스 (시작값, per-cam/zone 조정)
| 파라미터 | 시작값 | 비고 |
|---|---|---|
| 몸통각도(FALLING 전이) | ~45° 상향돌파 + 하강속도 | 서있음0° 누움90° |
| FALLEN 확정 (OR) | 각도>70° 또는 높이급붕괴 또는 COM하강 또는 머리<엉덩이/AR>1.25 | 시점강건 |
| bbox 종횡비 | > 1.25 (Δ>0.35 급변) | |
| 관절 신뢰도 | conf ≥ 0.5, 핵심4·가시≥10 | |
| 낙상 확정 지속 | prone > 3초 (20프레임 다수결) | |
| 낙상후 미동 | 관절변위<임계 ≥10초 | 5~15초 |
| 자세무관 부동(F3b) | 좌위 90~180초 / 위험구역 더 짧게 | |
| 미동 임계 | 측정 정지지터 + 마진 | 지터 무한미발화 방지 |
| 유령사고 재출현 대기(T) | 5~15초 | 미재출현 시 상향 |
| 구역 침입 디바운스 | 0.5~1초 | |
| 하트비트/다운 | 30초 / 90초 무신호 | |
| 보관 | 일상 30 |
법률 확정 §16 |
| 낙상 중요캠 fps | ≥ 12 |
|
| PCIe | Gen3 강제 | dtparam=pciex1_gen=3 |
| 확인 SLA (위급) | 예: 60~120초 → 2차 에스컬레이션 | 온콜 구조 확정 §16 |
16. 남은 미결정 (사용자/법률 확인 필요)
- 보관기간: env 설정으로 진행(정확값 TBD, 법률 확정 시 조정). 일상/실사고 legal-hold 모두 환경변수. 낙상/실신=민감정보 확정은 법률 확인.
- 끼임 E-stop 능동개입: 안전PLC 인증·책임 감수하고 기계정지 출력? 아니면 detect-and-alert 한정? (v1은 훅만)
- 온콜/에스컬레이션 현실: 각 사이트 24/7 온콜 구조? 119/노동관서 보고 연동 형태?
- RTC BOM 비용: 유닛마다 HW RTC + 로컬 NTP 추가 수용?
- 업데이트 물류: 서명 번들을 사이트 업링크 vs USB 스니커넷? 서명·배포 권한자?
- 카메라 소싱: 그린필드 CSI/USB 한정 vs 기존 IP/RTSP/ONVIF 수신 + 고객 VMS 이벤트 내보내기(레트로핏 세일즈)?
- 떨어짐/부딪힘/밀폐공간: P4 착수 여부 및 우선순위(외부센서 필요).
문서 끝. 다음 단계: 사용자 리뷰 → writing-plans 스킬로 P1 구현 계획 수립.