수동출사에서 자동운전 전환 시 레시피/페이지 이동·출사 경로 정적분석. 소스 무수정·런타임 검증 미실시.
결론: 출사 경로 자체는 정상. 다만 종결부 3노드 미실행(파형·카운트·비트리셋), 자동 경로 Door 인터락 부재, 중알람 정지 ID 불일치가 확인됨.
PLC 확인 4문항(PAGE_COMPLETE 감시 / Door 차단 보장 / REQ OFF 보장 / Resume REQ 재발행) 포함.
자동 전환 전 판단 근거 확보를 위한 로그만 추가. 분기/리턴/비트쓰기 무수정.
- [Enter] 활성 레시피 페이지별 객체 수 1회 스캔 (빈 레이어 사전 경고)
- [CheckPageNo] REQ 진입 시점 ON 여부 (레벨/엣지 전환 판단 근거)
- [DoorCond] 출사 직전 Door 판정 기록 전용 - 차단하지 않음
- [사이클요약] 레시피/페이지/객체수/용접ms/GateON ms/PAGE_CMP/Resume 1줄
- [중알람] H알람 정지 대상 ID 불일치 경고 (StopSequence 호출은 그대로)
Door 차단과 정지 ID 수정은 극성/알람목록 확인 후 별건으로 진행한다. 원복: 마커 [로그계측 2026-09-16] 전수 검색 후 삭제 (2파일 10곳).
getScannerParameter 가 null 을 반환하는 타입에서 NumberOfCount 접근 시 NullReferenceException 이 발생하던 문제. null 이면 로그 남기고 해당 객체만 건너뜀(return 0). 원래도 출사 분기가 없어 용접되지 않던 타입이라 동작 변경 없음. 지원 타입(Line/Dot/Arc/Arc3Point/Spline/SnowMan/ZigZag/Group) 경로 무변경. 예외가 실제 프로세스 종료로 이어지는지는 미확인(호스트 Aurora.exe 소스 없음). 빌드/현장 검증 미실시.
OnActivatedRecipe 의 무조건 SaveRecipe 를 활성==선택 조건부로 변경하고 불일치 시 스킵 로그. PreSaved/OnSaved 에 활성!=선택 저장 차단과 안내 모달 추가. ISSUE-260826-04 의 트리거 차단이며 근본 해결은 아님. 현장에서 차단 동작 확인 완료.
메뉴얼/레시피 화면에 DI Laser_EMISSION_ON(10) 기반 출사중 램프 추가. 260904 현장 실측으로 DI 10 이 DO 9 의 에코가 아닌 실제 발진 피드백임을 확증하여 LaserIOControl 주석도 정정. 출사조건 스냅샷은 [LaserCond] 로그로 4개 시점(ShotOn/Heartbeat/ShotOff/DoorForceOff)에 기록. 표시·기록 전용이며 출사 차단 로직은 변경 없음.
## 배경 (현장 사고 2026-09-02)
파워측정 / 파워캘 / 롱텀(1시간 연속출사) 작업 중 Door Open 상태에서 레이저가
출사되었다. 현장 요청: "메뉴얼에서도 Door open 상태에서 레이저 출사 안 되도록
Interlock 필요".
## 원인 (수정 전)
1) SeqComponentTeachingRun.CheckCondition_Interlock()
Door 차단 코드가 '#warning to KSJ > 지워도 무방해보임' 과 함께 전체 주석 처리
되어 있었다. 남은 검사는 HasAlarmLevelHigh() 뿐이라 Door Open 이어도 통과한다.
이 함수가 Manual 경로(Teaching Run / Laser Shot On / Scanner Calibration)의
유일한 출사 게이트였다.
2) UCScannerLaserControlViewModel.PerformCmdLaserShotOnPercent / ...OnWatt
IsUseLaserAutoOffChecked == false 분기(= 파워측정 직접 출사)는 시퀀스를 아예
타지 않고 _Scanner.LaserSignalOn() 을 직접 호출한다. 이 분기에는 Door / EMO /
Busy / LaserReady 어떤 인터락도 없었다. LaserSignalOn 은 자동 오프가 없어
Shot Off 를 누를 때까지 계속 출사되며, 이것이 롱텀 1시간 연속출사의 구현
경로다. 이번 사고의 실제 경로.
3) Door 신호 2계통이 모두 출사를 막지 않고 있었다
- PLC 비트: AlarmManager.IsPlcDoorOpen() 을 호출하는 살아있는 코드가 0곳
(SeqComponentTeachingRun 주석, UCMainAutoRunViewModel 블록 주석)
- IO DI 접점: IODevice.MonitorIOInterfaceMap 이 DoorLockOpen1~4 를 읽지만
타워램프 점등과 EVENT_DOOR_INTERLOCK 발행만 하고, 그 이벤트의 구독자가 없다
## 변경 (수정 후)
[WeldingCommon/Alarm/AlarmManager.cs]
- IsDoorOpen(caller) 신규: PLC 비트(PLC_DOOR_INTERLOCK)와 IO DI 접점
(DoorLockOpen1~4)을 OR 판정. 한쪽 배선/맵이 틀려도 다른 쪽이 잡도록 했다.
- IsIoDoorOpen(), GetDoorStateText() 신규.
- PAIXIO.ReadDiBit 은 비트 1개마다 DI 배열 전체를 읽으므로(PAIXIO.cs:305~307)
80ms TTL 캐시를 두어 100ms 감시 1틱당 실제 읽기 1회로 제한했다.
- IsPlcDoorOpen(): _Plc 지연 조회 보완. 기존에는 AlarmManager 생성 시점에 PLC
등록이 안 끝났으면 _Plc 가 null 로 남아 영구히 false 를 반환 → Door 인터락이
조용히 무력화될 수 있었다.
- PLC/IO 미연결 계통은 판정에서 제외(의도적 fail-open). Door 맵이 없는 타 설비가
이 변경으로 갑자기 출사 불가가 되는 것을 막기 위함. PTOP 는 둘 다 연결되어 있다.
[WeldingCommon/Views/Manual/Scanner/UCScannerLaserControlViewModel.cs]
- PerformCmdLaserShotOnPercent / ...OnWatt 진입부에 Door 게이트 추가
-> 시퀀스 분기와 직접 출사 분기를 모두 커버한다.
- OnMonitoring(100ms)에 MonitorDoorInterlock() 추가: 출사 중 Door 가 열리면
StopExecution + LaserSignalOff + SetStandby 로 강제 차단한다. 시작 게이트만으로는
롱텀 도중 문이 열리는 이번 사고 상황을 막을 수 없어 추가했다.
- VisibleChanged: 직접 출사 중에는 화면을 벗어나도 감시 타이머를 유지한다.
기존처럼 Stop 하면 롱텀 출사 중 Door 감시가 통째로 사라진다.
- 롱텀 추적용 10초 주기 하트비트 로그(Door 상태 + DA1/DA2 전압) 추가.
[ILSOS_PrismaticRD_PTOP/Sequences/Manual/SeqComponentTeachingRun.cs]
- CheckCondition_Interlock(): 주석 처리돼 있던 Door 차단을 IsDoorOpen() 으로 복구.
- DoComponentWelding(): ExecuteList 직전 최종 게이트 추가. 시작 게이트는 시퀀스
진입 시 1회만 돌아, 객체가 여러 개일 때 매 출사 직전 재확인이 필요하다.
## 영향 범위
- SeqAutoRunPTOP 은 자체 ExecuteWelding(SeqAutoRunPTOP.cs:1314)을 사용하며
SeqComponentTeachingRun 을 서브시퀀스로 타지 않는다 -> Auto 생산 동작 변경 없음.
- WeldingCommon 공용 파일을 수정했으나, Door 맵이 없는 설비는 fail-open 으로
기존 동작이 유지된다.
## 남은 사항 (별건)
- 본 변경은 SW 방어이지 안전 인터락이 아니다. Door 감시가 UI 스레드
DispatcherTimer 기반이라 UI 정지 시 함께 멈춘다. Class 4 레이저 기준 최종
차단은 PLC/하드와이어 안전회로로 별도 협의가 필요하다.
- SeqComponentTeachingRun 의 EMO 차단(IsPlcEmoAlarm)도 함께 주석 처리되어 있다.
이번 범위에서 제외했으며, PLC_EMO_STATUS 맵 확인 후 복구 여부를 결정한다.
- UCMainAutoRunViewModel.ApproveAutorunByUserOrAuto() 전체가 블록 주석
(399~431행)이다. Auto 시작 게이트 복구는 Vision Recipe 검사까지 함께 살아나므로
별건으로 검토한다.
본접 5Page -> 6Page 미진행(로봇 미이동) 건 - PLC 원인 확정
- PLC 제어 담당 회신: PLC 프로그램상 잘못된 부분 확인, 샘플 테스트 시 수정 반영 예정
- PC 측 신호는 정상 확인 완료 - PC 수정 사항 없음
- 수정 반영 후 5->6 Page 이동 재검증 필요
- 그때까지 현장은 6Page 수동(Manual) 진행
5.3 절을 'PLC 확인 대기' -> 'PLC 협의 항목'으로 바꾸고 해소/미해소 구분
5.4 운용 현황에 6Page 수동 진행 명시
Doc/인수인계 신규 - 본 레이저 교체 현황 및 인수인계
- 발진기 사양(BFMC-3000/3000M -> MFMC-2000/2000M), IO 채널맵 DI/DO 8~11
- 번들 G3 출사 조건(Key ON -> Remote ON), Start 상시 점등
- IsLaserReady 인터락 기준을 DO Laser_REMOTE 되읽기로 확정한 경위
- 발진기 교체 후 출력 재조정 이력(12_1page 450/850 미접합 -> 650/1050)
- 레시피/페이지는 PLC 지시 추종 구조 (11->12 변경은 PC 소스 무관)
- 타 현장 캘판 레시피 복사 시 motorPos 격자 불일치 주의
- 미결사항: 소스결함 3건, 진단계측 원복, PLC 확인대기
Doc/산출물문서 260828판 3건 추가 (260616/260622/260626 원본 보존)
- 23. SW 점검 결과: IO List 본 레이저 DI/DO 반영, R13 오기 정정, Gantt 3~12월 확장
- 27. HMI Manual: 15 -> 18장, Device/Setting/Alarm 신규(캡처 대기 플레이스홀더)
- 27. 가접용접 매뉴얼: 수동 출사 시 전/후 이미지 미저장 안내 추가
Doc/LGPRI문서: 260730 레시피NUM변경(PLC 협의 완료본) 추적 추가
소스 변경 없음 - 분석 및 문서화만 수행
증상: 버튼을 한 번 눌러도 반응이 없고 두 번 눌러야 Laser_REMOTE 가 켜진다(현장 확인).
원인: toggleIO 가 "다음에 쓸 값"을 VM 이 기억하는 방식이라 실제 DO 와 어긋난다.
SeqAutoRunPTOP 가 같은 DO 를 쓰면서 toggleIO 를 갱신하지 않기 때문 —
:1220 용접시작 true / :1243 용접종료 false / :1701 정지 false
어긋나면 버튼이 같은 값을 다시 써서 아무 변화가 없다.
조치: 현재 DO 를 읽어 반전한다(바로 위 PerformCmdLaserGuideBeam :607-608 과 동일 패턴).
- 버튼 1회 입력에 TRUE/FALSE 가 정확히 기록된다
- 누가 중간에 DO 를 건드려도 항상 현재 상태 기준으로 동작한다
- 표시(OnMonitoring 의 IsLaserReady = ReadDO(Laser_REMOTE))와 1:1 로 맞는다
- AC_KEY(DO 8)는 전원 투입 계층이라 건드리지 않는다
toggleIO 필드는 원복 대비로 남겨둔다(주석 블록 2개가 참조). 외부 참조·XAML 바인딩 없음.
원복: "260826 이전 원본" region 을 살리고 아래 2줄을 제거.
부수 확인: "뷰 전환 시 REMOTE 꺼짐" 은 VisibleChanged(:251-260)에 DO 쓰기가 없고
시퀀스가 끄는 정상 동작이라 별도 조치하지 않는다.
본접 레시피(23/24)에서 page 5 완료 후 page 6 으로 진행되지 않는 건의 원인 구간을
좁히기 위해 CheckPageNo 대기 중 PLC/PC 신호 전체 스냅샷을 기록한다.
2026-08-26 현장 재현으로 원인 확정 완료.
진단계측 (마커 [진단계측 2026-08-26], region 삭제로 원복):
- CheckPageNo 대기 진입 시 스냅샷 1회
- 1초 주기 변화 감지 (값이 바뀔 때만 기록 -> 정상 통과 구간은 1~2줄, 로그 폭주 없음)
- 기존 60초 TIMEOUT 로그에 누적 대기시간 + 스냅샷 추가
- REQ 수신 순간 확정값 (성공 케이스 기준선)
- 기록: PLC 입력 9종(REQ/PAGE/RECIPE/AUTO/AUTO_REQ/M70515/TRIG_REQ/CMP_ACK/D70510)
+ PC 출력 되읽기 7종. 읽기 실패는 E 로 표기해 "0 인지 못 읽은 건지" 구분
- REQ 폴링은 10ms 유지, 스냅샷만 1초 주기(MC 개별읽기 16회라 주기 단축 금지)
계측 결과 (상세 문서는 로컬 전용 — docs/ 는 .gitignore 추적 제외):
docs/분석/2026/08/26/Page5_Page6_REQ_미발행_PLC문의_260826.md
- page5->6 진입 시 PC 출력이 가접/본접 비트 단위로 완전 동일한데 PLC 반응만 다름
가접 21/22: 2.39s / 2.41s 후 REQ:1 -> page6 진행
본접 23 : 76.6s 동안 REQ:0 / PAGE:5 / AUTO:1 무변화 -> 이동 스텝 미진입
- PC_WELD_COMPLETE 는 전환 조건이 아님이 증명됨(전 구간 0 인데 가접은 정상 진행)
- 에코 워드 0/0 에서도 REQ 발행됨 -> "PC 에코 == PLC 워드" 조건 아님 (260820 문항 c 종결)
- REQ 가 페이지 워드보다 약 200ms 먼저 올라옴(성공 케이스 포함) -> PLC 에 순서 교정 요청
PLC 제어팀 전달 완료, 회신 대기 중.
배경: 2026-08-12 현장 로그에 PLC_AUTO_REQ / PLC_MANUAL_REQ 를 직접 찍는 흔적이 없어,
PLC 가 REQ 를 준 것인지 PC 가 자체 버튼으로 움직인 것인지 사후 판별이 불가능했다.
기존 rising edge 분기는 ON 전이만 찍으므로 OFF 전이·상시 ON 여부도 알 수 없다.
추가:
- CheckPLCCommand 진입부에 M70501(AUTO_STATUS) / M70502(AUTO_REQ) / M70503(MANUAL_REQ)
의 ON/OFF 양방향 전이 로그. ChangeChecker 키를 ON/OFF 2개로 분리해 잡는다.
"AUTO/MANUAL 동시 ON -> return" 가드보다 앞에 두어 동시 ON 구간도 남긴다.
- EVENT_AUTO_RUN_START_REQUEST / STOP_REQUEST 발행 지점에 발행 사실 로그 2줄.
변화가 없으면 한 줄도 남지 않으므로 100ms 주기여도 로그 폭주는 없다.
원복: "[진단계측 2026-08-13]" region 통째로 삭제 + rising edge 분기의 Log.W 2줄 삭제.
PLC 측 회신(REQ 선행 문제 확인요청 3문항)으로 판정이 끝나면 제거할 것.
레이저 발진기 교체(임시 Core/Ring 2대 -> 본 레이저 Max MFMC-2000/2000M 1대)에
따른 IO 재정의. 현장 적용 후 정상 동작 확인.
- ePrismaticDIAddress / ePrismaticDOAddress 를 본 레이저 38핀 커넥터 매뉴얼 기준으로
재정의. 상태 신호 8개 -> 4개. 도면(엑셀) 라벨 오기도 함께 정정
(Laser_FIRE -> Laser_MAIN_PWR_STATE)
- PAIX_PTOP / SeqAutoRunPTOP 의 중복 enum 정의 제거.
WeldingCommon 의 PAIX_PrismaticScanner 를 IO 채널 번호의 단일 소스로 통일
- 발진 게이트를 Core/Ring_Control 2발 -> Laser_REMOTE 1발로 변경
(ExecuteWelding ON/OFF, 정지 시 해제)
- DO 8 충돌 제거: Auto 시작 시 PCLBADReadyStatus(=8) write 삭제.
본 레이저 배선에서 DO 8 = Laser_AC_KEY 라 그대로 두면 Auto 시작이
레이저 AC KEY 릴레이를 켠다. LBAD 는 미등록 디바이스라 무의미
- GetLaserReady() 를 Laser_READY 단독 판정으로 변경
- 가이드빔 DO 를 EX_Red_Control -> Laser_GUIDE_BEAM_CONTROL 로 전환
- IO Board 에 설정 화면(UCIOInterfaceView) 연결
- IsLaserReady 표시를 DO Laser_REMOTE 되읽기로 확정 (260826 협의, 현장 미검증)
원복: 각 파일의 "260824 이전 원본" region 을 살리고 아래 블록을 제거하면 된다.
bit15(M70515) 팝업은 상승엣지 1회라 닫으면 값이 사라져, 현장에서 작업자가
레시피/페이지를 잊는 문제가 있었다. 팝업과 같은 기준·같은 워드를 화면 상단
전폭 띠로 ON 구간 내내 표시한다(Collapsed 시 높이 0이라 평소 화면 영향 없음).
공용(WeldingCommon)은 Status만 읽고 PTOP을 참조하지 않는다 —
값을 넣지 않는 타 설비는 분기문 없이 자동 미표시.
PLC는 PC 에코 워드가 0이면 레이저 출사 신호를 내지 않는다(2026-08-20 PLC측 확정).
bit15 가접 운전은 페이지마다 정지하므로 OnSeqActionStop의 무조건 0 초기화가
페이지마다 0/0 창을 열었고, PC는 다음 PAGE_CHANGE_REQ를 받아야만 재에코한다.
0 초기화는 SeqStatusMonitor가 Auto OFF 시에만 담당하도록 일원화.
- 260813: ResyncRecipePage 노드 추가. ResumeMode·시뮬·PLC 워드 무효 시
재동기를 생략하고 CheckPageNo 의 REQ 대기로 넘긴다.
재동기 상한 10초(RESYNC_TIMEOUT_SEC) 초과 시 수렴 미완으로 포기.
- 260818: CheckPageNoComp 를 outer while 로 감싸 Page 수렴 후 PLC 의
Recipe/Page 를 다시 읽어 PC 확정값과 대조. 어긋나면 Recipe 부터
재확정 후 Page 재수렴.
260812 15:17:29 로그 대응 — Page 수렴 중 PLC 가 Page 를 6→2 로 바꾸며
Recipe 도 함께 바꿨을 때 PC 가 옛 Recipe(22)를 에코한 채 남아
PLC_WELD_TRIGGER_REQ 가 오지 않고 타임아웃만 반복되던 문제.
원복: 각 region 통째로 삭제 (260818 은 outer while 제거 후 들여쓰기 복원).
AutoZip 으로 만든 zip 만으로는 빌드가 되지 않았다. 별도 PC(C:\Test)에서 풀어
Debug|x64 로 돌리면 37개 중 16개가 실패했다.
원인은 -xr! 이 재귀 매칭이라는 점이다. -xr!External / -xr!packages 가 루트뿐 아니라
하위 아무 depth 의 같은 이름 폴더까지 전부 걸러냈다. 화이트리스트에 .dll 이 없던 것도
겹쳐, HintPath 가 프로젝트 상대경로로 가리키는 DLL 6개가 통째로 빠졌다.
AuroraACS\External\ACS.SPiiPlusNET.dll (AuroraACS.csproj:39)
AuroraLaser\External\AuroraModbus.csharp.dll
AuroraDeviceCommon\Packages\NModbus.3.0.80\...\NModbus.dll (AuroraDeviceCommon.csproj:55)
AuroraDeviceCommon\Packages\NModbus.Serial.3.0.80\...\NModbus.Serial.dll
AuroraHeightSensor\Packages\MEDAQLib\MEDAQLib.dll (AuroraHeightSensor.csproj:124)
AuroraHeightSensor\Packages\MEDAQLib\MEDAQLib.NET.dll
AuroraDeviceCommon 이 NModbus 를 못 찾아 실패하면 _out\x64-Debug\AuroraDeviceCommon.dll
이 안 생기고, 이후 13개 프로젝트가 CS0006 으로 연쇄 실패했다. XAML MC3074 3건
(EnumToStringConverter·MainPage·UCWorkPos)도 같은 원인이다.
수정
- -xr!External / -xr!packages 삭제. -x!External -x!External\* -x!packages -x!packages\*
로 대체해 루트만 제외한다.
- 화이트리스트에 -ir!*.dll 추가. obj·bin·_out* 이 이미 제외돼 있고 루트 두 폴더도
빠지므로 실제로 늘어나는 건 위 6개뿐이다.
- 완료 메시지에 받는 쪽 준비물을 출력한다 - zip + 루트 External\ + 루트 packages\.
검증: 재압축 후 별도 폴더에 풀고 루트 External·packages 만 복사해 Debug|x64 빌드 성공.
인코딩은 CP949 를 유지했다. UTF-8 로 저장하면 콘솔 한글이 전부 깨진다(실측).
저장소를 통째로 전달하려면 21.6GB(.git 8.2 / Doc 5.1 / _out 1.2 / packages 1.1 …)를
옮겨야 했다. 실제로 필요한 것은 Visual Studio에서 다시 빌드할 수 있는 소스뿐이고,
그 집합은 2,025개 / 20.2MB → 압축 후 5.8MB 다.
압축 암호는 ub8877 이다. AutoZip.bat 상단 PW 변수에 정의돼 있고 7za 의 -p 로 넘어간다.
zip 기본 암호화(ZipCrypto)를 쓴다 — AES-256 은 구버전 알집에서 열리지 않는 사례가 있어
호환을 택했다. 바꾸려면 압축 명령에 -mem=AES256 만 붙이면 된다.
암호가 걸린 사내 전달용 아카이브이며 자격증명이 아니다.
동작
- 배치파일 위치(%~dp0)를 기준으로만 동작한다. 절대경로 없음.
- 파일 목록을 박아두지 않고 확장자 화이트리스트로 거른다. .cs/.xaml 을 추가해도
이 배치파일은 고칠 필요가 없다.
- 포함: .sln .csproj .cs .xaml .resx .config .settings .manifest .snk
+ 빌드 리소스 이미지(.png .ico .jpg .bmp .gif .cur .ttf)
csproj 에 <Resource Include="Resources\*.png" /> 가 있어 이미지를 빼면 빌드가 깨진다.
- 제외: obj bin .git .vs packages _out* External Doc docs _dummyImages
_workspace .claude .serena __pycache__ 및 이전 *.zip
- 결과물은 루트에 ILSOS_All_src_YYYYMMDD_HHmmss.zip 으로 떨어지고,
다음 실행 때 압축 대상에서 제외된다(.gitignore 에도 등록).
tools/7za.exe (7-Zip 18.05 x64, 단독 실행본)를 동봉했다. Windows 기본 tar/Compress-Archive
는 암호 zip 을 만들지 못하고 이 PC에 7-Zip 이 설치돼 있지 않아 설치 없이 돌아가게 했다.
7-Zip 은 LGPL 이라 재배포 가능하다.
인코딩은 CP949 로 저장했다. UTF-8 + chcp 65001 조합은 cmd 가 배치 실행 도중 코드페이지를
바꿀 때 파일 읽기 위치가 어긋나 이후 줄이 통째로 오파싱된다(실행 실패 확인).
검증: zip 생성/암호(무암호 테스트 실패·정상 암호 통과)/포함(.cs 1365 .xaml 289 .resx 59
.csproj 45)/제외 전 항목 0건/재실행 시 이전 zip 미포함/cmd 한글 출력 정상.
한계 — External·packages 를 제외하므로 받는 쪽에서 참조 DLL 과 NuGet 패키지는 따로 확보해야 한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
docs·CLAUDE.md·README.md·rules.md·.claude·.ubisam_agent 를 추적에서 해제.
로컬 전용 문서와 에이전트 설정이 저장소에 올라와 있어 정리한다.
파일은 디스크에 그대로 유지되며 .gitignore 로 재추적을 막는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
OnSeqActionStop()에서 PC_RECIPE_NO/PC_PAGE_NO를 0으로 초기화한다. ResumeMode 여부와 무관하게 지운다 - 재기동 시 CheckRecipeNoComp -> CheckPageNoComp가 PLC 워드를 다시 읽어 재에코하므로 핸드셰이크는 성립.
- 260805/260806 주석 원문과 if(!ResumeMode) 로그 블록은 그대로 보존
- SeqStatusMonitor의 Auto OFF 초기화와 중복이며, 거기 있던 M70515 보존 예외는 이번 코드가 무시 -> bit15 Resume은 보존값 상실
- 빌드/런타임 미검증. 문제 시 260811 region 삭제로 원복
작업일지: docs/작업일지/2026_08_11.md
CheckPageNoComp 에코 수렴 루프에서 PC_PAGE_NO 를 쓴 직후 되읽어 비교하면
PLC 데이터 업데이트 주기가 반영되기 전 값을 읽어 수렴 판정이 흔들릴 수 있다.
WriteWord 이후 되읽기 전에 200ms 대기를 넣는다.
대상: SeqAutoRunPTOP.cs CheckPageNoComp() "4. 되읽어 수렴 확인" 직전
PLCController.DoActivate() 가 PLC 연결을 열기 전에 _monitorPlcInterfaceMap 을
기동해, 연결 확립 전 LiveStatusUpdate() 가 돌면서
ALARM_DEVICE_PLC_DISCONNECT(210002) 오알람이 매 기동마다 발생했다.
원인
- Livetimer 가 초기화되지 않아 DateTime.MinValue 상태 → (Now - MinValue) 가
항상 10000ms 를 초과해 워치독이 오판. 임계값 조정으로는 해결 불가.
- MicroTimer 첫 콜백이 주기(100ms) 뒤가 아니라 Start() 직후(약 1ms)라
경합이 아니라 100% 재현되는 결정적 버그.
실측 (2026-08-10 16:12:25.904)
Livetimer=0001-01-01, elapsed=63921975145904ms,
isLive=False, IsActivated=False, IsConnected=False
조치
- _monitorPlcInterfaceMap.Start() 를 base.DoActivate() 성공 이후로 이동
- Livetimer = DateTime.Now 로 기준시각 확보 후 타이머 기동
- 두 조치는 각각 단독으로는 무효. 반드시 함께 적용해야 한다.
- 수정 전/후를 #region 2개(검색: 260810 기동 오알람)로 기록해 원복 가능
검증: 2026-08-10 현장 재기동 확인 — 기동 시 210002 미발생
미해결(별건): Livetimer 이중 용도, ReadBit .err 무시, ClearAlarm 부재,
SeqAlarmMonitor 의 무지연 루프 및 Laser/Chiller 즉시 알람
상세: docs/분석_PLC210002_기동오알람_260810.md
작업일지: docs/작업일지/2026_08_10.md
레시피 티칭 화면 Scout 출사 시 SaveTag를 normal_{recipeId}_{pageNo}로 주입해 1_HHmmss_normal_23_5.PNG 형태로 저장. 공통 시퀀스 SeqScoutNormal은 무수정(기존 SaveTag 확장점 사용). 페이지 번호는 1-base로 AutoRun의 auto_{recipe}_{page}_pre/post와 숫자 정합. 원복 마커: #region 260807. 현장 검증 완료.
PLC가 PC 에코 넘버(PC_PAGE_NO/PC_RECIPE_NO) 일치를 상시 확인하는 것으로 확정(260806)됨에 따라, PC 책임을 검증에서 '정확히 읽고 → 내부 상태 갱신 → 에코'로 전환.
- CheckRecipeNoComp/CheckPageNoComp를 수렴 루프로 재작성 (에코 후 되읽어 일치 확인, 어긋나면 재읽기, 맞는 즉시 다음 노드로)
- 에코 없이 return 하던 경로 제거 (RecipeNo=0/미등록 → 에코 안 하고 재시도)
- 범위 밖 PageNo: 3초 무한대기 → 200ms 재읽기, 에코 안 함
- Page 3회 수집(600ms)·Recipe 800ms 재폴링 제거 → 정상 흐름 지연 0
- while 탈출 후 context.Stopped 가드 추가
- ReadOutWord(eWordOutput) 헬퍼 추가 (ReadOutBit 패턴 준용)
- 시뮬레이션 가드: IsSimul이면 수렴 생략 (PLC 워드가 항상 0이라 못 빠져나감)
구버전은 #region 260806 으로 전량 주석 보존 — 원복 시 블록 교체.
분석: docs/분석/2026/08/06/
기동 중 RecipeFieldScan 싱글톤이 비어 있는 상태에서 SaveAndLoadFieldScanFromLasaDb
가 Save 를 Load 보다 먼저 수행해(MainPage.cs:539 -> :540) 대상 FieldHelper.json 이
"[]" 2바이트로 파괴됐다. 현장 3건 확인 — RMS(07-29), U_Frame _pre welding(08-03),
Bottom_Frame_Welding(08-03). 3건 모두 Aurora 초기화 직후 4~19초, 사용자 입력이
불가능한 구간이며 형제 TeachingEditor.json 은 옛 mtime 을 유지했다.
RecipeFieldScan
- SaveFieldHelper 진입부: 완주한 로드의 결과가 아닌 빈 상태면 저장을 건너뛴다.
Load(:540)는 그대로 돌아 파일의 실제 데이터로 싱글톤을 채운다. 사용자가 페이지를
지워 정당하게 비운 경우는 loadedOnce 로 구분해 통과시킨다.
- LoadFieldHelper: loadedOnce 를 Clear 와 짝지어 리셋하고, 완주해도 결과가 0건이면
로드로 보지 않는다. Clear 이후 예외가 나는 경로에서 플래그만 남아 가드가
무력화되는 것을 막는다.
- 맨 catch 를 LastSaveError 기록으로 교체. throw 하지 않는 이유는 ReloadSetting
경로가 Rx OnNext 안이라(UCScannerObjectTeachingViewModel.cs:55-57) 전파 시
구독이 끊겨 티칭 화면 갱신이 영구 정지하기 때문이다.
RecipeHelper
- SaveRecipe 에 저장 대상과 메모리 신원(Recipe.SelectedRecipeFile) 불일치를
Aurora Logger 로 남기는 관측 코드 추가. 저장은 막지 않는다. 기준을
Dao.SystemRecipe.WorkRecipeFile 로 잡지 않은 것은 그 값이
SystemParameterILSOS.json 에 영속되고 Aurora SystemParameter 와 파일을
공유해 신원으로 쓸 수 없기 때문이다.
교차 오염(내용이 채워진 채 엉뚱한 레시피에 기록되는 현상)은 이 변경으로 막히지
않는다. 관측 로그로 발생 경로를 확정한 뒤 별건으로 조치한다.
검증: LASAGUI/WeldingCommon/ILSOS_PrismaticRD_PTOP 빌드 오류 0,
빌드 산출물 직접 로드한 시뮬레이션 31건 전수 통과.
역할 분리 원칙 확립:
- ubisam-ppt-make: PPTX 렌더링 엔진 (build_deck.py). 레이아웃·디자인 토큰 SSoT.
When to use에 deliverables 위임 케이스 추가 + 역할 경계 명시.
- ubisam-deliverables: 산출물 오케스트레이터. PPTX 직접 생성 금지 명시.
Step C를 "ubisam-ppt-make에 위임" 구조로 재작성.
- 09-pptx-integration.md: 역할 분리 원칙 헤더 추가, build_deck.py 경로·SSoT 명시.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SKILL.md: C항목 2.설계 PPTX를 한 줄 실행 명령으로 교체, 불변규칙에 pptx 재생산 추가
- 06-procedure.md: xlsx 재생산과 동등한 pptx 재생산 절차 섹션 추가
- 09-pptx-integration.md: 자동 재생산(build_02설계_pptx.py)과 수동 절차를 구분 기재
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
[SW Version 시트]
- 점검 내용과 점검 결과 사이에 '요청자', '작업자' 2개 컬럼 삽입
- 표 스타일·상단 요약 병합셀 위치 보정(제목 B1:I2 확장, 라벨/날짜 정렬)
[Gantt 시트 신규]
- 프로젝트 6단계 일정 간트차트(타임라인 2026-05~08 일 단위)
- 월/주/일 3행 헤더를 일 날짜 기반 수식으로 자동 생성
- 막대는 조건부서식으로 시작일~종료일 구간을 상태색 자동 채움
(날짜만 입력/수정하면 막대 자동 갱신, 미정 단계는 공백)
- 단계 반영: 제작 2026-05-01~06-30 진행완료(오창공장 이전 전 완료),
셋업 미정(7/15 이후 오창공장), 양산·CS 미정
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Laser On Display 타이밍을 맞추기 위해 PC_WELD_BUSY bit
기록 위치 변경 (SeqAutoRunPTOP)
- 레시피 Scanner Cam 팝업(WDScannerCamMotion)을 직접 실행
모드(publishMode:false)로 변경하고, 창 표시 시 모니터
타이머/Limit 초기화를 호출해 모션 미동작·좌표 0 고정 해소
- 작업일지 2026-06-26 추가, Laser Interface 문서 갱신
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Use Interlock ON 시 ① 안전구역 게이트(기존) 유지 + ② 레시피별 방향 차단(신규). Recipe 폴더의 Recipe_Laser_Interlock.json(Front/Down 0/1)에 저장하고, 경로는 FieldHelper.json과 동일 소스(DB.Dao.SystemRecipe.WorkRecipeFile) 사용. Auto/Manual 양쪽 적용(Manual은 ①+② 신규), VM 체크박스는 레시피 전환 시 Background 우선순위 재로드로 stale 방지.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>