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<DetectedChannel> discoverChannels();
|
|
/** 批量查询通道实时快照,不形成最终原始采集数据。 */
|
Map<ChannelIdentity, RealtimeSnapshot> inquire(Set<ChannelIdentity> channels);
|
|
/** 返回厂商无关的观测结果;失败也以离线事实返回,不把协议异常泄漏给业务。 */
|
default Map<ChannelIdentity, DeviceObservation> observe(Set<ChannelIdentity> channels)
|
{
|
if (channels == null || channels.isEmpty()) return Map.of();
|
try
|
{
|
Map<ChannelIdentity, RealtimeSnapshot> snapshots = inquire(channels);
|
Map<ChannelIdentity, DeviceObservation> 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<ChannelIdentity, DeviceObservation> 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;
|
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()
|
{
|
}
|
}
|