← 전체 글
히스토리언/약 12분 읽기/ 조회

히스토리언이 Pump Trip을 놓친 이유: Exception과 Periodic 수집의 차이

Exception과 periodic 수집은 서로 다른 사실을 저장한다. Tag별로 어떻게 고르면 300 ms interlock을 잃지 않는지, 그리고 시운전 때 어떻게 증명하는지 정리했다.

히스토리언SCADA트렌드태그시운전

Trend은 평평했다. 그런데 pump는 trip했다.

Startup 6주 뒤, 누군가 하류 upset을 설명하려고 historian을 연다. 토출 압력 trend는 깨끗하고 밋밋한 선이다. 그런데 운전원은 pump가 kick out됐다가 자동으로 재기동했다고 분명히 말한다. 둘 다 맞다. Pump는 약 400 ms 동안 trip했고, run-feedback tag는 5초 periodic sample에 걸려 있었다. Bit가 low였던 그 창 동안 historian은 아예 쳐다보지 않았다.

히스토리언은 "공장"을 저장하지 않는다. 설정한 방식으로 들어온 sample만 저장하고, 그 수집 방식이 나중에 무엇을 증명할 수 있는지를 조용히 결정한다. 같은 PLC에 물린 두 시스템도 하나는 고정 clock으로 poll하고 다른 하나는 change마다 저장하면 history가 어긋난다. 어느 쪽도 틀린 게 아니다. 서로 다른 질문에 답할 뿐이다.

그러니 모든 tag에 하나의 수집 template을 적용하지 말자. Tag별로 고르되, tag 개수가 아니라 나중에 그 tag로 무엇을 확인하려는지를 기준으로 고른다.

Periodic은 자기가 눈이 먼다는 걸 숨기지 않는다

Periodic sampling은 무슨 일이 있든 1초, 10초, 60초처럼 고정 간격으로 값을 저장한다. 장점은 tag끼리 timestamp가 맞아 떨어져서 표 report와 상호 비교가 쉽다는 것이다. 단점은 sample 사이에 완전히 눈이 먼다는 것이고, 그 사실을 숨기지 않는다. 300 ms interlock, 압력 spike, limit switch bounce는 tick 사이에 들어가면 그대로 사라진다.

간격보다 느리게 움직이는 값에 쓴다. Tank level, 실내 온도, 냉각수 header 압력, 고정 주기 평균이 report에 정말로 필요한 값. Jacket 온도라면 나는 기꺼이 30초 periodic에 둔다. 하지만 safety interlock bit는 절대 여기 두지 않는다. 그 bit의 존재 이유가 바로 잠깐 바뀌는 그 순간이기 때문이다.

반대 함정도 있다. 거의 안 움직이는 값에 빠른 periodic을 거는 것. 한 shift 내내 42.0 m³/h에 앉아 있는 flow는 1초 archive가 필요 없다. "아직 42"를 시간당 3천 번 저장하려고 storage와 PLC/OPC poll 부하를 쓰는 셈이다.

Exception은 의미를 저장한다, deadband를 정직하게 잡는다면

Exception 수집은 source가 충분히 움직였을 때만 새 값을 저장한다. Discrete는 "충분히"가 상태 전이 자체다. Analog는 deadband인데, 여기서 사람들이 부주의해진다.

Deadband는 absolute(0.5 barg)일 수도, span 대비 %일 수도 있다. OPC UA는 이걸 spec에 못 박아 뒀다. DataChangeFilter(Part 4)가 DeadbandType으로 None, Absolute, Percent를 나르고, Percent는 node의 EURange(Part 8)에 대한 백분율이다. 즉 0~10 bar transmitter에 1% percent-deadband를 걸면 0.1 bar 미만 변화를 억제한다. 이 숫자는 tidy해 보이는 반올림 값이 아니라 sensor에서 뽑아야 한다. Transmitter가 ±0.25% of span이면, 그보다 좁은 deadband는 계측 noise를 저장하는 것이고, 그보다 10배 넓은 deadband는 disk를 아끼려고 실제 공정 변화를 버리는 것이다.

사람들이 자주 헷갈리는 구분 하나. 많은 플랫폼에서 exception과 compression은 별개의 두 단계이고, 한쪽만 설정하면 안전하다는 착각을 준다. OSIsoft/AVEVA PI가 가장 분명한 예다. Interface가 exception test(ExcDev/ExcMax/ExcMin)로 무엇을 interface 밖으로 내보낼지 정하고, archive가 다시 compression(CompDev/CompMax/CompMin, swinging-door 알고리즘)으로 실제로 무엇을 저장할지 정한다. 하류 compression이 변화를 버리면 촘촘한 exception deadband는 아무 소용이 없다. 둘 다 확인하지 않으면 한쪽만 튜닝해 놓고 historian이 고장 났다고 우기게 된다.

Exception이 값을 하는 곳. Motor run/stop feedback, valve open/closed, permissive와 interlock, operator setpoint와 mode change, 매 increment와 rollover가 순서대로 남아야 하는 counter. 약점은 강점의 거울상이다. 저장량을 아끼려고 잡은 deadband가 품질 조사에서 원인이 되고, 진짜로 noise가 많은 tag는 전부 sensor hash인 "변화" 수천 건으로 archive를 채운다.

