opencode 로 바꾸고 작업전 커밋

This commit is contained in:
windpacer
2026-05-08 17:22:10 +09:00
parent 15c17522c8
commit e923aab43b
202 changed files with 1336027 additions and 115 deletions

View File

@@ -442,6 +442,39 @@ PostgreSQL 시계열 데이터베이스 스키마
livevalue TEXT - 현재값
timestamp TIMESTAMPTZ - 최종 갱신 시각
테이블: tag_metadata (태그 메타데이터 - 변경 드묾)
base_tag TEXT - 기본 태그명 (예: 'ficq-6101', 'xv-6124')
attribute TEXT - 속성명 ('desc', 'area', 'state0descriptor', ...)
value TEXT - 메타데이터 값
node_id TEXT - OPC UA 노드 ID
loaded_at TIMESTAMPTZ - 마지막 로드 시각
뷰: v_tag_summary (실시간값 + 메타데이터 통합 뷰)
base_tag TEXT - 기본 태그명
pv TEXT - 현재 프로세스 값
sp TEXT - 설정값
op TEXT - 출력값
instate0 TEXT - 상태 비트 0 (true/false)
instate1 TEXT - 상태 비트 1 (true/false)
instate2 TEXT - 상태 비트 2 (true/false)
description TEXT - 장비 설명 (tag_metadata.desc)
area TEXT - 소속 플랜트 (tag_metadata.area)
state0_descriptor TEXT - 비트 0 의미 (예: "Run/Stop")
state1_descriptor TEXT - 비트 1 의미 (예: "Remote/Local")
state2_descriptor TEXT - 비트 2 의미 (예: "Trip/Normal")
새로운 태그 타입:
- 아날로그: ficq-6101.pv/sp/op (Double)
- 디지털 XV: xv-6124.pv/op (Int32), xv-6124.instate0~7 (Boolean)
- Pump: p-6102.pv/op (Int32), p-6102.instate0~7 (Boolean)
- 메타데이터: desc (String), area (Enum), state0descriptor~7 (String)
BCD 상태 조회 팁:
- instate0~7은 Boolean (true/false)
- state0descriptor~7은 해당 비트의 의미 설명
- instate0=true이고 state0descriptor="Run/Stop"이면 → "Run" 상태
- v_tag_summary 뷰를 사용하면 실시간값+메타데이터 한 번에 조회 가능
N분 간격 집계 공식 (time_bucket 금지, date_trunc 사용):
1분 버킷: date_trunc('minute', recorded_at) AS bucket
2분 버킷: to_timestamp(FLOOR(EXTRACT(EPOCH FROM recorded_at)/120)*120) AS bucket
@@ -514,7 +547,7 @@ def ask_iiot_llm(question: str, context: str = "") -> str:
)
user_msg = f"컨텍스트:\n{context}\n\n질문: {question}" if context else question
resp = _llm().chat.completions.create(
model=VLLM_MODEL,
model="Qwen3.6-27B-FP8",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": user_msg},
@@ -733,7 +766,7 @@ async def query_with_nl(question: str) -> str:
try:
def _call_llm():
return _llm().chat.completions.create(
model=VLLM_MODEL,
model="Qwen3.6-27B-FP8",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": question},
@@ -820,7 +853,7 @@ async def extract_pid_tags(text: str, source_type: str) -> str:
def _call_llm():
return _llm().chat.completions.create(
model=VLLM_MODEL,
model="Qwen3.6-27B-FP8",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": f"Source: {source_type}\n\nText:\n{truncated_text}"},
@@ -926,7 +959,7 @@ async def match_pid_tags(pid_tags: list[str], experion_tags: list[str]) -> str:
def _call_llm():
return _llm().chat.completions.create(
model=VLLM_MODEL,
model="Qwen3.6-27B-FP8",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": f"P&ID Tags:\n{pid_str}\n\nExperion Tags:\n{experion_str}"},
@@ -1017,7 +1050,7 @@ async def parse_pid_dxf(filepath: str) -> str:
def _call_llm():
return _llm().chat.completions.create(
model=VLLM_MODEL,
model="Qwen3.6-27B-FP8",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": f"Source: dxf\n\nText:\n{truncated_text}"},
@@ -1130,7 +1163,7 @@ async def parse_pid_pdf(filepath: str, use_ocr: bool = True) -> str:
def _call_llm():
return _llm().chat.completions.create(
model=VLLM_MODEL,
model="Qwen3.6-27B-FP8",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": f"Source: pdf\n\nText:\n{truncated_text}"},
@@ -1356,7 +1389,7 @@ async def _forward_request(port: int, tool_name: str, params: dict, one_shot: bo
params: 요청 파라미터
one_shot: True일 경우 요청 완료 후 워커 종료
"""
async with httpx.AsyncClient(timeout=60) as client: # 1분 타임아웃
async with httpx.AsyncClient(timeout=600) as client: # 5분 타임아웃 (대용량 DXF 처리용)
endpoint = "/execute/one_shot" if one_shot else "/execute"
response = await client.post(
f"http://localhost:{port}{endpoint}",