헤드리스 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 본문 서명 무영향 |
||
|---|---|---|
| .. | ||
| systemd | ||
| .gitignore | ||
| config.py | ||
| config_local.example.py | ||
| install.sh | ||
| README.md | ||
| requirements.txt | ||
| sht30_driver.py | ||
| sht30_sensor.py | ||
| test_connection.py | ||
| test_sensor.py | ||
| vendor.sh | ||
| wire.py | ||
| WIRING.html | ||
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, seeSYSTEM_OVERVIEW.mdin 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_KEYinconfig_local.pymust be exactly identical toAPI_KEYin the server'sconfig.local.php.- The server blocks replays via
timestampfreshness (±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
smbus2is pure Python (arch-independent), so it can be downloaded on an x86 build machine. Other wheels/debs such asrequestsmust be the aarch64 builds (runningvendor.shon 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 inconfig_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-Signatureheader) (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.pybuilds the body directly, signs those bytes, then raw POSTs). This matches firmwaresig.c/reference.py/ serververify_signature_rawbyte-for-byte. - If
config_local.pyis exposed, immediately rotateAPI_KEY(change it on the server at the same time).