package com.zy.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.zy.asrs.domain.enums.CrnStatusType; import com.zy.asrs.domain.enums.StationStatusType; import com.zy.asrs.domain.vo.CrnLatestDataVo; import com.zy.asrs.domain.vo.RgvLatestDataVo; import com.zy.asrs.domain.vo.StationLatestDataVo; import com.zy.asrs.entity.BasCrnpErr; import com.zy.asrs.entity.DeviceDataLog; import com.zy.asrs.entity.WrkLastno; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.BasCrnpErrService; import com.zy.asrs.service.DeviceLogReplayNormalizer; import com.zy.asrs.service.WrkLastnoService; import com.zy.asrs.service.WrkMastService; import com.zy.core.enums.CrnModeType; import com.zy.core.enums.DualCrnModeType; import com.zy.core.enums.RgvStatusType; import com.zy.core.enums.SlaveType; import com.zy.core.enums.WrkIoType; import com.zy.core.model.protocol.CrnProtocol; import com.zy.core.model.protocol.DualCrnProtocol; import com.zy.core.model.protocol.RgvProtocol; import com.zy.core.model.protocol.StationProtocol; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Service public class DeviceLogReplayNormalizerImpl implements DeviceLogReplayNormalizer { private static final int MAX_WRK_MAST_CACHE_SIZE = 4096; @Autowired private WrkMastService wrkMastService; @Autowired private WrkLastnoService wrkLastnoService; @Autowired private BasCrnpErrService basCrnpErrService; private final Map wrkMastCache = new ConcurrentHashMap<>(); private final Map wrkLastnoCache = new ConcurrentHashMap<>(); private final Map basCrnpErrCache = new ConcurrentHashMap<>(); @Override public Object normalizeState(DeviceDataLog logItem) { if (logItem == null || logItem.getType() == null || logItem.getWcsData() == null || logItem.getWcsData().isBlank()) { return null; } SlaveType slaveType = SlaveType.findInstance(logItem.getType()); if (slaveType == null) { return null; } if (slaveType == SlaveType.Crn) { return normalizeCrn(logItem); } if (slaveType == SlaveType.DualCrn) { return normalizeDualCrn(logItem); } if (slaveType == SlaveType.Rgv) { return normalizeRgv(logItem); } if (slaveType == SlaveType.Devp) { return normalizeStation(logItem); } return null; } @Override public Map buildFrame(Long timestamp, Long sampleSeq, Map stateByStream) { List stationStates = new ArrayList<>(); List crnStates = new ArrayList<>(); List dualCrnStates = new ArrayList<>(); List rgvStates = new ArrayList<>(); List> abnormalList = new ArrayList<>(); for (Map.Entry entry : stateByStream.entrySet()) { Object state = entry.getValue(); StreamIdentity identity = parseStreamIdentity(entry.getKey()); if (state instanceof StationLatestDataVo) { StationLatestDataVo stationState = (StationLatestDataVo) state; stationStates.add(compactStationState(stationState)); collectStationAbnormal(abnormalList, stationState, identity); continue; } if (state instanceof CrnLatestDataVo) { CrnLatestDataVo crnState = (CrnLatestDataVo) state; if (entry.getKey() != null && entry.getKey().contains("|DualCrn|")) { dualCrnStates.add(compactDualCrnState(crnState)); } else { crnStates.add(compactCrnState(crnState)); } collectCrnAbnormal(abnormalList, crnState); continue; } if (state instanceof RgvLatestDataVo) { RgvLatestDataVo rgvState = (RgvLatestDataVo) state; rgvStates.add(compactRgvState(rgvState)); collectRgvAbnormal(abnormalList, rgvState); } } Map frame = new LinkedHashMap<>(); frame.put("timestamp", timestamp); frame.put("sampleSeq", sampleSeq); frame.put("stationStates", stationStates); frame.put("crnStates", crnStates); frame.put("dualCrnStates", dualCrnStates); frame.put("rgvStates", rgvStates); frame.put("abnormalList", abnormalList); frame.put("summary", buildSummary(stationStates, crnStates, dualCrnStates, rgvStates, abnormalList)); return frame; } @Override public Map buildCompactFrame(Long timestamp, Long sampleSeq, Map stateByStream) { int stationCount = 0; int crnCount = 0; int dualCrnCount = 0; int rgvCount = 0; List> abnormalList = new ArrayList<>(); for (Map.Entry entry : stateByStream.entrySet()) { Object state = entry.getValue(); StreamIdentity identity = parseStreamIdentity(entry.getKey()); if (state instanceof StationLatestDataVo) { stationCount++; collectStationAbnormal(abnormalList, (StationLatestDataVo) state, identity); continue; } if (state instanceof CrnLatestDataVo) { if (entry.getKey() != null && entry.getKey().contains("|DualCrn|")) { dualCrnCount++; } else { crnCount++; } collectCrnAbnormal(abnormalList, (CrnLatestDataVo) state); continue; } if (state instanceof RgvLatestDataVo) { rgvCount++; collectRgvAbnormal(abnormalList, (RgvLatestDataVo) state); } } Map summary = new LinkedHashMap<>(); summary.put("stationCount", stationCount); summary.put("crnCount", crnCount); summary.put("dualCrnCount", dualCrnCount); summary.put("rgvCount", rgvCount); summary.put("abnormalCount", abnormalList.size()); summary.put("errorCount", abnormalList.stream().filter(item -> "ERROR".equals(item.get("level"))).count()); summary.put("blockCount", abnormalList.stream().filter(item -> "BLOCK".equals(item.get("level"))).count()); Map frame = new LinkedHashMap<>(); frame.put("timestamp", timestamp); frame.put("sampleSeq", sampleSeq); frame.put("abnormalList", abnormalList); frame.put("summary", summary); return frame; } private StationLatestDataVo compactStationState(StationLatestDataVo stationState) { StationLatestDataVo compact = new StationLatestDataVo(); compact.setStationId(stationState.getStationId()); compact.setTaskNo(stationState.getTaskNo()); compact.setTargetStaNo(stationState.getTargetStaNo()); compact.setAutoing(stationState.isAutoing()); compact.setLoading(stationState.isLoading()); compact.setInEnable(stationState.isInEnable()); compact.setOutEnable(stationState.isOutEnable()); compact.setEmptyMk(stationState.isEmptyMk()); compact.setFullPlt(stationState.isFullPlt()); compact.setRunBlock(stationState.isRunBlock()); compact.setInBarcodeError(stationState.isInBarcodeError()); compact.setPalletHeight(stationState.getPalletHeight()); compact.setError(stationState.getError()); compact.setBarcode(stationState.getBarcode()); compact.setStationStatus(stationState.getStationStatus()); return compact; } private CrnLatestDataVo compactCrnState(CrnLatestDataVo crnState) { CrnLatestDataVo compact = new CrnLatestDataVo(); compact.setCrnId(crnState.getCrnId()); compact.setCrnNo(crnState.getCrnNo()); compact.setCrnStatusType(crnState.getCrnStatusType()); compact.setBay(crnState.getBay()); compact.setLev(crnState.getLev()); compact.setTaskNo(crnState.getTaskNo()); compact.setWorkNo(crnState.getWorkNo()); compact.setMode(crnState.getMode()); compact.setStatus(crnState.getStatus()); compact.setLoading(crnState.getLoading()); compact.setForkOffset(crnState.getForkOffset()); compact.setLiftPos(crnState.getLiftPos()); compact.setWalkPos(crnState.getWalkPos()); compact.setTaskReceive(crnState.getTaskReceive()); compact.setSourceLocNo(crnState.getSourceLocNo()); compact.setLocNo(crnState.getLocNo()); compact.setDeviceStatus(crnState.getDeviceStatus()); return compact; } private CrnLatestDataVo compactDualCrnState(CrnLatestDataVo crnState) { CrnLatestDataVo compact = new CrnLatestDataVo(); compact.setCrnId(crnState.getCrnId()); compact.setCrnNo(crnState.getCrnNo()); compact.setCrnStatusType(crnState.getCrnStatusType()); compact.setBay(crnState.getBay()); compact.setLev(crnState.getLev()); compact.setTaskNo(crnState.getTaskNo()); compact.setTaskNoTwo(crnState.getTaskNoTwo()); compact.setMode(crnState.getMode()); compact.setStatus(crnState.getStatus()); compact.setStatusTwo(crnState.getStatusTwo()); compact.setLoading(crnState.getLoading()); compact.setLoadingTwo(crnState.getLoadingTwo()); compact.setForkOffset(crnState.getForkOffset()); compact.setForkOffsetTwo(crnState.getForkOffsetTwo()); compact.setLiftPos(crnState.getLiftPos()); compact.setWalkPos(crnState.getWalkPos()); compact.setTaskReceive(crnState.getTaskReceive()); compact.setTaskReceiveTwo(crnState.getTaskReceiveTwo()); compact.setDeviceStatus(crnState.getDeviceStatus()); return compact; } private RgvLatestDataVo compactRgvState(RgvLatestDataVo rgvState) { RgvLatestDataVo compact = new RgvLatestDataVo(); compact.setRgvNo(rgvState.getRgvNo()); compact.setTaskNo(rgvState.getTaskNo()); compact.setTrackSiteNo(rgvState.getTrackSiteNo()); compact.setRgvStatusType(rgvState.getRgvStatusType()); return compact; } private CrnLatestDataVo normalizeCrn(DeviceDataLog logItem) { CrnProtocol protocol = JSON.parseObject(logItem.getWcsData(), CrnProtocol.class); if (protocol == null) { return null; } CrnLatestDataVo vo = new CrnLatestDataVo(); vo.setCrnId(protocol.getCrnNo()); vo.setCrnNo(protocol.getCrnNo()); vo.setOffset(protocol.getBay() == null ? 0D : Double.valueOf(protocol.getBay())); vo.setBay(protocol.getBay()); vo.setLev(protocol.getLevel()); vo.setTaskNo(protocol.getTaskNo()); vo.setWorkNo(protocol.getTaskNo()); vo.setMode(resolveCrnMode(protocol)); vo.setStatus(resolveCrnStatus(protocol)); vo.setLoading(protocol.getLoaded() != null && protocol.getLoaded() == 1 ? "有物" : "无物"); vo.setForkOffset(resolveCrnForkOffset(protocol)); vo.setLiftPos(resolveCrnLiftPos(protocol)); vo.setWalkPos(protocol.getWalkPos() != null && protocol.getWalkPos() == 1 ? "不在定位" : "在定位"); vo.setTaskReceive(protocol.getTaskReceive() == null ? "-" : String.valueOf(protocol.getTaskReceive())); vo.setXspeed(formatDecimal(protocol.getXSpeed())); vo.setYspeed(formatDecimal(protocol.getYSpeed())); vo.setZspeed(formatDecimal(protocol.getZSpeed())); vo.setWeight(protocol.getWeight()); vo.setBarcode(protocol.getBarcode()); vo.setWarnCode(protocol.getAlarm() == null ? "-" : String.valueOf(protocol.getAlarm())); vo.setAlarm(resolveCrnAlarm(protocol.getAlarm())); vo.setLaserValue(protocol.getLaserValue()); vo.setExtend(protocol.getExtend()); vo.setDeviceStatus(resolveCrnDeviceStatus(protocol)); if (protocol.getAlarm() != null && protocol.getAlarm() > 0) { vo.setCrnStatus(CrnStatusType.MACHINE_ERROR); return vo; } if (protocol.getTaskNo() != null && protocol.getTaskNo() > 0) { WrkMast wrkMast = getWrkMast(protocol.getTaskNo()); if (wrkMast != null) { vo.setSourceLocNo(wrkMast.getSourceLocNo()); vo.setLocNo(wrkMast.getLocNo()); vo.setCrnStatus(CrnStatusType.process(wrkMast.getIoType())); return vo; } } vo.setCrnStatus(protocol.getModeType() == CrnModeType.AUTO ? CrnStatusType.MACHINE_AUTO : CrnStatusType.MACHINE_UN_AUTO); return vo; } private CrnLatestDataVo normalizeDualCrn(DeviceDataLog logItem) { DualCrnProtocol protocol = JSON.parseObject(logItem.getWcsData(), DualCrnProtocol.class); if (protocol == null) { return null; } CrnLatestDataVo vo = new CrnLatestDataVo(); vo.setCrnId(protocol.getCrnNo() == null ? logItem.getDeviceNo() : protocol.getCrnNo()); vo.setCrnNo(vo.getCrnId()); Integer bay = protocol.getBay() != null ? protocol.getBay() : protocol.getBayTwo(); Integer taskNo = protocol.getTaskNo() != null && protocol.getTaskNo() > 0 ? protocol.getTaskNo() : protocol.getTaskNoTwo(); vo.setBay(bay); vo.setOffset(bay == null ? 0D : Double.valueOf(bay)); vo.setTaskNo(taskNo); vo.setTaskNoTwo(protocol.getTaskNoTwo()); vo.setDeviceTaskNo(protocol.getDeviceTaskNo()); vo.setDeviceTaskNoTwo(protocol.getDeviceTaskNoTwo()); vo.setMode(resolveDualCrnMode(protocol)); vo.setStatus(resolveDualCrnStatus(protocol)); vo.setStatusTwo(resolveDualCrnStatusTwo(protocol)); vo.setLoading(protocol.getLoaded() != null && protocol.getLoaded() == 1 ? "有物" : "无物"); vo.setLoadingTwo(protocol.getLoadedTwo() != null && protocol.getLoadedTwo() == 1 ? "有物" : "无物"); vo.setLev(protocol.getLevel()); vo.setForkOffset(resolveDualCrnForkOffset(protocol)); vo.setForkOffsetTwo(resolveDualCrnForkOffsetTwo(protocol)); vo.setLiftPos(resolveDualCrnLiftPos(protocol)); vo.setWalkPos(protocol.getWalkPos() != null && protocol.getWalkPos() == 0 ? "在定位" : "不在定位"); vo.setTaskReceive(protocol.getTaskReceive() == null ? "-" : String.valueOf(protocol.getTaskReceive())); vo.setTaskReceiveTwo(protocol.getTaskReceiveTwo() == null ? "-" : String.valueOf(protocol.getTaskReceiveTwo())); vo.setTaskSend(protocol.getTaskSend() == null ? "-" : String.valueOf(protocol.getTaskSend())); vo.setTaskSendTwo(protocol.getTaskSendTwo() == null ? "-" : String.valueOf(protocol.getTaskSendTwo())); vo.setXspeed(formatDecimal(protocol.getXSpeed())); vo.setYspeed(formatDecimal(protocol.getYSpeed())); vo.setZspeed(formatDecimal(protocol.getZSpeed())); vo.setWarnCode(protocol.getAlarm() == null ? "-" : String.valueOf(protocol.getAlarm())); vo.setExtend(protocol.getExtend()); vo.setDeviceStatus(resolveDualCrnDeviceStatus(protocol)); if (protocol.getAlarm() != null && protocol.getAlarm() > 0) { vo.setCrnStatus(CrnStatusType.MACHINE_ERROR); } else { vo.setCrnStatus(protocol.getModeType() == DualCrnModeType.AUTO ? CrnStatusType.MACHINE_AUTO : CrnStatusType.MACHINE_UN_AUTO); } return vo; } private RgvLatestDataVo normalizeRgv(DeviceDataLog logItem) { RgvProtocol protocol = JSON.parseObject(logItem.getWcsData(), RgvProtocol.class); if (protocol == null) { return null; } RgvLatestDataVo vo = new RgvLatestDataVo(); vo.setRgvNo(protocol.getRgvNo()); vo.setTaskNo(protocol.getTaskNo()); vo.setTrackSiteNo(String.valueOf(protocol.getRgvPos())); vo.setRgvStatus(RgvStatusType.get(protocol.getStatus())); return vo; } private StationLatestDataVo normalizeStation(DeviceDataLog logItem) { StationProtocol protocol = JSON.parseObject(logItem.getWcsData(), StationProtocol.class); if (protocol == null) { return null; } WrkLastno inTaskRange = getWrkLastno(WrkIoType.IN.id); WrkLastno outTaskRange = getWrkLastno(WrkIoType.OUT.id); StationLatestDataVo vo = new StationLatestDataVo(); vo.setStationId(protocol.getStationId()); vo.setTaskNo(protocol.getTaskNo()); vo.setTargetStaNo(protocol.getTargetStaNo()); vo.setAutoing(protocol.isAutoing()); vo.setLoading(protocol.isLoading()); vo.setInEnable(protocol.isInEnable()); vo.setOutEnable(protocol.isOutEnable()); vo.setEmptyMk(protocol.isEmptyMk()); vo.setFullPlt(protocol.isFullPlt()); vo.setRunBlock(protocol.isRunBlock()); vo.setEnableIn(protocol.isEnableIn()); vo.setInBarcodeError(protocol.isInBarcodeError()); vo.setPalletHeight(protocol.getPalletHeight()); vo.setError(protocol.getError()); vo.setErrorMsg(protocol.getErrorMsg()); vo.setBarcode(protocol.getBarcode()); vo.setSystemWarning(protocol.getSystemWarning()); vo.setWeight(protocol.getWeight()); vo.setIoMode(protocol.getIoMode()); vo.setTaskWriteIdx(protocol.getTaskWriteIdx()); vo.setTaskBufferItems(protocol.getTaskBufferItems()); StationStatusType statusType = StationStatusType.process(protocol); String stationStatus = statusType == null ? "site-unauto" : statusType.toString().toLowerCase().replaceAll("_", "-"); if (protocol.isAutoing() && protocol.isLoading() && protocol.getTaskNo() != null && protocol.getTaskNo() > 0 && !protocol.isRunBlock()) { String taskClass = getStationTaskClass(protocol.getTaskNo(), inTaskRange, outTaskRange); if (taskClass != null) { stationStatus = taskClass; } } vo.setStationStatus(stationStatus); return vo; } private String getStationTaskClass(Integer taskNo, WrkLastno inTaskRange, WrkLastno outTaskRange) { if (taskNo == null || taskNo <= 0) { return null; } if (isInRange(taskNo, inTaskRange)) { return "machine-pakin"; } if (isInRange(taskNo, outTaskRange)) { return "machine-pakout"; } return null; } private boolean isInRange(Integer taskNo, WrkLastno taskRange) { if (taskRange == null || taskRange.getsNo() == null || taskRange.geteNo() == null) { return false; } return taskNo >= taskRange.getsNo() && taskNo <= taskRange.geteNo(); } private void collectStationAbnormal(List> abnormalList, StationLatestDataVo stationState, StreamIdentity identity) { if (stationState.getError() != null && stationState.getError() > 0) { abnormalList.add(buildAbnormal("Devp", identity.deviceNo, stationState.getStationId(), "ERROR", "站点故障", stationState.getErrorMsg())); return; } if (stationState.isRunBlock()) { abnormalList.add(buildAbnormal("Devp", identity.deviceNo, stationState.getStationId(), "BLOCK", "站点堵塞", "任务号 " + stationState.getTaskNo())); return; } if (!stationState.isAutoing()) { abnormalList.add(buildAbnormal("Devp", identity.deviceNo, stationState.getStationId(), "MANUAL", "站点手动", "当前不在自动模式")); } } private void collectCrnAbnormal(List> abnormalList, CrnLatestDataVo crnState) { if (crnState.getCrnStatus() != null && "machine-error".equals(crnState.getCrnStatus())) { abnormalList.add(buildAbnormal("Crn", crnState.getCrnId(), null, "ERROR", "堆垛机故障", "任务号 " + crnState.getTaskNo())); } } private void collectRgvAbnormal(List> abnormalList, RgvLatestDataVo rgvState) { if ("none".equals(rgvState.getRgvStatus())) { abnormalList.add(buildAbnormal("Rgv", rgvState.getRgvNo(), null, "OFFLINE", "RGV离线", "轨道位 " + rgvState.getTrackSiteNo())); } } private Map buildSummary(List stationStates, List crnStates, List dualCrnStates, List rgvStates, List> abnormalList) { Map summary = new LinkedHashMap<>(); summary.put("stationCount", stationStates.size()); summary.put("crnCount", crnStates.size()); summary.put("dualCrnCount", dualCrnStates.size()); summary.put("rgvCount", rgvStates.size()); summary.put("abnormalCount", abnormalList.size()); summary.put("errorCount", abnormalList.stream().filter(item -> "ERROR".equals(item.get("level"))).count()); summary.put("blockCount", abnormalList.stream().filter(item -> "BLOCK".equals(item.get("level"))).count()); return summary; } private Map buildAbnormal(String type, Integer deviceNo, Integer stationId, String level, String title, String detail) { Map abnormal = new LinkedHashMap<>(); abnormal.put("type", type); abnormal.put("deviceNo", deviceNo); abnormal.put("stationId", stationId); abnormal.put("level", level); abnormal.put("title", title); abnormal.put("detail", detail); return abnormal; } private Map buildTarget(String type, Integer deviceNo, Integer stationId, String title, String detail) { Map target = new LinkedHashMap<>(); target.put("type", type); target.put("deviceNo", deviceNo); target.put("stationId", stationId); target.put("title", title); target.put("detail", detail); return target; } private StreamIdentity parseStreamIdentity(String streamId) { StreamIdentity identity = new StreamIdentity(); if (streamId == null || streamId.isBlank()) { return identity; } String[] parts = streamId.split("\\|"); if (parts.length >= 3) { identity.type = parts[1]; identity.deviceNo = parseInteger(parts[2]); } if (parts.length >= 4) { identity.stationId = parseInteger(parts[3]); } return identity; } private Integer parseInteger(String value) { try { return value == null || value.isBlank() ? null : Integer.parseInt(value); } catch (Exception e) { return null; } } private String resolveCrnMode(CrnProtocol protocol) { if (protocol == null || protocol.getModeType() == null) { return "-"; } return protocol.getModeType().desc; } private String resolveCrnStatus(CrnProtocol protocol) { if (protocol == null || protocol.getStatusType() == null) { return "-"; } return protocol.getStatusType().desc; } private String resolveCrnForkOffset(CrnProtocol protocol) { if (protocol == null || protocol.getForkPosType() == null) { return "-"; } return protocol.getForkPosType().desc; } private String resolveCrnLiftPos(CrnProtocol protocol) { if (protocol == null || protocol.getLiftPosType() == null) { return "-"; } return protocol.getLiftPosType().desc; } private String resolveDualCrnMode(DualCrnProtocol protocol) { if (protocol == null || protocol.getModeType() == null) { return "-"; } return protocol.getModeType().desc; } private String resolveDualCrnStatus(DualCrnProtocol protocol) { if (protocol == null || protocol.getStatusType() == null) { return "-"; } return protocol.getStatusType().desc; } private String resolveDualCrnStatusTwo(DualCrnProtocol protocol) { if (protocol == null || protocol.getStatusTypeTwo() == null) { return "-"; } return protocol.getStatusTypeTwo().desc; } private String resolveDualCrnForkOffset(DualCrnProtocol protocol) { if (protocol == null || protocol.getForkPosType() == null) { return "-"; } return protocol.getForkPosType().desc; } private String resolveDualCrnForkOffsetTwo(DualCrnProtocol protocol) { if (protocol == null || protocol.getForkPosTypeTwo() == null) { return "-"; } return protocol.getForkPosTypeTwo().desc; } private String resolveDualCrnLiftPos(DualCrnProtocol protocol) { if (protocol == null || protocol.getLiftPosType() == null) { return "-"; } return protocol.getLiftPosType().desc; } private String formatDecimal(Number value) { if (value == null) { return "-"; } return String.format("%.2f", value.doubleValue()); } private String resolveCrnAlarm(Integer alarmCode) { if (alarmCode == null || alarmCode <= 0) { return "-"; } BasCrnpErr alarm = getBasCrnpErr(alarmCode); return alarm == null ? "未知异常" : alarm.getErrName(); } private WrkMast getWrkMast(Integer taskNo) { if (taskNo == null || taskNo <= 0) { return null; } if (wrkMastCache.size() > MAX_WRK_MAST_CACHE_SIZE) { wrkMastCache.clear(); } return wrkMastCache.computeIfAbsent(taskNo, wrkMastService::getById); } private WrkLastno getWrkLastno(Integer id) { if (id == null || id <= 0) { return null; } return wrkLastnoCache.computeIfAbsent(id, wrkLastnoService::getById); } private BasCrnpErr getBasCrnpErr(Integer alarmCode) { if (alarmCode == null || alarmCode <= 0) { return null; } return basCrnpErrCache.computeIfAbsent(alarmCode, basCrnpErrService::getById); } private String resolveCrnDeviceStatus(CrnProtocol protocol) { if (protocol == null) { return "OFFLINE"; } if (protocol.getAlarm() != null && protocol.getAlarm() > 0) { return "ERROR"; } if (protocol.getTaskNo() != null && protocol.getTaskNo() > 0) { return "WORKING"; } if (protocol.getModeType() == CrnModeType.AUTO) { return "AUTO"; } return "OFFLINE"; } private String resolveDualCrnDeviceStatus(DualCrnProtocol protocol) { if (protocol == null) { return "OFFLINE"; } if (protocol.getAlarm() != null && protocol.getAlarm() > 0) { return "ERROR"; } boolean hasTask = protocol.getTaskNo() != null && protocol.getTaskNo() > 0 || protocol.getTaskNoTwo() != null && protocol.getTaskNoTwo() > 0; if (hasTask) { return "WORKING"; } if (protocol.getModeType() == DualCrnModeType.AUTO) { return "AUTO"; } return "OFFLINE"; } private static class StreamIdentity { private String type; private Integer deviceNo; private Integer stationId; } }