| | |
| | | requiredArray(object, "channels").forEach(item -> channels.add(collectorChannelState(item))); |
| | | List<CollectorMeasurementRecord> history = new ArrayList<>(); |
| | | requiredArray(object, "history").forEach(item -> history.add(collectorMeasurementRecord(item))); |
| | | List<CollectorRealtimeMeasurement> latestMeasurements = new ArrayList<>(); |
| | | JSONArray latest = object.getJSONArray("latestMeasurements"); |
| | | if (latest != null) |
| | | latest.forEach(item -> latestMeasurements.add(collectorRealtimeMeasurement(item))); |
| | | else |
| | | latestMeasurements.addAll(latestMeasurementsFromLegacyHistory(history, channels)); |
| | | return new CollectorState(collectorId, deviceCode, ip, mac, name, manufacturer, model, |
| | | channelCount, online, requiredInteger(object, "sampleIntervalMs"), |
| | | requiredLong(object, "nextSequence"), optionalInstant(object, "lastSampledAt"), |
| | | channels, history, collectorHistoryFaults(object.get("historyFaults"))); |
| | | channels, latestMeasurements, history, collectorHistoryFaults(object.get("historyFaults"))); |
| | | } |
| | | |
| | | private CollectorChannelState collectorChannelState(Object value) |
| | |
| | | measurement, object.getString("unit")); |
| | | } |
| | | |
| | | private CollectorRealtimeMeasurement collectorRealtimeMeasurement(Object value) |
| | | { |
| | | JSONObject object = jsonObject(value); |
| | | BigDecimal measurement = object.getBigDecimal("value"); |
| | | if (measurement == null) throw new IllegalStateException("Missing BTS simulator state field: value"); |
| | | return new CollectorRealtimeMeasurement(object.getString("adapterCode"), object.getString("collectorCode"), |
| | | object.getString("channelCode"), requiredLong(object, "sequenceId"), |
| | | requiredInstant(object, "deviceTime"), object.getString("deviceTimeRaw"), |
| | | requiredInstant(object, "serverReceivedAt"), object.getString("metricCode"), |
| | | measurement, object.getString("unit")); |
| | | } |
| | | |
| | | /** 兼容 Ticket06 开发期间已写入但尚未拆分快照模型的状态。 */ |
| | | private List<CollectorRealtimeMeasurement> latestMeasurementsFromLegacyHistory( |
| | | List<CollectorMeasurementRecord> history, List<CollectorChannelState> channels) |
| | | { |
| | | java.util.Set<String> configured = new java.util.HashSet<>(); |
| | | channels.forEach(channel -> channel.metrics().forEach(metric -> |
| | | configured.add(channel.channelCode() + "\u0000" + metric.metricCode()))); |
| | | java.util.Map<String, CollectorRealtimeMeasurement> latest = new java.util.LinkedHashMap<>(); |
| | | for (CollectorMeasurementRecord record : history) |
| | | { |
| | | String key = record.channelCode() + "\u0000" + record.metricCode(); |
| | | if (configured.contains(key)) |
| | | latest.put(key, new CollectorRealtimeMeasurement(record.adapterCode(), record.collectorCode(), |
| | | record.channelCode(), record.sequenceId(), record.deviceTime(), record.deviceTimeRaw(), |
| | | record.serverReceivedAt(), record.metricCode(), record.value(), record.unit())); |
| | | } |
| | | return List.copyOf(latest.values()); |
| | | } |
| | | |
| | | private CollectorHistoryFaults collectorHistoryFaults(Object value) |
| | | { |
| | | if (value == null) return CollectorHistoryFaults.none(); |