헤드리스 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 본문 서명 무영향
156 lines
6.5 KiB
Markdown
156 lines
6.5 KiB
Markdown
# 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`](../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`](../sql/schema_sht30.sql),
|
||
> [`../docs/INSTALL_PI_SERVER.md`](../docs/INSTALL_PI_SERVER.md),
|
||
> [`../docs/SHT30_SENSOR2_SETUP.md`](../docs/SHT30_SENSOR2_SETUP.md).
|
||
|
||
---
|
||
|
||
## 4. Installation
|
||
|
||
### 4.1 Prepare configuration values
|
||
|
||
```bash
|
||
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)
|
||
|
||
```bash
|
||
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.
|
||
|
||
```bash
|
||
# (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
|
||
|
||
```bash
|
||
# 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)
|
||
|
||
```bash
|
||
# 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).
|