diff --git a/DeviceCommand/Base/EnovaDataReporter.cs b/DeviceCommand/Base/EnovaDataReporter.cs
new file mode 100644
index 0000000..9fa197e
--- /dev/null
+++ b/DeviceCommand/Base/EnovaDataReporter.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Model.Model;
+using Newtonsoft.Json;
+
+namespace DeviceCommand.Base
+{
+
+ public class EnovaDataReporter : IEnovaDataReporter
+ {
+ private readonly HttpClient _httpClient;
+
+ // 显式实现/自动属性,方便外部随时更新配置
+ public string TargetUrl { get; set; } = "http://127.0.0.1:8080/api/channel/state";
+ public int TimeoutMilliseconds { get; set; } = 5000;
+
+ ///
+ /// 构造函数注入 HttpClient(符合 Prism 依赖注入规范)
+ ///
+ public EnovaDataReporter(HttpClient httpClient)
+ {
+ // 如果容器没有注入,则给个默认的单例/实例防空
+ _httpClient = httpClient ?? new HttpClient();
+ }
+
+ public async Task ReportChannelStateAsync(List dataList, CancellationToken ct = default)
+ {
+ if (dataList == null || dataList.Count == 0)
+ {
+ return new EnovaReportResponse { Success = false, ErrorInfo = "上报数据集合为空" };
+ }
+
+ if (string.IsNullOrWhiteSpace(TargetUrl))
+ {
+ return new EnovaReportResponse { Success = false, ErrorInfo = "目标上报 URL 未配置" };
+ }
+
+ try
+ {
+ // 1. 序列化为标准 JSON 字符串
+ string jsonPayload = JsonConvert.SerializeObject(dataList);
+ var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
+
+ // 2. 绑定联动超时控制
+ using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
+ if (TimeoutMilliseconds > 0)
+ {
+ cts.CancelAfter(TimeoutMilliseconds);
+ }
+
+ HttpResponseMessage response = await _httpClient.PostAsync(TargetUrl, content, cts.Token);
+
+ // 4. 解析返回值
+ if (response.IsSuccessStatusCode)
+ {
+ string responseContent = await response.Content.ReadAsStringAsync();
+ var result = JsonConvert.DeserializeObject(responseContent);
+ return result ?? new EnovaReportResponse { Success = true }; // 防止对方返回空Body [cite: 261]
+ }
+ else
+ {
+ return new EnovaReportResponse
+ {
+ Success = false,
+ ErrorInfo = $"服务器响应错误代码: {(int)response.StatusCode} {response.ReasonPhrase}"
+ };
+ }
+ }
+ catch (Exception ex)
+ {
+ // 完美承接你上位机原有的异常日志记录器逻辑
+ // Logger.LoggerHelper.ErrorWithNotify($"Enova3 数据上传失败: {ex.Message}");
+ return new EnovaReportResponse { Success = false, ErrorInfo = $"网络异常: {ex.Message}" };
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DeviceCommand/Base/IBaseInterface.cs b/DeviceCommand/Base/IBaseInterface.cs
new file mode 100644
index 0000000..ebffb50
--- /dev/null
+++ b/DeviceCommand/Base/IBaseInterface.cs
@@ -0,0 +1,16 @@
+using NModbus;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DeviceCommand.Base
+{
+ public interface IBaseInterface
+ {
+ public bool IsConnected { get; }
+ public Task ConnectAsync(CancellationToken ct = default);
+ public void Close();
+ }
+}
diff --git a/DeviceCommand/Base/IEnovaDataReporter.cs b/DeviceCommand/Base/IEnovaDataReporter.cs
new file mode 100644
index 0000000..15a6087
--- /dev/null
+++ b/DeviceCommand/Base/IEnovaDataReporter.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Model.Model;
+
+namespace DeviceCommand.Base
+{
+ ///
+ /// Enova3 上位机数据上报核心接口
+ ///
+ public interface IEnovaDataReporter
+ {
+ ///
+ /// 客户平台接收数据的目标 HTTP URL
+ ///
+ string TargetUrl { get; set; }
+
+ ///
+ /// HTTP 请求超时时间(毫秒)
+ ///
+ int TimeoutMilliseconds { get; set; }
+
+ ///
+ /// 异步推送通道的实时状态数据到客户平台
+ ///
+ /// 包含各通道状态的采集数据集合
+ /// 取消令牌
+ /// 平台服务器的响应状态
+ Task ReportChannelStateAsync(List dataList, CancellationToken ct = default);
+ }
+}
\ No newline at end of file
diff --git a/DeviceCommand/Base/IModbusDevice.cs b/DeviceCommand/Base/IModbusDevice.cs
new file mode 100644
index 0000000..360e843
--- /dev/null
+++ b/DeviceCommand/Base/IModbusDevice.cs
@@ -0,0 +1,19 @@
+using NModbus;
+
+
+namespace DeviceCommand.Base
+{
+ public interface IModbusDevice : IBaseInterface,IDisposable
+ {
+ IModbusMaster Modbus { get; }
+
+ Task WriteSingleRegisterAsync(byte slaveAddress, ushort registerAddress, ushort value, CancellationToken ct = default);
+ Task WriteMultipleRegistersAsync(byte slaveAddress, ushort startAddress, ushort[] values, CancellationToken ct = default);
+ Task ReadHoldingRegistersAsync(byte slaveAddress, ushort startAddress, ushort numberOfPoints, CancellationToken ct = default);
+
+ Task WriteSingleCoilAsync(byte slaveAddress, ushort coilAddress, bool value, CancellationToken ct = default);
+ Task ReadCoilsAsync(byte slaveAddress, ushort startAddress, ushort numberOfPoints, CancellationToken ct = default);
+
+ Task ReadInputRegistersAsync(byte slaveAddress, ushort startAddress, ushort numberOfPoints, CancellationToken ct = default);
+ }
+}
\ No newline at end of file
diff --git a/DeviceCommand/Base/IS7Device.cs b/DeviceCommand/Base/IS7Device.cs
new file mode 100644
index 0000000..b58d401
--- /dev/null
+++ b/DeviceCommand/Base/IS7Device.cs
@@ -0,0 +1,22 @@
+using S7.Net;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace DeviceCommand.Base
+{
+ public interface IS7Device : IBaseInterface, IDisposable
+ {
+ // 暴露出 S7.Net 原生的 Plc 对象,方便外部进行复杂扩展
+ Plc PlcContext { get; }
+
+ // 核心读写接口(支持直接传物理地址,如 "DB1.DBD0" 或 "M0.0")
+ Task WriteAsync(string address, object value, CancellationToken ct = default);
+ Task