a502322188
손상된 .git 히스토리(missing tree)로 재초기화 후 작업트리 전체 커밋. .claude/ 만 제외(로컬 에이전트 설정). 구 저장소 백업(.git_corrupt_backup/) 포함. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
290 lines
9.9 KiB
Markdown
290 lines
9.9 KiB
Markdown
# WSL2 설치 → ErvCollector 실행 가이드 (윈도우 PC)
|
|
|
|
미니PC 구입 전, **윈도우 PC + WSL2(Ubuntu)** 에서 수집/모니터·제어 서버(`ErvCollector`)와
|
|
InfluxDB·Grafana 를 띄워 전체 파이프라인을 검증하기 위한 단계별 가이드.
|
|
|
|
> 대상: `TestProgram/WebDashBoard/ErvCollector`
|
|
> 순서대로 복사·붙여넣기 하면 됩니다. (Ubuntu 24.04 기준)
|
|
|
|
---
|
|
|
|
## 0. 사전 요약 (무엇을 깔고 띄우나)
|
|
|
|
| 구성요소 | 역할 | 포트 |
|
|
|---|---|---|
|
|
| ErvCollector(.NET) | 현장 EW11 TCP 수신 + 웹 대시보드/제어 API | 6001~6003(수집), 8080(HTTP) |
|
|
| InfluxDB OSS 2.x | 시계열 데이터 24시간 저장(1년 보관) | 8086 |
|
|
| Grafana | 장기 분석 대시보드(선택) | 3000 |
|
|
|
|
---
|
|
|
|
## 1. WSL2 + Ubuntu 설치 (Windows PowerShell, 관리자)
|
|
|
|
```powershell
|
|
wsl --install -d Ubuntu-24.04
|
|
# 설치 후 재부팅 → Ubuntu 최초 실행 시 사용자/암호 설정
|
|
wsl --status # 버전 2 확인
|
|
wsl --update
|
|
```
|
|
|
|
이후 명령은 모두 **Ubuntu(WSL) 터미널** 안에서 실행한다.
|
|
|
|
---
|
|
|
|
## 2. WSL systemd 활성화 (서비스 자동실행용)
|
|
|
|
```bash
|
|
sudo tee /etc/wsl.conf >/dev/null <<'EOF'
|
|
[boot]
|
|
systemd=true
|
|
EOF
|
|
```
|
|
```powershell
|
|
# Windows PowerShell 에서 WSL 재시작
|
|
wsl --shutdown
|
|
```
|
|
다시 Ubuntu 터미널을 열고 확인:
|
|
```bash
|
|
systemctl is-system-running # running 또는 degraded 면 OK
|
|
```
|
|
|
|
---
|
|
|
|
## 3. .NET 10 SDK 설치
|
|
|
|
```bash
|
|
sudo apt-get update
|
|
sudo apt-get install -y dotnet-sdk-10.0 || {
|
|
# 패키지가 없으면 공식 스크립트로 설치
|
|
curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 10.0
|
|
echo 'export PATH="$HOME/.dotnet:$PATH"' >> ~/.bashrc && source ~/.bashrc
|
|
}
|
|
dotnet --version
|
|
```
|
|
|
|
---
|
|
|
|
## 4. InfluxDB OSS 2.x 설치 + 초기 설정
|
|
|
|
```bash
|
|
# 저장소 등록 및 설치
|
|
curl -s https://repos.influxdata.com/influxdata-archive_compat.key \
|
|
| sudo gpg --dearmor -o /usr/share/keyrings/influxdata.gpg
|
|
echo "deb [signed-by=/usr/share/keyrings/influxdata.gpg] https://repos.influxdata.com/debian stable main" \
|
|
| sudo tee /etc/apt/sources.list.d/influxdata.list
|
|
sudo apt-get update && sudo apt-get install -y influxdb2 influxdb2-cli
|
|
sudo systemctl enable --now influxdb
|
|
|
|
# 초기 설정 : org=herv, bucket=erv, 보관 1년(8760h), 토큰을 직접 지정
|
|
influx setup \
|
|
--org herv --bucket erv --retention 8760h \
|
|
--username admin --password 'change-this-pw' \
|
|
--token herv-erv-token-0001 \
|
|
--force
|
|
```
|
|
|
|
> 위 `--token herv-erv-token-0001` 값을 그대로 `appsettings.json` 의 `Influx.Token` 에 넣으면 된다.
|
|
> (토큰을 따로 확인하려면 `influx auth list`)
|
|
|
|
---
|
|
|
|
## 5. (선택) Grafana 설치
|
|
|
|
```bash
|
|
sudo apt-get install -y apt-transport-https software-properties-common
|
|
curl -s https://apt.grafana.com/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/grafana.gpg
|
|
echo "deb [signed-by=/usr/share/keyrings/grafana.gpg] https://apt.grafana.com stable main" \
|
|
| sudo tee /etc/apt/sources.list.d/grafana.list
|
|
sudo apt-get update && sudo apt-get install -y grafana
|
|
sudo systemctl enable --now grafana-server
|
|
```
|
|
- 브라우저에서 `http://localhost:3000` (초기 admin / admin)
|
|
- Connections → Data sources → **InfluxDB** 추가
|
|
- Query language: **Flux**
|
|
- URL: `http://localhost:8086`
|
|
- Organization: `herv`, Token: `herv-erv-token-0001`, Default bucket: `erv`
|
|
- 패널 쿼리 예시(거실 PM2.5 추이):
|
|
```flux
|
|
from(bucket: "erv")
|
|
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|
|
|> filter(fn: (r) => r._measurement == "erv_room" and r._field == "pm25" and r.site == "site01" and r.room == "1")
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 프로젝트 가져오기
|
|
|
|
> ⚠️ `ErvCollector` 는 공용 라이브러리 **`ErvProtocol`**(경로상 `HERV/TestProgram/ErvProtocol`)을 프로젝트 참조한다.
|
|
> (csproj: `..\..\ErvProtocol\ErvProtocol.csproj`) → 빌드 시 이 폴더가 **상대경로로 함께 있어야** 한다.
|
|
|
|
**방법 1 — 원본 위치에서 바로 빌드 (가장 간단, 권장)**
|
|
```bash
|
|
cd /mnt/d/project/nuvoton/HERV/TestProgram/WebDashBoard/ErvCollector
|
|
# ../../ErvProtocol 가 /mnt/d/.../HERV/TestProgram/ErvProtocol 로 자동 해석됨
|
|
```
|
|
> `/mnt` 는 다소 느리지만 경로 문제 없이 동작.
|
|
|
|
**방법 2 — 리눅스 홈으로 복사 (빌드 빠름, 상대구조 유지 필수)**
|
|
```bash
|
|
mkdir -p ~/herv
|
|
cp -r /mnt/d/project/nuvoton/HERV/TestProgram/ErvProtocol ~/herv/ErvProtocol
|
|
cp -r /mnt/d/project/nuvoton/HERV/TestProgram/WebDashBoard ~/herv/WebDashBoard
|
|
cd ~/herv/WebDashBoard/ErvCollector
|
|
# ../../ErvProtocol → ~/herv/ErvProtocol (깊이 일치) ✓
|
|
```
|
|
|
|
### appsettings.json 수정
|
|
```bash
|
|
nano appsettings.json
|
|
```
|
|
- `Influx.Token` → `herv-erv-token-0001` (4장에서 지정한 값)
|
|
- `Http.Prefix` → 로컬 검증은 `http://localhost:8080/`, **LAN 의 EW11 접속까지** 받으려면 `http://*:8080/`
|
|
- (권장) `Http.Token` → 임의의 제어 인증 토큰 지정
|
|
|
|
---
|
|
|
|
## 7. 빌드 & 실행
|
|
|
|
```bash
|
|
# 6장에서 정한 ErvCollector 폴더에서 (방법1: /mnt/d/... , 방법2: ~/herv/WebDashBoard/ErvCollector)
|
|
dotnet run # 참조된 ErvProtocol 라이브러리도 자동으로 함께 빌드됨
|
|
```
|
|
정상 기동 로그:
|
|
```
|
|
ErvCollector 시작. Influx=http://127.0.0.1:8086 bucket=erv 샘플주기=10s
|
|
HTTP 대시보드/제어 ← http://localhost:8080/
|
|
현장 'site01' ← TCP 포트 6001 대기
|
|
현장 'site02' ← TCP 포트 6002 대기
|
|
현장 'site03' ← TCP 포트 6003 대기
|
|
```
|
|
→ **Windows 브라우저**에서 `http://localhost:8080/` 접속(WSL localhost 는 Windows 와 공유됨).
|
|
|
|
---
|
|
|
|
## 8. 동작 검증 (EW11 없이)
|
|
|
|
`ErvCollector` 실행 중인 상태에서, **다른 Ubuntu 터미널**을 열고 데모 STATUS 프레임을 주입:
|
|
|
|
```bash
|
|
python3 - <<'PY'
|
|
import socket
|
|
# STATUS(0x81) 78바이트 예시 프레임 (PC_ERV_Protocol.md)
|
|
frame = bytes.fromhex(("AA 81 49 01 02 01 03 01 01 01 00 1E 00 32 01 2C 02 BC 00 00 "
|
|
"01 00 16 00 23 00 B4 02 6C 03 05 00 2A 03 00 00 30 00 46 02 08 03 84 02 03 00 58 04 "
|
|
"01 00 0C 00 12 00 5A 01 E0 04 00 00 0F 01 00 00 21 00 37 01 2C 02 D0 02 09 00 3C 02 EB 43").replace(" ",""))
|
|
s=socket.create_connection(("127.0.0.1",6001)) # 현장1 포트
|
|
import time
|
|
for _ in range(20):
|
|
s.sendall(frame); time.sleep(1) # 1초마다 1프레임
|
|
s.close()
|
|
PY
|
|
```
|
|
|
|
확인:
|
|
```bash
|
|
# 최신 상태 JSON (site01 online:true 로 채워짐)
|
|
curl -s http://localhost:8080/api/latest | head -c 400; echo
|
|
|
|
# 제어 테스트 (전원 OFF 프레임을 site01 소켓으로 송신 → 콜렉터 로그에 '송신' 찍힘)
|
|
curl -s -X POST http://localhost:8080/api/control \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-Auth-Token: <설정한 Http.Token, 없으면 생략>" \
|
|
-d '{"site":"site01","action":"power","value":0}'
|
|
```
|
|
- 브라우저 `http://localhost:8080/` 상단 칩이 **서버연동**, 현장1 점이 초록(온라인)으로 표시.
|
|
- InfluxDB 적재 확인:
|
|
```bash
|
|
influx query 'from(bucket:"erv") |> range(start:-10m) |> filter(fn:(r)=>r._measurement=="erv_room") |> limit(n:5)'
|
|
```
|
|
|
|
---
|
|
|
|
## 9. (선택) 24시간 자동 실행 — systemd 서비스
|
|
|
|
```bash
|
|
# ErvCollector 폴더에서 게시(참조 ErvProtocol 포함 단일 폴더로 묶임)
|
|
dotnet publish -c Release -o ~/erv-publish
|
|
|
|
sudo tee /etc/systemd/system/erv-collector.service >/dev/null <<EOF
|
|
[Unit]
|
|
Description=ERV Collector
|
|
After=network.target influxdb.service
|
|
|
|
[Service]
|
|
WorkingDirectory=$HOME/erv-publish
|
|
ExecStart=$HOME/erv-publish/ErvCollector
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now erv-collector
|
|
journalctl -u erv-collector -f # 실시간 로그
|
|
```
|
|
|
|
---
|
|
|
|
## 10. 외부 EW11(LAN) 에서 WSL 서비스로 접속하게 만들기
|
|
|
|
WSL2 는 기본 NAT 라 LAN 의 EW11 이 WSL 내부 포트에 직접 못 붙는다. 둘 중 하나:
|
|
|
|
**방법 A — Mirrored networking (Windows 11 22H2+, 권장)**
|
|
`%UserProfile%\.wslconfig` (Windows 측, 메모장):
|
|
```ini
|
|
[wsl2]
|
|
networkingMode=mirrored
|
|
```
|
|
```powershell
|
|
wsl --shutdown
|
|
```
|
|
→ WSL 이 호스트 IP 공유 → EW11 은 **윈도우 PC LAN IP : 6001~6003** 으로 접속. `appsettings.json` 의 `Http.Prefix` 도 `http://*:8080/` 권장.
|
|
|
|
**방법 B — portproxy (Windows 10)**
|
|
관리자 PowerShell:
|
|
```powershell
|
|
$wsl = (wsl hostname -I).Trim().Split(" ")[0]
|
|
foreach ($p in 6001,6002,6003,8080) {
|
|
netsh interface portproxy add v4tov4 listenport=$p listenaddress=0.0.0.0 connectport=$p connectaddress=$wsl
|
|
}
|
|
```
|
|
> 방법 B 의 WSL 내부 IP 는 재부팅마다 바뀌므로 재실행 필요(방법 A 가 편함).
|
|
|
|
**Windows 방화벽 인바운드 허용** (관리자 PowerShell):
|
|
```powershell
|
|
New-NetFirewallRule -DisplayName "ERV Collector" -Direction Inbound -Protocol TCP -LocalPort 6001-6003 -Action Allow
|
|
New-NetFirewallRule -DisplayName "ERV Web" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow
|
|
```
|
|
|
|
EW11(IOTService) 설정: TCP Client / Server=윈도우 PC IP / Port=현장별 6001~6003 / 115200 8N1 / AES / Keepalive.
|
|
|
|
---
|
|
|
|
## 11. 종료 · 재시작 · 트러블슈팅
|
|
|
|
```bash
|
|
# 서비스 제어
|
|
sudo systemctl restart erv-collector
|
|
sudo systemctl status influxdb grafana-server erv-collector
|
|
|
|
# 포트 점유 확인
|
|
ss -ltnp | grep -E '6001|6002|6003|8080|8086'
|
|
```
|
|
|
|
| 증상 | 원인 / 조치 |
|
|
|---|---|
|
|
| `HTTP 서버 시작 실패` | `Http.Prefix` 가 `+`/`*` 인데 권한 부족 → WSL(Linux)에선 보통 OK. Windows 직접 실행 시 `localhost` 사용 |
|
|
| `Influx write FAIL: 연결 거부` | InfluxDB 미기동 → `sudo systemctl start influxdb`, 토큰/org/bucket 확인 |
|
|
| 브라우저에서 8080 접속 안됨 | WSL localhost 공유는 보통 자동. 안되면 `wsl --shutdown` 후 재시도 / 방화벽 |
|
|
| EW11 이 못 붙음 | 10장(mirrored/portproxy + 방화벽), `Http.Prefix=http://*:8080/`, 같은 서브넷 여부 |
|
|
| `dotnet` 없음 | 3장 재확인, `source ~/.bashrc` |
|
|
|
|
---
|
|
|
|
## 12. 참고 문서
|
|
- 수집서버 상세: `ErvCollector/README.md`
|
|
- 프레임 규격: `../TestProgram/PC_ERV_Protocol.md`
|
|
- EW11 클라우드 전송 검토: `../EW11_RS485 TO WIFI/260603_EW11_클라우드전송_검토.md`
|