POSA_LEAKSMS/raspberry_pi4_pms7003/systemd/pms7003-sensor.service
cw2007 ec78be0bda feat(pms7003): 누수 노드에 미세먼지(PM2.5/PM10) 통합
센서1·3(누수 노드)에 PMS7003 를 온습도와 동일 sensor_id 로 통합하고 metric_type='pms7003'
로 구분해 수집한다. LED 는 스위칭 없이 상시 점등 방식으로 확정.

- raspberry_pi4_pms7003/: PMS7003 노드 풀세트(드라이버·센서·install·systemd·vendor·배선·연결테스트·프레임 단위테스트)
- 서버: evaluate_metric_thresholds() 에 pm25/pm10 선택 인자 추가(온습도 전용 호출 후방호환),
  sensor_data.php 수집 경로에 pms7003 metric 반영, config.php/예시에 PM 임계 추가
- SQL: migration_pms7003.sql · schema_sht30.sql 정합, tools/migration_leak_add_{pms7003,sht30} 마이그레이터
- tests/pm_threshold_test.php + run_tests.sh 러너 등록
- .gitignore: 노드별 config_local.py 커밋 차단
2026-07-19 10:46:33 +09:00

66 lines
2.5 KiB
Desktop File

# =============================================================================
# /etc/systemd/system/pms7003-sensor.service
# Service that auto-runs the particulate-matter (PMS7003) monitor on Raspberry Pi 4 boot
#
# Installation:
# sudo cp systemd/pms7003-sensor.service /etc/systemd/system/
# sudo systemctl daemon-reload
# sudo systemctl enable pms7003-sensor
# sudo systemctl start pms7003-sensor
# sudo systemctl status pms7003-sensor
#
# * Adjust the WorkingDirectory/ExecStart paths to match the actual deployment path.
# The example below assumes deployment under /home/pi/raspberry_pi4_pms7003.
# =============================================================================
[Unit]
Description=PMS7003 Particulate-Matter Sensor Monitor v2 (Pi 4)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=pi
Group=pi
# dialout group required to access /dev/serial0 (the primary UART)
SupplementaryGroups=dialout
WorkingDirectory=/home/pi/raspberry_pi4_pms7003
ExecStart=/home/pi/raspberry_pi4_pms7003/venv/bin/python pms7003_sensor.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=pms7003-sensor
# Environment variables
Environment=PYTHONUNBUFFERED=1
# Process-private /tmp isolation
PrivateTmp=true
# -- Sandboxing (hardening) -- blocks root escalation and filesystem tampering if the daemon is compromised --------
# User=pi is a NOPASSWD sudo account, so NoNewPrivileges blocks the setuid(sudo) escalation path.
NoNewPrivileges=true
# Root filesystem read-only + only /var/log writable (including log rotation). /tmp is PrivateTmp.
ProtectSystem=strict
ReadWritePaths=/var/log
# /home is read-only (reads own code/config_local.py only; blocks writes and access to other accounts' homes).
ProtectHome=read-only
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true
RestrictRealtime=true
# HTTPS(POST) + local sockets (DNS/journal) only. UART is unaffected since /dev/serial0 is a char device (not a socket).
# AF_NETLINK required -- glibc getaddrinfo/NSS uses netlink to enumerate local addresses
# (omitting it makes DNS resolution intermittently fail -> server POST impossible). AF_INET/6=HTTPS, AF_UNIX=DNS/journal.
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
# * Do not use PrivateDevices -- it hides /dev/serial0 and makes the sensor inaccessible.
# Restart cap (stop after 5 failures within 10 minutes)
StartLimitBurst=5
StartLimitInterval=600s
[Install]
WantedBy=multi-user.target