Realtime DB 추가 및 Historical DB추가

This commit is contained in:
windpacer
2026-04-14 09:56:37 +00:00
parent 323aec34af
commit 68758f1bb8
23 changed files with 1743 additions and 47 deletions

View File

@@ -52,6 +52,14 @@
<span class="ni">05</span>
<span class="nl">노드맵 대시보드</span>
</li>
<li class="nav-item" data-tab="pb">
<span class="ni">06</span>
<span class="nl">포인트빌더</span>
</li>
<li class="nav-item" data-tab="hist">
<span class="ni">07</span>
<span class="nl">이력 조회</span>
</li>
</ul>
<div class="sb-foot">
@@ -308,9 +316,6 @@
<div class="pane-tag">NODE MAP / MASTER</div>
</header>
<!-- 통계 카드 -->
<div id="nm-stat-row" class="nm-stat-row hidden"></div>
<!-- 필터 카드 -->
<div class="card">
<div class="card-cap">필터 조건</div>
@@ -336,15 +341,16 @@
<input id="nf-nid" class="inp" placeholder="포함 검색"/>
</div>
<div class="fg">
<label>데이터 타입</label>
<select id="nf-dtype" class="inp">
<option value="">전체</option>
</select>
<label>데이터 타입 <em>(직접 입력)</em></label>
<input id="nf-dtype" class="inp" placeholder="예: Double, Int32"/>
</div>
</div>
<!-- 이름 OR 조건 선택 (최대 4개) -->
<!-- 이름 OR 조건 선택 (최대 4개) — 불러오기 버튼으로 옵션 채움 -->
<div class="fg nm-name-row">
<label>이름 선택 <em>(OR 조건, 최대 4개)</em></label>
<label style="display:flex;align-items:center;gap:8px">
이름 선택 <em>(OR 조건, 최대 4개)</em>
<button class="btn-b btn-sm" onclick="nmLoadNames()" style="margin-left:4px">▼ 옵션 불러오기</button>
</label>
<div class="nm-name-selects">
<select id="nf-name-1" class="inp nm-name-sel"><option value="">— 선택 안 함 —</option></select>
<select id="nf-name-2" class="inp nm-name-sel"><option value="">— 선택 안 함 —</option></select>
@@ -377,6 +383,156 @@
<div id="nm-table" class="tbl-wrap hidden"></div>
</section>
<!-- ══════════════════════════════════════════════════════
06 포인트빌더
═══════════════════════════════════════════════════════ -->
<section class="pane" id="pane-pb">
<header class="pane-hdr">
<div>
<h1>포인트빌더</h1>
<p>node_map_master 에서 실시간 모니터링할 포인트를 선택해 realtime_table 을 구성합니다.</p>
</div>
<div class="pane-tag">REALTIME / BUILD</div>
</header>
<!-- 빌더 카드 -->
<div class="cols-2">
<div class="card">
<div class="card-cap">조건으로 테이블 작성</div>
<div class="fg">
<label>이름(name) 선택 <em>(OR 조건, 최대 8개)</em>
<button class="btn-b btn-sm" onclick="pbLoad()" style="margin-left:4px">▼ 옵션 불러오기</button>
</label>
<div class="pb-name-grid" id="pb-name-grid">
<!-- JS 에서 드롭다운 동적 생성 -->
<select id="pb-n1" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="pb-n2" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="pb-n3" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="pb-n4" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="pb-n5" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="pb-n6" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="pb-n7" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="pb-n8" class="inp"><option value="">— 선택 안 함 —</option></select>
</div>
</div>
<div class="fg">
<label>데이터 타입(data_type) 직접 입력 <em>(OR 조건, 최대 2개)</em></label>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px">
<input id="pb-dt1" class="inp" placeholder="예: Double"/>
<input id="pb-dt2" class="inp" placeholder="예: Int32"/>
</div>
</div>
<button class="btn-a" onclick="pbBuild()">🔨 테이블 작성하기</button>
<div id="pb-build-log" class="logbox hidden" style="margin-top:10px"></div>
</div>
<div class="card">
<div class="card-cap">수동 포인트 추가</div>
<div class="fg">
<label>Node ID 직접 입력</label>
<input id="pb-manual-nid" class="inp" placeholder="ns=2;s=Honeywell.Experion..."/>
</div>
<button class="btn-b" onclick="pbAddManual()"> 추가</button>
<div id="pb-manual-log" class="logbox hidden" style="margin-top:10px"></div>
<div class="card-cap" style="margin-top:20px">실시간 구독 제어</div>
<div class="cols-2" style="gap:8px;margin-bottom:10px">
<div class="fg">
<label>서버 IP</label>
<input id="pb-rt-ip" class="inp" value="192.168.0.20"/>
</div>
<div class="fg">
<label>포트</label>
<input id="pb-rt-port" class="inp" type="number" value="4840"/>
</div>
<div class="fg">
<label>클라이언트 호스트</label>
<input id="pb-rt-client" class="inp" value="dbsvr"/>
</div>
<div class="fg">
<label>계정</label>
<input id="pb-rt-user" class="inp" value="mngr"/>
</div>
<div class="fg" style="grid-column:1/-1">
<label>비밀번호</label>
<input id="pb-rt-pw" class="inp" type="password" value="mngr"/>
</div>
</div>
<div class="btn-row">
<button class="btn-a" onclick="rtStart()">▶ 구독 시작</button>
<button class="btn-b" onclick="rtStop()">■ 구독 중지</button>
<button class="btn-b btn-sm" onclick="rtStatus()">상태 확인</button>
</div>
<div id="pb-rt-status" class="logbox hidden" style="margin-top:8px"></div>
</div>
</div>
<!-- 포인트 목록 -->
<div class="card" style="margin-top:0">
<div class="card-cap" style="display:flex;justify-content:space-between;align-items:center">
<span>포인트 목록 <span id="pb-count" class="mut">(0개)</span></span>
<button class="btn-b btn-sm" onclick="pbRefresh()">↻ 새로 고침</button>
</div>
<div id="pb-table" class="tbl-wrap">
<div style="padding:20px;color:var(--t2)">포인트가 없습니다. 위에서 테이블을 작성하세요.</div>
</div>
</div>
</section>
<!-- ══════════════════════════════════════════════════════
07 이력 조회
═══════════════════════════════════════════════════════ -->
<section class="pane" id="pane-hist">
<header class="pane-hdr">
<div>
<h1>이력 조회</h1>
<p>history_table 의 시계열 데이터를 조회합니다.</p>
</div>
<div class="pane-tag">HISTORY / TREND</div>
</header>
<div class="card">
<div class="card-cap">조회 조건</div>
<div class="fg">
<label style="display:flex;align-items:center;gap:8px">
태그 선택 <em>(최대 8개, OR 조건)</em>
<button class="btn-b btn-sm" onclick="histLoad()" style="margin-left:4px">▼ 옵션 불러오기</button>
</label>
<div class="pb-name-grid">
<select id="hf-t1" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="hf-t2" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="hf-t3" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="hf-t4" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="hf-t5" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="hf-t6" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="hf-t7" class="inp"><option value="">— 선택 안 함 —</option></select>
<select id="hf-t8" class="inp"><option value="">— 선택 안 함 —</option></select>
</div>
</div>
<div class="cols-3">
<div class="fg">
<label>시작 시간</label>
<input id="hf-from" class="inp" type="datetime-local"/>
</div>
<div class="fg">
<label>종료 시간</label>
<input id="hf-to" class="inp" type="datetime-local"/>
</div>
<div class="fg">
<label>최대 행 수</label>
<input id="hf-limit" class="inp" type="number" value="500" min="10" max="5000"/>
</div>
</div>
<div class="btn-row">
<button class="btn-a" onclick="histQuery()">🔍 조회</button>
<button class="btn-b" onclick="histReset()">초기화</button>
</div>
</div>
<div id="hist-result-info" class="nm-result-info hidden" style="margin:8px 0"></div>
<div id="hist-table" class="tbl-wrap hidden"></div>
</section>
</main>
</div>