diff --git a/ADP.sln b/ADP.sln
index 8070f1d..4a7e18f 100644
--- a/ADP.sln
+++ b/ADP.sln
@@ -35,10 +35,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateInfoMoudle", "UpdateI
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonitorModule", "MonitorModule\MonitorModule.csproj", "{850A5BE8-0BC1-4D6A-8351-DD812C9C4427}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CAN驱动", "CAN驱动\CAN驱动.csproj", "{D1868672-0132-4B1A-A393-C2CF49A25E74}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceEditModule", "DeviceEditModule\DeviceEditModule.csproj", "{170AD4C1-189D-4FBE-B10D-2A4304527834}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "USBCANFD", "USBCANFD\USBCANFD.csproj", "{C011DC26-E2F8-4F40-AD62-C5D50BA56CE8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -105,14 +105,14 @@ Global
{850A5BE8-0BC1-4D6A-8351-DD812C9C4427}.Debug|Any CPU.Build.0 = Debug|Any CPU
{850A5BE8-0BC1-4D6A-8351-DD812C9C4427}.Release|Any CPU.ActiveCfg = Release|Any CPU
{850A5BE8-0BC1-4D6A-8351-DD812C9C4427}.Release|Any CPU.Build.0 = Release|Any CPU
- {D1868672-0132-4B1A-A393-C2CF49A25E74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D1868672-0132-4B1A-A393-C2CF49A25E74}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D1868672-0132-4B1A-A393-C2CF49A25E74}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D1868672-0132-4B1A-A393-C2CF49A25E74}.Release|Any CPU.Build.0 = Release|Any CPU
{170AD4C1-189D-4FBE-B10D-2A4304527834}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{170AD4C1-189D-4FBE-B10D-2A4304527834}.Debug|Any CPU.Build.0 = Debug|Any CPU
{170AD4C1-189D-4FBE-B10D-2A4304527834}.Release|Any CPU.ActiveCfg = Release|Any CPU
{170AD4C1-189D-4FBE-B10D-2A4304527834}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C011DC26-E2F8-4F40-AD62-C5D50BA56CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C011DC26-E2F8-4F40-AD62-C5D50BA56CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C011DC26-E2F8-4F40-AD62-C5D50BA56CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C011DC26-E2F8-4F40-AD62-C5D50BA56CE8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ADP/ADP.csproj b/ADP/ADP.csproj
index cbaa45c..52c2fdc 100644
--- a/ADP/ADP.csproj
+++ b/ADP/ADP.csproj
@@ -19,7 +19,6 @@
-
@@ -31,6 +30,7 @@
+
diff --git a/CAN驱动/CAN.cs b/CAN驱动/CAN.cs
deleted file mode 100644
index 4056f0b..0000000
--- a/CAN驱动/CAN.cs
+++ /dev/null
@@ -1,417 +0,0 @@
-using Common.Attributes;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Text.Json;
-using TSMaster;
-namespace CAN驱动
-{
- [ADPCommand]
- public class CAN
- {
-
- public static event Action ConnectEvent;
- public static event Action DisConnectEvent;
- public static bool ConnectFlag { get; set; } = false;
-
- ///
- /// 初始化CAN驱动
- ///
- ///
- ///
- ///
- [Browsable(false)]
- public static int Init(string ProjectName, string? filePath = null)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- return TsMasterApi.initialize_lib_tsmaster(ProjectName);
- }
- else
- {
- return TsMasterApi.initialize_lib_tsmaster_with_project(ProjectName, Path.GetFullPath(filePath));
- }
- }
-
- ///
- /// 释放CAN驱动
- ///
- [Browsable(false)]
- public static void Release()
- {
- TsMasterApi.finalize_lib_tsmaster();
- }
-
- public static int obj = 0;
- public static TCANFDQueueEvent_Win32 listener;
- [Browsable(false)]
- public static int RegisterListener(TCANFDQueueEvent_Win32 listenEvent)
- {
- listener = listenEvent;
- var re = TsMasterApi.tsapp_register_event_canfd(ref obj, listener);
- Debug.Assert(re == 0);
- return re;
- }
-
- [Browsable(false)]
- public static int UnRegisterListener(TCANFDQueueEvent_Win32 listenEvent = null)
- {
- if (listenEvent is not null)
- {
- listener = listenEvent;
- }
- var re = TsMasterApi.tsapp_unregister_event_canfd(ref obj, listener);
- Debug.Assert(re == 0);
- return re;
- }
-
- ///
- /// 连接
- ///
- ///
- public static int Connect()
- {
-
- var re = TsMasterApi.tsapp_connect();
- if (re == 0)
- {
- re = TsMasterApi.tscom_can_rbs_start();
- if (re == 0)
- {
- ConnectFlag = true;
- Task.Run(() => ConnectEvent?.Invoke());
- }
- else
- {
- Debug.WriteLine($"CAN_RBS启动失败,错误代码:{re}");
- }
- }
- else
- {
- Debug.WriteLine($"CAN连接失败,错误代码:{re}");
- return re;
- }
- return re;
- }
-
- ///
- /// 断开
- ///
- ///
- public static int DisConnect()
- {
- var re = TsMasterApi.tsapp_disconnect();
- //Debug.Assert(re == 0);
- if (re == 0)
- {
- ConnectFlag = false;
- Task.Run(() => DisConnectEvent?.Invoke());
- }
- else
- {
- Debug.WriteLine($"断开CAN连接失败,错误代码:{re}");
- }
-
-
- return re;
- }
-
- ///
- /// 加载DBC
- ///
- ///
- ///
- ///
- ///
- [Browsable(false)]
- public static int LoadDBC(string filePath, int[] channel, out uint databaseID)
- {
- databaseID = 0;
-
- var re = TsMasterApi.tsdb_load_can_db(Path.GetFullPath(filePath), string.Join(",", channel), ref databaseID);
- foreach (var item in channel)
- {
- DBCParse.parse(databaseID, item);
- DBCParse.rbs_parse(databaseID, item);
- }
-
- return re;
- }
-
- ///
- /// 卸载DBC
- ///
- ///
- ///
- [Browsable(false)]
- public static int UnLoadDBC(uint? databaseID = null)
- {
- if (databaseID == null)
- {
- return TsMasterApi.tsdb_unload_can_dbs();
- }
- else
- {
- return TsMasterApi.tsdb_unload_can_db(databaseID.Value);
- }
- }
-
- ///
- /// 开始记录日志
- ///
- ///
- ///
- public static int StartLogging(string filePath)
- {
- return TsMasterApi.tsapp_start_logging(Path.GetFullPath(filePath));
- }
-
- ///
- /// 结束记录日志
- ///
- ///
- public static int StopLogging()
- {
- return TsMasterApi.tsapp_stop_logging();
- }
-
- ///
- /// 弹出通道映射窗口
- ///
- ///
- ///
- [Browsable(false)]
- public static int ShowChannelMappingWindow(bool isWait = false)
- {
- return TsMasterApi.tsapp_show_tsmaster_window("Hardware", isWait);
- }
-
- ///
- /// 获取信号值
- ///
- ///
- ///
- ///
- ///
- public static double GetSignalValue(byte channel, string AMsgName, string ASgnName)
- {
- double value = double.NaN;
- var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
- var re = TsMasterApi.tsdb_get_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, ref value);
-
- return value;
- }
-
- ///
- /// 获取信号值
- ///
- ///
- ///
- ///
- ///
- ///
- [Browsable(false)]
- public static int GetSignalValue(byte channel, string AMsgName, string ASgnName, ref double value)
- {
- var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
- return TsMasterApi.tsdb_get_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, ref value);
- }
-
- ///
- /// 获取信号值
- ///
- ///
- ///
- ///
- ///
- ///
-
- [Browsable(false)]
- public static int GetSignalValue(ref TLIBCANFD ACANFD, string AMsgName, string ASgnName, ref double value)
- {
- return TsMasterApi.tsdb_get_signal_value_canfd(ref ACANFD, AMsgName, ASgnName, ref value);
- }
-
- ///
- /// 设置信号值
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public static int SetSignalValue(byte channel, string AMsgName, string ASgnName, double AValue, bool isSend = false, float sendPeriod = 0)
- {
- var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
- find.ACANFD.FIdxChn = channel;
- var re = TsMasterApi.tsdb_set_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, AValue);
- Debug.Assert(re == 0);
- if (re != 0) throw new Exception($"设置报文失败!返回代码{re}");
- if (re != 0) return re;
- if (isSend)
- {
- if (sendPeriod == 0)
- {
- return TsMasterApi.tsapp_transmit_canfd_async(ref find.ACANFD);
- }
- else
- {
- return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
- }
- }
- return 0;
- }
-
-
- ///
- /// 设置信号值
- ///
- ///
- ///
- ///
- ///
- public static int SetSignalValue(APP_CHANNEL channel, string AMsgName, float sendPeriod = 0)
- {
- var find = DBCParse.MsgDatabase[(byte)channel].First(s => s.msg_name == AMsgName);
- find.ACANFD.FIdxChn = (byte)channel;
- if (sendPeriod == 0)
- {
- return TsMasterApi.tsapp_transmit_canfd_async(ref find.ACANFD);
- }
- else
- {
- return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
- }
- }
-
- ///
- /// 发送自定义报文
- ///
- ///
- [Browsable(false)]
- public static int SetMsg(TLIBCANFD msg)
- {
- return TsMasterApi.tsapp_transmit_canfd_async(ref msg);
- }
-
- ///
- /// 设置报文
- ///
- /// 通道
- /// DBC数据库ID
- /// 报文数组
- public static void SetMsg(APP_CHANNEL channel, int ID, byte[] bytes)
- {
- var find = DBCParse.MsgDatabase[(byte)channel].FirstOrDefault(s => s.ACANFD.FIdentifier == ID);
- if (find != null)
- {
- Array.Copy(bytes, 0, find.ACANFD.FData, 0, Math.Min(bytes.Length, find.ACANFD.FData.Length));
- }
- }
-
- ///
- /// 发送自定义报文
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public static int SendMsg(APP_CHANNEL AIdxChn, int AID, bool AIsTx, bool AIsExt,
- bool AIsRemote, byte ADLC, byte[] ADataArray, bool AIsFD = true, bool AIsBRS = false,
- bool isUpdateDBCDatabase = false, float sendPeriod = 0)
- {
- var send = new TLIBCANFD
- {
- FIdxChn = (byte)AIdxChn,
- FProperties = 0,
- FIdentifier = AID,
- FDLC = ADLC,
- FTimeUS = 0uL,
- FData = new byte[64],
- FFDProperties = 0,
- FIsTx = AIsTx,
- FIsError = false,
- FIsExt = AIsExt,
- FIsRemote = AIsRemote,
- FIsFD = AIsFD,
- FIsBRS = AIsBRS
- };
- int length = Math.Min(ADataArray.Length, 64);
- Array.Copy(ADataArray, 0, send.FData, 0, length);
- int re;
- if (sendPeriod == 0)
- {
- re = TsMasterApi.tsapp_transmit_canfd_async(ref send);
- }
- else
- {
- re = TsMasterApi.tsapp_add_cyclic_msg_canfd(ref send, sendPeriod);
- }
-
- if (isUpdateDBCDatabase)
- {
- var find = DBCParse.MsgDatabase[(byte)AIdxChn].FirstOrDefault(s => s.ACANFD.FIdentifier == send.FIdentifier);
- if (find != null)
- {
- Array.Copy(send.FData, 0, find.ACANFD.FData, 0, Math.Min(ADataArray.Length, find.ACANFD.FData.Length));
- }
- }
- return re;
- }
-
- ///
- /// 添加循环发送报文
- ///
- ///
- ///
- ///
- ///
- public static int AddCyclicMsg(byte channel, string AMsgName, float sendPeriod)
- {
- var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
- find.ACANFD.FIdxChn = channel;
- return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
- }
-
- ///
- /// 清除循环发送的报文
- ///
- ///
- public static int DeleteCyclicMsgs()
- {
- return TsMasterApi.tsapp_delete_cyclic_msgs();
- }
-
- ///
- /// 获取错误提示
- ///
- /// 错误代码
- ///
- public static string GetErrorDescription(int errorCode)
- {
- IntPtr ADesc = IntPtr.Zero;
- TsMasterApi.tsapp_get_error_description(errorCode, ref ADesc);
-
- if (ADesc == IntPtr.Zero) return $"未知错误代码: {errorCode}";
-
- // 假设返回的是 ANSI 字符串(如 C 的 char*)
- string? description = Marshal.PtrToStringAnsi(ADesc);
-
- return description ?? $"未知错误代码: {errorCode}";
- }
-
- }
-}
diff --git a/CAN驱动/DBCParse.cs b/CAN驱动/DBCParse.cs
deleted file mode 100644
index 47ab723..0000000
--- a/CAN驱动/DBCParse.cs
+++ /dev/null
@@ -1,269 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Security.Cryptography;
-using System.Text;
-using System.Text.Json.Serialization;
-using System.Threading.Tasks;
-using TSMaster;
-
-namespace CAN驱动
-{
- public struct can_network
- {
- [JsonInclude]
- public string network_name;
- [JsonInclude]
- public can_node[] can_nodes;
-
- }
- public struct can_node
- {
- [JsonInclude]
- public string node_name;
- [JsonInclude]
- public can_message[] tx_can_Messages;
- [JsonInclude]
- public can_message[] rx_can_Messages;
- }
- public struct can_message
- {
- [JsonInclude]
- public string message_name;
- [JsonInclude]
- public string[] signals;
- }
-
- public class _Msg_
- {
- public int msg_type { get; set; }
- public int msg_id { get; set; }
- public int msg_cyclic { get; set; }
- public byte msg_dlc { get; set; }
- public string msg_name { get; set; }
- public string[] signal_Name { get; set; }
- public int msg_brs { get; set; }
- public TLIBCANFD ACANFD;
- }
- public enum Msg_Type
- {
- CAN = 0,
- CANFD = 1,
- }
- ///
- /// DBC 文件信息类型枚举,用于指定 tsdb_get_can_db_info 查询的内容类型。
- ///
- public enum DBCINFO
- {
- /// 网络名称
- NETWORK_Name = 0,
-
- /// CAN 报文总数
- CAN_MSG_COUNT = 11,
- /// CAN FD 报文总数
- CANFD_MSG_COUNT = 12,
- /// 节点总数
- NODE_COUNT = 14,
-
- /// 信号名称
- SIGNAL_NAME = 33,
-
- /// CAN 报文类型
- CAN_MSG_TYPE = 40,
- /// CAN 报文 DLC(数据长度码)
- CAN_MSG_DLC = 41,
- /// CAN 报文 ID
- CAN_MSG_ID = 42,
- /// CAN 报文周期
- CAN_MSG_CYCLIC = 43,
- /// CAN 报文名称
- CAN_MSG_NAME = 44,
- /// CAN 报文信号数量
- CAN_MSG_SIGNAL_COUNT = 47,
- /// CAN 报文信号名称索引
- CAN_MSG_SIGNAL_NAME_INDEX = 48,
-
- /// CAN FD 报文类型
- CANFD_MSG_TYPE = 60,
- /// CAN FD 报文 DLC(数据长度码)
- CANFD_MSG_DLC = 61,
- /// CAN FD 报文 ID
- CANFD_MSG_ID = 62,
- /// CAN FD 报文周期
- CANFD_MSG_CYCLIC = 63,
- /// CAN FD 报文名称
- CANFD_MSG_NAME = 64,
- /// CAN FD 报文信号数量
- CANFD_MSG_SIGNAL_COUNT = 67,
- /// CAN FD 报文信号名称索引
- CANFD_MSG_SIGNAL_NAME_INDEX = 68,
-
- /// 节点名称
- NODE_Name = 101,
- /// 节点发送 CAN 报文数量
- NODE_TX_CAN_COUNT = 103,
- /// 节点发送 CAN 报文索引
- NODE_TX_CAN_MESSAGE_INDEX = 104,
- /// 节点接收 CAN 报文数量
- NODE_RX_CAN_COUNT = 105,
- /// 节点接收 CAN 报文索引
- NODE_RX_CAN_MESSAGE_INDEX = 106,
- /// 节点发送 CAN FD 报文数量
- NODE_TX_CANFD_COUNT = 107,
- /// 节点发送 CAN FD 报文索引
- NODE_TX_CANFD_MESSAGE_INDEX = 108,
- /// 节点接收 CAN FD 报文数量
- NODE_RX_CANFD_COUNT = 109,
- /// 节点接收 CAN FD 报文索引
- NODE_RX_CANFD_MESSAGE_INDEX = 110,
- }
-
- public class DBCParse
- {
- public static List> MsgDatabase { get; set; } =
- [.. Enumerable.Range(0, 12).Select(_ => new List<_Msg_>())];
- public static can_network can_Network;
- public static string tsdb_get_can_db_info(uint ADatabaseId, int AType, int AIndex, int ASubIndex)
- {
- nint tmpInt = new nint();
- int ret = TsMasterApi.tsdb_get_can_db_info(ADatabaseId, AType, AIndex, ASubIndex, ref tmpInt);
- if (ret == 0)
- {
- return Marshal.PtrToStringAnsi(tmpInt) ?? "";
- }
- else
- return "";
- }
-
- public static void parse(uint Aid, int channel)
- {
- int CANcount = int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CAN_MSG_COUNT, 0, 0));
- for (int i = 0; i < CANcount; i++)
- {
- _Msg_ temp = new _Msg_();
- temp.msg_type = int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CAN_MSG_TYPE, i, 0));
- temp.msg_dlc = byte.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CAN_MSG_DLC, i, 0));
- temp.msg_id = int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CAN_MSG_ID, i, 0));
- temp.msg_name = tsdb_get_can_db_info(Aid, (int)DBCINFO.CAN_MSG_NAME, i, 0);
- temp.msg_cyclic = int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CAN_MSG_CYCLIC, i, 0));
- temp.signal_Name = new string[int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CAN_MSG_SIGNAL_COUNT, i, 0))];
- for (int signalcount = 0; signalcount < temp.signal_Name.Length; signalcount++)
- {
- temp.signal_Name[signalcount] = tsdb_get_can_db_info(Aid, (int)DBCINFO.SIGNAL_NAME, int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CAN_MSG_SIGNAL_NAME_INDEX, i, signalcount)), 0);
- }
- temp.msg_brs = 0;
- temp.ACANFD = new TLIBCANFD(APP_CHANNEL.CHN1,
- temp.msg_id,
- true,
- temp.msg_type == 1 || temp.msg_type == 4 ? true : false,
- false, temp.msg_dlc,
- temp.msg_type < 2 ? false : true,
- false);
- MsgDatabase[channel].Add(temp);
-
- }
-
- CANcount = int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CANFD_MSG_COUNT, 0, 0));
- for (int i = 0; i < CANcount; i++)
- {
- _Msg_ temp = new _Msg_();
- temp.msg_type = int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CANFD_MSG_TYPE, i, 0));
- temp.msg_dlc = byte.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CANFD_MSG_DLC, i, 0));
- temp.msg_id = int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CANFD_MSG_ID, i, 0));
- temp.msg_name = tsdb_get_can_db_info(Aid, (int)DBCINFO.CANFD_MSG_NAME, i, 0);
- temp.msg_cyclic = int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CANFD_MSG_CYCLIC, i, 0));
- temp.signal_Name = new string[int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CANFD_MSG_SIGNAL_COUNT, i, 0))];
- for (int signalcount = 0; signalcount < temp.signal_Name.Length; signalcount++)
- {
- temp.signal_Name[signalcount] = tsdb_get_can_db_info(Aid, (int)DBCINFO.SIGNAL_NAME, int.Parse(tsdb_get_can_db_info(Aid, (int)DBCINFO.CANFD_MSG_SIGNAL_NAME_INDEX, i, signalcount)), 0);
- }
- temp.msg_brs = int.Parse(tsdb_get_can_db_info(Aid, 69, i, 0));
- temp.ACANFD = new TLIBCANFD(APP_CHANNEL.CHN1, temp.msg_id, true, temp.msg_type == 1 || temp.msg_type == 4 ? true : false, false, temp.msg_dlc, temp.msg_type < 2 ? false : true, temp.msg_brs == 1 ? true : false);
- MsgDatabase[channel].Add(temp);
- }
- MsgDatabase[channel].Sort((a, b) => a.msg_id.CompareTo(b.msg_id));
- }
-
- public static void rbs_parse(uint AID, int channel)
- {
- can_Network = new can_network();
- can_Network.network_name = tsdb_get_can_db_info(AID, (int)DBCINFO.NETWORK_Name, 0, 0);
- int Node_count = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_COUNT, 0, 0));
- can_Network.can_nodes = new can_node[Node_count];
- for (int i = 0; i < Node_count; i++)
- {
- can_Network.can_nodes[i].node_name = tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_Name, i, 0);
- int tx_can_count = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_TX_CAN_COUNT, i, 0));
- int tx_canfd_count = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_TX_CANFD_COUNT, i, 0));
-
- int rx_can_count = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_RX_CAN_COUNT, i, 0));
- int rx_canfd_count = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_RX_CANFD_COUNT, i, 0));
-
- //获取tx_can结构体
- can_Network.can_nodes[i].tx_can_Messages = new can_message[tx_can_count + tx_canfd_count];
-
- can_Network.can_nodes[i].rx_can_Messages = new can_message[rx_can_count + rx_canfd_count];
- //获取报文名以及信号名
- //1 get can_message idnex
- //2 get can message name
- //3 get signal count
- //4 get signal name
- int tx_index = -1;
- for (int tx_can = 0; tx_can < tx_can_count; tx_can++)
- {
- int can_message_idnex = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_TX_CAN_MESSAGE_INDEX, i, tx_can));
- can_Network.can_nodes[i].tx_can_Messages[tx_can].message_name = tsdb_get_can_db_info(AID, (int)DBCINFO.CAN_MSG_NAME, can_message_idnex, 0);
-
- can_Network.can_nodes[i].tx_can_Messages[tx_can].signals = new string[int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.CAN_MSG_SIGNAL_COUNT, can_message_idnex, 0))];
- for (int signalcount = 0; signalcount < can_Network.can_nodes[i].tx_can_Messages[tx_can].signals.Length; signalcount++)
- {
- can_Network.can_nodes[i].tx_can_Messages[tx_can].signals[signalcount] = tsdb_get_can_db_info(AID, (int)DBCINFO.SIGNAL_NAME, int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.CAN_MSG_SIGNAL_NAME_INDEX, can_message_idnex, signalcount)), 0);
- }
-
- tx_index = tx_can;
- }
- for (int tx_can = 0; tx_can < tx_canfd_count; tx_can++, tx_index++)
- {
- int can_message_idnex = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_TX_CANFD_MESSAGE_INDEX, i, tx_can));
- can_Network.can_nodes[i].tx_can_Messages[tx_index + 1].message_name = tsdb_get_can_db_info(AID, (int)DBCINFO.CANFD_MSG_NAME, can_message_idnex, 0);
-
- can_Network.can_nodes[i].tx_can_Messages[tx_index + 1].signals = new string[int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.CANFD_MSG_SIGNAL_COUNT, can_message_idnex, 0))];
- for (int signalcount = 0; signalcount < can_Network.can_nodes[i].tx_can_Messages[tx_index + 1].signals.Length; signalcount++)
- {
- can_Network.can_nodes[i].tx_can_Messages[tx_index + 1].signals[signalcount] = tsdb_get_can_db_info(AID, (int)DBCINFO.SIGNAL_NAME, int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.CANFD_MSG_SIGNAL_NAME_INDEX, can_message_idnex, signalcount)), 0);
- }
- }
-
- int rx_index = -1;
- for (int tx_can = 0; tx_can < rx_can_count; tx_can++)
- {
- int can_message_idnex = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_RX_CAN_MESSAGE_INDEX, i, tx_can));
- can_Network.can_nodes[i].rx_can_Messages[tx_can].message_name = tsdb_get_can_db_info(AID, (int)DBCINFO.CAN_MSG_NAME, can_message_idnex, 0);
-
- can_Network.can_nodes[i].rx_can_Messages[tx_can].signals = new string[int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.CAN_MSG_SIGNAL_COUNT, can_message_idnex, 0))];
- for (int signalcount = 0; signalcount < can_Network.can_nodes[i].rx_can_Messages[tx_can].signals.Length; signalcount++)
- {
- can_Network.can_nodes[i].rx_can_Messages[tx_can].signals[signalcount] = tsdb_get_can_db_info(AID, (int)DBCINFO.SIGNAL_NAME, int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.CAN_MSG_SIGNAL_NAME_INDEX, can_message_idnex, signalcount)), 0);
- }
-
- rx_index = tx_can;
- }
- for (int tx_can = 0; tx_can < rx_canfd_count; tx_can++, rx_index++)
- {
- int can_message_idnex = int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.NODE_RX_CANFD_MESSAGE_INDEX, i, tx_can));
- can_Network.can_nodes[i].rx_can_Messages[rx_index + 1].message_name = tsdb_get_can_db_info(AID, (int)DBCINFO.CANFD_MSG_NAME, can_message_idnex, 0);
-
- can_Network.can_nodes[i].rx_can_Messages[rx_index + 1].signals = new string[int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.CANFD_MSG_SIGNAL_COUNT, can_message_idnex, 0))];
- for (int signalcount = 0; signalcount < can_Network.can_nodes[i].rx_can_Messages[rx_index + 1].signals.Length; signalcount++)
- {
- can_Network.can_nodes[i].rx_can_Messages[rx_index + 1].signals[signalcount] = tsdb_get_can_db_info(AID, (int)DBCINFO.SIGNAL_NAME, int.Parse(tsdb_get_can_db_info(AID, (int)DBCINFO.CANFD_MSG_SIGNAL_NAME_INDEX, can_message_idnex, signalcount)), 0);
- }
- }
- }
- }
- }
-
-
-}
diff --git a/CAN驱动/Interop.TSMasterAPI.dll b/CAN驱动/Interop.TSMasterAPI.dll
deleted file mode 100644
index 1d1400b..0000000
Binary files a/CAN驱动/Interop.TSMasterAPI.dll and /dev/null differ
diff --git a/CAN驱动/TSMaster.dll b/CAN驱动/TSMaster.dll
deleted file mode 100644
index a34dd33..0000000
Binary files a/CAN驱动/TSMaster.dll and /dev/null differ
diff --git a/DeviceCommand/Devices/N36600.cs b/DeviceCommand/Devices/N36600.cs
index ada9ade..a5a430f 100644
--- a/DeviceCommand/Devices/N36600.cs
+++ b/DeviceCommand/Devices/N36600.cs
@@ -172,7 +172,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 快捷设置电压电流(double 电压, double 电流, CancellationToken ct = default)
{
- string cmd = string.Format(CultureInfo.InvariantCulture, ":APPLY {0:F3},{1:F3}{2}", 电压, 电流, SCPIDelimiter);
+ // 修正:去除前缀冒号,规范应用 APPL 短格式
+ string cmd = string.Format(CultureInfo.InvariantCulture, "APPL {0:F3},{1:F3}{2}", 电压, 电流, SCPIDelimiter);
await SendAsync(cmd, ct);
}
@@ -181,7 +182,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 查询快捷电压电流设定(CancellationToken ct = default)
{
- return await WriteReadAsync($":APPLY?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号
+ return await WriteReadAsync($"APPL?{SCPIDelimiter}", SCPIDelimiter, ct);
}
#endregion
@@ -194,7 +196,8 @@ namespace DeviceCommand.Device
[Monitorable("低压直流电源电流")]
public virtual async Task 查询实际电流(CancellationToken ct = default)
{
- return await WriteReadAsync($":MEASure:CURRent?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号,改用标准 MEAS:CURR?
+ return await WriteReadAsync($"MEAS:CURR?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
@@ -203,16 +206,18 @@ namespace DeviceCommand.Device
[Monitorable("低压直流电源功率")]
public virtual async Task 查询实际功率(CancellationToken ct = default)
{
- return await WriteReadAsync($":MEASure:POWer?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号,改用标准 MEAS:POW?
+ return await WriteReadAsync($"MEAS:POW?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
/// 3.5.3 查询通道输出端子上测得的直流电压值 (V)
- ///
[Monitorable("低压直流电源电压")]
public virtual async Task 查询实际电压(CancellationToken ct = default)
{
- return await WriteReadAsync($":MEASure:VOLTage?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号,改用标准 MEAS:VOLT?
+ return await WriteReadAsync($"MEAS:VOLT?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
@@ -220,7 +225,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 查询电压电流功率数组(CancellationToken ct = default)
{
- return await WriteReadAsync($":MEASure:VAP?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号
+ return await WriteReadAsync($"MEAS:VAP?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
@@ -228,7 +234,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 查询测得电池容量(CancellationToken ct = default)
{
- return await WriteReadAsync($":MEASure:CAPAcity?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号
+ return await WriteReadAsync($"MEAS:CAP?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
@@ -236,7 +243,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 查询恒流输出时间长度(CancellationToken ct = default)
{
- return await WriteReadAsync($":MEASure:TIMEr:CC?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号
+ return await WriteReadAsync($"MEAS:TIM:CC?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
@@ -244,7 +252,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 查询总输出时间长度(CancellationToken ct = default)
{
- return await WriteReadAsync($":MEASure:TIME:OUTPut?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号
+ return await WriteReadAsync($"MEAS:TIME:OUTP?{SCPIDelimiter}", SCPIDelimiter, ct);
}
#endregion
@@ -256,8 +265,9 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置DC输出(bool 开启, CancellationToken ct = default)
{
+ // 修正:去除前缀冒号,改用 OUTP 短格式
string 状态 = 开启 ? "ON" : "OFF";
- await SendAsync($":OUTPut {状态}{SCPIDelimiter}", ct);
+ await SendAsync($"OUTP {状态}{SCPIDelimiter}", ct);
}
///
@@ -265,7 +275,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 查询DC输出状态(CancellationToken ct = default)
{
- return await WriteReadAsync($":OUTPut?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号
+ return await WriteReadAsync($"OUTP?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
@@ -273,8 +284,9 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置定时器状态(bool 开启, CancellationToken ct = default)
{
+ // 修正:去除前缀冒号
string 状态 = 开启 ? "ON" : "OFF";
- await SendAsync($":OUTPut:TIMEr {状态}{SCPIDelimiter}", ct);
+ await SendAsync($"OUTP:TIM {状态}{SCPIDelimiter}", ct);
}
///
@@ -282,7 +294,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置定时器时间(double 秒数, CancellationToken ct = default)
{
- string cmd = string.Format(CultureInfo.InvariantCulture, ":OUTPut:TIMEr:DATA {0:F1}{1}", 秒数, SCPIDelimiter);
+ // 修正:去除前缀冒号
+ string cmd = string.Format(CultureInfo.InvariantCulture, "OUTP:TIM:DATA {0:F1}{1}", 秒数, SCPIDelimiter);
await SendAsync(cmd, ct);
}
@@ -291,8 +304,9 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置输出模式优先(bool 是CV优先, CancellationToken ct = default)
{
+ // 修正:去除前缀冒号
string 模式 = 是CV优先 ? "CV" : "CC";
- await SendAsync($":OUTPut:MODE {模式}{SCPIDelimiter}", ct);
+ await SendAsync($"OUTP:MODE {模式}{SCPIDelimiter}", ct);
}
#endregion
@@ -304,7 +318,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 清除电流保护状态(CancellationToken ct = default)
{
- await SendAsync($":CURRent:PROTection:CLEar{SCPIDelimiter}", ct);
+ // 修正:去除前缀冒号
+ await SendAsync($"CURR:PROT:CLE{SCPIDelimiter}", ct);
}
///
@@ -312,8 +327,9 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置电流保护使能(bool 启用, CancellationToken ct = default)
{
+ // 修正:去除前缀冒号,将 STATE 改为更常用的 STAT 简写
string 状态 = 启用 ? "ON" : "OFF";
- await SendAsync($":CURRent:PROTection:STATE {状态}{SCPIDelimiter}", ct);
+ await SendAsync($"CURR:PROT:STAT {状态}{SCPIDelimiter}", ct);
}
///
@@ -321,7 +337,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置过流保护值(double 电流, CancellationToken ct = default)
{
- string cmd = string.Format(CultureInfo.InvariantCulture, ":CURRent:PROTection {0:F3}{1}", 电流, SCPIDelimiter);
+ // 修正:去除前缀冒号。按 NGI 通用指令树,加上层级限制或者直接作用于 CURR:PROT
+ string cmd = string.Format(CultureInfo.InvariantCulture, "CURR:PROT {0:F3}{1}", 电流, SCPIDelimiter);
await SendAsync(cmd, ct);
}
@@ -330,7 +347,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置电流(double 电流, CancellationToken ct = default)
{
- string cmd = string.Format(CultureInfo.InvariantCulture, ":CURRent {0:F3}{1}", 电流, SCPIDelimiter);
+ // 修正:去除前缀冒号,改用标准 CURR 短格式
+ string cmd = string.Format(CultureInfo.InvariantCulture, "CURR {0:F3}{1}", 电流, SCPIDelimiter);
await SendAsync(cmd, ct);
}
@@ -339,7 +357,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 清除电压保护状态(CancellationToken ct = default)
{
- await SendAsync($":VOLTage:PROTection:CLEar{SCPIDelimiter}", ct);
+ // 修正:去除前缀冒号
+ await SendAsync($"VOLT:PROT:CLE{SCPIDelimiter}", ct);
}
///
@@ -347,8 +366,9 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置电压保护使能(bool 启用, CancellationToken ct = default)
{
+ // 修正:去除前缀冒号
string 状态 = 启用 ? "ON" : "OFF";
- await SendAsync($":VOLTage:PROTection:STATE {状态}{SCPIDelimiter}", ct);
+ await SendAsync($"VOLT:PROT:STAT {状态}{SCPIDelimiter}", ct);
}
///
@@ -356,7 +376,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置过压保护值(double 电压, CancellationToken ct = default)
{
- string cmd = string.Format(CultureInfo.InvariantCulture, ":VOLTage:PROTection {0:F3}{1}", 电压, SCPIDelimiter);
+ // 修正:去除前缀冒号
+ string cmd = string.Format(CultureInfo.InvariantCulture, "VOLT:PROT {0:F3}{1}", 电压, SCPIDelimiter);
await SendAsync(cmd, ct);
}
@@ -365,7 +386,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置电压(double 电压, CancellationToken ct = default)
{
- string cmd = string.Format(CultureInfo.InvariantCulture, ":VOLTage {0:F3}{1}", 电压, SCPIDelimiter);
+ // 修正:去除前缀冒号,改用标准 VOLT 短格式
+ string cmd = string.Format(CultureInfo.InvariantCulture, "VOLT {0:F3}{1}", 电压, SCPIDelimiter);
await SendAsync(cmd, ct);
}
@@ -374,7 +396,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置电压上限限制(double 电压, CancellationToken ct = default)
{
- string cmd = string.Format(CultureInfo.InvariantCulture, ":VOLTage:LIMIT {0:F3}{1}", 电压, SCPIDelimiter);
+ // 修正:去除前缀冒号
+ string cmd = string.Format(CultureInfo.InvariantCulture, "VOLT:LIM {0:F3}{1}", 电压, SCPIDelimiter);
await SendAsync(cmd, ct);
}
@@ -383,7 +406,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置功率(double 功率, CancellationToken ct = default)
{
- string cmd = string.Format(CultureInfo.InvariantCulture, ":POWer {0:F3}{1}", 功率, SCPIDelimiter);
+ // 修正:去除前缀冒号,改用标准 POW 短格式
+ string cmd = string.Format(CultureInfo.InvariantCulture, "POW {0:F3}{1}", 功率, SCPIDelimiter);
await SendAsync(cmd, ct);
}
@@ -392,8 +416,9 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置恒功率输出使能(bool 启用, CancellationToken ct = default)
{
+ // 修正:去除前缀冒号
string 状态 = 启用 ? "ON" : "OFF";
- await SendAsync($":POWer:STATE {状态}{SCPIDelimiter}", ct);
+ await SendAsync($"POW:STAT {状态}{SCPIDelimiter}", ct);
}
#endregion
@@ -405,8 +430,9 @@ namespace DeviceCommand.Device
///
public virtual async Task 设置蜂鸣器状态(bool 开启, CancellationToken ct = default)
{
+ // 修正:去除前缀冒号
string 状态 = 开启 ? "ON" : "OFF";
- await SendAsync($":SYSTem:BEEPer:STATE {状态}{SCPIDelimiter}", ct);
+ await SendAsync($"SYST:BEEP:STAT {状态}{SCPIDelimiter}", ct);
}
///
@@ -414,7 +440,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 蜂鸣器鸣叫(CancellationToken ct = default)
{
- await SendAsync($":SYSTem:BEEPer{SCPIDelimiter}", ct);
+ // 修正:去除前缀冒号
+ await SendAsync($"SYST:BEEP{SCPIDelimiter}", ct);
}
///
@@ -422,7 +449,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 查询错误记录数量(CancellationToken ct = default)
{
- return await WriteReadAsync($":SYSTem:ERRor:COUNT?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号
+ return await WriteReadAsync($"SYST:ERR:COUN?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
@@ -430,7 +458,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 查询错误信息(CancellationToken ct = default)
{
- return await WriteReadAsync($":SYSTem:ERRor?{SCPIDelimiter}", SCPIDelimiter, ct);
+ // 修正:去除前缀冒号
+ return await WriteReadAsync($"SYST:ERR?{SCPIDelimiter}", SCPIDelimiter, ct);
}
///
@@ -438,7 +467,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 切换本地控制模式(CancellationToken ct = default)
{
- await SendAsync($":SYSTem:LOCal{SCPIDelimiter}", ct);
+ // 修正:去除前缀冒号
+ await SendAsync($"SYST:LOC{SCPIDelimiter}", ct);
}
///
@@ -446,7 +476,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 切换远程控制模式(CancellationToken ct = default)
{
- await SendAsync($":SYSTem:REMote{SCPIDelimiter}", ct);
+ // 修正:去除前缀冒号
+ await SendAsync($"SYST:REM{SCPIDelimiter}", ct);
}
///
@@ -454,7 +485,8 @@ namespace DeviceCommand.Device
///
public virtual async Task 远程控制模式锁定(CancellationToken ct = default)
{
- await SendAsync($":SYSTem:RWLock{SCPIDelimiter}", ct);
+ // 修正:去除前缀冒号
+ await SendAsync($"SYST:RWL{SCPIDelimiter}", ct);
}
#endregion
diff --git a/MonitorModule/ViewModels/MonitorViewModel.cs b/MonitorModule/ViewModels/MonitorViewModel.cs
index 091fb83..7d7778c 100644
--- a/MonitorModule/ViewModels/MonitorViewModel.cs
+++ b/MonitorModule/ViewModels/MonitorViewModel.cs
@@ -182,12 +182,14 @@ namespace MonitorModule.ViewModels
channel.Record(time, args.Value);
// 入队数据库批量写入
+ // CreateTime 使用 args.Time(采样触发时刻),而不是 DateTime.Now(设备响应到达时刻),
+ // 这样即使设备响应有延迟,数据库里的时间戳仍然按设定采样间隔分布。
var entity = new MonitorValueEntity
{
MonitorName = channel.DisplayName,
MonitorValue = args.Value,
Scope = args.Scope,
- CreateTime = DateTime.Now,
+ CreateTime = args.Time,
IsDel = 0
};
_insertQueue.Enqueue(entity);
diff --git a/MonitorModule/ViewModels/RecordViewModel.cs b/MonitorModule/ViewModels/RecordViewModel.cs
index ca39e72..1b1d886 100644
--- a/MonitorModule/ViewModels/RecordViewModel.cs
+++ b/MonitorModule/ViewModels/RecordViewModel.cs
@@ -1,8 +1,13 @@
-using Logger;
+using Common.Attributes;
+using DeviceCommand.Base;
+using Logger;
+using Model.Entity;
+using ORM;
using SqlSugar;
using System.Collections.ObjectModel;
using System.Data;
using System.IO;
+using System.Reflection;
using System.Text;
using System.Windows.Input;
using UIShare.GlobalVariable;
@@ -12,9 +17,9 @@ using UIShare.ViewModelBase;
namespace MonitorModule.ViewModels
{
///
- /// 记录界面:用于查看运行目录下 SQL/ADP.db 中的数据。
- /// 功能:表选择 / 关键字 WHERE 查询 / 分页 / 导出 CSV。
- /// 仍延续 ScopedContext 隔离 + 双击展开 的范式,每个工位独立一份查询状态。
+ /// 记录界面:查询 MonitorValueEntity 表中的历史监测数据。
+ /// 功能:监测项筛选 / 台架筛选 / 日期筛选 / 分页 / 导出 CSV。
+ /// 使用 SqlSugarContext.DbContext 全局单例,与写入端共用同一数据库连接。
///
public class RecordViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable
{
@@ -30,30 +35,39 @@ namespace MonitorModule.ViewModels
set => SetProperty(ref _testStatus, value);
}
- public ObservableCollection TableNames
+ /// 监测项名称下拉列表
+ public ObservableCollection MonitorNames
{
- get => _tableNames;
- set => SetProperty(ref _tableNames, value);
+ get => _monitorNames;
+ set => SetProperty(ref _monitorNames, value);
}
- public string? SelectedTable
+ /// 选中的监测项(null = 全部)
+ public string? SelectedMonitorName
{
- get => _selectedTable;
- set
- {
- if (SetProperty(ref _selectedTable, value))
- {
- PageIndex = 1;
- Query();
- }
- }
+ get => _selectedMonitorName;
+ set => SetProperty(ref _selectedMonitorName, value);
}
- // 用户填写的 WHERE 子句(不带 WHERE 关键字),例如:Status='OK' AND Id>10
- public string WhereClause
+ /// 台架(作用域)下拉列表
+ public ObservableCollection ScopeNames
{
- get => _whereClause;
- set => SetProperty(ref _whereClause, value);
+ get => _scopeNames;
+ set => SetProperty(ref _scopeNames, value);
+ }
+
+ /// 选中的台架(null = 全部)
+ public string? SelectedScope
+ {
+ get => _selectedScope;
+ set => SetProperty(ref _selectedScope, value);
+ }
+
+ /// 查询日期(null = 全部日期)
+ public DateTime? SelectedDate
+ {
+ get => _selectedDate;
+ set => SetProperty(ref _selectedDate, value);
}
public DataTable ResultTable
@@ -111,40 +125,38 @@ namespace MonitorModule.ViewModels
#region 命令
public ICommand LoadedCommand { get; }
- public ICommand RefreshTablesCommand { get; }
public ICommand QueryCommand { get; }
+ public ICommand ClearFilterCommand { get; }
public ICommand FirstPageCommand { get; }
public ICommand PrevPageCommand { get; }
public ICommand NextPageCommand { get; }
public ICommand LastPageCommand { get; }
public ICommand ExportCsvCommand { get; }
- // 双击展开/折叠:与 MonitorView/AutomatedTestingView 共用
public ICommand RefreshCommand { get; }
#endregion
+
#region 私有字段
- // 数据库相对路径:运行目录\SQL\ADP.db(数据库未就绪时容错处理,不抛异常)
- private static readonly string DbFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SQL");
- private static readonly string DbPath = Path.Combine(DbFolder, "ADP.db");
- private static readonly string ConnStr = $"Data Source={DbPath};Version=3;";
- private bool IsInitiated = false;
private IScopedProvider _scope;
private string _testStatus = string.Empty;
- private ObservableCollection _tableNames = new();
- private string? _selectedTable;
- private string _whereClause = string.Empty;
+ private ObservableCollection _monitorNames = new();
+ private string? _selectedMonitorName;
+ private ObservableCollection _scopeNames = new(new[] { "全部", "TestCell1", "TestCell2", "TestCell3", "TestCell4", "TestCell5", "TestCell6", "TestCell7", "TestCell8" });
+ private string? _selectedScope = "全部";
+ private DateTime? _selectedDate;
private DataTable _resultTable = new();
private string _statusMessage = "未连接";
private int _pageIndex = 1;
private int _pageSize = 50;
private long _totalCount;
+ private bool IsInitiated = false;
#endregion
public RecordViewModel(IContainerExtension container) : base(container)
{
_globalInfo = container.Resolve();
- LoadedCommand = new DelegateCommand(LoadTables);
- RefreshTablesCommand = new DelegateCommand(LoadTables);
+ LoadedCommand = new DelegateCommand(LoadFilterOptions);
QueryCommand = new DelegateCommand(() => { PageIndex = 1; Query(); });
+ ClearFilterCommand = new DelegateCommand(ClearFilter);
FirstPageCommand = new DelegateCommand(() => { if (PageIndex > 1) { PageIndex = 1; Query(); } });
PrevPageCommand = new DelegateCommand(() => { if (PageIndex > 1) { PageIndex--; Query(); } });
NextPageCommand = new DelegateCommand(() => { if (PageIndex < TotalPages) { PageIndex++; Query(); } });
@@ -158,105 +170,136 @@ namespace MonitorModule.ViewModels
_scope?.Dispose();
}
- #region 数据库操作
- private SqlSugarClient CreateClient()
+ #region 筛选条件加载
+ ///
+ /// 加载筛选条件:监测项通过反射发现(与 MonitorViewModel 一致),台架从数据库查询。
+ ///
+ private void LoadFilterOptions()
{
- return new SqlSugarClient(new ConnectionConfig
- {
- DbType = SqlSugar.DbType.Sqlite,
- ConnectionString = ConnStr,
- IsAutoCloseConnection = true,
- InitKeyType = InitKeyType.Attribute
- });
+ // 监测项:反射发现当前作用域所有带 [Monitorable] 的设备方法
+ DiscoverMonitorNames();
+
+ Query();
}
///
- /// 读取数据库中的所有用户表。数据库不存在时不报错,仅在状态栏提示。
+ /// 反射扫描当前作用域 DeviceManager 中所有带 [Monitorable] 特性的设备方法,
+ /// 生成与 MonitorViewModel 完全一致的 DisplayName 列表,填充到下拉框。
+ /// 这样即使数据库还没数据,用户也能看到所有可筛选的监测项。
///
- private void LoadTables()
+ private void DiscoverMonitorNames()
{
+ MonitorNames = new ObservableCollection();
+
+ if (_scope == null) return;
+
try
{
- if (!Directory.Exists(DbFolder)) Directory.CreateDirectory(DbFolder);
- if (!File.Exists(DbPath))
+ var deviceManager = _scope.Resolve();
+ if (deviceManager?.DeviceMap == null || deviceManager.DeviceMap.Count == 0)
{
- TableNames = new ObservableCollection();
- SelectedTable = null;
- ResultTable = new DataTable();
- TotalCount = 0;
- StatusMessage = $"数据库尚未创建:{DbPath}";
+ StatusMessage = "当前工位无可用设备";
return;
}
- using var db = CreateClient();
- var tables = db.DbMaintenance.GetTableInfoList(false)
- .Select(t => t.Name)
- .OrderBy(n => n)
- .ToList();
+ // 构建 设备实例 → 硬件指纹 的反向查找表
+ var instanceToFp = new Dictionary