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

히스토리언 다운샘플링에서 정작 필요한 trip을 잃지 않으려면

오래된 공정 데이터를 평균 내면 trip이 사라지고 peak가 낮아지고 적산값이 틀어진다. 태그를 분류하고, 종류별 다운샘플 방법을 고르고, 값과 함께 품질을 남기고, purge를 운영에 걸기 전에 시험하는 법.

히스토리언트렌드SCADA프로젝트 노트체크리스트

가동 6주 뒤, 고객이 batch 4471 동안 반응기 압력이 어땠는지 묻는다. 트렌드를 여니 매끈한 선이다 — 간밤에 돈 purge job이 raw 1초 sample을 시간 평균으로 바꿔 버렸고, interlock을 걸었던 90초짜리 dip이 평균 속으로 깔끔하게 사라졌기 때문이다. 숫자는 아직 DB에 있다. 그런데 그 사건은 없다.

보존 기간과 다운샘플링은 대개 프로젝트 후반, 디스크 추정치가 이미 빡빡하고 누군가 돌릴 knob을 찾을 때 정해진다. 그건 어떤 값이 1주·1개월·1년, 그리고 한 번의 감사 주기 뒤에도 어떤 질문에 답할 수 있어야 하는지를 정하기엔 나쁜 시점이다. 저장 설정처럼 보이지만 사실은 엔지니어링 결정이다.

사용자마다 필요한 해상도가 다르므로, 각자가 실제로 던지는 질문에서 출발한다.

사용자자주 묻는 질문필요한 데이터 모양
운전원어제 이상 상황 때 실제로 무엇이 흔들렸나?이벤트 전후의 raw에 가까운 트렌드
공정 엔지니어이번 달에 루프가 계속 헌팅했나?주기성을 볼 수 있는 충분한 해상도
보전 담당자펌프가 몇 번 기동했나?상태 edge 또는 신뢰할 수 있는 counter
에너지 담당자구역별 일 사용량이 얼마인가?유효 구간이 표시된 집계값
품질 담당자이 lot에서 기록된 값이 무엇인가?원본 기록 또는 승인된 재계산 규칙

보존 정책은 태그 종류마다 네 가지를 적게 쓴다. 무엇을 raw로 남기고, 무엇을 줄이고, 무엇을 삭제하고, 그 상세를 잃는 걸 누가 승인했는가. 마지막 칸이 회의에서 당신을 구한다.

보존 규칙을 건드리기 전에 태그를 나눈다

모든 태그에 같은 규칙을 걸면 디스크 예산을 태우거나, 필요했던 데이터를 버리거나 둘 중 하나다. 모터 운전 bit, 중요 반응기 온도, 시험 결과, 화면 전용 진단 flag는 한 달만 지나면 공통점이 없다. 현장에서 버티는 분류는 이렇다.

  • 중요 공정값: 온도, 압력, 유량, 레벨, recipe 실제값, utility 조건.
  • 설비 상태와 알람: 운전 상태, fault 상태, mode, permissive summary, alarm event.
  • Counter와 totalizer: 전력, 물, 압축공기, 생산량, 운전 시간.
  • 대량 진단 태그: 통신 품질, scan time, heartbeat, driver 내부 counter.
  • 시운전 임시 태그: tuning, test, troubleshooting 때문에 만든 태그.

각 그룹의 raw 보존 기간과 장기 보존 기간을 따로 정한다. 내가 보통 정착하는 값: 중요 공정값 raw는 18개월, 이후 1분 집계(또는 검증된 event 기반 기록)로 7년; 설비 상태와 alarm event는 길게 — 싸고, 사고를 재구성할 때 쓰는 게 이것이기 때문이다; 대량 진단은 open된 지원 건이 없으면 30~90일. 시운전 태그는 만드는 날 삭제 날짜를 같이 박는다 — 안 그러면 영원히 살고, TT_TEST_3이 뭐였는지 아무도 기억 못 한다.

다운샘플링은 압축이 아니라 답을 바꾼다

집계 방법을 잘못 고르면 정밀도가 아니라 사건을 잃는다. 방법이 태그의 성격과 맞아야 한다.

방법맞는 용도주의할 점
Average변화가 느린 analog 값짧은 spike와 trip을 숨김
Min/max pairenvelope 확인평균 하나보다 저장량이 늘어남
Last valuestep 형태의 상태값analog 값에는 오해를 만들기 쉬움
Time-weighted average노출 시간, 평균 운전 조건품질과 유효 시간이 정확해야 함
Event count기동, 정지, trip, alarmedge 기준이 명확해야 함
Delta total전력, 물, 유량 적산rollover와 reset 처리가 필요함

이상 분석에서 한 번이라도 열어 볼 analog라면, 구간마다 평균과 함께 min/max를 남긴다. 1시간 평균 하나로는 steam header dip이 사라지지만, min/max는 raw가 지워진 뒤에도 그 excursion을 남긴다. 상태 태그는 그 구간에 ON이었던 비율이 마지막 값보다 낫다 — last value는 펌프가 10:59:59에 돌고 있었다는 것만 말하고 나머지 3599초는 아무것도 말하지 않는다.

