10. Alarm 서비스
client.alarm() 으로 접근합니다. 알람 조회 · 집계, 확인, 숨긴 발생 · 서비스 제외를 제공합니다. 모든 메서드는 ApiResult<T> 를 돌려줍니다 — isOk() 가 참이면 getData() 로 값을 얻습니다. 알람 설정(Config) 관리는 client.alarmConfig() 쪽입니다.
9.1 메서드 일람
| 메서드 | 반환 타입 | HTTP | 엔드포인트 |
|---|---|---|---|
get(alarm_seq) | ApiResult<AlarmResponse> | GET | /api/v5/alarm/{alarm_seq} |
list(limit) | ApiResult<List<AlarmResponse>> | GET | /api/v5/alarm?limit=... |
active(site_id, limit) | ApiResult<List<AlarmResponse>> | GET | /api/v5/alarm/active |
search(criteria) | ApiResult<List<AlarmResponse>> | GET | /api/v5/alarm/search |
readOne(alarm_seq, read_user_id) | ApiResult<Boolean> | PUT | /api/v5/alarm/{alarm_seq}/read |
batchRead(alarm_seqs, read_user_id) | ApiResult<AlarmBatchReadResponse> | POST | /api/v5/alarm/batch/read |
readAll(user_id) | ApiResult<Boolean> | POST | /api/v5/alarm/read/all |
deliveries(alarm_seq) | ApiResult<List<AlarmDeliveryResponse>> | GET | /api/v5/alarm/{alarm_seq}/deliveries |
suppressed(kind, asset_id, design_reason, ref_id, active, limit) | ApiResult<List<AlarmSuppressedResponse>> | GET | /api/v5/alarm/suppressed |
outOfService(active) | ApiResult<List<AlarmOutOfServiceResponse>> | GET | /api/v5/alarm/out-of-service |
takeOutOfService(request) | ApiResult<AlarmOutOfServiceResponse> | POST | /api/v5/alarm/out-of-service |
returnToService(out_of_service_id, force, note) | ApiResult<AlarmReturnToServiceResponse> | POST | /api/v5/alarm/out-of-service/{out_of_service_id}/return |
readOne · batchRead · readAll 은 토큰이면 부를 수 있습니다. V5 토큰은 ADMIN · API 역할로만 발급되므로 콘솔의 «모두 확인은 ADMIN» 구분이 V5 에는 따로 없습니다.
limit ≤ 1000입니다.
경로의 read 는 이름만 남은 것입니다. 서버는 알람 하나에 확인 하나를 기록합니다 — 확인.
9.2 AlarmResponse DTO
알람 본체 + 위치(tag/opc/site) JOIN 결과를 함께 포함합니다.
알람 본체 필드
| 필드 | 타입 | 설명 |
|---|---|---|
alarm_seq | long | 알람 시퀀스 (PK) |
alarm_config_id | String | 알람 설정 ID |
priority | String | 우선순위 (INFO, WARN, ERROR) |
description | String | 알람 메시지 |
is_on | Boolean | 현재 활성 여부 |
acknowledged | Boolean | 확인됐는지 |
acknowledged_by | String | 확인자 — 로그인 아이디 또는 직원 ID |
acknowledged_by_type | String | 확인자 종류 (USER, EMPLOYEE) |
acknowledged_at | Long | 확인 시각 (밀리초) |
on_timestamp | long | 발생 시각 (밀리초) |
off_timestamp | Long | 해제 시각 (null = 미해제) |
on_duration | long | 지속 시간 (밀리초) |
off_reason | String | 해제 사유 — 알람 해제 사유 |
band | String | 울린 밴드 |
숨겨진 발생은 이 행에 없습니다. suppressed() 로 읽습니다.
위치 JOIN 필드 (list 응답에 포함)
| 필드 | 설명 |
|---|---|
tag_id, tag_name, tag_description | 태그 정보 |
opc_id, opc_name | OPC 정보 |
site_id, site_name | 사이트 정보 |
tag_location | 자산 경로 문자열 (SITE > AREA > LINE > EQUIPMENT) |
9.3 알람 우선순위
| 코드 | 화면 말 |
|---|---|
INFO | 정보 |
WARN | 경고 |
ERROR | 심각 |
9.4 사용 예시
최근 알람 목록
import java.util.List;
import plantpulse.api.v5.dto.response.AlarmResponse;
import plantpulse.api.v5.result.ApiResult;
ApiResult<List<AlarmResponse>> result = client.alarm().list(50);
if (result.isOk()) {
for (AlarmResponse a : result.getData()) {
System.out.printf("[%s] %s - %s (%s)%n",
a.getPriority(),
a.getSite_name(),
a.getDescription(),
a.getTag_location());
}
}
활성 알람
List<AlarmResponse> active = client.alarm().active("SITE_000001", 500).getData();
System.out.println("현재 활성 알람: " + active.size() + "건");
미확인 활성 알람
long unacked = client.alarm().active("SITE_000001", 500).getData().stream()
.filter(a -> !Boolean.TRUE.equals(a.getAcknowledged()))
.count();
알람 확인
확인자는 토큰의 사용자입니다. read_user_id 는 null 로 둡니다 — 토큰 사용자와 다른 이름을 넣으면 HTTP 422 입니다. 누군가 먼저 확인했으면 HTTP 409 alarm.already_acknowledged 이고 처음 기록이 유지됩니다.
ApiResult<Boolean> r = client.alarm().readOne(12345L, null);
현장 앱처럼 직원 이름으로 확인할 때는 요청 머리글 X-PP-Performed-By 에 직원을 싣습니다. 그러면 acknowledged_by_type 이 EMPLOYEE 로 남습니다.
누구에게 보냈나
읽음 표시가 없는 발송 기록입니다 — recipient_type · recipient_id · recipient_name · channel(CONSOLE, EMAIL, SMS, APP) · sent_at.
client.alarm().deliveries(12345L).getData().forEach(d ->
System.out.println(d.getRecipient_name() + " / " + d.getChannel()));
숨겨진 발생
잠시 숨김 · 설계 억제 · 서비스 제외로 숨겨진 발생입니다. 필터는 모두 null 을 쓸 수 있습니다.
| 인자 | 값 |
|---|---|
kind | SHELVED, SUPPRESSED_BY_DESIGN, OUT_OF_SERVICE |
design_reason | MAINTENANCE, REPAIR (SUPPRESSED_BY_DESIGN 일 때) |
ref_id | 원인 ID — ALARM_SHELVE_…, 달력 ID, 정비 오더 ID, ALARM_OUT_OF_SERVICE_… |
active | true = 지금 켜진 것 |
limit | 1~1000 (기본 200) |
var hidden = client.alarm().suppressed("SUPPRESSED_BY_DESIGN", "ASSET_ID", "REPAIR", null, true, 100);
서비스 제외와 복귀
쓰기는 ADMIN 토큰만 할 수 있습니다. 자동 복귀는 없습니다. 복귀 점검이 거절되면 HTTP 422 이고 서비스 제외가 유지됩니다.
| 거절 | HTTP | 코드 |
|---|---|---|
| 이미 서비스 제외 중 | 409 | alarm.oos.already |
| 이유 값 · 메모 · 예정 복귀가 틀림 | 422 | alarm.oos.reason_invalid · memo_required · window_invalid |
| 복귀 점검 실패 | 422 | alarm.oos.return_not_normal · return_no_value |
| 그래도 복귀인데 사유 없음 | 422 | alarm.oos.note_required |
| 이미 복귀함 | 409 | alarm.oos.already_returned |
force 를 true 로 하고 note 를 주면 점검을 넘겨 복귀합니다(return_check = FORCED). 이유는 SENSOR_REMOVED, EQUIPMENT_REMOVED, CALIBRATION, MODIFICATION, OTHER 입니다. OTHER 와 안전·환경 알람은 메모가 필수입니다.
var r = client.alarm().returnToService("ALARM_OUT_OF_SERVICE_000001", false, null);
알람 설정 ID
새 알람 설정 ID 는 서버가 발급합니다(ALARM_CONFIG_ + 6자리). GET /api/v5/alarm/config/new-id 로 받아 쓰며, 직접 지은 ID 로 만들면 HTTP 422 alarm.invalid.alarm_config_id 입니다. 밴드 알람은 API 로 만들지 않습니다 — 태그의 알람 설정(patchAlarm)이 만들고, POST /alarm/config 로 밴드를 만들려 하면 HTTP 409 alarm.band.edit_on_tag 입니다.
태그의 밴드 설정은 ID 를 지어내지 말고 GET /api/v5/alarm/config/list/by-tag?tag_id=… 에서 alarm_config_priority 가 BAND 인 것을 찾습니다. 변경 이력(/alarm/config/{alarm_config_id}/revisions)의 alarm_config_id 는 밴드 설정이 아직 없는 태그의 행에서 null 일 수 있습니다.
알람 시스템 성능
SDK 메서드는 없습니다. V5 로 직접 읽습니다 — GET /api/v5/alarm/performance?scope_type=SITE&scope_id=…&days=7. 지표는 알람 성능을 보세요.