1.0.0 이후 edge/ 는 한 줄도 바뀌지 않았다(git diff 확인). 바뀐 것은 서버뿐이라 서버 전용 릴리스로 낸다. 왜 버전을 올리는가: dist/ 재생성으로 DeviceHealthWatch 가 이미 패키지에 들어가 있는데 VERSION 은 1.0.0 이었다. 그대로 두면 "1.0.0" 이름표를 단 서로 다른 패키지가 두 종류 생긴다. 기능 추가이므로 1.1.0. - VERSION 1.0.0 -> 1.1.0 - CHANGELOG "미출시 (main)" 절을 1.1.0 으로 확정 - dist 재생성 + 구버전 ZIP 제거(같은 폴더에 두 버전이 있으면 잘못 집는다) -> move-detect-cafe24-1.1.0-20260904.zip - 사용설명서·경영진 덱·소개서 재생성 (전부 VERSION 을 표기에 쓴다) Pi 번들은 이번 릴리스에서 갱신하지 않았다. edge/ 가 불변이라 내용은 1.0.0 과 동일하고, 재빌드는 arm64 + 네트워크(pip download, fetch_hailo_hef)가 있는 빌드 머신에서만 가능하다. dist/ 에는 1.0.0 타르볼이 그대로 남아 있으므로, Pi 를 납품할 때 그 머신에서 재빌드해 파일명 버전을 맞춰야 한다. 검증: pytest 308 passed / phpunit 240 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBjuR7DW6PNNMows4KnbYU
20 KiB
move_detect — 작업장 안전 AI CCTV
쓰러진 작업자를 3초면 알아채고, 즉시 현장에 울리고, 5분 안에 확인되지 않으면 위로 올립니다.
실내 공장·창고의 안전사고를 엣지 AI가 실시간으로 감지하고, 감지에서 끝내지 않고 현장 경광등과 담당자 통보까지 이어지도록 만든 온프레미스 안전관리 시스템입니다. 영상은 외부로 나가지 않습니다 — 사고 순간의 스냅샷 3장(얼굴 자동 블러)만 전달합니다.
버전 1.1.0 · 2026-08-28
1. 왜 만들었나
1-1. CCTV는 이미 있는데, 왜 사고를 못 막나
대부분의 작업장에는 이미 CCTV가 달려 있습니다. 그런데도 사고가 발생하면 다음 세 가지가 반복됩니다.
첫째, 아무도 보고 있지 않습니다. 카메라 수십 대를 실시간으로 지켜보는 인력은 어디에도 없습니다. CCTV는 사실상 사후 확인용 녹화기로만 쓰이고 있고, 그것은 사고를 막는 장치가 아니라 사고를 설명하는 장치입니다.
둘째, 발견이 늦을수록 피해가 커집니다. 넘어짐 자체보다 위험한 것은 넘어진 뒤 방치되는 시간입니다. 의식을 잃은 작업자에게 그 시간은 곧 후유장해와 사망 위험의 크기입니다. 야간·주말·단독 작업 시간대에는 이 공백이 몇 시간 단위로 벌어집니다.
셋째, 사고 후에 증명할 자료가 없습니다. 사고가 나면 사업주는 "무엇을 위험으로 보고 있었고, 어떤 통제를 걸어두었으며, 사건 당시 그것이 작동했는가"를 설명해야 합니다. 녹화 영상만으로는 그 질문에 답할 수 없습니다.
1-2. 이 세 가지를 각각 겨냥했습니다
| 문제 | move_detect의 답 |
|---|---|
| 아무도 안 보고 있다 | AI가 24시간 대신 봅니다. 사람은 감지된 사건만 봅니다 |
| 발견이 늦다 | 감지 즉시 현장 경광등이 울리고, 확인이 없으면 상위 담당자로 자동 확대됩니다 |
| 증명할 자료가 없다 | 사건마다 증거·통보·조치·위험요인이 묶인 사고조사 패키지가 한 번에 나옵니다 |
1-3. 설계를 결정한 세 가지 제약
이 제품의 형태는 다음 세 제약에서 나왔습니다. 기능보다 이 제약이 먼저입니다.
- 작업자를 감시하지 않는다. 라이브뷰가 없습니다. 영상은 저장도 전송도 하지 않습니다. 사고 순간의 스냅샷만, 그것도 얼굴을 블러 처리한 뒤에 보냅니다. 근로자 동의를 받기 어려운 구조로는 현장에 들어갈 수 없습니다.
- 인터넷이 끊겨도 동작한다. 폐쇄망 현장을 전제로 만들었습니다. 정전·회선 장애는 위험이 오히려 높아지는 시간대인데, 그때 시스템이 함께 죽으면 의미가 없습니다.
- 클라우드 GPU를 쓰지 않는다. 추론은 현장 장비에서 끝납니다. 월 사용료가 없고, 영상이 외부로 나갈 이유 자체가 없어집니다.
2. 무엇을 하는가
기능을 나열하기 전에 구조를 먼저 봅니다. 이 제품은 하나의 사슬입니다.
감지 대응 증거
───────── ───────────────── ────────────────────
17종 이벤트 → 현장 경광등 (즉시) → 사고조사 패키지
엣지 AI 판정 담당자 통보 증거 3프레임
얼굴 블러 미확인 시 상위 확대 통보 이력 · 조치 이력
위·변조 탐지 감사기록
사슬의 어느 한 칸이 비면 나머지가 무의미해집니다. 감지만 있으면 아무도 모르고, 대응만 있으면 나중에 설명할 수 없습니다.
2-1. 감지 — 무엇을 알아채는가
엣지가 17종을 판정하고, 여기에 서버가 발행하는 '미확인 경보 확대' 1종이 더해집니다. 사람에 대한 것, 구역 규칙에 대한 것, 그리고 감시 장비 자신에 대한 것으로 나뉩니다.
사람의 위험 상태
| 이벤트 | 무엇을 잡는가 |
|---|---|
| 넘어짐 | 기립→쓰러짐 전이를 자세로 판정. 쓰러진 자세가 3초(조정 가능) 지속되면 확정 — 앉는 동작과 구분 |
| 넘어짐 후 미동 없음 | 쓰러진 뒤 움직임이 없으면 위급으로 승격 — 의식 소실 의심 |
| 장시간 부동 | 자세와 무관하게 오래 움직이지 않는 작업자 |
| 위험 상태 소실 | 위험한 상태였던 사람이 화면에서 사라짐 (가림·추락 등) |
| 넘어질 뻔함 (니어미스) | 사고 직전까지 갔다가 회복 — 사고 전 신호 |
| 작업자세 부담 | 허리·팔 각도 노출 시간 집계 (익명 통계) |
구역 규칙 위반 — 관리자가 카메라 화면 위에 그린 구역에 대해 판정합니다.
| 이벤트 | 무엇을 잡는가 |
|---|---|
| 경고구역 진입 / 제한구역 침입 / 협착구역 침입 | 등급별 구역 진입 |
| 단독 작업 | 2인 1조 구역에 혼자 있는 상태가 지속 |
| 정원 초과 / 체류 상한 초과 | 구역별 인원·체류시간 규칙 위반 |
감시 자신의 건전성 — 이 항목들이 이 제품의 차별점입니다.
| 이벤트 | 왜 필요한가 |
|---|---|
| 카메라 화각 변경 | 청소하다 삼각대를 스치면 위험구역이 엉뚱한 바닥을 가리킵니다. 그런데 프레임은 계속 들어오고 화면은 정상으로 보입니다 — 이 조용한 실패를 감지합니다 |
| 카메라 가림 / 조도 저하 | 렌즈가 덮이거나 조명이 죽어 검출력이 떨어진 상태 |
| 장치 이상 | 노드가 응답을 멈춘 상태. 서버가 하트비트의 부재로 판정합니다 — 전원이나 회선이 끊긴 노드는 자기가 죽었다고 신고할 수 없기 때문입니다 |
| 감시 성능 저하 | 노드는 살아 있으나 프레임률이 떨어지거나, 카메라 하나가 오류이거나, 발열로 성능이 깎인 상태. 한 번 튄 값이 아니라 지속될 때만 사건이 됩니다 |
| 미확인 경보 확대 | 위급 사건을 정해진 시간 동안 아무도 확인하지 않았다는 사실 자체를 사건으로 만듭니다 |
보호구 미착용 · 중장비 근접 · 화재/연기 3종은 감지기 배선과 이벤트 규격이 준비되어 있으나 추론 모델이 확보되지 않아 비활성 상태입니다. 자세한 내용은 9장을 보십시오.
2-2. 대응 — 어떻게 사람에게 닿는가
감지가 화면에만 뜨면 그것은 기록 장치입니다. 이 제품은 세 갈래로 사람에게 닿습니다.
-
현장 경광등·부저 (즉시, 네트워크 불필요) 감지한 엣지 노드가 자기 GPIO로 직접 울립니다. 서버도 인터넷도 거치지 않으므로 회선이 끊겨도, 서버가 죽어도 동작합니다. 어떤 현장이든 이것부터 설정하도록 안내합니다.
-
담당자 통보 (메일 · 사내 웹훅/문자 게이트웨이) 심각도 기준을 채널마다 정할 수 있습니다. 통보에는 현장 사진이 들어가지 않습니다 — 링크만 보내고, 사진은 로그인한 사람만 봅니다.
-
미확인 시 자동 확대 위급 사건이 정해진 시간(기본 5분) 동안 확인되지 않으면 상위 담당자에게 올라갑니다. "감지했다"를 "누군가 보게 만들었다"로 바꾸는 장치입니다.
2-3. 증거 — 나중에 무엇으로 설명하는가
- 사고조사 패키지 (1클릭) — 사건 개요와 대응 소요 시간, 증거 3프레임, 같은 카메라의 전후 30분 타임라인, 누구에게 언제 통보가 갔는지, 해당 위험요인과 통제 대책, 그 카메라의 개선 조치 이력, 서명란. 인쇄해 그대로 제출합니다.
- 위·변조 탐지 감사기록 — 확인·설정변경·구역편집이 모두 해시로 연결되어 기록됩니다. 중간을 고치거나 지우면 그 이후 전 구간이 어긋나 탐지됩니다.
- 위험성평가 연계 — 감지 유형별로 어떤 위험요인을 통제하고 있는지 기록하고, 사고조사 패키지에 함께 실립니다.
2-4. 운영 — 현장이 스스로 굴릴 수 있는가
납품 후 고객이 손댈 수 없는 시스템은 결국 꺼집니다.
- 감지 임계값 편집 — 허용 범위와 설명이 화면에 붙어 있어 잘못된 값이 저장되지 않습니다
- 정비 중 알람 억제 — 계획된 작업 동안 통보만 보류. 사유 필수, 최대 8시간, 자동 만료. 감지와 기록은 계속되므로 그 시간대도 사후에 조사할 수 있습니다
- 오탐 관리 — 카메라·유형별 오탐율을 보고 재조정 대상을 고릅니다
- 교대 인수인계 — 누가 어떤 미처리 건을 넘겨받았는지 기록
- 설비 성능 추이 — "지금 살아 있는가"가 아니라 "점점 나빠지고 있는가"
- 설치 점검 화면 — 각 단계가 실제로 동작하는지 조회해서 확인
3. 기대효과
3-1. 즉시 달라지는 것
| 항목 | 도입 전 | 도입 후 |
|---|---|---|
| 야간·단독 작업 중 쓰러짐 | 다음 순찰·교대까지 방치 | 감지 즉시 경광등, 미확인 시 상위 확대 |
| 위험구역 관리 | 표지판과 교육에 의존 | 진입·단독작업·정원초과를 규칙으로 판정 |
| 사고 조사 | 녹화 뒤져 반나절 | 1클릭 패키지 (전후 맥락·통보·조치 포함) |
| CCTV 인력 | 봐야 보임 | 감지된 사건만 봄 |
| 안전 활동 증빙 | 문서로 주장 | 시스템 기록으로 제시 |
3-2. 시스템이 스스로 측정해 보여주는 효과
이 제품은 자기 효과를 스스로 계측합니다. 도입 효과를 공급자 주장이 아니라 고객 화면의 숫자로 확인할 수 있다는 뜻입니다. 안전 리포트에 다음이 나옵니다.
- 평균 대응 시간 (TTA) — 감지에서 확인까지 걸린 시간. 이 숫자가 줄어드는 것이 곧 "발견이 빨라졌다"의 증거입니다
- 니어미스 : 사고 비율 — 사고 전 신호가 얼마나 먼저 잡히는지. 니어미스가 상대적으로 많다는 것은 예방이 앞단에서 작동하고 있다는 뜻입니다
- 개선 조치 전·후 감지 밀도 — 매트를 깔았더니 그 카메라의 넘어짐이 줄었는가. 통계적으로 유의하지 않은 변화는 "판정 보류"로 표시합니다 — 표본 6건에서 나온 "33% 개선"을 성과로 적으면 안전회의에서 한 번 반박당하고 그 자료 전체가 신뢰를 잃습니다
- 오탐율 추이 — 시스템이 현장에 맞게 조정되고 있는지
- 요일×시간 사고 패턴 · 전조 급증 경보 — 인력 배치와 사전 개입의 근거
3-3. 관리 부담이 줄어드는 지점
- 사고조사 자료를 사람이 모으지 않습니다 — 사고 다음 날 반나절을 쓸 수 있는 사람은 없습니다
- 위험성평가와 실제 감지가 한 곳에 연결되어 있어 갱신 근거가 자동으로 쌓입니다
- 교대 인수인계와 정비 억제가 기록으로 남아, "그때 왜 알람이 없었나"에 답할 수 있습니다
- 감사기록 위·변조 탐지로, 제출한 기록의 신뢰성을 별도로 주장할 필요가 없습니다
3-4. 약속하지 않는 것
과장은 도입 후 신뢰를 무너뜨리므로 미리 적습니다.
- 사고를 없애지 못합니다. 이 시스템은 사고를 더 빨리 발견하고, 전조를 앞당겨 보여주고, 대응과 증거를 정리합니다. 사고 자체를 막는 것은 설비·공정·교육이며, 이 시스템은 그 개선의 근거를 제공하는 역할입니다.
- 감지율 100%는 없습니다. 가려짐·역광·극단적 조도에서는 놓칩니다. 그래서 감시 자신의 건전성(화각 변경·가림·조도)을 별도 이벤트로 감지해 못 보고 있다는 사실을 알립니다.
- 오탐은 초기에 반드시 발생합니다. 현장마다 조명·동선·작업 자세가 달라, 첫 2~4주는 임계값 조정 기간으로 잡아야 합니다. 그 조정을 고객이 직접 할 수 있도록 오탐율 통계와 임계값 편집 화면을 넣었습니다.
- 법적 판단을 대신하지 않습니다. 리포트와 사고조사 패키지는 안전 활동을 뒷받침하는 보조 자료이며, 공식 재해 통계나 법정 서식을 대체하지 않습니다.
4. 시스템 구성
[카메라 CSI/USB · Pi당 2~4대]
│
┌──────────▼──────────────────────────────┐
│ Raspberry Pi 5 + Hailo-8 (26 TOPS) │ ← 엣지: 자세추정 · 이벤트 판정
│ · 얼굴 블러 (저장 전) │ · 경광등 GPIO 직접 구동
│ · 오프라인 큐 (회선 단절 대비) │ · 카메라 무결성 감시
└──────────┬──────────────────────────────┘
│ HMAC 서명 POST — 스냅샷 3장 + 메타데이터만 (영상 없음)
▼
┌─────────────────────────────────────────┐
│ 웹 대시보드 (PHP 8 + MySQL) │ ← 일반 웹호스팅에서 동작
│ 이벤트 콘솔 · 구역 편집 · 안전 리포트 │ 별도 서버 투자 불필요
│ 안전 관리 · 시스템 설정 · 사고조사 │
└──────────┬──────────────────────────────┘
│
메일 · 사내 웹훅/문자 게이트웨이
4-1. 엣지 노드
- 하나의 공유 자세추정 모델로 모든 이벤트를 판정 — 카메라마다 모델을 더 올리지 않습니다
- CSI·USB 카메라 혼용, CPU 폴백 경로 내장
- 회선 단절 시 오프라인 큐에 보관 후 복구되면 재전송 (중복 전송은 서버가 제거)
- systemd 상주 + 워치독 + 하트비트 텔레메트리
- 감지 타이머는 단조 시계 기반이라 시스템 시각이 바뀌어도 오판하지 않습니다
4-2. 서버·대시보드
| 화면 | 누가 | 무엇을 |
|---|---|---|
| 이벤트 | 운영자 | 실시간 스트림, 확인·오탐 판정, 날짜 조회, 일괄 처리 |
| 이벤트 상세 | 운영자 | 증거 3프레임, 판정, 조치 기록, 사고조사 패키지 진입 |
| 구역 설정 | 안전관리자 | 카메라 화면 위 폴리곤, 등급·점유 규칙, 위험 히트맵 |
| 안전 리포트 | 안전관리자 | 주간 회의용 지표 한 장 (인쇄) |
| 안전 관리 | 안전관리자 | 인수인계 · 정비 억제 · 위험성평가 · 설비 성능 |
| 시스템 설정 | 관리자 | 통보 경로 · 감지 임계값 |
이 외에 설치 점검(구성이 실제로 동작하는지 단계별 확인)과 사고조사 패키지(인쇄용 단일 문서) 화면이 있습니다.
5. 개인정보 보호와 보안
작업자 감시 도구로 비치는 순간 현장 도입이 막힙니다. 그래서 프라이버시는 설정이 아니라 구조로 넣었습니다.
| 영역 | 적용 |
|---|---|
| 영상 | 라이브뷰 없음, 영상 저장·전송 없음. 사건 스냅샷 3장만 |
| 얼굴 | 저장 전에 자동 블러. 원본은 어디에도 남지 않음 |
| 접근 | 스냅샷은 인증 프록시 경유. 보존기간 경과 시 자동 삭제 |
| 통보 | 알림에 이미지 미포함 — 링크만 전송 |
| 전송 보안 | HMAC 서명 + nonce로 위·변조·재전송 차단, 장치·IP별 rate limit |
| 인증 | Argon2id, 로그인 잠금(사용자명 열거 차단), 세션 고정 방지 |
| 권한 | 역할 기반 접근제어 + 현장 스코프, 전 요청 CSRF |
| 웹 | CSP nonce (unsafe-inline 없음), DOM 주입은 textContent만 |
| 기록 | 감사로그 해시체인 — 수정·삭제·우회삽입 탐지 |
6. 납품과 운영
- 웹호스팅 업로드 패키지 — 서버 일체(마이그레이션 8종 포함)를 zip 하나로 업로드, 설정 파일 한 개만 수정
- Pi 설치 번들 — 온라인 설치와 폐쇄망 오프라인 번들 모두 제공. 런타임 휠·모델·소스를 전부 동봉해 설치 중 네트워크가 필요 없습니다
- 동봉 문서 — 설치 안내서 · 역할별 사용 설명서(실제 화면 캡처 포함 단일 HTML) · 변경 내역 · 납품 점검 리포트
- 자동 실행 2종 — 통보 디스패처(1분) · 보존기간 정리(일 1회)
- 운영 도구 — 백업/복구, 감사기록 무결성 검증, 시연용 데모 데이터 생성
7. 품질 근거
| 항목 | 현황 |
|---|---|
| 자동화 테스트 | 535건 (엣지 Python 311 · 서버 PHP 224), 스킵 0 (하드웨어 항목 제외) |
| 납품 감사 | 1차 43건 + 재감사 12건 = 55건 전량 해소, 판정 적합 |
| 상호운용 검증 | HMAC 골든 벡터로 엣지(Python) ↔ 서버(PHP) 대조 |
| 계층 정합 검증 | 감지 유형이 엣지·검증기·DB·화면 네 곳에서 일치하는지 자동 검사 |
| 납품물 검증 | 산출물↔소스 패리티, 패키지 내부 클래스 해석·문법 검사, 무결성 해시 |
| CI | 검증 명령 단일화, 스킵 발생 시 빌드 실패 |
감사에서 실제로 잡힌 대표 사례: 신규 감지 유형이 서버 검증기에만 누락되어 감지기가 구현·배포되고도 아무 이벤트도 남기지 못하던 상태를 발견해 수정하고, 재발 방지 테스트를 추가했습니다. 이런 "조용한 실패"를 찾는 것이 이 프로젝트 감사 사이클의 목적입니다.
8. 기술 스택
| 구분 | 기술 |
|---|---|
| 엣지 하드웨어 | Raspberry Pi 5 + AI HAT+ (Hailo-8, 26 TOPS) |
| 엣지 소프트웨어 | Python, Hailo HEF 자세추정 (CPU 폴백 내장) |
| 카메라 | CSI (picamera2) · USB (V4L2 MJPEG), Pi당 2~4대 |
| 서버 | PHP 8 + PDO + MySQL — 일반 웹호스팅에서 동작 |
| 프런트엔드 | 바닐라 JavaScript (빌드 도구 없음) |
| 배포 | 오프라인 번들 · systemd · zip 업로드 패키지 |
9. 현재 한계와 다음 단계
9-1. 모델 확보가 선행되어야 하는 항목
보호구 미착용 · 중장비 근접 · 화재/연기 감지는 감지기 배선·이벤트 규격·테스트까지 완성되어 있고 추론 모델만 비어 있습니다. 라이선스 조건을 만족하는 가중치 확보와 엣지 컴파일이 선행 조건입니다.
이 상태를 "곧 됩니다"로 켜두지 않고 명시적으로 비활성으로 둔 것은 의도적입니다 — 켜져 있으면 현장은 감지되고 있다고 믿게 되고, 그 믿음이 가장 위험합니다.
9-2. 현장 설치 시 검증할 항목
코드로 닫을 수 없고 실장비에서만 확인 가능한 항목입니다. 설치 시 반드시 수행합니다.
- 경광등 실제 구동 (배선·극성·유지시간)
- 카메라 무결성 임계값을 현장 조명·진동에 맞게 조정
- 낙상 판정 타이밍을 실제 영상으로 조정 — 블라인드 조정은 감지 누락을 만들 수 있어 현장 확보 후로 미뤘습니다
- 통보 1회 실발송 (시험 발송으로 대상 확인 후)
9-3. 다음 단계
- 위 감지 3종 활성화 (모델 확보 시)
- 기계 가동 상태 연동 협착 판정 — 협착구역은 기계가 돌 때만 위험합니다
- 다현장 통합 운영 (본사 관점 롤업은 이미 제공)
부록. 한눈에 보기
| 한 줄 정의 | 쓰러진 작업자를 3초면 알아채고, 현장에 즉시 울리고, 5분 안에 확인되지 않으면 위로 올리며, 그 전 과정을 증거로 남기는 시스템 |
| 핵심 차별점 | ① 감지에서 끝나지 않고 현장 경광등·에스컬레이션까지 ② 감시 자신의 고장을 감지 ③ 사고조사 패키지 1클릭 ④ 위·변조 탐지 감사기록 |
| 프라이버시 | 라이브뷰·영상 전송 없음 · 얼굴 저장 전 블러 · 알림에 이미지 미포함 |
| 운영 비용 | 클라우드 GPU 없음, 일반 웹호스팅에서 동작 |
| 감지 유형 | 17종 활성 (+ 모델 확보 대기 3종) |
| 검증 | 테스트 535건 · 납품 감사 55건 전량 해소 |