Files
HC900-Crawler/docs/작업플랜-온도프로파일-사용자정의.md
windpacer d88784635e docs: 작업지시·진단·아키텍처 설계 문서 추가
온도프로파일/PV일관성/PointBuilder/history 작업지시, 신호태그·스팀유량 진단, 베이직아키텍처 재설계, MSDS, LLM채팅 구조 등.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 08:12:01 +09:00

6.6 KiB

온도 프로파일 — 사용자 정의 기준밴드 적용

배경

현재 gen_temp_profiles.py가 4개월치 데이터를 k-means 클러스터링하여 P0/P1/P2를 자동 분류하고, 각 클러스터의 median/std를 tempref.json에 저장 → 시스템이 이를 기준밴드로 사용.

문제: 클러스터링 결과를 신뢰할 수 없고, reb_temp 노이즈에 따라 제품매칭이 5초~1분 단위로 튀어 밴드가 불안정함.

해결 방향: 운전자가 각 제품의 단계별 정상값(target + 허용편차)을 직접 정의하고, 선택한 제품 정의를 시스템이 고정 기준으로 사용함. 자동매칭 제거.

핵심 원칙

사용자가 선택한 제품 정의는 절대 자동으로 변경되지 않는다. 실제 공정값이 기준에서 벗어나면 deviated 플래그만 표시하고, 기준 자체는 유지.


Phase A — 데이터 모델 + 백엔드 API

A1. DB Entity: UserTempProfile

Infrastructure/Database/ 에 추가.

public class UserTempProfile
{
    public int Id { get; set; }
    public string ColumnName { get; set; } = "";       // "C-6111"
    public string Label { get; set; } = "";             // "경질원료"
    public string? Description { get; set; }

    // Stage definitions: serialized as JSON
    // {"reb_temp": {"median":124, "std":2}, "T_B": {"median":111, "std":2}, ...}
    public string StageDefsJson { get; set; } = "{}";

    // Vacuum
    public double VacuumTarget { get; set; }
    public double VacuumDev { get; set; }

    // Span AD
    public double SpanAD { get; set; }

    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
}

StageDefsJson은 기존 TempStat(median, std) 구조와 동일하므로 JsonSerializer.Deserialize<Dictionary<string, TempStat>>()로 복원 가능.

Hc900DbContextDbSet<UserTempProfile> 추가 + migration.

A2. API: 프로파일 CRUD

Method Path 용도
GET /api/steam/profiles?col=C-6111 컬럼별 프로파일 목록
POST /api/steam/profiles 생성/갱신 (Id=0이면 INSERT, >0이면 UPDATE)
DELETE /api/steam/profiles/{id} 삭제

A3. API: TempProfile / TempProfileHistory 수정

GET /api/steam/tempprofile/{col}?profileLabel=경질원료

  • profileLabel이 있으면 → DB에서 해당 프로파일 로드 → ComputeStages에 전달
  • profileLabel이 없으면 → 자동매칭 없음, 첫 번째 사용자 프로파일 사용 or 에러
  • 자동매칭(기존 tempref.json P0/P1/P2)은 완전 제거

응답에 auto-generated 참고 데이터도 함께 반환 (비교용):

{
  "column": "C-6111",
  "userProfile": { "label": "경질원료", "description": "...", "stages": {...} },
  "stages": [
    { "stage": "reb_temp", "current": 120.5,
      "target": 124, "dev": 2, "z": -1.75, "deviated": false }
  ],
  "autoRef": {
    "matchedProduct": "P0",
    "stages": [ { "stage": "reb_temp", "refMedian": 84.81, "refStd": 0.5, "z": ... } ]
  }
}
  • stages[i].target/dev = 사용자 정의값
  • autoRef = 기존 tempref.json의 자동매칭 결과 (참고용, 별도 색상으로 표시)
  • 사용자 정의가 없으면 autoRef만 반환 (하위호환)

GET /api/steam/tempprofile/{col}/history?profileLabel=경질원료

  • 모든 스냅샷이 동일한 사용자 정의 프로파일 기준으로 z-score 계산
  • 각 스냅샷의 stages는 사용자 정의 target/dev 기준
  • autoRef도 각 스냅샷별로 계산하여 함께 반환

A4. ComputeStages 리팩터

private static (List<object> stages, object vacuum, double? spanAD) ComputeStages(
    Dictionary<string, double?> cur,
    TempRef tref,                    // auto-generated reference (nullable)
    UserTempProfile? userProfile)    // user-defined profile (nullable)
  • userProfile이 있으면 → 그 값으로 z-score 계산 (median=target, std=dev)
  • tref → autoRef 용도로만 사용 (비교 표시)
  • 제품매칭 로직 제거

Phase B — 프론트엔드: 프로파일 관리 UI

B1. 프로파일 CRUD 화면

위치: steam.html 내 모달 또는 별도 관리 페이지

  • 컬럼 선택 드롭다운 (C-6111, C-6211, ...)
  • 제품 목록 테이블 (Label, Description, 각 단계 target/dev, vacuum, spanAD)
  • Add / Edit (인라인 or 폼) / Delete 버튼
  • 저장 시 POST /api/steam/profiles

입력 필드 (제품 하나당):

단계 Target 허용편차(±)
reb_temp [input] [input]
T_B [input] [input]
T_C [input] [input]
T_D [input] [input]
진공 [input] [input]
Span AD [input] (단일값, std 없음)

초기값 제안: 기존 tempref.json의 P0/P1/P2 데이터를 불러와서 "기본값으로 채우기" 버튼

B2. 제품 선택기

steam.html 온도 프로파일 탭 상단에 드롭다운 추가.

  • DB에 저장된 사용자 정의 프로파일 목록 표시
  • 선택 즉시 stTempLoad(profileLabel) 호출 → 전체 차트 리로드
  • 선택값은 localStorage에 저장 (페이지 새로고침 시 유지)

Phase C — 차트: 이중 밴드 표시

C1. 두 개의 밴드

구분 색상 스타일 의미
사용자 정의 밴드 녹계열 (#4caf50 fill) 굵은 실선 중앙값 + 투명 fill 기준 — 이게 정상이다
자동 (tempref.json) 청회색 (#78909c fill) 가는 점선 중앙값 + 연한 fill 참고 — 실제 운전 통계

C2. 실시간 라인

  • 두 밴드 위에 실시간 current 값 표시 (파랑 굵은 실선, circle symbol)

C3. 과거 스냅샷

  • 선택 시점 line: amber (#fa3) 굵은 실선
  • 현재 실시간 참조: thin dashed blue line
  • 두 밴드는 동일하게 유지 (사용자 정의 + auto-ref)

마이그레이션

  1. 기존 tempref.jsonproducts를 초기 UserTempProfile seed data로 DB에 로드
  2. 기존 자동매칭 코드를 deprecated 처리 (autoRef 비교용으로만 유지)
  3. UI에 "데이터 초기화" 버튼 — tempref.json에서 다시 불러오기

작업 순서 (권장)

  1. A1 — Entity + DbContext + migration
  2. A2 — CRUD API endpoints
  3. A3 — TempProfile/TempProfileHistory 수정 + ComputeStages 리팩터
  4. B1 — 프로파일 관리 UI (모달)
  5. B2 — 제품 선택기 드롭다운
  6. C — 이중 밴드 차트 렌더링
  7. 시드 데이터 + 테스트

보류 사항

  • gen_temp_profiles.py 수정: 자동 클러스터링 유지, 출력에 user-defined 템플릿 포함
  • 다중 컬럼 동시 표시 (현재 단일 컬럼, 필요시 별도 논의)