POSA_LEAKSMS/raspberry_pi4_sht30/config.py
cw2007 992d0f4428 fix(sht30): 온습도 보고 주기를 노드별로 — 누수쪽 10분, Pi-B 1시간
REPORT_INTERVAL 을 config_local 로 오버라이드 가능하게 확장(양의 정수 검증).
누수 노드 co-센서(id 1/3)는 config_local 에서 600s(10분, 누수 노드 주기와 정합),
독립 Pi-B(sensor2)는 config.py 기본 3600s(1시간) 유지. 하드코딩 대신 config_local
로 노드별 지정 → config.py 드리프트 방지.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nd7QvbgEWCjSQtUYnGNvvV
2026-07-15 10:27:14 +09:00

115 lines
7 KiB
Python

# =============================================================================
# config.py - Temperature/Humidity (SHT30) monitoring module (Pi 4 Model B) config — non-secret defaults
#
# Operational/secret values such as server URL / API_KEY / device identifiers (DEVICE_ID/LOCATION)
# are loaded from config_local.py. config_local.py is excluded from commits via .gitignore.
# Setup: cp config_local.example.py config_local.py → fill in the real values
#
# This module is "Module 2" (temperature/humidity). The server (php/) dashboard shows sensor_id=2 as the
# default temperature/humidity sensor, so the SENSOR_ID default is set to 2.
# =============================================================================
# ─────────────────────────────────────────────
# Sensor identity (for server dashboard display; not secret)
# SENSOR_ID is the key in the server's leak_sensor_metric / leak_sensor_status. Dashboard default chart=2.
# ─────────────────────────────────────────────
SENSOR_ID = 2
SENSOR_NAME = "Sensor 2 (SHT30)"
# ─────────────────────────────────────────────
# I2C bus config (Pi 4 40-pin header)
# SDA = GPIO2 (physical pin 3), SCL = GPIO3 (physical pin 5) → I2C bus 1
# ADDR pin: GND=0x44, VDD=0x45
# ─────────────────────────────────────────────
I2C_BUS = 1
I2C_ADDR = 0x44
# Force simulation. If True, runs with dummy measurements without hardware (for server integration checks).
# Even if False, the driver auto-falls back to simulation when smbus2 is not installed / I2C is disabled.
FORCE_SIMULATION = False
# ─────────────────────────────────────────────
# Measurement/report intervals (same defaults as firmware app_config.h)
# ─────────────────────────────────────────────
REPORT_INTERVAL = 3600 # Normal measure/report interval (seconds) = 1 hour
# Server offline detection must exceed this: METRIC_HEARTBEAT_TIMEOUT_SEC
# (default 7500s ≈ 2 missed hourly reports + margin) covers it.
# Override per-node in config_local.py if a different cadence is needed.
MEASURE_RETRY_DELAY = 5 # Wait before retry after a failed measurement (seconds)
# ─────────────────────────────────────────────
# Physical plausibility range for temp/humidity (same as firmware classify_metric_status)
# Values outside this range are reported as metric_status="out_of_range".
# * Operational threshold judgments (high/low temp, high/low humidity) and SMS are all handled
# by the server (config.php METRIC_*). This module only faithfully reports measurements.
# ─────────────────────────────────────────────
TEMP_LOW_C = -40.0
TEMP_HIGH_C = 125.0
RH_LOW = 0.0
RH_HIGH = 100.0
# Module identity version (server app_version field; the server only records it, does not validate)
APP_VERSION = "v2606-sht30-rpi4"
# ─────────────────────────────────────────────
# Logging config
# ─────────────────────────────────────────────
LOG_FILE = "/var/log/sht30_sensor.log"
LOG_MAX_BYTES = 5 * 1024 * 1024 # 5MB
LOG_BACKUP_COUNT = 3
# ─────────────────────────────────────────────
# HTTP retry config (same defaults as firmware APP_HTTP_*)
# ─────────────────────────────────────────────
HTTP_TIMEOUT = 10 # Single request timeout (seconds)
HTTP_RETRY_COUNT = 3 # Number of retries
HTTP_RETRY_DELAY = 5 # Wait between retries (seconds)
# ─────────────────────────────────────────────
# Load operational/secret values (fail closed)
# If config_local.py is missing, abort immediately with a clear error instead of
# starting incorrectly with placeholder/hardcoded secrets.
# ─────────────────────────────────────────────
try:
from config_local import ( # noqa: F401 (sht30_sensor.py re-imports from config)
API_URL,
API_KEY,
DEVICE_ID,
DEVICE_LOCATION,
)
except ImportError as e:
raise RuntimeError(
"config_local.py not found. "
"Run `cp config_local.example.py config_local.py`, then fill in the real server URL / API_KEY / "
"device info. (Never commit secret values.)"
) from e
# ─────────────────────────────────────────────
# Optional override — per-device values from config_local.py.
# Editing the tracked config.py per device causes deployment drift, so a co-located
# node (e.g. a leak node reporting temp/humidity under the SAME sensor_id 1 or 3)
# overrides SENSOR_ID / SENSOR_NAME here instead. If config_local defines neither,
# the defaults above (SENSOR_ID=2) are kept — backward compatible for Pi-B.
# ─────────────────────────────────────────────
try:
from config_local import SENSOR_ID # noqa: F811 — per-device sensor_id override
except ImportError:
pass
try:
from config_local import SENSOR_NAME # noqa: F811 — per-device display name override
except ImportError:
pass
try:
# Per-device report cadence. Leak-node co-sensor (id 1/3) reports every 600s (10 min)
# to match the leak node's cadence; the standalone Pi-B (sensor2) keeps the 3600s (1 h) default.
from config_local import REPORT_INTERVAL # noqa: F811 — per-device report interval override
except ImportError:
pass
# Validate (fail closed) — a typo must not silently start with a wrong/plausible id.
if not (isinstance(SENSOR_ID, int) and 1 <= SENSOR_ID <= 255):
raise RuntimeError(f"SENSOR_ID must be int 1..255 (check config_local.py): {SENSOR_ID!r}")
if not (isinstance(SENSOR_NAME, str) and SENSOR_NAME):
raise RuntimeError("SENSOR_NAME must be a non-empty string (check config_local.py).")
if not (isinstance(REPORT_INTERVAL, int) and REPORT_INTERVAL > 0):
raise RuntimeError(f"REPORT_INTERVAL must be a positive int (seconds) (check config_local.py): {REPORT_INTERVAL!r}")