package com.battery.device.api; import java.util.List; import java.util.Map; import java.util.Set; import com.battery.device.api.model.AdapterCapabilities; import com.battery.device.api.model.ChannelIdentity; import com.battery.device.api.model.DetectedChannel; import com.battery.device.api.model.DeviceControlCommand; import com.battery.device.api.model.RealtimeSnapshot; import com.battery.device.api.model.DeviceObservation; import com.battery.device.api.model.ObservationFailureReason; public interface DeviceAdapter extends DeviceObservationAdapter { /** 返回适配器实例的稳定代码。 */ String adapterCode(); /** 返回运行时已启用的设备能力。 */ AdapterCapabilities capabilities(); /** 发现当前端点可见的检测柜通道。 */ List discoverChannels(); /** 批量查询通道实时快照,不形成最终原始采集数据。 */ Map inquire(Set channels); /** 返回厂商无关的观测结果;失败也以离线事实返回,不把协议异常泄漏给业务。 */ default Map observe(Set channels) { if (channels == null || channels.isEmpty()) return Map.of(); try { Map snapshots = inquire(channels); Map observations = new java.util.LinkedHashMap<>(); channels.forEach(channel -> { RealtimeSnapshot snapshot = snapshots.get(channel); observations.put(channel, snapshot == null ? DeviceObservation.offline(channel, "OFFLINE") : DeviceObservation.from(snapshot)); }); return Map.copyOf(observations); } catch (DeviceAdapterException exception) { ObservationFailureReason reason = normalizeFailureReason(exception.failureCode()); Map offline = new java.util.LinkedHashMap<>(); channels.forEach(channel -> offline.put(channel, DeviceObservation.offline(channel, reason))); return Map.copyOf(offline); } } /** 将适配器实现细节收敛为业务可识别的失败分类。 */ private static ObservationFailureReason normalizeFailureReason(String failureCode) { if (failureCode == null || failureCode.isBlank()) return ObservationFailureReason.INVALID_RESPONSE; return switch (failureCode.trim().toUpperCase(java.util.Locale.ROOT)) { case "CONNECTION_FAILED" -> ObservationFailureReason.CONNECTION_FAILED; case "TIMEOUT" -> ObservationFailureReason.TIMEOUT; case "DISCONNECTED" -> ObservationFailureReason.DISCONNECTED; case "UNSUPPORTED" -> ObservationFailureReason.UNSUPPORTED; // 只读白名单拒绝(ADR-0068)不是"传输坏了",而是这条请求本就不该发:归为不支持。 case "READ_ONLY_REJECTED" -> ObservationFailureReason.UNSUPPORTED; case "MALFORMED_XML", "MISSING_FIELD", "INVALID_VALUE", "IDENTITY_MISMATCH", "UNEXPECTED_COMMAND" -> ObservationFailureReason.PARSE_FAILED; default -> ObservationFailureReason.TRANSPORT_FAILED; }; } /** 执行设备控制;只读适配器始终拒绝该调用。 */ default void control(ChannelIdentity channel, DeviceControlCommand command) { throw new UnsupportedOperationException("Device control is not enabled for this adapter"); } @Override default void close() { } }