| | |
| | | TTest test = tests.selectTestById(testId); |
| | | List<CabinetCandidate> cabinets = candidates.snapshot(Instant.now()).cabinets(); |
| | | List<LiveSource> sources = new ArrayList<>(); |
| | | boolean receiving = "RECEIVING".equals(test.getReceptionStatus()); |
| | | boolean receiving = "RUNNING".equals(test.getTestStatus()) && "RECEIVING".equals(test.getReceptionStatus()); |
| | | for (TTestBattery battery : test.getBatteries() == null ? List.<TTestBattery>of() : test.getBatteries()) |
| | | { |
| | | if (battery.getBinding() != null) |
| | |
| | | sources.add(collectorSource(battery, receiving)); |
| | | } |
| | | List<Map<String, Object>> exceptions = new ArrayList<>(); |
| | | if (receiving) |
| | | exceptions.addAll(sources.stream().filter(source -> !"COLLECTOR".equals(source.sourceType()) |
| | | && "OFFLINE".equals(source.deviceStatus())) |
| | | .map(source -> Map.<String, Object>of("sourceType", source.sourceType(), "sourceId", source.sourceId(), |
| | | "batteryNo", source.batteryNo(), "status", source.deviceStatus(), "message", "数据来源当前不可观测")) |
| | | .toList()); |
| | | java.util.Set<String> offlineSources = new java.util.HashSet<>(); |
| | | // 完成或暂停后只保留历史异常事实,实时控制台不再展示开放预警。 |
| | | if (receiving && mapper != null) { |
| | | mapper.selectWarningExceptions(testId, "OPEN").forEach(item -> exceptions.add(Map.of( |
| | | "exceptionId", item.getExceptionId(), "sourceType", item.getSourceType(), |
| | | "metricCode", item.getMetricCode(), "value", item.getAbnormalValue(), "unit", item.getUnit(), |
| | | "status", item.getExceptionStatus(), "message", "测试预警异常"))); |
| | | mapper.selectWarningExceptions(testId, "OPEN").forEach(item -> { |
| | | boolean offline = "DEVICE_OFFLINE".equals(item.getExceptionType()); |
| | | if (offline) offlineSources.add(item.getSourceType() + ":" + item.getSourceIdentity()); |
| | | // 离线异常没有测量值,必须允许空值,不能用 Map.of 构造响应。 |
| | | Map<String, Object> warning = new LinkedHashMap<>(); |
| | | warning.put("exceptionId", item.getExceptionId()); |
| | | warning.put("exceptionType", item.getExceptionType()); |
| | | warning.put("sourceType", item.getSourceType()); |
| | | warning.put("sourceIdentity", item.getSourceIdentity()); |
| | | warning.put("metricCode", item.getMetricCode()); |
| | | warning.put("value", item.getAbnormalValue()); |
| | | warning.put("unit", item.getUnit()); |
| | | warning.put("status", item.getExceptionStatus()); |
| | | warning.put("message", offline ? "接收期间设备离线,等待处理" : "测试预警异常"); |
| | | exceptions.add(warning); |
| | | }); |
| | | } |
| | | if (receiving) { |
| | | for (LiveSource source : sources) { |
| | | if (!"OFFLINE".equals(source.deviceStatus())) continue; |
| | | String identity = offlineIdentity(test, source); |
| | | if (!offlineSources.add(source.sourceType() + ":" + identity)) continue; |
| | | exceptions.add(Map.of("exceptionType", "DEVICE_OFFLINE", "sourceType", source.sourceType(), |
| | | "sourceId", source.sourceId(), "sourceIdentity", identity, |
| | | "status", "OPEN", "message", "接收中数据来源离线,当前无法取得测量数据")); |
| | | } |
| | | } |
| | | String testStatus = test.getTestStatus(); |
| | | TestPlanSnapshot testPlan = detectorTestPlan(test); |
| | | return new LiveState(testId, testStatus, test.getReceptionStatus(), Instant.now().toEpochMilli(), sources, exceptions, testPlan); |
| | | } |
| | | |
| | | private String offlineIdentity(TTest test, LiveSource source) |
| | | { |
| | | if ("COLLECTOR".equals(source.sourceType())) return String.valueOf(source.sourceId()); |
| | | for (TTestBattery battery : test.getBatteries()) { |
| | | var binding = battery.getBinding(); |
| | | if (binding != null && Objects.equals(binding.getChannelId(), source.sourceId())) |
| | | return binding.getAdapterCode() + ":" + binding.getDevtype() + ":" + binding.getDevid() |
| | | + ":" + binding.getSubdevid() + ":" + binding.getChlid(); |
| | | } |
| | | return String.valueOf(source.sourceId()); |
| | | } |
| | | |
| | | private TestPlanSnapshot detectorTestPlan(TTest test) |
| | | { |
| | | if (adapter == null) return null; |