LGES-OC5-PtoP-Welder/docs/작업지시서/2026-08-03_에코워드_정지시_초기화_정리.md
2026-08-06 11:29:00 +09:00

216 lines
10 KiB
Markdown

# 작업지시서 — AutoRun 정지 시 에코 워드(PC_RECIPE_NO/PC_PAGE_NO) 초기화 정리
- 작성일: 2026-08-03
- 대상 브랜치: `feature/ubisam-pptx-integration` (현장 반영 시 작업 PC 브랜치 기준)
- 작업 분류: 정리 / 선택 적용 — **옵션 1·2·3은 서로 독립이며, 전부 적용할 필요 없음**
- ⚠️ 본 문서는 **수정안(검토용)** 입니다. **아직 소스는 변경하지 않았습니다.**
- 근거 분석: [레시피 저장 교차 오염 원인분석 §9](../분석/2026/08/03/레시피저장_활성vs선택_교차오염_원인분석.md#9-별건-autorun-정지-시-에코-워드pc_recipe_nopc_page_no-초기화-여부)
---
## 0. 한 줄 요약
**"OnSeqActionStop이 워드를 안 지운다"는 사실이지만, 실제로는 `SeqStatusMonitor`가 대신 지우고 있습니다.**
정말로 안 지워지는 구간은 **bit15 Resume 정지 하나뿐**입니다.
그리고 **PC측 에코 워드를 0으로 지워도 PC 로직에는 아무 영향이 없습니다** (PC는 자기 에코를 되읽지 않음).
---
## 1. 현재 동작 (수정 전 기준)
### 1-1. `OnSeqActionStop` — 초기화 코드 없음
`Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs:1209-1212`
```csharp
// 260512 워드
// 260621: 에코 워드(PC_PAGE_NO/PC_RECIPE_NO)는 정지 시 0으로 지우지 않음 — PLC가 정합 확인에 쓰는
// 마지막 핸드셰이크 값을 보존(다음 사이클에 어차피 재에코). 기존 0 초기화 2줄 제거.
Log.I("[OnSeqActionStop] PLC IO Output Word Init"); // ← 실제 동작 없이 문구만 남음
```
→ **로그만 보면 초기화한 것처럼 보입니다.** 이번 혼선의 원인.
### 1-2. 실제 초기화 주체 — `SeqStatusMonitor`
`Machines/ILSOS_PrismaticRD_PTOP/Sequences/Monitoring/SeqStatusMonitor.cs:94-109`
```csharp
if (plcAutoOff || (pcAutoOff && !weldReadyAlive)) {
_plc.WriteWord(eWordOutput.PC_RECIPE_NO, 0);
_plc.WriteWord(eWordOutput.PC_PAGE_NO, 0);
}
```
`OnSeqActionStop:1200`이 `PC_AUTO_STATUS=false`를 쓰므로 → StatusMonitor가 약 60ms 내 `pcAutoOff` 하강엣지 감지 → 초기화.
| 정지 유형 | M70515(bit15) | 실제 결과 |
|---|:---:|---|
| 일반 정지 · 알람 정지 · ForceError | OFF | **0으로 초기화됨** |
| bit15 Resume 정지 | ON | **보존됨** ← 유일한 미초기화 구간 |
---
## 2. 판단 근거 — "PC측 초기화해도 된다"는 타당함
| # | 근거 | 확인 위치 |
|---|---|---|
| ① | **PC는 자기 에코를 되읽지 않는다.** `PC_RECIPE_NO`/`PC_PAGE_NO`는 소스 전체에서 `WriteWord`만 존재. 판정은 항상 PLC 입력 워드로 함 | `CheckRecipeNoComp:349`(D70502), `CheckPageNoComp:571`(D70501) |
| ② | **재진입 시 반드시 재에코된다.** 동일 레시피여도 에코 유지, 페이지는 매번 에코 | `SeqAutoRunPTOP.cs:395`, `:429`, `:563` |
| ③ | **260621에 보존으로 바꾼 근거가 현재 코드에서 성립하지 않는다.** `ResumeMode`는 핸드셰이크를 스킵하지 않음(소비처는 `CheckCycleStop:872-877` 한 곳, bit15 ACK OFF + 플래그 해제뿐). Resume은 `RunSequenceAutoRun()`으로 시퀀스를 처음부터 재시작 | `SeqAutoRunPTOP.cs:872-877`, `UCMainAutoRunViewModel.cs:283-284` |
> ③ 관련: 주석 `SeqAutoRunPTOP.cs:131`, `UCMainAutoRunViewModel.cs:260`의 **"핸드셰이크 스킵"은 현재 구현과 불일치**합니다(옵션A 전환 시 스킵이 사라졌으나 주석·보존 로직만 잔존).
---
## 3. 선행 확인 사항 (옵션 3에만 해당)
| # | 항목 | 확인 대상 |
|---|---|---|
| ★ | **PLC 래더가 `D70001`/`D70002`(PC 에코)를 상시 레벨로 비교하는 인터락이 있는가?** | PLC 담당자 1줄 확인 |
- **있다(가정 A)** → 정지 중 0이 되면 불일치로 기동 금지/알람 가능 → **옵션 3 보류**
- **없다(가정 B, ACK 비트와 함께 1회만 확인)** → 0 초기화 무해 → **옵션 3 적용 가능**
> 현재 PC 코드는 B 전제로 작성돼 있고(`CheckPageNoComp:563→573`), **일반 정지에서는 이미 0으로 지우는데 현장 문제 보고가 없습니다.** B일 가능성이 높습니다. 옵션 1·2는 이 확인 없이도 진행 가능합니다.
---
## 4. 옵션 (독립 적용 — 전부 할 필요 없음)
### ✅ 옵션 2 — 문서화 정리만 (권장 시작점, 동작 변경 없음)
**목적**: 초기화 책임이 `SeqStatusMonitor`에 있음을 코드에 명시해 같은 혼선 재발 방지.
**대상**: `SeqAutoRunPTOP.cs:1209-1212`
```csharp
// [변경 전]
// 260512 워드
// 260621: 에코 워드(PC_PAGE_NO/PC_RECIPE_NO)는 정지 시 0으로 지우지 않음 — PLC가 정합 확인에 쓰는
// 마지막 핸드셰이크 값을 보존(다음 사이클에 어차피 재에코). 기존 0 초기화 2줄 제거.
Log.I("[OnSeqActionStop] PLC IO Output Word Init");
// [변경 후]
// 260621: 에코 워드(PC_PAGE_NO/PC_RECIPE_NO)는 여기서 지우지 않는다.
// 260803: 실제 초기화 주체는 SeqStatusMonitor.UpdateStatus (SeqStatusMonitor.cs:94-109).
// 이 함수가 PC_AUTO_STATUS=false(:1200)를 쓰면 StatusMonitor가 하강엣지를 잡아
// PC_RECIPE_NO/PC_PAGE_NO를 0으로 초기화한다(단, M70515 ON인 bit15 Resume 구간은 보존).
// → 여기서 중복 초기화하지 말 것.
Log.I("[OnSeqActionStop] 에코 워드 초기화는 StatusMonitor 담당 — 여기서는 미처리");
```
| 항목 | 내용 |
|---|---|
| 수정 파일 | `SeqAutoRunPTOP.cs` 1개 (주석 + 로그 문구) |
| 동작 변경 | **없음** |
| 검증 | 빌드 확인만 |
| 롤백 | 불필요 |
---
### ⚠️ 옵션 1 — `OnSeqActionStop`에 0 초기화 2줄 복원
**권장하지 않음.** 아래 이유로 사실상 옵션 3과 같아집니다.
```csharp
// SeqAutoRunPTOP.cs:1212 부근에 추가
_PLC.WriteWord(eWordOutput.PC_RECIPE_NO, 0);
_PLC.WriteWord(eWordOutput.PC_PAGE_NO, 0);
```
| 문제 | 내용 |
|---|---|
| 중복 | StatusMonitor가 이미 같은 일을 함 (일반 정지 경로) |
| **부작용** | `OnSeqActionStop`에는 **M70515 예외가 없음** → bit15 Resume 정지에서도 워드가 0이 됨 = **옵션 3의 동작 변경이 그대로 발생**하는데, 근거·검증은 옵션 3보다 부실 |
| 결론 | 굳이 한다면 옵션 3으로 **한 곳(StatusMonitor)에서** 처리할 것 |
> 그래도 적용해야 한다면, 3장 ★ 확인을 옵션 3과 동일하게 선행하고 6장 T3를 반드시 검증하세요.
---
### 🔬 옵션 3 — bit15 보존 예외 제거 (실제 동작 변경, 검증 필요)
**전제**: 3장 ★ 확인이 **가정 B**로 나온 경우에만 진행.
**대상**: `SeqStatusMonitor.cs:104`
```csharp
// [변경 전]
if (plcAutoOff || (pcAutoOff && !weldReadyAlive))
// [변경 후] — bit15 구간에서도 정지 시 에코 워드를 0으로 초기화
if (plcAutoOff || pcAutoOff)
```
로그 문구도 함께 정리:
```csharp
Log.W($"[StatusMonitor] Auto OFF(PLC:{plcAutoOff}/PC:{pcAutoOff}) → PC_RECIPE_NO/PC_PAGE_NO 0 초기화");
```
**연계 정리 (옵션 3 적용 시 같이 처리 권장)** — 보존이 불필요해지므로 잔존 주석의 사실관계를 맞춥니다.
| 위치 | 현재 주석 | 문제 |
|---|---|---|
| `UCMainAutoRunViewModel.cs:226` | `// 정지 시 에코 워드(PC_RECIPE_NO/PC_PAGE_NO)·활성 레시피 보존 (OnSeqActionStop이 워드 0 안 씀)` | 옵션 3 적용 시 **보존되지 않음** → 문구 수정 필요 |
| `SeqAutoRunPTOP.cs:131` | `// bit15 Resume — 정지 시 상태보존 + 재개 시 핸드셰이크 스킵` | **"핸드셰이크 스킵"은 현재도 사실이 아님** (2장 ③) |
| `UCMainAutoRunViewModel.cs:260` | `// (ResumeMode 유지 → 핸드셰이크 스킵)` | 동일. :284 로그는 "정상 핸드셰이크"라고 적혀 있어 자기모순 |
| 항목 | 내용 |
|---|---|
| 수정 파일 | `SeqStatusMonitor.cs` 1개 (+ 주석 3곳) |
| 동작 변경 | **있음** — bit15 Resume 정지 중 D70001/D70002가 0이 됨 |
| 롤백 | `pcAutoOff` → `(pcAutoOff && !weldReadyAlive)` 원복 |
---
## 5. 옵션 선택 가이드
| 상황 | 권장 |
|---|---|
| 일단 혼선만 없애고 싶다 | **옵션 2만** |
| PLC 담당자 확인이 아직 안 됐다 | **옵션 2만** (옵션 1·3 보류) |
| 확인 결과 가정 B, bit15 구간도 깨끗이 0으로 맞추고 싶다 | **옵션 2 + 옵션 3** |
| 옵션 1 | 단독 적용 비권장 (4장 참고) |
---
## 6. 테스트 시나리오
| # | 절차 | 대상 옵션 | 기대 결과 |
|---|---|:---:|---|
| T1 | 일반 AutoRun 정지 → D70001/D70002 확인 | 전 옵션 | **0** (수정 전과 동일 — 회귀 없음) |
| T2 | 정지 후 AutoRun 재시작 → 1사이클 진행 | 전 옵션 | `CheckRecipeNoComp`/`CheckPageNoComp` 로그에 에코 재기록 확인, PLC 정상 진행 |
| T3 | **bit15 ON → 팝업 [확인] → Manual 전환 상태에서 D70001/D70002 확인** | **옵션 3** | 옵션 3 적용 시 **0**. PLC측 알람/기동금지 없어야 함 |
| T4 | T3 상태에서 **[AutoRun Resume]** 버튼 → 재개 | **옵션 3** | 정상 재개. `CheckRecipeNoComp:395/429`·`CheckPageNoComp:563` 에코 복구 로그 확인 |
| T5 | 알람 정지(ForceError) → 워드 확인 | 전 옵션 | 0 (StatusMonitor 경로) |
**T4가 옵션 3의 핵심 검증 항목입니다.** 여기서 PLC가 Resume을 거부하면 → 가정 A → 옵션 3 롤백.
---
## 7. 영향도 요약
| | 옵션 1 | 옵션 2 | 옵션 3 |
|---|:---:|:---:|:---:|
| 수정 파일 수 | 1 | 1 | 1 (+주석 2파일) |
| 동작 변경 | 있음 | **없음** | 있음 |
| PLC 맵 변경 | 없음 | 없음 | 없음 |
| PLC 담당 확인 필요 | ★ 필요 | 불필요 | ★ 필요 |
| 현장 검증 필요 | T1~T5 | 빌드만 | T1~T5 |
| 권장도 | ✕ | ◎ | ○ (확인 후) |
---
## 8. 작업 순서 체크리스트
- [ ] (옵션 3 진행 시) 3장 ★ — PLC 래더의 D70001/D70002 상시 비교 인터락 유무 확인
- [ ] 적용할 옵션 결정 (5장 가이드)
- [ ] 옵션 2 적용 — `SeqAutoRunPTOP.cs:1209-1212` 주석·로그 정리
- [ ] (선택) 옵션 3 적용 — `SeqStatusMonitor.cs:104` + 연계 주석 3곳
- [ ] 빌드 확인
- [ ] T1·T2 검증 (전 옵션 공통 회귀 확인)
- [ ] (옵션 3 적용 시) T3·T4 현장 검증
- [ ] SW Version 시트 반영 · 버전업