Files
HC900-Crawler/scripts/load_state_labels.py
windpacer 16fc7a2598 Initial commit: HC900 Crawler
Honeywell HC900을 Modbus TCP로 직접 폴링 → gRPC → C# 크롤러 → PostgreSQL.
기존 Experion OPC UA 데이터 경로를 HC900 직접 통신으로 대체.

- industrial-comm/cpp: C++ Modbus 게이트웨이 (gRPC 서버)
- src: C# .NET 8 ASP.NET Core 크롤러 + 웹 UI (3-Layer)
- mcp-server: Python FastMCP (RAG/NL2SQL/P&ID)
- 다중 컨트롤러(N-Controller) 지원

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 20:28:14 +09:00

49 lines
1.4 KiB
Python

#!/usr/bin/env python3
"""
xlsx의 StatusPoint DescriptorState0~7 → hc900.tag_metadata 로드
실행: python3 scripts/load_state_labels.py
"""
import openpyxl
import psycopg2
from pathlib import Path
XLSX_PATH = Path(__file__).parent.parent / "docs" / "Sinam_Tag_all.xlsx"
DB_DSN = "host=localhost port=5432 dbname=iiot_platform user=postgres password=postgres"
wb = openpyxl.load_workbook(XLSX_PATH, read_only=True, data_only=True)
ws = wb['Sheet1']
rows = list(ws.iter_rows(values_only=True))
headers = rows[1]
col = {h: i for i, h in enumerate(headers) if h}
conn = psycopg2.connect(DB_DSN)
cur = conn.cursor()
inserted = 0
for row in rows[2:]:
name = str(row[col['ItemName']] or '').strip()
cls = str(row[col['Class']] or '').strip()
if cls != 'StatusPoint' or not name:
continue
base_tag = name.lower()
for i in range(8):
key = f'DescriptorState{i}'
if key not in col:
continue
val = row[col[key]]
if val is None or val == '':
continue
cur.execute("""
INSERT INTO hc900.tag_metadata (base_tag, attribute, value)
VALUES (%s, %s, %s)
ON CONFLICT (base_tag, attribute) DO UPDATE SET value = EXCLUDED.value
""", (base_tag, f'state{i}', str(val)))
inserted += 1
conn.commit()
cur.close()
conn.close()
print(f"완료: {inserted}개 상태 레이블 저장")