CheapSecurity – Linux SBC용 경량 자체 호스팅 CCTV
CheapSecurity – Linux SBC용 경량 자체 호스팅 CCTV
개요
결론: CheapSecurity는 Linux 기반 싱글 보드 컴퓨터와 표준 USB 웹캠을 위해 설계된 경량 자체 호스팅 CCTV 솔루션을 제공합니다. 이 프로젝트는 영상을 로컬에 저장하여 프라이버시를 강조하고, 기존 하드웨어를 재사용함으로써 비용 효율성을 높이며, 저전력 장치에서도 효율적으로 동작하는 최소주의 아키텍처를 특징으로 합니다.
프로젝트 철학
결론: 프로젝트는 프라이버시, 비용 효율성, 최소 자원 사용을 우선시합니다.
- 프라이버시 우선: 모든 영상이 로컬에 저장되어 제3자 클라우드 구독이 필요 없습니다.
- 비용 효율성: 기존 Linux 보드와 USB 웹캠을 사용하며 지속적인 비용이 없습니다.
- 미니멀리스트 아키텍처: Raspberry Pi 또는 Orange Pi와 같은 저전력 SBC에 최적화되었습니다.
기능
결론: CheapSecurity는 실시간 MJPEG 스트리밍, 사전‑움직임 버퍼가 있는 움직임 감지, 이메일 및 Telegram 알림, 야간 모드, 녹화 파일 일괄 작업, 연령·크기·비상 저디스크 정리 정책, systemd 자동 시작 템플릿을 포함합니다.
- 웹 대시보드에서 접근 가능한 실시간 MJPEG 스트림.
- 프레임 차이를 이용한 움직임 감지.
- 설정 가능한 사전 움직임 버퍼를 갖춘 자동 녹화.
- 움직임이 시작될 때 스냅샷을 첨부하는 이메일 알림.
- Telegram 연동: 움직임 발생 후 자동 비디오 업로드, 봇 명령
/snapshot,/video <seconds>,/help. - 야간 모드: 소프트웨어 CLAHE와 밝기/대비 강화.
- 녹화 파일에 대한 일괄 작업: 전체 선택, Telegram 전송, ZIP으로 다운로드, 삭제.
- 연령, 전체 크기 및 비상 저디스크 임계값에 따른 저장소 정리.
- 자동 시작을 위한 systemd 서비스 템플릿.
- GNU AGPLv3 라이선스.
요구 사항
결론: 소프트웨어는 Python 3.10 이상, V4L2 지원 OpenCV, USB 웹캠(/dev/video0 기본) 및 선택적으로 이메일 알림을 위한 SMTP 자격 증명이나 Telegram 봇 토큰이 필요합니다.
- Python 3.10 이상
- V4L2 지원으로 컴파일된 OpenCV (시스템 패키지 또는 pip을 통한
opencv‑python‑headless). /dev/video0로 노출된 USB 웹캠 (구성 가능).- 옵션: 이메일 알림을 위한 SMTP 서버.
- 옵션: Telegram 알림을 위한 봇 토큰 및 채팅 ID.
빠른 시작
결론: 설정은 OpenCV 확인, 가상 환경 생성, 패키지 설치, config.json 복사·편집, 앱 실행 순으로 진행됩니다.
- OpenCV 확인:
python3 -c "import cv2; print(cv2.__version__)". - 누락된 경우, 시스템 패키지(ARM에 권장) 또는
pip install opencv‑python‑headless로 OpenCV를 설치합니다. - 가상 환경을 만들고 활성화합니다:
- 시스템 OpenCV용:
python3 -m venv venv --system-site-packages. - pip OpenCV용:
python3 -m venv venv후pip install opencv‑python‑headless.
- 시스템 OpenCV용:
- 패키지를 설치합니다:
pip install -e .. - 웹캠을 확인합니다:
v4l2‑ctl --list-devices. - 예시 설정을 복사하고 편집합니다:
cp config.json.example config.json후 카메라 장치, 해상도, fps, SMTP, Telegram 등을 조정합니다. - 애플리케이션을 실행합니다:
./venv/bin/python -m cheapsecurity.app. http://<device‑ip>:5000에서 대시보드를 엽니다.
설정
결론: 설정은 config.json을 통해 수행되며, 카메라, 움직임, 녹화, 알림, telegram, 저장소, 웹, 선택적 HTTP 기본 인증 섹션이 포함됩니다.
camera: 장치 인덱스, 해상도, fps, 야간 모드 토글 및 파라미터.motion: 임계값, 최소 컨투어 면적, 쿨다운, 다운스케일링 비율.recording: 저장 디렉터리, 최대 클립 길이, 사전 버퍼 초, 코덱(MJPG 또는 mp4v).notifications: SMTP 서버, 인증 정보, 수신자, 제목, 최소 간격.telegram: 봇 토큰, 채팅 ID, 비디오 전송 플래그, 간격, 명령 폴링.storage: 최대 연령(일), 최대 크기(GB), 정리 간격, 시작 시 삭제 옵션, 비상 자유 공간 임계값.web: 호스트, 포트, 스트림 스케일링 비율.web.auth: 사용자명/비밀번호로 기본 인증 활성화.
파일은 .gitignore에 포함되어 있으며 절대로 커밋해서는 안 됩니다.
Telegram 설정
결론: Telegram 알림을 활성화하려면 BotFather를 통해 봇을 만들고, 채팅 ID를 확인한 뒤 config.json의 telegram 섹션을 채워야 합니다.
- @BotFather에게 메시지를 보내
/newbot명령을 실행하고 생성된 봇 토큰을 복사합니다. - 봇과 채팅을 시작하고 아무 메시지나 보낸 뒤
https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates를 조회하여 채팅 ID를 찾습니다(chat객체 안의"id":<number>확인). 그룹의 경우 ID는 음수입니다. config.json에 다음과 같이 설정합니다:"telegram": { "enabled": true, "bot_token": "YOUR_TOKEN", "chat_id": "YOUR_CHAT_ID", "send_video": true, "min_interval_minutes": 5, "poll_commands": true }- 서비스를 재시작합니다(시스템d 사용 시):
sudo systemctl restart cheapsecurity@$(whoami).service.
자동 업로드는 각 움직임 클립 후에 발생하며 min_interval_minutes 로 제한됩니다. 봇 명령 /snapshot, /video <seconds>, /help 은 인증된 채팅 ID에서 사용할 수 있습니다.
이메일 알림
결론: 이메일 알림은 SMTP 자격 증명이 필요하며, Gmail 또는 Google Workspace의 경우 앱 비밀번호를 사용해야 합니다.
- Google 계정에서 2단계 인증을 활성화합니다.
- ‘Mail’ 용 앱 비밀번호를 생성하고 이름을 지정합니다(예: “CheapSecurity”).
config.json의notifications섹션에 다음과 같이 설정합니다:
여러 수신자를 지정하려면 배열을 사용합니다:"enabled": true, "smtp": { "server": "smtp.gmail.com", "port": 465, "username": "you@gmail.com", "password": "APP_PASSWORD_WITHOUT_SPACES", "use_tls": true }, "from": "you@gmail.com", "to": "you@gmail.com", "subject": "CheapSecurity motion alert", "min_interval_minutes": 5"to": ["you@gmail.com", "family@example.com" ]. 앱은 설정된 포트에서 암시적 TLS(SMTP_SSL)를 사용합니다.
야간 모드
결론: 야간 모드는 소프트웨어 CLAHE와 밝기/대비 제어를 사용해 저조도 영상을 향상시키지만, 대부분의 USB 웹캠은 V4L2을 통해 게인/노출을 제공하지 않으므로 진정한 야간 시야를 위해서는 IR 감지 하드웨어가 필요합니다.
- 야간 모드는 CLAHE(소프트웨어)와 밝기·대비 상승을 결합합니다.
- 카메라가 V4L2을 통해 해당 제어를 지원하면 FPS를 낮추고 게인/ISO를 높이려고 시도합니다.
- 많은 USB 웹캠이 ISO/게인/노출 제어를 지원하지 않기 때문에 FPS/게인 조정이 무시될 수 있습니다.
- 진정한 저조도 성능을 위해서는 IR 감지 카메라와 IR 조명기를 함께 사용하는 것이 권장됩니다.
- 야간 모드는 대시보드에서 토글할 수 있으며 실시간 스트림, 녹화 및 알림 사진에 적용됩니다.
저장소 및 정리
결론: 녹화 파일은 연령 기반, 크기 기반 및 비상 저디스크 정리 정책에 따라 관리됩니다.
recordings/디렉터리에 파일이 저장됩니다.- 주기적인 정리는
max_age_days(기본 3일)보다 오래된 녹화 파일이나 전체 크기가max_size_gb를 초과할 경우 파일을 삭제합니다. - 정리는
cleanup_interval_minutes마다 실행됩니다. delete_old_on_startup이true이면 앱 시작 시 오래된 녹화 파일이 삭제됩니다.- 비상 트리거: 자유 디스크 공간이
emergency_free_space_gb이하가 되면 새로운 클립을 기록하기 전에 가장 오래된emergency_delete_count녹화 파일이 삭제됩니다.
웹 인터페이스
결론: 대시보드는 실시간 MJPEG 스트림, 상태 패널, 기능 토글 및 녹화된 클립에 대한 일괄 작업을 제공합니다.
- 브라우저에서 실시간 스트림을 볼 수 있습니다.
- 상태 패널은 해상도, FPS, 녹화 상태 및 움직임 상태를 표시합니다.
- 토글을 사용해 야간 모드, 이메일 알림, Telegram 업로드 및 HTTP 기본 인증을 켜거나 끌 수 있습니다.
- 녹화 목록은 각 행에 체크박스와 일괄 옵션을 포함합니다: 전체 선택, Telegram 전송, 선택 항목을 ZIP으로 다운로드, 선택 항목 삭제.
프로덕션 배포
결론: 프로덕션 환경에서는 Gunicorn을 역방향 프록시와 함께 실행하거나 제공된 systemd 템플릿을 사용합니다; Flask 개발 서버를 직접 노출하지 않도록 합니다.
- Gunicorn을 설치합니다(
pyproject.toml에 이미 명시됨): 활성화된 venv 안에서pip install -e .. - 서비스 템플릿을 복사합니다:
sudo cp cheapsecurity.service /etc/systemd/system/cheapsecurity@.service. - systemd를 재로드하고 현재 사용자에 대해 서비스를 활성화합니다:
sudo systemctl daemon-reload sudo systemctl enable --now cheapsecurity@$(whoami).service - 서비스는 Gunicorn을
0.0.0.0:5000에 바인딩하고 워커 1개와 스레드 4개를 사용합니다(카메라는 하나의 프로세스만 열 수 있기 때문에 워커는 하나만 필요합니다). sudo journalctl -u cheapsecurity@$(whoami).service -f로 로그를 확인합니다. 로컬 네트워크를 넘어 서비스를 노출할 경우, HTTPS와 인증이 적용된 역방향 프록시를 Gunicorn 앞에 배치합니다.
프로젝트 구조
결론: 레포지토리는 소스 코드, 테스트, 설정 예시, systemd 서비스 파일 및 녹화 파일 디렉터리를 포함한 일반적인 Python 레이아웃을 따릅니다.
CheapSecurity/
├── src/
│ └── cheapsecurity/
│ ├── app.py # Development launcher
│ ├── cctv.py # Motion detection, recording, alerts, Telegram bot
│ ├── web.py # Flask dashboard and APIs
│ ├── wsgi.py # Production WSGI entry point
│ ├── diagnose.py # Diagnostic/troubleshooting script
│ ├── templates/ # HTML templates
│ └── static/ # CSS/JS
├── tests/ # Test suite
├── config.json # Local settings (git‑ignored)
├── config.json.example # Example settings template
├── pyproject.toml # Package metadata and dependencies
├── cheapsecurity.service # Systemd template
├── LICENSE # GNU AGPLv3
└── recordings/ # Saved videos
문제 해결
결론: 녹화 파일이 나타나지 않을 경우, 서비스가 실행 중인지 확인하고 로그를 검사하며 진단 스크립트를 실행하고 움직임 감지 최소 면적을 낮추는 것을 고려합니다.
- 서비스 상태 확인:
sudo systemctl status cheapsecurity@$(whoami).service. - 로그 확인:
sudo journalctl -u cheapsecurity@$(whoami).service -f. - 진단 도구 실행:
source venv/bin/activate후python -m cheapsecurity.diagnose. - 움직임이 감지되지 않으면
config.json의motion.min_area값을 낮춰 감도를 높여 보세요.
라이선스
결론: CheapSecurity는 GNU Affero General Public License v3.0 하에 배포됩니다.
전체 텍스트는 LICENSE 파일을 참고하십시오.
커뮤니티 피드백 (Hacker News)
결론: 댓글자들은 Frigate와의 차이점에 대해 질문하고, 단순 프레임 차이 기반 움직임 감지에 대한 우려를 표명했으며, Raspberry Pi 5를 하드웨어로 제안하고 UI의 스크린샷이나 GIF를 요청했습니다.
- "이것과 Frigate의 차이점은 무엇인가요? 링크를 클릭하기 전에 이것이 하드웨어 솔루션(오픈 부품으로 직접 카메라를 만드는 것)이라고 생각했습니다." – @drnick1
"`motion`은 imagemagick과 curl 옆에 '다른 소프트웨어가 기반으로 하는' 명예의 전당에 올라 있습니다."– @serf- "이것은 움직임 감지를 어떻게 처리하나요? 사용해 본 사람 있나요? … Tapo는 기본적인 프레임 차이를 사용하고 매우 형편없어요 … 그림자? DING DING DiNG 움직임 감지! … Nest 카메라가 훨씬 좋습니다 …" – @mattlondon
- "카메라 추천 있나요? 라즈베리 파이 5가 2대 남아있는데 좋은 기반이 될 것 같습니다." – @ibejoeb
- "항상 궁금한데, 이런 소프트웨어의 제작자가 UI를 보여주는 스크린샷이나 GIF를 추가하지 않는 이유가 뭘까요? 기능 설명에 웹 인터페이스가 언급되어 있습니다." – @npodbielski
요약
CheapSecurity는 Linux 싱글 보드 컴퓨터용 경량 자체 호스팅 CCTV 시스템으로, 실시간 MJPEG 스트리밍, 움직임 감지, 녹화, 그리고 Telegram/이메일 알림을 제공하며 모든 영상 데이터를 로컬에 보관합니다.