- Controller.csv: 컨트롤러 설정 정보 - HC900-PID.txt: PID 파라미터 참조 - HW_Universal_Modbus/: HC900 Modbus 통신 매뉴얼 - 작업지시서-대소문자-DB정합성: 대소문자 DB 정합성 작업 지시 - WARNING-문제점: 프로젝트 이슈 트래킹
9.1 KiB
작업지시서 — 태그명 대소문자 통일 & DB 정합성 (전 탭)
대상: 후속 작업 LLM. 이 문서만으로 독립 실행 가능하도록 배경·파일·라인·검증을 모두 포함함. 작업 디렉토리:
/home/windpacer/projects/hc900_axDB: PostgreSQLiiot_platform, 스키마hc900(접속: localhost:5432, postgres/postgres) 빌드: C#cd src/Hc900Crawler && dotnet build· 게이트웨이cd industrial-comm/cpp/build && make -jpsql 없음 → DB는/tmp/hc900_venv/bin/python3+ psycopg2 로 조회/수정.
0. 핵심 원칙 (반드시 준수)
태그명은 단 하나의 표기 = Experion ItemName 원형 대소문자, 예 FICQ-6101.PV.
게이트웨이 register-map tag, hc900_map_master.tagname = hc900_tag, realtime_table.tagname,
history_table.tagname, FF 설정, 모든 곳에서 동일 표기. 절대 ToLower()/LOWER() 변환 금지.
- 컨트롤러는 컨트롤러당 게이트웨이 프로세스 1개, 각자 own gRPC 포트. 태그는 컨트롤러 내에서만 유일.
- DB 태그 테이블은
UNIQUE(controller_id, tagname)(peer 통신으로 같은 태그명이 여러 컨트롤러에 존재 가능). - 이미 완료된 것(참고):
Hc900RealtimeService.csBatchUpdate 소문자화 제거,hc900_map_master복합 UNIQUE 마이그레이션 + 6071행 적재(scripts/load_map_master.py),register-map-c{1..4}.json,config/gateway-config.json.
1. 현재 DB 상태 (조사 결과)
| 테이블 | 행수 | 비고 |
|---|---|---|
| hc900_map_master | 6071 | ✅ 적재됨 (proper-case) |
| realtime_table | 가변 | 구 크롤러가 소문자로 재기록 중 → 재빌드+재시작 필요 |
| history_table | 55272 | 구 소문자 데이터 혼재 |
| event_history_table | 0 | 크롤러 가동 중 누적됨 |
| tag_metadata | 0 | ⚠ 상태레이블/설명 없음 → TASK 3 |
| pid_equipment | 0 | P&ID 추출 시 채워짐(별도) |
| ff_configs / ff_columns | 없음 | ⚠ 테이블 미생성 → TASK 5 |
| node_map_master | 530080 | 구 ExperionCrawler용(Text-to-SQL). 손대지 말 것 |
2. 작업 목록
TASK 1 — FF 서브시스템 소문자화 전면 제거 (최우선)
문제: FF가 태그를 ToLowerInvariant()로 저장/매칭. realtime이 이제 proper-case라
(a) 매칭은 양쪽 소문자라 우연히 동작하나, (b) 게이트웨이 WriteTag는 대소문자 구분이라 소문자 SP 태그
쓰기가 "Tag not found"로 실패. FF 설정도 소문자로 저장됨.
수정 대상 (모든 .ToLowerInvariant() / .ToLower() 를 제거하고 원형 유지):
src/Infrastructure/Control/FeedforwardSupervisor.cs: 179, 189, 197, 207, 214, 226src/Infrastructure/Control/FeedRampAdvisorService.cs: 28, 37, 41 (특히.EndsWith(".pv")→.PV대응 주의)src/Infrastructure/Control/SimOverrideStore.cs: 20, 30src/Infrastructure/Control/FeedforwardConfigStore.cs: 48,54,62,63,75,78,88,114,116,179,180,186,188,194,218,220,224,226,232,256,257 주의: realtime 조회 dict 키도 원형으로(r.TagName그대로). 비교 필요 시 양쪽 원형 동일 비교. 기존 데이터 마이그레이션: ff_* 테이블에 이미 저장된 소문자 태그를 proper-case로 갱신하거나 설정 재저장. proper-case 정답은hc900_map_master.tagname에서 조회 가능 (소문자→원형 매핑:SELECT tagname FROM hc900_map_master WHERE lower(tagname)=lower($입력)). 검증: FF 탭 advisory에 PV/SP 값 표시됨; SP 쓰기가 게이트웨이에서 성공(success=true).
TASK 2 — 태그 쓰기 UI: MODE 접미사 오류 + MD 읽기전용
문제: src/Hc900Crawler/wwwroot/js/write.js:47 이 tagName + '.MODE' 로 전송하나,
register-map의 모드 태그는 .MD(읽기전용). 모드 변경은 별도 R/W 레지스터로 해야 함:
- Auto/Manual →
<loop>.AutoManState(0=Manual,1=Auto) - LSP/RSP(=CASC) →
<loop>.RemLocSPState(0=LSP,1=RSP) - SP1/SP2 →
<loop>.SP_SelectState, Tune →<loop>.TuneSetState(읽기 상태는<loop>.MD= LoopStatus, 0=RSP AUTO,1=RSP MAN,4=LSP AUTO,5=LSP MAN) 수정: write.js 모드 UI를 위 R/W 레지스터로 쓰도록 변경(.MODE제거). 드롭다운을 Auto/Manual·LSP/RSP 등 개별 제어로 재구성 권장. 검증: C3(192.168.0.240, 데모, 쓰기 허용)에서FICQ-6101.RemLocSPState=1쓰면 Experion이 CASC 표시,=0이면 LSP 복귀. (Modbus 직접 검증:/tmp/hc900_venv/bin/python3+pymodbus, 0x0AFC 레지스터.)
TASK 3 — tag_metadata 적재 (상태레이블·설명) + controller_id
문제: tag_metadata 0행 → 디지털 태그가 상태레이블({1|RUN|}) 없이 raw 숫자로 표시.
Hc900RealtimeService.cs:164가 WHERE attribute LIKE 'state%' AND controller_id=$1로 조회하나
scripts/load_state_labels.py:39는 (base_tag, attribute, value)만 INSERT(controller_id 없음).
수정:
scripts/load_state_labels.py에 controller_id 컬럼 추가 INSERT,--controller인자화, Sinam에서 컨트롤러별 StatusPoint만 필터.base_tag는 realtime tagname과 매칭되는 원형 Experion ItemName 사용 (소문자 금지). (state0~7 + description/area/sub_area 도 동일 규칙)- 4개 컨트롤러 적재 실행.
검증: 디지털 태그 livevalue가
{N|레이블|}형식; 태그관리/트렌드에 설명 표시.
TASK 4 — v_tag_summary 뷰 대소문자 ✅ 완료
진단 결과: Hc900DbContext.cs:519에서 이미 split_part(tagname, '.', 1) 사용, LOWER() 없음.
base_tag가 원형으로 유지됨. 작업 불필요.
TASK 5 — ff_* 테이블 생성 보장 ✅ 완료
진단 결과: Hc900DbContext.cs:1124-1182에 ff_column_config, ff_stream_config 테이블이
이미 CREATE TABLE IF NOT EXISTS + ALTER TABLE ... ADD COLUMN IF NOT EXISTS로 생성됨.
작업지시서가 언급한 ff_configs/ff_columns는 실제 테이블명이 아님. 테이블은 이미 존재.
검증: FF 탭 로드 시 500 없음; 설정 저장/조회 동작.
TASK 6 — PidExtractorService 태그 매칭
문제: src/Core/Application/Services/PidExtractorService.cs:381-384가
tag_no.Split('.')[0].ToLowerInvariant() vs TagName.ToLower() 비교.
수정: 양쪽 원형 비교 또는 명시적 대소문자 무시 비교로 일관화(소문자 변환 데이터 저장은 금지).
검증: P&ID 추출 후 장비-태그 링크 정상.
TASK 7 — 게이트웨이 대소문자 정책 (방어적, 선택)
게이트웨이 WriteTag/ReadTags는 tag_index_ exact-match로 대소문자 구분.
TASK 1·2로 모든 호출자가 원형을 보내면 불필요하나, 견고성 위해
industrial-comm/cpp/src/gateway.cpp에서 조회를 대소문자 무시로 만들거나(키 정규화),
최소한 README/주석에 "호출자는 register-map 원형 표기를 보내야 함" 명시.
3. 탭별 영향 요약 (확인용)
| 탭(pane/js) | 백킹 | 상태 |
|---|---|---|
| Setup (panes/setup.html, js/setup.js) | gateway-config.json, HealthCheck | ✅ 수정완료(연결판정·placeholder) |
| 태그 관리 (pb) | hc900_map_master | ✅ 수정완료(적재+복합UNIQUE) |
| 이력 조회 (hist) | history_table | ⚠ 구 소문자 이력 혼재 — 재시작 후 신규는 원형. 과거 데이터 마이그레이션 여부 결정 |
| 이벤트 (evt) | event_history_table | 크롤러 누적. 이벤트 감지 서비스가 tagname 비교 시 대소문자 점검 |
| 태그 쓰기 (write) | gateway/write | ⚠ TASK 2 |
| 트렌드 (trend) | history_table, v_tag_summary | ⚠ TASK 4 의존 |
| FF (ff) | ff_* , realtime, gateway write | ⚠ TASK 1,5 |
| P&ID (pid) | pid_equipment | ⚠ TASK 6 (링크) |
| Text-to-SQL (t2s) | node_map_master(구) | 별개 체계 — 손대지 말 것 |
| RAG (kbadmin), 문서(docs), LLM(llmchat) | kb_*, 파일시스템 | 태그 무관 — 영향 없음 |
4. 마무리 절차 (모든 TASK 후)
cd src/Hc900Crawler && dotnet build(0 errors 확인)- 게이트웨이 변경 시
cd industrial-comm/cpp/build && make -j - 크롤러 재시작 (구 프로세스가 소문자 재기록 중이므로 필수). 재시작 후:
- realtime_table 이 원형 태그로 재생성되는지 확인
- 필요 시 구 소문자 잔재 정리:
DELETE FROM realtime_table(재폴링으로 즉시 복구)
- 회귀 검증: 각 탭 로드 + Setup 연결상태(C3만 green) + 태그관리 livevalue 표시 + FF SP 쓰기.
5. 참고 사실 (맥락 없는 LLM용)
- 컨트롤러 IP: C1=192.168.0.250, C2=192.168.0.230, C3=192.168.0.240(데모,쓰기OK), C4=192.168.0.220. modbus 502.
- gRPC 포트: C1 50051 … C4 50054 (
config/gateway-config.json). 현재 C3만 물리 연결됨. - 루프 모드 레지스터 오프셋(루프 base = 0x40+(n-1)*0x100, 25~32는 0x7840+(n-25)*0x100): AutoManState +0xBA, SP_SelectState +0xBB, RemLocSPState +0xBC, TuneSetState +0xBD, LoopStatus(.MD,R) +0xBE.
- 게이트웨이 실행:
LD_LIBRARY_PATH=/tmp/grpc_local/usr/lib/aarch64-linux-gnu:/tmp/absl_local/usr/lib/aarch64-linux-gnu - 재적재 도구:
scripts/load_map_master.py --from-config config/gateway-config.json,scripts/build_register_map_from_sinam.py --controller Cn --sinam docs/Sinam_Tag_all.xlsx -o docs/register-map-cn.json