POSA_LEAKSMS/raspberry_pi4_sht30/WIRING.html
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

558 lines
28 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Temp/Humidity Node Wiring & Pinmap — Pi-B / SHT30 (sensor_id=2)</title>
<style>
:root{
--ink:#1a1d21; --muted:#5c6570; --line:#dfe3e8; --bg:#eef1f4; --card:#ffffff;
--accent:#1971c2; --accent-d:#155a9c; --warn:#e03131; --warnbg:#fff5f5;
--ok:#2f9e44; --gnd:#343a40; --chip:#eef2f6; --code:#0b3d2e;
--mono:"D2Coding","Consolas","Menlo","Courier New",ui-monospace,monospace;
--sans:"Malgun Gothic","Apple SD Gothic Neo","Noto Sans KR","Segoe UI",system-ui,-apple-system,sans-serif;
}
*{box-sizing:border-box;}
html,body{margin:0;padding:0;}
body{
font-family:var(--sans); color:var(--ink); background:var(--bg);
line-height:1.6; -webkit-font-smoothing:antialiased;
}
.wrap{max-width:1000px; margin:0 auto; padding:22px 18px 60px;}
/* ---------- Header ---------- */
.hero{
background:linear-gradient(135deg,#1f2933 0%,#283746 55%,#2f4a5a 100%);
color:#fff; border-radius:16px; padding:26px 28px;
box-shadow:0 8px 24px rgba(20,30,40,.18);
}
.hero .eyebrow{font-size:12.5px; letter-spacing:.14em; text-transform:uppercase;
color:#9fc3e0; font-weight:700; margin:0 0 6px;}
.hero h1{margin:0 0 8px; font-size:27px; line-height:1.25; font-weight:800;}
.hero p.sum{margin:0 0 16px; font-size:14.5px; color:#d7e2ec; max-width:72ch;}
.chips{display:flex; flex-wrap:wrap; gap:8px;}
.chip{
display:inline-flex; align-items:center; gap:6px;
background:rgba(255,255,255,.12); border:1px solid rgba(255,255,255,.22);
color:#eef5fb; font-size:12.5px; font-weight:600; padding:5px 11px; border-radius:999px;
}
.chip.mono{font-family:var(--mono); letter-spacing:.01em;}
.chip b{color:#fff;}
/* ---------- Sections ---------- */
section{
background:var(--card); border:1px solid var(--line); border-radius:14px;
padding:22px 24px; margin-top:20px; box-shadow:0 2px 10px rgba(20,30,40,.05);
}
h2{
display:flex; align-items:center; gap:11px; margin:0 0 16px;
font-size:19px; font-weight:800; color:var(--ink);
}
h2 .n{
flex:0 0 auto; width:30px; height:30px; border-radius:9px;
background:var(--accent); color:#fff; font-size:15px; font-weight:800;
display:flex; align-items:center; justify-content:center;
}
h2 small{font-weight:600; font-size:13px; color:var(--muted);}
/* ---------- Pinmap SVG ---------- */
.svg-pin{display:block; width:100%; max-width:460px; height:auto; margin:2px auto 0;}
.diagram-cap{text-align:center; color:var(--muted); font-size:12.5px; margin:12px 0 0;}
.legend{
display:flex; flex-wrap:wrap; justify-content:center; gap:12px 18px;
margin:16px auto 2px; max-width:640px;
}
.legend span{display:inline-flex; align-items:center; gap:7px; font-size:12.5px; color:var(--ink);}
.sw{width:15px; height:15px; border-radius:50%; flex:0 0 auto; border:1px solid rgba(0,0,0,.15);}
.sw.pwr{background:#2f9e44;} .sw.i2c{background:#1971c2;}
.sw.gnd{background:#343a40;}
.sw.altgnd{background:#ced4da; border:1.5px dashed #868e96;}
.sw.off{background:#dee2e6;}
/* SVG element classes */
.p-pwr{fill:#2f9e44; stroke:#248a3b; stroke-width:1.5;}
.p-i2c{fill:#1971c2; stroke:#155a9c; stroke-width:1.5;}
.p-gnd{fill:#343a40; stroke:#1f2429; stroke-width:1.5;}
.p-altgnd{fill:#ced4da; stroke:#868e96; stroke-width:1.5; stroke-dasharray:3 2;}
.p-off{fill:#dee2e6; stroke:#c3c9cf; stroke-width:1;}
.rail{fill:#f1f3f5; stroke:#ced4da; stroke-width:1.5;}
.pnum{font-family:var(--mono); font-size:12px; font-weight:700; text-anchor:middle; dominant-baseline:central;}
.pnum-l{fill:#ffffff;} .pnum-d{fill:#495057;}
.plbl{font-family:var(--mono); font-size:12px; dominant-baseline:central;}
.lbl-l{text-anchor:end;} .lbl-r{text-anchor:start;}
.lbl-used{fill:#1a1d21; font-weight:700;}
.lbl-alt{fill:#5c6570; font-weight:600;}
.lbl-off{fill:#adb5bd; font-weight:500;}
.cap-svg{font-family:var(--sans); font-size:12.5px; fill:#5c6570; font-weight:600; text-anchor:middle;}
/* ---------- Table ---------- */
table{width:100%; border-collapse:collapse; font-size:14px;}
thead th{
background:#f1f4f7; color:#2b3541; text-align:left; font-weight:700;
padding:10px 12px; border-bottom:2px solid #ccd4dc; font-size:13px;
}
tbody td{padding:11px 12px; border-bottom:1px solid var(--line); vertical-align:top;}
tbody tr:last-child td{border-bottom:none;}
.mono{font-family:var(--mono);}
.pinbadge{
display:inline-block; min-width:26px; text-align:center; font-family:var(--mono);
font-weight:700; font-size:13px; color:#fff; background:var(--accent);
border-radius:6px; padding:2px 7px;
}
.pinbadge.gnd{background:var(--gnd);} .pinbadge.pwr{background:var(--ok);}
.pinbadge.na{background:#adb5bd;}
td .warn-inline{color:var(--warn); font-weight:700;}
/* ---------- Schematic ---------- */
.svg-sch{display:block; width:100%; max-width:840px; height:auto; margin:0 auto;}
.box{fill:#f8f9fa; stroke:#495057; stroke-width:2; rx:8;}
.boxtitle{font-family:var(--sans); font-size:14px; font-weight:800; fill:#1a1d21; text-anchor:middle;}
.term{font-family:var(--mono); font-size:12.5px; font-weight:700; fill:#2b3541;}
.w-pwr{stroke:#e03131; stroke-width:3; fill:none; stroke-linecap:round; stroke-linejoin:round;}
.w-i2c{stroke:#1971c2; stroke-width:3; fill:none; stroke-linecap:round; stroke-linejoin:round;}
.w-gnd{stroke:#343a40; stroke-width:3; fill:none; stroke-linecap:round; stroke-linejoin:round;}
.w-addr{stroke:#495057; stroke-width:2.5; fill:none; stroke-dasharray:6 4; stroke-linecap:round;}
.res{fill:#ffffff; stroke:#212529; stroke-width:2;}
.wlbl{font-family:var(--sans); font-size:12px; font-weight:700; fill:#2b3541;}
.rlbl{font-family:var(--mono); font-size:12px; font-weight:700; fill:#b02a2a;}
.jn{fill:#212529;}
.sch-note{color:var(--muted); font-size:12.5px; text-align:center; margin:12px 0 0;}
/* ---------- Callouts ---------- */
.warn{
background:var(--warnbg); border:1.5px solid #ffc9c9; border-left:6px solid var(--warn);
border-radius:12px; padding:16px 18px; margin:0 0 16px; display:flex; gap:14px; align-items:flex-start;
}
.warn .ic{flex:0 0 auto; width:34px; height:34px;}
.warn h3{margin:0 0 4px; color:#c92a2a; font-size:16px; font-weight:800;}
.warn p{margin:0; font-size:14px; color:#5a2020;}
.warn b{color:#c92a2a;}
ul.notes{margin:6px 0 0; padding:0; list-style:none;}
ul.notes li{position:relative; padding:7px 0 7px 24px; border-bottom:1px dashed var(--line); font-size:14px;}
ul.notes li:last-child{border-bottom:none;}
ul.notes li::before{content:""; position:absolute; left:4px; top:14px; width:8px; height:8px;
background:var(--accent); border-radius:2px; transform:rotate(45deg);}
code, .kbd{font-family:var(--mono); background:#eef2f6; color:#0b3d2e; padding:1px 6px; border-radius:5px; font-size:13px;}
.cmd{
font-family:var(--mono); background:#12211b; color:#c8f7d8; border-radius:10px;
padding:12px 14px; font-size:13.5px; margin:12px 0 0; overflow-x:auto;
}
.cmd .cm{color:#7fd6a3;} .cmd .ok{color:#ffd43b;}
/* ---------- Checklist ---------- */
ol.check{margin:0; padding:0; list-style:none; counter-reset:ck;}
ol.check li{
counter-increment:ck; position:relative; display:flex; align-items:flex-start; gap:12px;
padding:11px 4px 11px 0; border-bottom:1px solid var(--line); font-size:14px;
}
ol.check li:last-child{border-bottom:none;}
ol.check li .num{
flex:0 0 auto; width:24px; height:24px; border-radius:50%; background:#e7eef5; color:#1f5f97;
font-weight:800; font-size:12.5px; display:flex; align-items:center; justify-content:center;
}
ol.check li .num::before{content:counter(ck);}
ol.check li .cbox{flex:0 0 auto; width:18px; height:18px; border:2px solid #9aa6b1; border-radius:4px; margin-top:1px;}
ol.check li .txt{flex:1;}
ol.check li .txt b{color:var(--warn);}
footer{margin-top:26px; text-align:center; color:var(--muted); font-size:12px;}
/* ---------- Print ---------- */
@media print{
body{background:#fff;}
.wrap{max-width:none; padding:0;}
.hero{background:#fff !important; color:#111; border:2px solid #111; box-shadow:none;}
.hero .eyebrow{color:#444;} .hero p.sum{color:#222;}
.chip{background:#f2f2f2; color:#111; border:1px solid #999;}
.chip b{color:#000;}
h2 .n{background:#111;}
section{box-shadow:none; border:1px solid #999; break-inside:avoid; page-break-inside:avoid;}
table, tr, td, th, .warn, .card{break-inside:avoid; page-break-inside:avoid;}
.svg-pin, .svg-sch{max-width:100%;}
.cmd{background:#f2f2f2; color:#111; border:1px solid #999;}
a{color:#000;}
}
@media (max-width:560px){
.hero h1{font-size:22px;} h2{font-size:17px;}
}
</style>
</head>
<body>
<div class="wrap">
<!-- ============ 1. HEADER ============ -->
<header class="hero">
<p class="eyebrow">Field Installation Doc · Wiring &amp; Pinmap</p>
<h1>Temp/Humidity Node — Site 1 / Server Room</h1>
<p class="sum">
A measurement node connecting the SHT30 temperature/humidity sensor to the Raspberry Pi (Pi-B) over I2C (bus 1, address 0x44).
This node only reports readings to the server every <b>5 minutes</b>; high/low temperature and high/low humidity threshold decisions and SMS dispatch are handled by the server.
</p>
<div class="chips">
<span class="chip">Raspberry Pi 4 Model B</span>
<span class="chip mono">BCM2711</span>
<span class="chip">Raspberry Pi OS Bookworm 64-bit</span>
<span class="chip">Sensirion SHT30 (Hanjin Data P4422-3)</span>
<span class="chip mono">I2C bus <b>1</b></span>
<span class="chip mono">addr <b>0x44</b></span>
<span class="chip mono">sensor_id=<b>2</b></span>
<span class="chip">Report interval 5 min</span>
</div>
</header>
<!-- ============ 2. PINMAP SVG ============ -->
<section>
<h2><span class="n">2</span>40-Pin Header Pinmap Diagram <small>Used pins highlighted · others in gray</small></h2>
<svg class="svg-pin" viewBox="0 0 520 672" role="img" aria-label="Raspberry Pi 40-pin GPIO header pinmap">
<!-- caption -->
<text class="cap-svg" x="260" y="20">40-pin GPIO header (J8) · physical pin numbers</text>
<!-- rails -->
<rect class="rail" x="186" y="46" width="28" height="600" rx="14"/>
<rect class="rail" x="306" y="46" width="28" height="600" rx="14"/>
<!-- Row 1 : pin1 (square = pin1 marker) / pin2 -->
<rect class="p-pwr" x="188" y="48" width="24" height="24" rx="5"/>
<text class="pnum pnum-l" x="200" y="60">1</text>
<text class="plbl lbl-l lbl-used" x="176" y="60">3V3</text>
<circle class="p-off" cx="320" cy="60" r="12"/>
<text class="pnum pnum-d" x="320" y="60">2</text>
<text class="plbl lbl-r lbl-off" x="344" y="60">5V</text>
<!-- Row 2 : pin3 / pin4 -->
<circle class="p-i2c" cx="200" cy="90" r="12"/>
<text class="pnum pnum-l" x="200" y="90">3</text>
<text class="plbl lbl-l lbl-used" x="176" y="90">GPIO2 (SDA1)</text>
<circle class="p-off" cx="320" cy="90" r="12"/>
<text class="pnum pnum-d" x="320" y="90">4</text>
<text class="plbl lbl-r lbl-off" x="344" y="90">5V</text>
<!-- Row 3 : pin5 / pin6 -->
<circle class="p-i2c" cx="200" cy="120" r="12"/>
<text class="pnum pnum-l" x="200" y="120">5</text>
<text class="plbl lbl-l lbl-used" x="176" y="120">GPIO3 (SCL1)</text>
<circle class="p-gnd" cx="320" cy="120" r="12"/>
<text class="pnum pnum-l" x="320" y="120">6</text>
<text class="plbl lbl-r lbl-used" x="344" y="120">GND</text>
<!-- Row 4 : pin7 / pin8 -->
<circle class="p-off" cx="200" cy="150" r="12"/>
<text class="pnum pnum-d" x="200" y="150">7</text>
<text class="plbl lbl-l lbl-off" x="176" y="150">GPIO4</text>
<circle class="p-off" cx="320" cy="150" r="12"/>
<text class="pnum pnum-d" x="320" y="150">8</text>
<text class="plbl lbl-r lbl-off" x="344" y="150">GPIO14 (TXD)</text>
<!-- Row 5 : pin9 / pin10 -->
<circle class="p-altgnd" cx="200" cy="180" r="12"/>
<text class="pnum pnum-d" x="200" y="180">9</text>
<text class="plbl lbl-l lbl-alt" x="176" y="180">GND</text>
<circle class="p-off" cx="320" cy="180" r="12"/>
<text class="pnum pnum-d" x="320" y="180">10</text>
<text class="plbl lbl-r lbl-off" x="344" y="180">GPIO15 (RXD)</text>
<!-- Row 6 : pin11 / pin12 -->
<circle class="p-off" cx="200" cy="210" r="12"/>
<text class="pnum pnum-d" x="200" y="210">11</text>
<text class="plbl lbl-l lbl-off" x="176" y="210">GPIO17</text>
<circle class="p-off" cx="320" cy="210" r="12"/>
<text class="pnum pnum-d" x="320" y="210">12</text>
<text class="plbl lbl-r lbl-off" x="344" y="210">GPIO18</text>
<!-- Row 7 : pin13 / pin14 -->
<circle class="p-off" cx="200" cy="240" r="12"/>
<text class="pnum pnum-d" x="200" y="240">13</text>
<text class="plbl lbl-l lbl-off" x="176" y="240">GPIO27</text>
<circle class="p-altgnd" cx="320" cy="240" r="12"/>
<text class="pnum pnum-d" x="320" y="240">14</text>
<text class="plbl lbl-r lbl-alt" x="344" y="240">GND</text>
<!-- Row 8 : pin15 / pin16 -->
<circle class="p-off" cx="200" cy="270" r="12"/>
<text class="pnum pnum-d" x="200" y="270">15</text>
<text class="plbl lbl-l lbl-off" x="176" y="270">GPIO22</text>
<circle class="p-off" cx="320" cy="270" r="12"/>
<text class="pnum pnum-d" x="320" y="270">16</text>
<text class="plbl lbl-r lbl-off" x="344" y="270">GPIO23</text>
<!-- Row 9 : pin17 / pin18 -->
<circle class="p-off" cx="200" cy="300" r="12"/>
<text class="pnum pnum-d" x="200" y="300">17</text>
<text class="plbl lbl-l lbl-off" x="176" y="300">3V3</text>
<circle class="p-off" cx="320" cy="300" r="12"/>
<text class="pnum pnum-d" x="320" y="300">18</text>
<text class="plbl lbl-r lbl-off" x="344" y="300">GPIO24</text>
<!-- Row 10 : pin19 / pin20 -->
<circle class="p-off" cx="200" cy="330" r="12"/>
<text class="pnum pnum-d" x="200" y="330">19</text>
<text class="plbl lbl-l lbl-off" x="176" y="330">GPIO10 (MOSI)</text>
<circle class="p-altgnd" cx="320" cy="330" r="12"/>
<text class="pnum pnum-d" x="320" y="330">20</text>
<text class="plbl lbl-r lbl-alt" x="344" y="330">GND</text>
<!-- Row 11 : pin21 / pin22 -->
<circle class="p-off" cx="200" cy="360" r="12"/>
<text class="pnum pnum-d" x="200" y="360">21</text>
<text class="plbl lbl-l lbl-off" x="176" y="360">GPIO9 (MISO)</text>
<circle class="p-off" cx="320" cy="360" r="12"/>
<text class="pnum pnum-d" x="320" y="360">22</text>
<text class="plbl lbl-r lbl-off" x="344" y="360">GPIO25</text>
<!-- Row 12 : pin23 / pin24 -->
<circle class="p-off" cx="200" cy="390" r="12"/>
<text class="pnum pnum-d" x="200" y="390">23</text>
<text class="plbl lbl-l lbl-off" x="176" y="390">GPIO11 (SCLK)</text>
<circle class="p-off" cx="320" cy="390" r="12"/>
<text class="pnum pnum-d" x="320" y="390">24</text>
<text class="plbl lbl-r lbl-off" x="344" y="390">GPIO8 (CE0)</text>
<!-- Row 13 : pin25 / pin26 -->
<circle class="p-altgnd" cx="200" cy="420" r="12"/>
<text class="pnum pnum-d" x="200" y="420">25</text>
<text class="plbl lbl-l lbl-alt" x="176" y="420">GND</text>
<circle class="p-off" cx="320" cy="420" r="12"/>
<text class="pnum pnum-d" x="320" y="420">26</text>
<text class="plbl lbl-r lbl-off" x="344" y="420">GPIO7 (CE1)</text>
<!-- Row 14 : pin27 / pin28 -->
<circle class="p-off" cx="200" cy="450" r="12"/>
<text class="pnum pnum-d" x="200" y="450">27</text>
<text class="plbl lbl-l lbl-off" x="176" y="450">GPIO0 (ID_SD)</text>
<circle class="p-off" cx="320" cy="450" r="12"/>
<text class="pnum pnum-d" x="320" y="450">28</text>
<text class="plbl lbl-r lbl-off" x="344" y="450">GPIO1 (ID_SC)</text>
<!-- Row 15 : pin29 / pin30 -->
<circle class="p-off" cx="200" cy="480" r="12"/>
<text class="pnum pnum-d" x="200" y="480">29</text>
<text class="plbl lbl-l lbl-off" x="176" y="480">GPIO5</text>
<circle class="p-altgnd" cx="320" cy="480" r="12"/>
<text class="pnum pnum-d" x="320" y="480">30</text>
<text class="plbl lbl-r lbl-alt" x="344" y="480">GND</text>
<!-- Row 16 : pin31 / pin32 -->
<circle class="p-off" cx="200" cy="510" r="12"/>
<text class="pnum pnum-d" x="200" y="510">31</text>
<text class="plbl lbl-l lbl-off" x="176" y="510">GPIO6</text>
<circle class="p-off" cx="320" cy="510" r="12"/>
<text class="pnum pnum-d" x="320" y="510">32</text>
<text class="plbl lbl-r lbl-off" x="344" y="510">GPIO12</text>
<!-- Row 17 : pin33 / pin34 -->
<circle class="p-off" cx="200" cy="540" r="12"/>
<text class="pnum pnum-d" x="200" y="540">33</text>
<text class="plbl lbl-l lbl-off" x="176" y="540">GPIO13</text>
<circle class="p-altgnd" cx="320" cy="540" r="12"/>
<text class="pnum pnum-d" x="320" y="540">34</text>
<text class="plbl lbl-r lbl-alt" x="344" y="540">GND</text>
<!-- Row 18 : pin35 / pin36 -->
<circle class="p-off" cx="200" cy="570" r="12"/>
<text class="pnum pnum-d" x="200" y="570">35</text>
<text class="plbl lbl-l lbl-off" x="176" y="570">GPIO19</text>
<circle class="p-off" cx="320" cy="570" r="12"/>
<text class="pnum pnum-d" x="320" y="570">36</text>
<text class="plbl lbl-r lbl-off" x="344" y="570">GPIO16</text>
<!-- Row 19 : pin37 / pin38 -->
<circle class="p-off" cx="200" cy="600" r="12"/>
<text class="pnum pnum-d" x="200" y="600">37</text>
<text class="plbl lbl-l lbl-off" x="176" y="600">GPIO26</text>
<circle class="p-off" cx="320" cy="600" r="12"/>
<text class="pnum pnum-d" x="320" y="600">38</text>
<text class="plbl lbl-r lbl-off" x="344" y="600">GPIO20</text>
<!-- Row 20 : pin39 / pin40 -->
<circle class="p-altgnd" cx="200" cy="630" r="12"/>
<text class="pnum pnum-d" x="200" y="630">39</text>
<text class="plbl lbl-l lbl-alt" x="176" y="630">GND</text>
<circle class="p-off" cx="320" cy="630" r="12"/>
<text class="pnum pnum-d" x="320" y="630">40</text>
<text class="plbl lbl-r lbl-off" x="344" y="630">GPIO21</text>
<!-- pin1 hint -->
<text class="cap-svg" x="260" y="662" style="font-size:11px;">■ square marker = pin 1 (relative to board orientation)</text>
</svg>
<div class="legend">
<span><i class="sw pwr"></i>3.3V power — pin 1</span>
<span><i class="sw i2c"></i>I2C SDA/SCL — pins 3·5</span>
<span><i class="sw gnd"></i>GND (used) — pin 6</span>
<span><i class="sw altgnd"></i>Alt GND (optional) — 9·14·20·25·30·34·39</span>
<span><i class="sw off"></i>Unused pins</span>
</div>
<p class="diagram-cap">The pin numbers and signals in this diagram match the standard Raspberry Pi 4 Model B (BCM2711) 40-pin header layout.</p>
</section>
<!-- ============ 3. PINMAP TABLE ============ -->
<section>
<h2><span class="n">3</span>Pinmap Table <small>SHT30 → 40-pin header</small></h2>
<table>
<thead>
<tr><th style="width:30%">Signal</th><th style="width:24%">BCM</th><th style="width:14%">Phys pin</th><th>Notes</th></tr>
</thead>
<tbody>
<tr>
<td><b>3.3V power</b> (VCC)</td>
<td class="mono">—</td>
<td><span class="pinbadge pwr">1</span></td>
<td><span class="warn-inline">★ Must be 3.3V — do NOT connect 5V (pins 2·4)</span></td>
</tr>
<tr>
<td><b>I2C data</b> (SDA)</td>
<td class="mono">GPIO2 / SDA1</td>
<td><span class="pinbadge">3</span></td>
<td>4.7kΩ pull-up → 3.3V <span style="color:var(--muted)">(omit if built into module)</span></td>
</tr>
<tr>
<td><b>I2C clock</b> (SCL)</td>
<td class="mono">GPIO3 / SCL1</td>
<td><span class="pinbadge">5</span></td>
<td>4.7kΩ pull-up → 3.3V <span style="color:var(--muted)">(omit if built into module)</span></td>
</tr>
<tr>
<td><b>Ground</b> (GND)</td>
<td class="mono">—</td>
<td><span class="pinbadge gnd">6</span></td>
<td>Alt GND available: <span class="mono">9 · 14 · 20 · 25 · 30 · 34 · 39</span></td>
</tr>
<tr>
<td><b>Address select</b> (ADDR)</td>
<td class="mono">—</td>
<td><span class="pinbadge na">GND</span></td>
<td>ADDR → GND ⇒ <span class="mono">0x44</span> (selected) · ADDR → VDD ⇒ <span class="mono">0x45</span></td>
</tr>
</tbody>
</table>
</section>
<!-- ============ 4. SCHEMATIC SVG ============ -->
<section>
<h2><span class="n">4</span>Wiring Schematic <small>sensor ↔ header ↔ pull-up resistors</small></h2>
<svg class="svg-sch" viewBox="0 0 840 400" role="img" aria-label="SHT30 wiring schematic">
<!-- component boxes -->
<rect class="box" x="70" y="90" width="150" height="290" rx="8"/>
<rect class="box" x="640" y="90" width="150" height="290" rx="8"/>
<text class="boxtitle" x="145" y="116">SHT30 sensor module</text>
<text class="boxtitle" x="715" y="116">Pi 40-pin header</text>
<!-- SHT30 terminal labels (right side) -->
<text class="term" x="210" y="150" text-anchor="end">VCC</text>
<text class="term" x="210" y="200" text-anchor="end">SDA</text>
<text class="term" x="210" y="250" text-anchor="end">SCL</text>
<text class="term" x="210" y="305" text-anchor="end">GND</text>
<text class="term" x="210" y="350" text-anchor="end">ADDR</text>
<!-- Pi terminal labels (left side) -->
<text class="term" x="650" y="150">3V3 (pin 1)</text>
<text class="term" x="650" y="200">SDA1 (pin 3)</text>
<text class="term" x="650" y="250">SCL1 (pin 5)</text>
<text class="term" x="650" y="305">GND (pin 6)</text>
<!-- POWER wire (also 3V3 rail for pull-ups) -->
<path class="w-pwr" d="M220 150 H640"/>
<text class="wlbl" x="300" y="140" fill="#b02a2a">Power 3.3V</text>
<!-- GND wire -->
<path class="w-gnd" d="M220 305 H640"/>
<text class="wlbl" x="300" y="322" fill="#2b3541">Ground GND</text>
<!-- SDA wire (with hop over SCL pull-up branch at x=480) -->
<path class="w-i2c" d="M220 200 H470 A10 9 0 0 1 490 200 H640"/>
<text class="wlbl" x="300" y="216" fill="#155a9c">SDA → GPIO2</text>
<!-- SCL wire -->
<path class="w-i2c" d="M220 250 H640"/>
<text class="wlbl" x="300" y="266" fill="#155a9c">SCL → GPIO3</text>
<!-- ADDR -> GND -->
<path class="w-addr" d="M220 350 H300 V305"/>
<text class="wlbl" x="228" y="368" fill="#3b444d">ADDR → GND = 0x44</text>
<circle class="jn" cx="300" cy="305" r="4"/>
<!-- Pull-up R1 on SDA (x=400) -->
<path class="w-i2c" d="M400 200 V190"/>
<rect class="res" x="390" y="165" width="20" height="25" rx="3"/>
<path class="w-i2c" d="M400 165 V150"/>
<circle class="jn" cx="400" cy="200" r="4"/>
<circle class="jn" cx="400" cy="150" r="4"/>
<text class="rlbl" x="416" y="180">R1 4.7kΩ</text>
<!-- Pull-up R2 on SCL (x=480), branch rises past SDA (hop) up to rail -->
<path class="w-i2c" d="M480 250 V188"/>
<rect class="res" x="470" y="163" width="20" height="25" rx="3"/>
<path class="w-i2c" d="M480 163 V150"/>
<circle class="jn" cx="480" cy="250" r="4"/>
<circle class="jn" cx="480" cy="150" r="4"/>
<text class="rlbl" x="496" y="178">R2 4.7kΩ</text>
</svg>
<p class="sch-note">
Pull-up resistors R1·R2 (4.7kΩ ×2) connect to the 3.3V rail. <b>Omit if built into the SHT30 module</b>.
The half-circle (hop) on the SDA line only marks a wire crossing — it is not an electrical connection.
</p>
</section>
<!-- ============ 5. ELECTRICAL NOTES ============ -->
<section>
<h2><span class="n">5</span>Electrical Design · Cautions</h2>
<div class="warn">
<svg class="ic" viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 2 L23 21 H1 Z" fill="#ffe3e3" stroke="#e03131" stroke-width="1.6" stroke-linejoin="round"/>
<line x1="12" y1="9" x2="12" y2="15" stroke="#e03131" stroke-width="2.2" stroke-linecap="round"/>
<circle cx="12" cy="18" r="1.4" fill="#e03131"/>
</svg>
<div>
<h3>Critical Warning — On the Pi it MUST be 3.3V</h3>
<p>Connect the SHT30's <b>VCC to physical pin 1 (3.3V)</b>.
<b>Do NOT connect 5V (pins 2·4) on the Pi</b> — the SHT30 module itself tolerates 2.4–5.5V, but
powering it with 5V pulls the SDA/SCL lines up to 5V as well, which <b>damages the 3.3V-only Pi GPIO</b>.
Double-check the pin numbers before wiring.</p>
</div>
</div>
<ul class="notes">
<li><b>I2C pull-ups:</b> Connect a 4.7kΩ pull-up resistor on each of SDA and SCL to 3.3V. Can be omitted if built into the sensor module.</li>
<li><b>Address setting:</b> ADDR → GND gives <code>0x44</code> (default), ADDR → VDD gives <code>0x45</code>. Must match the <code>I2C_ADDR</code> value in <code>config.py</code>.</li>
<li><b>I2C bus:</b> Uses bus 1. I2C must be enabled after boot (<code>raspi-config</code> or <code>dtparam=i2c_arm=on</code>).</li>
<li><b>Wiring length:</b> Short cables are recommended for I2C. Long cables may cause communication errors or require adjusting the pull-up values.</li>
<li><b>Role split:</b> This node only reports readings to the server every 5 minutes. High/low temperature and high/low humidity <b>threshold decisions and SMS dispatch are done by the server</b>.</li>
<li><b>Config file:</b> <code>raspberry_pi4_sht30/config.py</code> (<code>I2C_BUS=1</code>, <code>I2C_ADDR=0x44</code>). Per-device values are overridden in <code>config_local.py</code>.</li>
</ul>
<div class="cmd">
<span class="cm"># Check I2C connection (OK if 0x44 appears in the grid)</span>
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
40: -- -- -- -- <span class="ok">44</span> -- -- -- -- -- -- -- -- -- -- --
</div>
</section>
<!-- ============ 6. INSTALL CHECKLIST ============ -->
<section>
<h2><span class="n">6</span>Installation Checklist</h2>
<ol class="check">
<li><span class="num"></span><span class="cbox"></span><span class="txt">Do wiring work with <b>power disconnected</b> (no hot-plugging)</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Connect VCC → physical pin 1 (3.3V) — re-verify it is <b>NOT a 5V pin (2·4)</b></span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Connect GND → physical pin 6 (or 9·14·20·25·30·34·39 for alt GND)</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Connect SDA → pin 3 (GPIO2), SCL → pin 5 (GPIO3)</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Connect 4.7kΩ ×2 pull-up resistors from SDA·SCL → 3.3V (omit if built into module)</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Verify ADDR → GND (address 0x44 selected)</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Re-check all wiring, then power up the Pi</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Verify I2C is enabled (raspi-config / dtparam=i2c_arm=on)</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Run <code>i2cdetect -y 1</code> → confirm <code>0x44</code> is shown</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Verify I2C_BUS=1, I2C_ADDR=0x44 in config.py / config_local.py</span></li>
<li><span class="num"></span><span class="cbox"></span><span class="txt">Check measurement log and server reception (5-min reporting OK)</span></li>
</ol>
</section>
<footer>
Temp/Humidity Node · Pi-B (sensor_id=2, Site 1 / Server Room) · SHT30 I2C wiring doc — for on-site printing
</footer>
</div>
</body>
</html>