방식은 tag가 증명해야 할 것에 맞춘다

Tag 개수가 아니라 tag 의도에서 시작한다.

Tag 종류권장 방식현장 메모
느린 analog process valuePeriodic, 또는 sensor 기준 deadband의 exceptionRamp와 운전 한계가 trend에 보이는지 확인
짧은 spike가 있는 빠른 analog빠른 periodic + min/max, 또는 tight threshold exception시운전 중 알려진 disturbance를 trend로 확인
Motor run feedbackChange 기반 exceptionStart와 stop 전이를 모두 저장
Alarm active stateAlarm journal과 별도로 change 기반 exceptionHistorian timing과 alarm record가 일치해야 함
Operator setpointChange 기반 exception, 가능하면 user/audit 정보 포함작지만 유효한 setpoint 변경을 compression으로 없애지 않음
Production counterChange 기반, 또는 rollover 처리를 명시한 periodicReset, rollover, manual correction 동작 기록
Quality/comms statusChange 기반 + periodic heartbeat오래 평평한 "Good"이 죽은 collector를 숨기면 안 됨

Heartbeat 행은 보기보다 중요하다. Communication-status tag를 change에만 저장하면, collector가 조용히 죽어도 "Good"이 영원히 평평하게 남는다. 변화가 없는 것과 정상인 것이 똑같아 보인다. 그 tag 하나에 건 periodic heartbeat가 "02:14에 데이터를 잃었다"와 "언제 잃었는지 모른다"의 차이를 만든다.

짧은 event는 첫 장애 회의 전에 증명한다

Historian이 모두가 다투는 그 event를 놓쳤다는 걸 downtime 회의에서 알게 되지 말자. 아직 공장이 손안에 있을 때 5분짜리 시운전 test를 만든다.

Discrete tag: 알고 있는 on-off-on sequence를 실제 driver 경로로 force하고, 신경 쓰는 최소 시간에 가까운 pulse를 하나 넣는다. Interlock이 250 ms 동안 켜질 수 있으면 250 ms를 test한다. 그리고 historian이 각 전이를 순서대로 저장했는지, timestamp가 PLC diagnostic이나 alarm journal과 맞는지 확인한다.

Analog tag: 정상 운전 ramp를 만든 뒤 deadband보다 조금 큰 변화 하나와 조금 작은 변화 하나를 주입한다. Trend는 실제 움직임은 보여 주고 noise만 삼켜야 한다.

Import file가 아니라 live collector를 대상으로 한다. CSV import는 archive가 데이터를 담을 수 있다는 것만 증명한다. Scan class, driver queue, store-and-forward 순서에 대해서는 아무것도 증명하지 못하는데, 짧은 event가 사라지는 곳이 바로 거기다.

Scan rate, deadband, compression은 같이 무너진다

이 설정들은 사슬로 엮여 있고, 상류에서 난 실수는 하류에서 복구되지 않는다. Collector가 아예 scan하지 않은 event는 촘촘한 deadband로 되살릴 수 없다. Scan rate가 빨라도 compression이 나중에 변화를 버리면 헛일이다. 그래서 tag 하나마다 이 항목들을 한 묶음으로 본다.

  • Source 값의 PLC task period
  • SCADA driver poll rate, 또는 OPC UA subscription publishing/sampling interval
  • Historian exception threshold / deadband
  • 별도 단계라면 compression rule (위 PI 참고)
  • Archive sample의 minimum/maximum interval
  • Bad quality, disconnect, backfill 때의 동작

전형적인 함정. 화면이 500 ms마다 refresh되니 live HMI에서는 tag가 완벽해 보이는데, historian collector는 10초 scan class에 들어가 있다. 운전원은 자기 눈으로 event를 봤다. Historian은 자고 있었다.

Deadband를 크게 잡기 전에 하나만 더

큰 deadband가 매력적인 건 storage는 line item이고 나쁜 history는 아니기 때문이다. 장애, audit, warranty claim이 그것을 line item으로 바꾸기 전까지는. Storage는 싸다. 정작 사람들이 묻는 질문에 답 못 하는 1년치 데이터는 싸지 않다.

중요한 discrete는 sampled trend를 믿지 말고 raw transition을 남긴다. Peak가 의미를 갖는 값은 min/max나 짧은 주기 summary를 같이 둔다. 오래된 고해상도 데이터는 오늘 데이터를 과압축하는 대신 retention tier로 밀어 넣는다. 그리고 sample 수가 많은 tag는 startup 일주일 뒤에 리뷰한다. 범인 대부분은 실제 공정 변화가 아니라 wiring noise, 불안정한 scaling, 펄럭이는 quality flag다.

무엇으로 정하든, 중요한 tag마다 다음 엔지니어에게 한 줄 메모를 남긴다. 수집 방식, scan/subscription interval, deadband와 compression, archive interval, bad-quality 동작, 그리고 짧은 event·ramp·rollover가 실제로 들어왔다는 시운전 근거. Historian 설정은 control system 설계의 일부다. 저장소 부가 작업으로 다루면, 몇 년치 데이터가 있어도 누군가 끝내 묻는 그 한 질문에 답하지 못한다.