chore: .gitignore에 Python 캐시 및 가상환경 무시 규칙 추가

This commit is contained in:
windpacer
2026-05-03 03:58:23 +09:00
parent f71ec310e4
commit a0404b1fee
254 changed files with 33 additions and 5083599 deletions

View File

@@ -1,145 +0,0 @@
# 🎨 Graph Pipeline Phase 4: 활용 및 시각화 (Application & Visualization)
이 문서는 P&ID Graph Pipeline의 최종 단계인 **활용 및 시각화**의 상세 구현 계획을 다룹니다. 앞선 단계에서 구축한 [기하학적 데이터 $\rightarrow$ 위상 그래프 $\rightarrow$ 시스템 태그 매핑] 결과물을 결합하여, 운영자가 도면 상에서 실시간 공정 상태를 파악하고 장애 영향도를 분석할 수 있는 인터페이스를 구현하는 것이 목표입니다.
---
## 📦 1. 필수 패키지 및 기술 스택
### 1.1 프론트엔드 (Visualization)
| 기술/라이브러리 | 용도 | 비고 |
|---|---|---|
| `SVG / Canvas API` | P&ID 도면 렌더링 및 데이터 오버레이 | 벡터 기반 정밀 렌더링 |
| `Cytoscape.js` / `D3.js` | 위상 그래프 시각화 및 인터랙티브 탐색 | 그래프 분석 뷰어 |
| `Vue.js` / `React` | 전체 UI 프레임워크 및 상태 관리 | `src/Web` 구조와 통합 |
| `Axios` / `WebSocket` | 실시간 OPC UA 데이터 수신 및 API 통신 | 실시간 업데이트 |
### 1.2 백엔드 (API & Analysis)
| 기술/라이브러리 | 용도 | 비고 |
|---|---|---|
| `ASP.NET Core` | Graph API 및 분석 엔드포인트 제공 | `ExperionCrawler` 메인 서버 |
| `NetworkX` (Python) | 영향도 분석 및 경로 추적 알고리즘 실행 | 분석 엔진 (Phase 2 활용) |
| `FastAPI` / `Flask` | Python 분석 엔진과 C# 서버 간의 브릿지 | 분석 마이크로서비스 |
---
## 📐 2. 상세 설계 구조
### 2.1 실시간 데이터 오버레이 (Real-time Overlay)
도면의 좌표 정보와 매핑된 시스템 태그를 연결하여 실시간 값을 표시합니다.
1. **매핑 데이터 로드:** `(도면노드ID, 시스템태그, 좌표)` 리스트를 프론트엔드로 전달.
2. **실시간 스트리밍:** `OPC UA` $\rightarrow$ `C# Server` $\rightarrow$ `WebSocket` $\rightarrow$ `Frontend`.
3. **동적 렌더링:** 태그 값이 변경되면 해당 좌표의 SVG 요소 색상을 변경하거나 툴팁에 현재 값을 표시.
### 2.2 영향도 분석 엔진 (Impact Analysis Engine)
특정 설비의 이상 발생 시 하류(Downstream) 영향을 계산합니다.
1. **분석 요청:** 사용자가 도면에서 특정 노드(예: 펌프 P-101)를 클릭.
2. **그래프 탐색:** Python 분석 엔진에서 `nx.descendants(G, 'P-101')` 실행.
3. **결과 반환:** 영향받는 모든 노드 ID 리스트와 경로(Path)를 반환.
4. **시각적 강조:** 도면 상에서 영향 경로를 하이라이트(예: 빨간색 선) 처리.
---
## 💻 3. 실제 구현 코딩 가이드 (Example)
### 3.1 [Backend] 영향도 분석 API (C# $\rightarrow$ Python Bridge)
```csharp
// src/Web/Controllers/PidGraphController.cs
// 1. 분석 상태 추적을 위한 DTO
public record AnalysisStatus(string taskId, double progress, string status, string message);
// 2. 실시간 진행 상태 조회 API (Phase 5 병렬 처리 반영)
[HttpGet("status/{taskId}")]
public async Task<IActionResult> GetAnalysisStatus(string taskId)
{
// Orchestrator가 관리하는 작업 상태 저장소(Redis/MemoryCache)에서 조회
var status = await _statusService.GetStatusAsync(taskId);
if (status == null) return NotFound();
return Ok(new {
taskId = status.TaskId,
progress = status.Progress, // 0.0 ~ 1.0
status = status.Status, // "Processing", "Completed", "Failed"
message = status.Message
});
}
[HttpGet("impact/{nodeId}")]
public async Task<IActionResult> GetImpactAnalysis(string nodeId)
{
// Python 분석 마이크로서비스에 요청
var response = await _httpClient.GetAsync($"http://python-analysis-api/impact/{nodeId}");
var result = await response.Content.ReadFromJsonAsync<ImpactResult>();
return Ok(result);
}
```
### 3.2 [Frontend] SVG 데이터 오버레이 및 진행률 표시 (JavaScript)
```javascript
// src/Web/wwwroot/js/pid-viewer.js
// 1. 실시간 값 업데이트
async function updateRealtimeValues(tagData) {
for (const [tag, value] of Object.entries(tagData)) {
const element = document.getElementById(`tag-node-${tag}`);
if (element) {
element.style.fill = value > threshold ? 'red' : 'green';
element.setAttribute('data-value', value);
const tooltip = document.getElementById('pid-tooltip');
tooltip.innerText = `${tag}: ${value}`;
}
}
}
// 2. 분석 진행 상태 표시 (Phase 5 병렬 처리 반영)
async function trackAnalysisProgress(taskId) {
const progressBar = document.getElementById('analysis-progress-bar');
const statusText = document.getElementById('analysis-status-text');
const pollStatus = async () => {
const response = await fetch(`/api/pid/status/${taskId}`);
const data = await response.json();
// 프로그레스 바 업데이트 (예: 20% -> 40% -> 100%)
progressBar.style.width = `${data.progress * 100}%`;
statusText.innerText = `분석 중... ${Math.round(data.progress * 100)}% (${data.message})`;
if (data.status !== 'Completed' && data.status !== 'Failed') {
setTimeout(pollStatus, 1000); // 1초 간격 폴링
} else {
statusText.innerText = data.status === 'Completed' ? '분석 완료!' : '분석 실패';
}
};
pollStatus();
}
```
### 3.3 [Analysis] 경로 추적 유틸리티 (Python)
```python
import networkx as nx
def get_propagation_path(graph, start_node, end_node):
"""장애 전파 경로를 최단 경로 기반으로 추출"""
try:
path = nx.shortest_path(graph, source=start_node, target=end_node)
return path
except nx.NetworkXNoPath:
return None
# 예: P-101에서 V-105까지의 영향 경로 추출
path = get_propagation_path(topology_graph, "P-101", "V-105")
```
---
## 🚀 4. Phase 4 완료 기준 (Definition of Done)
- [ ] P&ID 도면(SVG/Canvas) 위에 **실시간 OPC UA 값**이 정확한 좌표에 표시되는가?
- [ ] 병렬 처리 중인 분석 작업의 **진행 상태(Progress Bar)**가 UI에 실시간으로 반영되는가? (Phase 5 반영)
- [ ] 특정 노드 클릭 시 **하류 영향도 분석(Impact Analysis)** 결과가 시각적으로 하이라이트 되는가?
- [ ] C# 메인 서버와 Python 분석 엔진 간의 **API 통신**이 지연 없이 이루어지는가?
- [ ] 운영자가 도면을 통해 **이상 징후의 전파 경로**를 직관적으로 파악할 수 있는가?
- [ ] 전체 파이프라인(`추출 $\rightarrow$ 모델링 $\rightarrow$ 매핑 $\rightarrow$ 시각화`)이 통합되어 동작하는가?