## 배경 (현장 사고 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 검사까지 함께 살아나므로
별건으로 검토한다.
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>
각도에 따라 발진 위치가 달라져, Front/Down angle 평균을 임계값으로
Front/Down offset을 자동 선택해 적용(자동·수동 발진 공통).
- LaserInterlock: Horizontal/Vertical → Front/Down angle 로 변경
- SystemParameter: CellCenterOffset X/Y → Front/Down offset X/Y (4개)
- LaserAngleOffsetSelector 헬퍼 신규 + 선택값 LOG
- PLC 미연결 시 Front offset fallback
주의: 설정 프로퍼티명 변경으로 기존 저장값 자동 이관 안 됨(재입력 필요)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
현장 PLC 미연결로 임시 주석 처리했던 CheckCondition_Interlock()의
High(중대) 알람 인터락 블록을 원복. 현장 PLC 연결 완료에 따라 정상 동작.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 분석 문서 4종 추가 (docs/분석/2026/06/19):
알람부 종합 / MX Component PLC 연결 / AjinIO.ReadDoBit / 가이드빔 TruPulse(ExtPilotOnOff 미구현)
- AjinIO.ReadDoBit(int): 스텁(return true) 유지 + 구현(ReadDiBit 패턴) 주석 보존
- SeqComponentTeachingRun: 중알람 인터락 임시 주석 (현장 PLC 미연결 우회, 추후 원복)
- 레시피 Guide Beam: DO 17 read/write + IsConnected 가드 주석 (필요시 주석 토글 운용)
- 작업일지 2026-06-19 정리
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>