POSA_LEAKSMS/raspberry_pi4_sht30/README.md
cw2007 a72ea18130 i18n(pi): Raspberry Pi 번들 소스 한글 → 영어 (콘솔 mojibake 해소)
헤드리스 Pi 콘솔/journalctl에서 한글이 깨져 보이는 문제로, Pi 번들(02/03/04)에 들어가는 모든 소스의 사람-대상 텍스트를 영어로 전환. 코드·식별자·설정키·경로·숫자·hex·서명 스킴·f-string 플레이스홀더는 불변.

- raspberry_pi4/, raspberry_pi4_sht30/: 로그·주석·문서·센서명·위치 영어화
- tools/make_deploy_bundles.py: 생성 템플릿(config_local.py/setup.sh/SETUP.md/PI_META 위치) 영어화
- tools/harden_pi.sh, tools/set_network.sh: echo/주석 영어화
- WIRING.html: 영어화 + SHT30 전압 경고 정정 반영
- 서버 번들(01, php/)은 한글 유지(브라우저 대시보드, Pi에서 안 깨짐)
- 전 파이썬/셸 문법검사 통과, JSON 본문 서명 무영향
2026-07-10 10:44:13 +09:00

6.5 KiB
Raw Blame History

Temperature/Humidity (SHT30) Sensor Module — Raspberry Pi 4 Model B only (Module 2)

A module that reads a Sensirion SHT30 (Hanjin Data P4422-3, I2C) temperature/humidity sensor over the Raspberry Pi 4 Model B I2C bus and periodically reports to the cafe24 server (php/api/sensor_data.php). The server stores the measurements and performs high/low temperature and high/low humidity threshold evaluation, SMS, and dashboard display.

This folder is a port of the STM32F407 firmware (sht30_fw) behavior to Raspberry Pi 4 + Python, the "Module 2". The wire format (body/signature), CRC, and conversion formulas are byte-for-byte identical to the firmware. "Module 1" (leak + camera) is in the ../raspberry_pi4/ folder. For the full setup, see SYSTEM_OVERVIEW.md in the root.


1. Files

File Role
sht30_sensor.py Main — periodic measurement → body build/sign → POST (with retry), startup→periodic
sht30_driver.py SHT30 I2C measurement + CRC-8 verification + physical-value conversion (smbus2, simulation fallback)
wire.py Body JSON + raw-body HMAC signature (byte-identical to firmware jsonbody.c/sig.c)
config.py Non-secret default settings (sensor id/interval/range/I2C). Loads secrets from config_local
config_local.example.py Operational/secret-value template → copy to config_local.py for use (not committed)
requirements.txt Python dependencies (requests, smbus2, pinned)
install.sh Pi 4 install (air-gapped offline + online fallback, includes enabling I2C)
vendor.sh Pre-download dependencies for air-gapped use (run on the build machine)
test_connection.py Server connectivity/signed-POST check
test_sensor.py CRC/format self-check + one measurement (format check passes even without hardware)
systemd/sht30-sensor.service Service unit for auto-start on boot

2. Hardware (Pi 4 Model B baseline)

  • Raspberry Pi 4 Model B (BCM2711) + Raspberry Pi OS Bookworm 64-bit
  • SHT30 temperature/humidity sensor module (I2C, Hanjin Data P4422-3)
  • I2C pull-up resistors 4.7kΩ × 2 (omit if built into the module)
  • Power: USB-C 5V/3A, network: Pi 4 Gigabit Ethernet (wired) or WiFi

2.1 Pinout (I2C bus 1)

Signal Pi 4 pin Note
SHT30 VCC 3.3V (physical 1) No 5V
SHT30 GND GND (physical 6/9/14/…)
SHT30 SDA GPIO2 / SDA1 (physical 3) + 4.7kΩ pull-up → 3.3V
SHT30 SCL GPIO3 / SCL1 (physical 5) + 4.7kΩ pull-up → 3.3V
SHT30 ADDR GND → address 0x44 0x45 if tied to VDD (config.py I2C_ADDR)

3. Server compatibility (must verify)

This module reports to the current repo's php/ server (= the cafe24 SHT30 dashboard server). The server requires a raw-body HMAC signature.

X-Signature = lowercase_hex( HMAC-SHA256( key=API_KEY, msg=request body bytes ) )
  • API_KEY in config_local.py must be exactly identical to API_KEY in the server's config.local.php.
  • The server blocks replays via timestamp freshness (±600 seconds), so the Pi clock must be NTP-synchronized (enabled by default on Raspberry Pi OS).
  • It reports with sensor_id=2, and the server dashboard (dashboard.php) shows sensor 2 as the default chart.
  • Threshold alerts (high/low temperature, high/low humidity), SMS, and recovery evaluation are all performed by the server. This module only reports measurements.

For the server-side schema/deployment, see ../sql/schema_sht30.sql, ../docs/INSTALL_PI_SERVER.md, ../docs/SHT30_SENSOR2_SETUP.md.


4. Installation

4.1 Prepare configuration values

cp config_local.example.py config_local.py
# Open config_local.py and fill in API_URL / API_KEY / DEVICE_ID / DEVICE_LOCATION

If config_local.py is missing, execution stops immediately with a clear error (fail closed). Never commit config_local.py or API_KEY (handled by .gitignore).

4.2 Online install (internet-capable environment)

chmod +x install.sh
./install.sh
sudo reboot      # reboot once if I2C was newly enabled

4.3 Air-gapped offline install

On an internet-connected machine of the same architecture (aarch64, ideally the same Pi 4 + Bookworm 64-bit), download the dependencies first to build a bundle, then move it to the target Pi 4 and install.

# (build machine, internet YES) generate wheelhouse/ + debs/
./vendor.sh

# after copying wheelhouse/ and debs/ into this folder on the target Pi 4:
# (target Pi 4, internet NO)
./install.sh        # if debs/ · wheelhouse/ exist, it installs offline automatically

smbus2 is pure Python (arch-independent), so it can be downloaded on an x86 build machine. Other wheels/debs such as requests must be the aarch64 builds (running vendor.sh on the target arch is recommended).


5. Run / check

# is the sensor visible (0x44)
i2cdetect -y 1

# format/CRC self-check + one measurement (simulation if no hardware)
source venv/bin/activate
python3 test_sensor.py

# server connectivity/signature check
python3 test_connection.py

# actual run
python3 sht30_sensor.py

In environments without smbus2 installed or with I2C disabled (dev PC, etc.), it automatically runs in simulation mode.


6. Auto-start on boot (systemd)

# assumes the folder is placed at /home/pi/raspberry_pi4_sht30 (otherwise edit the path in the .service)
sudo cp systemd/sht30-sensor.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable sht30-sensor
sudo systemctl start sht30-sensor
sudo systemctl status sht30-sensor
journalctl -u sht30-sensor -f

SupplementaryGroups=i2c is required for /dev/i2c-1 access.


7. Security notes

  • Secrets (API_KEY), server URL, and device info live only in config_local.py (not committed). Committed files contain only placeholders.
  • The report body is protected against tampering by an HMAC-SHA256(API_KEY, raw_body) signature (X-Signature header) (immune to length-extension attacks). The legacy body-field sha256 fallback is disabled by default on the server.
  • The signed bytes and the transmitted bytes are always identical (wire.py builds the body directly, signs those bytes, then raw POSTs). This matches firmware sig.c / reference.py / server verify_signature_raw byte-for-byte.
  • If config_local.py is exposed, immediately rotate API_KEY (change it on the server at the same time).