
SOFTMOA TECHNOLOGY
설비 비가동 시간 집계 시스템 구축 방법
소프트모아가 정리한 기술 기록입니다.
Contents
설비가 멈춘 시간을 작업자 메모와 센서 기록에서 각각 더하면 같은 정지가 두 번 집계될 수 있습니다. 비가동 시간 집계 시스템은 기록 원본을 보존하되, 설비별로 겹친 구간을 합친 시간을 보고서에 사용하도록 설계해야 합니다. 아래는 실제 고객 사례가 아닌 구축 예시이며, 소프트모아에 적용 범위를 상담할 때 정할 기준을 다룹니다.
정지 버튼에서 교대 보고서까지
작업자는 태블릿에서 설비 M-01을 선택하고 ‘정지 시작’을 누릅니다. 화면에는 서버가 기록한 시작 시각과 기록 번호가 나타납니다. 사유는 고장, 자재 대기, 품종 교체, 미분류 중 선택하고 설명을 덧붙입니다. 이는 예시 분류이지 모든 공장에 적용할 표준은 아닙니다. 센서가 보내는 가동 신호의 부재도 곧바로 고장으로 확정하지 않고, 통신 끊김인지 생산 중단인지 확인할 후보로 둡니다.
작업 재개 때 ‘정지 종료’를 누르면 종료 시각이 채워집니다. 반장은 센서 구간과 수기 구간을 나란히 보고 사유와 시간을 확인합니다. 관리자는 설비·교대·기간을 선택해 합산 시간, 미종료 건수, 미분류 건수를 조회합니다. 정지 구간의 입력, 사유 확인, 보고서 확정을 각각 다른 처리로 남겨야 나중에 무엇이 수정됐는지 찾을 수 있습니다.
- 작업자는 담당 설비의 정지 등록과 종료 요청을 하고, 확정 보고서를 직접 수정하지 않습니다.
- 반장은 시간·사유를 확인하며, 수정 시 변경 전 값과 수정 이유를 남깁니다.
- 관리자는 교대 보고서를 확정합니다. 확정 뒤 정정은 새 버전으로 남기고 이전 보고서도 보존합니다.
4건의 기록이 55분이 아니라 45분인 이유
한 설비의 조회 범위를 09:00 이상 10:00 미만으로 잡겠습니다. 원본은 09:10~09:40, 09:20~09:25, 09:35~09:50, 09:55부터 아직 종료되지 않은 기록 4건입니다. 미종료 건은 조회 끝인 10:00까지만 임시 계산합니다. 기록별 30·5·15·5분을 더하면 55분이지만, 겹친 시간을 한 번만 세면 09:10~09:50의 40분과 09:55~10:00의 5분, 합계 45분입니다.
다음 SQL은 메모리 SQLite에서 실행한 예시입니다. s와 e는 09:00을 0으로 삼은 정수 분이며, NULL 종료값을 60으로 대체하는 규칙을 이 예시에서 정했습니다. COALESCE는 첫 번째 NULL이 아닌 인수를 반환하고, 인수 2개를 받는 MAX·MIN은 값의 상한·하한을 자르는 데 사용했습니다.[2] 윈도 함수에는 SQLite 3.25.0 이상이 필요합니다.[1]
WITH raw(id, s, e) AS (
VALUES (1,10,40), (2,20,25),
(3,35,50), (4,55,NULL)
), clipped AS (
SELECT id, MAX(s,0) AS s,
MIN(COALESCE(e,60),60) AS e
FROM raw
), valid AS (
SELECT * FROM clipped WHERE e > s
), prior AS (
SELECT *, MAX(e) OVER (
ORDER BY s,e,id
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
) AS prior_end
FROM valid
), tagged AS (
SELECT *, SUM(CASE
WHEN prior_end IS NULL OR s > prior_end
THEN 1 ELSE 0 END
) OVER (ORDER BY s,e,id ROWS UNBOUNDED PRECEDING) AS g
FROM prior
), merged AS (
SELECT MIN(s) AS s, MAX(e) AS e
FROM tagged GROUP BY g
)
SELECT s AS start_min, e AS end_min,
SUM(e-s) OVER () AS total_min
FROM merged ORDER BY s;
출력은 start_min, end_min, total_min 순서로 (10, 50, 45), (55, 60, 45)입니다. 45는 각 구간의 시간이 아니라 합쳐진 전체 시간으로 두 행에 반복됩니다. 날짜를 다루지 않는 작은 예제이므로 운영 저장값은 시간대가 명확한 시각으로 받고 조회 경계를 같은 기준으로 변환해야 합니다.
중첩된 구간에서는 바로 앞 기록의 종료값만 비교하면 부족합니다. 09:35 시작은 바로 앞 09:25 종료와 떨어져 있지만, 그보다 앞선 09:40 종료 구간과 겹칩니다. prior_end는 앞선 모든 행의 종료 최댓값을 구합니다. 이를 위해 MAX 집계에 ‘현재 행을 제외한 이전 행’ 프레임을 명시했습니다.[1] 같은 시각이면 e와 id까지 정렬해 순서를 고정합니다. 설비가 여러 대면 윈도 계산과 그룹 묶기를 설비별로 분리해야 합니다.
숫자를 확정하기 전에 남겨 둘 예외
종료가 없으면 위 조회의 5분은 확정 시간이 아닙니다. 화면에 ‘진행 중 포함’과 조회 기준 시각을 표시하고, 월말 확정 화면에서는 미종료 건을 확인하도록 막는 규칙을 둘 수 있습니다. 시작 시각 누락, 종료가 시작보다 이른 입력은 저장 단계에서 반려합니다. SQL의 e > s 필터는 조회 밖 구간 등을 제외할 뿐, 잘못된 원본을 고치는 검증기가 아닙니다.
전체 비가동 시간은 구간 합집합으로 계산해도 원인별 합계는 별도 결정이 필요합니다. 같은 시간에 고장과 자재 대기가 함께 표시되면 반장이 대표 사유를 고르거나, 구간을 나눠 사유를 확정해야 합니다. 원인별 시간을 무조건 더하면 전체 45분과 다시 달라질 수 있습니다. 휴게·계획 정비를 집계에서 제외할지와 교대 경계도 먼저 정하고 보고서에 기준을 표시합니다.
이 예제는 중복 시간만 확인합니다. 버튼 재전송에 대한 기록 번호 중복 방지, 서버 권한 검사, 센서 시각 오차, 통신 복구 후 지연 도착은 실제 구축에서 따로 시험해야 합니다. 비가동 45분만으로 가동률이나 OEE를 확정하지도 않습니다. 같은 범위의 계획 생산시간과 나머지 지표가 별도로 필요합니다.
SQL 확인 자료: [1] SQLite 윈도 함수 · [2] SQLite COALESCE·MAX·MIN
소프트모아는 해당 시스템을 구축합니다. 문의하기
