# 작업지시서 — bit15 기반 AutoRun "이어하기(Resume)" 구현 - 작성일: 2026-06-21 - 대상: `Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs` 외 (아래 1장) - 근거 분석: `docs/분석/2026/06/21/bit15_resume_재진입_문제분석_작업PC전달.md` - 현재 상태: **소스 미수정**. bit15 미구현. 본 지시서대로 구현. > 시나리오: PLC가 `PAGE_CHANGE_REQ(0x08)` 처리·`PAGE_CHANGE_COMPLETE` 응답 **후** 입력 bit15 ON → 장비 정지 > + 팝업 표시. 정지 중 작업자 수동작업 → "이어하기" 버튼이 AutoRun 시작 + 출력 bit15 ON → 페이지 > 핸드셰이크 건너뛰고 **중단된 그 페이지를 업로드→용접부터 이어감**. --- ## 0. 확정 사항 (질의 응답 반영) - **C-1. 비트 번호**: 입력 `0x0F`=M70515(PLC→PC, 정지요청), 출력 `0x0F`=M70015(PC→PC, 이어하기 신호). 둘 다 현재 `0x0A~0x0F` 예약공백(PLCController.Address.cs:27, 63). - **C-2. 정지 감지**: **기존 상시 모니터에서 입력 bit15 폴링** → AutoRun 정지 + 팝업. (알람 정지 패턴과 동일, AlarmManager_PTOP.cs:19 참고) - **C-3. 팝업**: 정보성 모달(확인 버튼), side effect 없음. - **C-4. 출력 bit15 수명**: 이어하기 시작 시 ON → **한 사이클(용접완료) 후 OFF**. --- ## 1. 작업 범위 (변경 대상) - `…/Device/PLC/PLCController.Address.cs` — 입력/출력 bit15 enum 추가 - `…/Sequences/SeqAutoRunPTOP.cs` — ResumeMode 플래그, OnSeqActionStop 보존 분기, CheckInitCondition resume 분기, 출력 bit15 OFF, Flow - `…/Views/Main/UCMainAutoRunViewModel.cs` (+ View) — RollbackRecipe 스킵 분기, "이어하기" 버튼/커맨드 - 상시 모니터 시퀀스(우선 `SeqStatusMonitor` 검토) — bit15 폴링 + 정지 트리거 + 팝업 - 팝업: 기존 모달 유틸(`MessageUtil` 등) 재사용 > 플래그 명칭은 제안값(작업 PC 확정): 비트 `PLC_RESUME_STOP_REQ`/`PC_RESUME_RUN`, 상태 `ResumeMode`. --- ## 2. 구현 절차 (Step) ### Step 1. 비트 정의 추가 - `eBitInput`에 `PLC_RESUME_STOP_REQ = 0x0F` (M70515) 추가. - `eBitOutput`에 `PC_RESUME_RUN = 0x0F` (M70015) 추가. ### Step 2. 정지 감지 (모니터 폴링) - 상시 모니터에서 `ReadBit(PLC_RESUME_STOP_REQ)` 폴링. - ON(엣지) 감지 시: 1. `ResumeMode = true` (Step 3 플래그) **먼저 set** 2. AutoRun이 Running이면 `SeqAutoRunPTOP.Stop()` 호출 3. 팝업 표시(Step 4) — `PLC_RECIPE_NO`/`PLC_PAGE_NO` 읽어 전달 - **엣지 처리**: bit15를 레벨로만 보면 정지/팝업 반복 → OFF→ON 엣지 1회만 반응(직전값 비교). ### Step 3. ResumeMode 플래그 + 정지 시 상태 보존 - `SeqAutoRunPTOP`에 `public bool ResumeMode { get; set; }` 추가(모니터·ViewModel·Sequence 공유). - `OnSeqActionStop`(SeqAutoRunPTOP.cs:1078): `if (ResumeMode)`면 - `PC_RECIPE_NO=0`(:1102) · `PC_PAGE_NO=0`(:1101) **쓰기 스킵** (에코 보존) - 나머지(용접비트/게이트 OFF/`StopExecution`+`JumpAbs`)는 **그대로** (안전) - `OnStopSequenceAutoRun`(UCMainAutoRunViewModel.cs:328): `if (ResumeMode)`면 `RollbackRecipe()`(:345) **스킵**. (워드 보존과 반드시 짝 — 안 하면 워드≠활성레시피) - 일반/알람/ForceError 정지는 `ResumeMode=false`라 기존대로 전체 리셋. ### Step 4. 팝업 (정보성 모달) - 내용(고정): ``` Recipe Number : [PLC_Recipe_No] Page Number : [PLC_Page_No] 용접 위치를 확인해주십시오. ``` - 값: `ReadWord(eWordInput.PLC_RECIPE_NO).data`, `ReadWord(eWordInput.PLC_PAGE_NO).data`. - UI 스레드(`Dispatcher`)에서 표시, 확인 버튼만. side effect 없음. ### Step 5. "이어하기" 버튼 - AutoRun 화면에 신규 버튼/커맨드 추가. - 동작: `if (!ResumeMode) { 경고 후 return; }` → `Status.SetStatus(Auto)` → `_SeqAutoRunPTOP.Start(param, OnCompleteAutoRunPTOP)`(UCMainAutoRunViewModel.cs:244 패턴) → `WriteBit(PC_RESUME_RUN, true)` → `PC_AUTO_STATUS(_P)` ON. - 기존 정상 AutoRun 버튼은 시작 시 `ResumeMode=false`로 두어 처음부터 동작(영향 없음). ### Step 6. resume 재진입 분기 (핸드셰이크 스킵) - `CheckInitCondition`(SeqAutoRunPTOP.cs:270, Decision): - `if (ResumeMode) return SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ;` (페이지 핸드셰이크 스킵, 유지된 `_CurrentPageNo`로 업로드→용접) - else `return SEQ_CHECK_PAGENO;` (기존, :284) - `Sequence_Enter`의 `Status.GetProcessingWeldingData().Clear()`(:230)가 resume에 문제 없는지 확인(용접리스트 재업로드라 무방 예상). ### Step 7. 출력 bit15 OFF (사이클 완료 후) - 이어붙인 페이지 용접 완료 직후 `WriteBit(PC_RESUME_RUN, false)` + `ResumeMode=false`. - 위치: `ExecuteWelding` 완료부(SeqAutoRunPTOP.cs:819 직전) 또는 `CheckCycleStop` 진입 시. (`CheckCycleStop`→`CheckPageNo` 루프(:829)라 이후는 정상 운전 복귀) - **현재 구현**: `CheckCycleStop` 진입 시 `if(ResumeMode)` 블록에서 `PC_MODE_CHANGE(_P) false` + `ResumeMode=false`. - **[대안 — PLC 협의 필요]** 출력 bit15 false 처리를, 시퀀스 1바퀴 후 **다시 PageChange 신호를 보고 있을 때(다음 PAGE_CHANGE_REQ가 true로 들어오는 그 코드블록 안)** 에서 수행하는 방안. 즉 `CheckPageNo`/`CheckPageNoComp`의 REQ 수신 시점에 PC_MODE_CHANGE를 내려주는 식. → PLC가 출력 bit15를 언제 클리어로 인식하는지(에코/ACK 타이밍)와 맞춰야 하므로 **PLC측과 합의 후 위치 확정.** ### Step 8. Builder/Flow + 빌드 - CheckInitCondition→Upload 엣지 추가: `sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ]);` - `Draw("SeqAutoRunPTOP.pdf")` 갱신 확인. - MSBuild Debug|x64 **0 오류**. --- ## 3. 검증 (Test) - [ ] 빌드 0 오류. - [ ] 입력 bit15 ON → 정지 + 팝업(Recipe/Page 값 정확). - [ ] 정지 후 `PC_RECIPE_NO`/`PC_PAGE_NO`가 **0으로 안 바뀜**, `RollbackRecipe` **미실행**(활성 레시피 유지). - [ ] "이어하기" 버튼 → 핸드셰이크 스킵, 유지된 페이지로 업로드→용접 이어짐. 출력 bit15 ON→완료 후 OFF. - [ ] 정상 AutoRun 버튼은 기존대로 처음부터(핸드셰이크 포함) 동작. - [ ] **알람/일반 Stop은 기존대로 전체 리셋**(워드 0 + RollbackRecipe) — resume 보존 미적용(플래그 분리 확인). - [ ] 페이지 용접 완료 후 라인 정합(실제 Laser 발진). --- ## 4. 리스크 / 주의 - **플래그 공유 동기화**(모니터↔ViewModel↔Sequence): 잘못되면 일반/알람 정지에도 보존이 적용됨 → 분리 검증 필수. - **mid-weld 중 bit15**: 스캐너 리스트 중도취소(StopExecution+JumpAbs)로 라인단위 복구 불가 → **페이지 단위 재시작만** 가능. 시나리오상 page change 직후에만 온다는 전제. - **팝업 모달 교착**: 시퀀스/모니터 스레드에서 직접 모달 금지 → `Dispatcher`로 UI 스레드 표시. - **출력 bit15 OFF 누락** 시 PLC가 계속 resume로 인식 → Step 7 누락 주의. - **팝업값 vs 적용값**: 정지 시점 값과 resume 시점 값이 다를 수 있음(그사이 PLC 변경). 필요 시 정지 때 읽은 값을 래치해 resume에 사용. --- ## 5. 완료 기준 (DoD) - [ ] bit15 입력 정지+팝업, 출력 bit15 ON→완료 OFF, 모두 런타임 확인. - [ ] resume 정지 시 레시피 에코·활성 레시피 보존, 일반/알람 정지는 기존 전체 리셋(분리) 확인. - [ ] 이어하기 시 핸드셰이크 스킵하고 정합된 레시피×페이지로 이어 용접. - [ ] 빌드 0 오류 + 작업일지 기록 + 커밋/푸시.