히스토리언이 OPC UA Historical Access(Part 11)를 지원한다면 이 이름들은 vendor label이 아니다 — 집계 함수는 OPC UA Part 13에 정의돼 있다: TimeAverage, Minimum, Maximum, Count, Interpolative 등. Bad quality sample이 낀 구간에 TimeAverage를 요청한 client는 깨끗해 보이는 숫자가 아니라 결과와 함께 quality flag를 받게 돼 있다. 그게 바로 다음 이야기다.

품질 없는 보존값은 거짓말을 한다

정상 sample 2개로 만든 10분 평균은, 600개로 만든 것과 똑같이 신뢰할 만해 보인다 — 값과 함께 품질을 남기지 않았다면. 장기 보존 row에는 최소한 이게 있어야 한다.

  • Timestamp와 시간 기준.
  • 값 또는 집계값.
  • 단위.
  • 원본 태그명과 태그명 변경 이력에 대응할 식별자.
  • 품질 또는 유효 시간 비율.
  • 계산 방법.
  • Time zone 또는 UTC 기준.
  • 필요한 경우 source sample count.

나중에 보고서가 문제 됐을 때 드러나는 차이다. 유효율 99.8%로 만든 일일 전력량과 통신 단절 4시간을 그대로 통과해 계산한 값은 같은 숫자가 아니고, 그 둘을 구분하는 건 metadata뿐이다.

법적 기록과 내가-보고-싶은-트렌드는 다른 종류다

어떤 데이터는 엔지니어가 보고 싶어서 남긴다. 어떤 데이터는 고객, 계약, 규정, 내부 품질 시스템이 남기라고 해서 남긴다. 21 CFR Part 11이나 그에 준하는 GxP 체계 아래라면, 두 번째 그룹에는 첫 번째에 없는 규칙 — audit trail, 조용한 수정 금지, 정해진 보존 — 이 붙고, 그 기록을 다운샘플하거나 재계산하는 건 혼자 내릴 결정이 아니다. 기록 종류마다 정한다.

  • 기준 시스템이 히스토리언인지, MES인지, batch system인지, LIMS인지.
  • Raw sample을 반드시 보존해야 하는지.
  • 늦게 들어온 데이터로 마감 구간을 다시 계산할 수 있는지.
  • 누가 수정하거나 삭제할 수 있는지.
  • Backup을 어떻게 복구하고 검증하는지.
  • 시간 변경, daylight-saving time, NTP 장애를 어떻게 처리하는지.

히스토리언이 기준 시스템이 아니라면 트렌드 화면 캡처가 유일한 근거가 되지 않게 해야 한다. 태그를 그 판단을 실제로 소유한 batch·lot·report record와 연결해 둔다.

Purge를 운영에 걸기 전에 실제 태그로 시험한다

Purge나 archive rule은 되돌릴 수 없는 문이다. 운영에서 돌기 전에, 아직 확인할 수 있는 데이터로 증명한다.

  1. 빠른 analog, 느린 analog, 상태 태그, counter, 진단 태그를 하나씩 고른다.
  2. 다운샘플링 전후 기간을 export한다.
  3. peak, minimum, total, 상태 지속 시간, event count를 비교한다.
  4. 트렌드 화면에서 집계 데이터인지 사용자가 알 수 있는지 본다.
  5. 보고서가 raw와 집계값을 label 없이 섞어 쓰지 않는지 확인한다.
  6. Archive 데이터를 test system에 복구해서 같은 query를 돌린다.
  7. Backup 보존 기간이 historian purge 지연 시간보다 긴지 확인한다.

그리고 purge job에는 dry-run 결과를 붙인다 — 태그 수, row 수, 가장 오래된·최신 timestamp, 예상 회수 용량 — row 하나 지우기 전에. 무엇을 지울지 말해 주지 못하는 purge는 무인으로 돌 자격이 없다.

실제로 마주치는 실패들

트렌드는 깨끗한데 trip이 없다. 다운샘플이 평균만 남겼다. 이상 분석에 쓰는 건 min/max나 event marker를 같이 남긴다.

마감된 일일 사용량이 보고 뒤에 바뀐다. 늦게 들어온 데이터나 backfill이 닫힌 기간을 다시 계산했다. 마감 시점과 별도의 정정 절차를 정한다 — backfill이 조용히 과거를 다시 쓰게 두지 마라.

Archive는 있는데 복구가 하루 걸린다. 아무도 복구를 시험하지 않았다. 그게 필요한 감사 때가 아니라 commissioning 때 복구 시간을 잰다.

태그명을 바꾸니 2년 전 보고서가 깨진다. 장기 데이터가 display name에만 묶여 있었다. 안정적인 tag id나 alias history를 남긴다.

보존을 제대로 걸었는데도 디스크가 찬다. Exception deadband가 너무 좁거나, 중복 collector, 또는 calculated tag이 추정보다 많은 row를 만든다. 태그 수가 아니라 row count 기준으로 많이 쓰는 태그를 정렬한다 — 시끄러운 analog 하나가 얌전한 태그 천 개를 이긴다.

이 전부를 가동 한 달 뒤에 다시 본다. 실제 운전은 어떤 태그가 시끄러운지, 어떤 데이터를 정말 자주 꺼내 보는지, 어떤 시운전 태그를 지워도 되는지 처음으로 알려 준다. 가동 전에 쓴 계획은 추측이었고, 둘째 달에 고친 계획이 진짜다.