fix bugs; add mqtt config
This commit is contained in:
parent
d21391fb0c
commit
64b0f0cd23
105
Form1.Designer.cs
generated
105
Form1.Designer.cs
generated
@ -31,14 +31,7 @@ partial class Form1
|
||||
private System.Windows.Forms.ComboBox comboBoxSpectrometerPort;
|
||||
private System.Windows.Forms.Label labelSpectrometerPort;
|
||||
private System.Windows.Forms.GroupBox groupBoxMQTT;
|
||||
private System.Windows.Forms.TextBox textBoxDeviceSecret;
|
||||
private System.Windows.Forms.Label labelDeviceSecret;
|
||||
private System.Windows.Forms.TextBox textBoxDeviceName;
|
||||
private System.Windows.Forms.Label labelDeviceName;
|
||||
private System.Windows.Forms.TextBox textBoxTopicRoot;
|
||||
private System.Windows.Forms.Label labelTopicRoot;
|
||||
private System.Windows.Forms.TextBox textBoxProductKey;
|
||||
private System.Windows.Forms.Label labelProductKey;
|
||||
private System.Windows.Forms.Label labelMqttStatus;
|
||||
private System.Windows.Forms.Button buttonStartStop;
|
||||
private System.Windows.Forms.TextBox textBoxLog;
|
||||
private System.Windows.Forms.Label labelLog;
|
||||
@ -58,14 +51,7 @@ partial class Form1
|
||||
this.comboBoxSpectrometerPort = new System.Windows.Forms.ComboBox();
|
||||
this.labelSpectrometerPort = new System.Windows.Forms.Label();
|
||||
this.groupBoxMQTT = new System.Windows.Forms.GroupBox();
|
||||
this.textBoxDeviceSecret = new System.Windows.Forms.TextBox();
|
||||
this.labelDeviceSecret = new System.Windows.Forms.Label();
|
||||
this.textBoxDeviceName = new System.Windows.Forms.TextBox();
|
||||
this.labelDeviceName = new System.Windows.Forms.Label();
|
||||
this.textBoxTopicRoot = new System.Windows.Forms.TextBox();
|
||||
this.labelTopicRoot = new System.Windows.Forms.Label();
|
||||
this.textBoxProductKey = new System.Windows.Forms.TextBox();
|
||||
this.labelProductKey = new System.Windows.Forms.Label();
|
||||
this.labelMqttStatus = new System.Windows.Forms.Label();
|
||||
this.buttonStartStop = new System.Windows.Forms.Button();
|
||||
this.textBoxLog = new System.Windows.Forms.TextBox();
|
||||
this.labelLog = new System.Windows.Forms.Label();
|
||||
@ -154,88 +140,23 @@ partial class Form1
|
||||
//
|
||||
// groupBoxMQTT
|
||||
//
|
||||
this.groupBoxMQTT.Controls.Add(this.textBoxDeviceSecret);
|
||||
this.groupBoxMQTT.Controls.Add(this.labelDeviceSecret);
|
||||
this.groupBoxMQTT.Controls.Add(this.textBoxDeviceName);
|
||||
this.groupBoxMQTT.Controls.Add(this.labelDeviceName);
|
||||
this.groupBoxMQTT.Controls.Add(this.textBoxTopicRoot);
|
||||
this.groupBoxMQTT.Controls.Add(this.labelTopicRoot);
|
||||
this.groupBoxMQTT.Controls.Add(this.textBoxProductKey);
|
||||
this.groupBoxMQTT.Controls.Add(this.labelProductKey);
|
||||
this.groupBoxMQTT.Controls.Add(this.labelMqttStatus);
|
||||
this.groupBoxMQTT.Location = new System.Drawing.Point(500, 12);
|
||||
this.groupBoxMQTT.Name = "groupBoxMQTT";
|
||||
this.groupBoxMQTT.Size = new System.Drawing.Size(300, 150);
|
||||
this.groupBoxMQTT.Size = new System.Drawing.Size(300, 60);
|
||||
this.groupBoxMQTT.TabIndex = 2;
|
||||
this.groupBoxMQTT.TabStop = false;
|
||||
this.groupBoxMQTT.Text = "MQTT设置";
|
||||
this.groupBoxMQTT.Text = "MQTT状态";
|
||||
//
|
||||
// textBoxDeviceSecret
|
||||
// labelMqttStatus
|
||||
//
|
||||
this.textBoxDeviceSecret.Location = new System.Drawing.Point(100, 115);
|
||||
this.textBoxDeviceSecret.Name = "textBoxDeviceSecret";
|
||||
this.textBoxDeviceSecret.Size = new System.Drawing.Size(190, 27);
|
||||
this.textBoxDeviceSecret.TabIndex = 7;
|
||||
this.textBoxDeviceSecret.Text = "1031a49a4f61c29a086f79b41ed971c7";
|
||||
//
|
||||
// labelDeviceSecret
|
||||
//
|
||||
this.labelDeviceSecret.AutoSize = true;
|
||||
this.labelDeviceSecret.Location = new System.Drawing.Point(6, 118);
|
||||
this.labelDeviceSecret.Name = "labelDeviceSecret";
|
||||
this.labelDeviceSecret.Size = new System.Drawing.Size(88, 20);
|
||||
this.labelDeviceSecret.TabIndex = 6;
|
||||
this.labelDeviceSecret.Text = "设备密钥:";
|
||||
//
|
||||
// textBoxDeviceName
|
||||
//
|
||||
this.textBoxDeviceName.Location = new System.Drawing.Point(100, 85);
|
||||
this.textBoxDeviceName.Name = "textBoxDeviceName";
|
||||
this.textBoxDeviceName.Size = new System.Drawing.Size(190, 27);
|
||||
this.textBoxDeviceName.TabIndex = 5;
|
||||
this.textBoxDeviceName.Text = "PubDevice";
|
||||
//
|
||||
// labelDeviceName
|
||||
//
|
||||
this.labelDeviceName.AutoSize = true;
|
||||
this.labelDeviceName.Location = new System.Drawing.Point(6, 88);
|
||||
this.labelDeviceName.Name = "labelDeviceName";
|
||||
this.labelDeviceName.Size = new System.Drawing.Size(88, 20);
|
||||
this.labelDeviceName.TabIndex = 4;
|
||||
this.labelDeviceName.Text = "设备名称:";
|
||||
//
|
||||
// textBoxTopicRoot
|
||||
//
|
||||
this.textBoxTopicRoot.Location = new System.Drawing.Point(100, 55);
|
||||
this.textBoxTopicRoot.Name = "textBoxTopicRoot";
|
||||
this.textBoxTopicRoot.Size = new System.Drawing.Size(190, 27);
|
||||
this.textBoxTopicRoot.TabIndex = 3;
|
||||
this.textBoxTopicRoot.Text = "a10inDdCRS6";
|
||||
//
|
||||
// labelTopicRoot
|
||||
//
|
||||
this.labelTopicRoot.AutoSize = true;
|
||||
this.labelTopicRoot.Location = new System.Drawing.Point(6, 58);
|
||||
this.labelTopicRoot.Name = "labelTopicRoot";
|
||||
this.labelTopicRoot.Size = new System.Drawing.Size(88, 20);
|
||||
this.labelTopicRoot.TabIndex = 2;
|
||||
this.labelTopicRoot.Text = "主题根路径:";
|
||||
//
|
||||
// textBoxProductKey
|
||||
//
|
||||
this.textBoxProductKey.Location = new System.Drawing.Point(100, 25);
|
||||
this.textBoxProductKey.Name = "textBoxProductKey";
|
||||
this.textBoxProductKey.Size = new System.Drawing.Size(190, 27);
|
||||
this.textBoxProductKey.TabIndex = 1;
|
||||
this.textBoxProductKey.Text = "gfcq950RDqt";
|
||||
//
|
||||
// labelProductKey
|
||||
//
|
||||
this.labelProductKey.AutoSize = true;
|
||||
this.labelProductKey.Location = new System.Drawing.Point(6, 28);
|
||||
this.labelProductKey.Name = "labelProductKey";
|
||||
this.labelProductKey.Size = new System.Drawing.Size(88, 20);
|
||||
this.labelProductKey.TabIndex = 0;
|
||||
this.labelProductKey.Text = "产品密钥:";
|
||||
this.labelMqttStatus.AutoSize = true;
|
||||
this.labelMqttStatus.Location = new System.Drawing.Point(6, 25);
|
||||
this.labelMqttStatus.Name = "labelMqttStatus";
|
||||
this.labelMqttStatus.Size = new System.Drawing.Size(69, 20);
|
||||
this.labelMqttStatus.TabIndex = 0;
|
||||
this.labelMqttStatus.Text = "未连接";
|
||||
this.labelMqttStatus.ForeColor = System.Drawing.Color.Red;
|
||||
//
|
||||
// buttonStartStop
|
||||
//
|
||||
|
381
Form1.cs
381
Form1.cs
@ -18,13 +18,24 @@ using aiot_paho_csharp;
|
||||
|
||||
namespace sscom_sender
|
||||
{
|
||||
public class MqttConfig
|
||||
{
|
||||
public string? ProductKey { get; set; }
|
||||
public string? Topic { get; set; }
|
||||
public string? DeviceName { get; set; }
|
||||
public string? DeviceSecret { get; set; }
|
||||
public string? Broker { get; set; }
|
||||
public int Port { get; set; }
|
||||
public bool UseSsl { get; set; }
|
||||
}
|
||||
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
private SerialPort gpsPort;
|
||||
private SerialPort spectrometerPort;
|
||||
private MqttClient mqttClient;
|
||||
private SerialPort? gpsPort;
|
||||
private SerialPort? spectrometerPort;
|
||||
private MqttClient? mqttClient;
|
||||
private bool isRunning = false;
|
||||
private string logFileName;
|
||||
private string? logFileName;
|
||||
|
||||
// 数据队列
|
||||
private ConcurrentQueue<GPSData> gpsDataQueue = new ConcurrentQueue<GPSData>();
|
||||
@ -32,11 +43,11 @@ namespace sscom_sender
|
||||
private ConcurrentQueue<string> logQueue = new ConcurrentQueue<string>();
|
||||
|
||||
// 线程控制
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private Task gpsTask;
|
||||
private Task spectrometerTask;
|
||||
private Task mqttTask;
|
||||
private Task logTask;
|
||||
private CancellationTokenSource? cancellationTokenSource;
|
||||
private Task? gpsTask;
|
||||
private Task? spectrometerTask;
|
||||
private Task? mqttTask;
|
||||
private Task? logTask;
|
||||
|
||||
// 数据缓冲区
|
||||
private StringBuilder gpsBuffer = new StringBuilder();
|
||||
@ -53,9 +64,19 @@ namespace sscom_sender
|
||||
// 初始化串口列表
|
||||
RefreshSerialPorts();
|
||||
|
||||
// 加载MQTT配置
|
||||
LoadMqttConfig();
|
||||
// 用异步的方式InitializeMQTT();
|
||||
// 初始化MQTT连接
|
||||
_ = Task.Run(() => InitializeMQTT());
|
||||
|
||||
// 创建日志文件名
|
||||
logFileName = Path.Combine(Application.StartupPath, "logs", $"log_{DateTime.Now:yyyyMMdd_HHmmss}.txt");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(logFileName));
|
||||
string? logDir = Path.GetDirectoryName(logFileName);
|
||||
if (!string.IsNullOrEmpty(logDir))
|
||||
{
|
||||
_ = Directory.CreateDirectory(logDir);
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshSerialPorts()
|
||||
@ -66,8 +87,8 @@ namespace sscom_sender
|
||||
|
||||
foreach (string port in ports)
|
||||
{
|
||||
comboBoxGPSPort.Items.Add(port);
|
||||
comboBoxSpectrometerPort.Items.Add(port);
|
||||
_ = comboBoxGPSPort.Items.Add(port);
|
||||
_ = comboBoxSpectrometerPort.Items.Add(port);
|
||||
}
|
||||
|
||||
if (ports.Length > 0)
|
||||
@ -116,7 +137,7 @@ namespace sscom_sender
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"启动失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
_ = MessageBox.Show($"启动失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,26 +152,38 @@ namespace sscom_sender
|
||||
buttonStartStop.Text = "开始";
|
||||
buttonStartStop.BackColor = SystemColors.Control;
|
||||
LogMessage("正在停止数据采集...");
|
||||
|
||||
|
||||
// 异步等待任务完成,避免阻塞UI线程
|
||||
Task.Run(() =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// 给任务一些时间优雅退出
|
||||
var tasks = new[] { gpsTask, spectrometerTask, mqttTask, logTask }.Where(t => t != null).ToArray();
|
||||
var tasks = new[] { gpsTask, spectrometerTask, mqttTask, logTask }
|
||||
.Where(t => t != null)
|
||||
.Cast<Task>()
|
||||
.ToArray();
|
||||
if (tasks.Length > 0)
|
||||
{
|
||||
Task.WaitAll(tasks, 2000); // 减少等待时间到2秒
|
||||
_ = Task.WaitAll(tasks, 2000); // 减少等待时间到2秒
|
||||
}
|
||||
|
||||
|
||||
// 关闭串口
|
||||
try { gpsPort?.Close(); } catch { }
|
||||
try { spectrometerPort?.Close(); } catch { }
|
||||
|
||||
|
||||
// 断开MQTT
|
||||
try { mqttClient?.Disconnect(); } catch { }
|
||||
|
||||
try
|
||||
{
|
||||
if (mqttClient != null)
|
||||
{
|
||||
mqttClient.Disconnect();
|
||||
mqttClient = null;
|
||||
this.Invoke(new Action(() => UpdateMqttStatus("未连接", false)));
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// 在UI线程上更新状态
|
||||
this.Invoke(new Action(() =>
|
||||
{
|
||||
@ -198,9 +231,68 @@ namespace sscom_sender
|
||||
}
|
||||
LogMessage("谱仪端口已打开");
|
||||
// 发送谱仪开始命令
|
||||
spectrometerPort.DiscardInBuffer();
|
||||
spectrometerPort.Write("$start\r\n");
|
||||
spectrometerPort.ReadTimeout = 1500;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private MqttConfig? mqttConfig;
|
||||
|
||||
private void LoadMqttConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
string configPath = Path.Combine(Application.StartupPath, "mqtt_config.json");
|
||||
LogMessage($"加载MQTT配置文件: {configPath}");
|
||||
if (File.Exists(configPath))
|
||||
{
|
||||
string json = File.ReadAllText(configPath);
|
||||
var config = JsonConvert.DeserializeObject<MqttConfig>(json);
|
||||
if (config != null)
|
||||
{
|
||||
mqttConfig = config;
|
||||
LogMessage("MQTT配置已加载");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage("MQTT配置文件内容无效,使用默认配置");
|
||||
mqttConfig = new MqttConfig
|
||||
{
|
||||
ProductKey = "gfcq950RDqt",
|
||||
Topic = "/gfcq950RDqt/PubDevice/user/update",
|
||||
DeviceName = "PubDevice",
|
||||
DeviceSecret = "1031a49a4f61c29a086f79b41ed971c7",
|
||||
Broker = "iot-06z00jfiubx584v.mqtt.iothub.aliyuncs.com",
|
||||
Port = 1883,
|
||||
UseSsl = true
|
||||
};
|
||||
string defaultJson = JsonConvert.SerializeObject(mqttConfig, Formatting.Indented);
|
||||
File.WriteAllText(configPath, defaultJson);
|
||||
LogMessage("已创建默认MQTT配置文件");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage("MQTT配置文件不存在,使用默认配置");
|
||||
mqttConfig = new MqttConfig
|
||||
{
|
||||
ProductKey = "gfcq950RDqt",
|
||||
Topic = "/gfcq950RDqt/PubDevice/user/update",
|
||||
DeviceName = "PubDevice",
|
||||
DeviceSecret = "1031a49a4f61c29a086f79b41ed971c7",
|
||||
Broker = "iot-06z00jfiubx584v.mqtt.iothub.aliyuncs.com",
|
||||
Port = 1883,
|
||||
UseSsl = true
|
||||
};
|
||||
// 保存默认配置到文件
|
||||
string json = JsonConvert.SerializeObject(mqttConfig, Formatting.Indented);
|
||||
File.WriteAllText(configPath, json);
|
||||
LogMessage("已创建默认MQTT配置文件");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage($"加载MQTT配置失败: {ex.Message}");
|
||||
mqttConfig = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,33 +300,62 @@ namespace sscom_sender
|
||||
{
|
||||
try
|
||||
{
|
||||
string productKey = textBoxProductKey.Text;
|
||||
string topicRoot = textBoxTopicRoot.Text;
|
||||
string deviceName = textBoxDeviceName.Text;
|
||||
string deviceSecret = textBoxDeviceSecret.Text;
|
||||
if (mqttConfig == null)
|
||||
{
|
||||
LogMessage("MQTT配置未加载,跳过MQTT连接");
|
||||
UpdateMqttStatus("配置未加载", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(mqttConfig.ProductKey) ||
|
||||
string.IsNullOrEmpty(mqttConfig.DeviceName) ||
|
||||
string.IsNullOrEmpty(mqttConfig.DeviceSecret))
|
||||
{
|
||||
LogMessage("MQTT配置项 ProductKey、DeviceName 或 DeviceSecret 为空,无法连接MQTT");
|
||||
UpdateMqttStatus("配置项缺失", false);
|
||||
return;
|
||||
}
|
||||
|
||||
MqttSign sign = new MqttSign();
|
||||
sign.calculate(productKey, deviceName, deviceSecret);
|
||||
|
||||
string broker = productKey + ".iot-as-mqtt.cn-shanghai.aliyuncs.com";
|
||||
mqttClient = new MqttClient(broker, 1883, true, null, null, MqttSslProtocols.TLSv1_2);
|
||||
mqttClient.Connect(sign.getClientid(), sign.getUsername(), sign.getPassword());
|
||||
|
||||
_ = sign.calculate(mqttConfig.ProductKey, mqttConfig.DeviceName, mqttConfig.DeviceSecret);
|
||||
|
||||
string broker = mqttConfig.Broker!;
|
||||
LogMessage($"MQTT连接到: {broker}");
|
||||
mqttClient = new MqttClient(broker, mqttConfig.Port, mqttConfig.UseSsl, null, null, MqttSslProtocols.TLSv1_2);
|
||||
_ = mqttClient.Connect(sign.getClientid(), sign.getUsername(), sign.getPassword());
|
||||
|
||||
LogMessage($"MQTT已连接到: {broker}");
|
||||
UpdateMqttStatus("已连接", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage($"MQTT连接失败: {ex.Message},将继续进行数据采集和日志记录");
|
||||
UpdateMqttStatus("连接失败", false);
|
||||
mqttClient = null; // 确保mqttClient为null,避免后续使用
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMqttStatus(string status, bool isConnected)
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
this.Invoke(new Action(() => UpdateMqttStatus(status, isConnected)));
|
||||
return;
|
||||
}
|
||||
|
||||
labelMqttStatus.Text = status;
|
||||
labelMqttStatus.ForeColor = isConnected ? System.Drawing.Color.Green : System.Drawing.Color.Red;
|
||||
}
|
||||
|
||||
private void GPSPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
string data = gpsPort.ReadExisting();
|
||||
gpsBuffer.Append(data);
|
||||
if (gpsPort != null)
|
||||
{
|
||||
string data = gpsPort.ReadExisting();
|
||||
_ = gpsBuffer.Append(data);
|
||||
}
|
||||
|
||||
// 处理完整的行
|
||||
string bufferContent = gpsBuffer.ToString();
|
||||
@ -242,7 +363,7 @@ namespace sscom_sender
|
||||
|
||||
if (bufferContent.EndsWith("\r") || bufferContent.EndsWith("\n"))
|
||||
{
|
||||
gpsBuffer.Clear();
|
||||
_ = gpsBuffer.Clear();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
ProcessGPSData(line);
|
||||
@ -250,12 +371,12 @@ namespace sscom_sender
|
||||
}
|
||||
else
|
||||
{
|
||||
gpsBuffer.Clear();
|
||||
_ = gpsBuffer.Clear();
|
||||
for (int i = 0; i < lines.Length - 1; i++)
|
||||
{
|
||||
ProcessGPSData(lines[i]);
|
||||
}
|
||||
gpsBuffer.Append(lines[lines.Length - 1]);
|
||||
_ = gpsBuffer.Append(lines[lines.Length - 1]);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -268,30 +389,82 @@ namespace sscom_sender
|
||||
{
|
||||
try
|
||||
{
|
||||
string data = spectrometerPort.ReadExisting();
|
||||
// LogMessage($"谱仪原始数据: {data}");
|
||||
spectrometerBuffer.Append(data);
|
||||
string data = spectrometerPort != null ? spectrometerPort.ReadExisting() : string.Empty;
|
||||
_ = spectrometerBuffer.Append(data);
|
||||
|
||||
// 处理完整的行
|
||||
// 处理缓冲区中的数据
|
||||
string bufferContent = spectrometerBuffer.ToString();
|
||||
string[] lines = bufferContent.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (bufferContent.EndsWith("\r") || bufferContent.EndsWith("\n"))
|
||||
// 清理无用的字符串
|
||||
bufferContent = bufferContent.Replace("Please again", "").Replace("ok", "");
|
||||
|
||||
// 按空格分割所有数据
|
||||
string[] allParts = bufferContent.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (allParts.Length < 16) {
|
||||
return;
|
||||
}
|
||||
// 查找日期格式的数据位置
|
||||
for (int i = 0; i < allParts.Length - 15; i++) // 确保后面还有15个字段
|
||||
{
|
||||
spectrometerBuffer.Clear();
|
||||
foreach (string line in lines)
|
||||
// 检查是否为日期格式 xxxx.xx.xx
|
||||
if (System.Text.RegularExpressions.Regex.IsMatch(allParts[i], @"^\d{4}\.\d{2}\.\d{2}$"))
|
||||
{
|
||||
ProcessSpectrometerData(line);
|
||||
// 检查后面是否有时间格式 xx:xx:xx
|
||||
if (i + 1 < allParts.Length && System.Text.RegularExpressions.Regex.IsMatch(allParts[i + 1], @"^\d{2}:\d{2}:\d{2}$"))
|
||||
{
|
||||
// 检查是否有足够的16个字段(日期 + 时间 + 14个数值)
|
||||
if (i + 15 < allParts.Length)
|
||||
{
|
||||
// 验证后面14个字段都是数值格式
|
||||
bool allValid = true;
|
||||
for (int j = i + 2; j <= i + 15; j++)
|
||||
{
|
||||
if (!System.Text.RegularExpressions.Regex.IsMatch(allParts[j], @"^\d+\.\d{2}$"))
|
||||
{
|
||||
allValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allValid)
|
||||
{
|
||||
// 构建完整的数据行
|
||||
string[] validData = new string[16];
|
||||
for (int k = 0; k < 16; k++)
|
||||
{
|
||||
validData[k] = allParts[i + k];
|
||||
}
|
||||
string completeDataLine = string.Join(" ", validData);
|
||||
|
||||
// 处理这条完整的数据
|
||||
ProcessSpectrometerData(completeDataLine);
|
||||
|
||||
// 从缓冲区中移除已处理的数据
|
||||
int endIndex = i + 16;
|
||||
if (endIndex < allParts.Length)
|
||||
{
|
||||
string[] remainingParts = new string[allParts.Length - endIndex];
|
||||
Array.Copy(allParts, endIndex, remainingParts, 0, remainingParts.Length);
|
||||
_ = spectrometerBuffer.Clear();
|
||||
_ = spectrometerBuffer.Append(string.Join(" ", remainingParts));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = spectrometerBuffer.Clear();
|
||||
}
|
||||
return; // 处理完一条数据后退出
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// 如果缓冲区太大,清理一部分旧数据
|
||||
if (spectrometerBuffer.Length > 10000)
|
||||
{
|
||||
spectrometerBuffer.Clear();
|
||||
for (int i = 0; i < lines.Length - 1; i++)
|
||||
{
|
||||
ProcessSpectrometerData(lines[i]);
|
||||
}
|
||||
spectrometerBuffer.Append(lines[lines.Length - 1]);
|
||||
string content = spectrometerBuffer.ToString();
|
||||
_ = spectrometerBuffer.Clear();
|
||||
_ = spectrometerBuffer.Append(content.Substring(content.Length / 2));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -302,7 +475,7 @@ namespace sscom_sender
|
||||
|
||||
private void ProcessGPSData(string data)
|
||||
{
|
||||
LogMessage($"GPS原始数据: {data}");
|
||||
LogMessage($"GPS原始数据: {data}", false);
|
||||
if (data.StartsWith("#BESTPOSA"))
|
||||
{
|
||||
try
|
||||
@ -336,7 +509,7 @@ namespace sscom_sender
|
||||
};
|
||||
|
||||
gpsDataQueue.Enqueue(gpsData);
|
||||
LogMessage($"GPS数据: 纬度={lat:F8}, 经度={lng:F8}");
|
||||
LogMessage($"GPS数据: 纬度={lat:F8}, 经度={lng:F8}", false);
|
||||
|
||||
}
|
||||
}
|
||||
@ -349,7 +522,7 @@ namespace sscom_sender
|
||||
|
||||
private void ProcessSpectrometerData(string data)
|
||||
{
|
||||
LogMessage($"谱仪原始数据: {data}");
|
||||
LogMessage($"谱仪完整原始数据: {data}", false);
|
||||
if (data.Equals("ok")) {
|
||||
LogMessage("谱仪已准备好");
|
||||
return;
|
||||
@ -369,8 +542,8 @@ namespace sscom_sender
|
||||
return;
|
||||
|
||||
// 解析时间戳 (xxxx.xx.xx xx:xx:xx)
|
||||
string dateStr = parts[0];
|
||||
string timeStr = parts[1];
|
||||
// string dateStr = parts[0];
|
||||
// string timeStr = parts[1];
|
||||
|
||||
SpectrometerData spectData = new SpectrometerData
|
||||
{
|
||||
@ -382,7 +555,7 @@ namespace sscom_sender
|
||||
};
|
||||
|
||||
spectrometerDataQueue.Enqueue(spectData);
|
||||
LogMessage($"谱仪数据: 时间={dateStr} {timeStr}, 剂量率={spectData.DoseRate:F2} nSv/h, 全谱计数率={spectData.TotalCountRate:F2} cps");
|
||||
LogMessage($"谱仪数据: 时间={spectData.Timestamp}, 剂量率={spectData.DoseRate:F2} nSv/h, 全谱计数率={spectData.TotalCountRate:F2} cps");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -409,38 +582,23 @@ namespace sscom_sender
|
||||
LogMessage("尝试读取谱仪数据");
|
||||
if (spectrometerPort != null && spectrometerPort.IsOpen)
|
||||
{
|
||||
// spectrometerPort.DiscardInBuffer();
|
||||
// spectrometerPort.Write("$start\r\n");
|
||||
// await Task.Delay(50, token); // 等待刷新完成
|
||||
// // spectrometerPort.ReadTimeout = 1500;
|
||||
// // string response = spectrometerPort.ReadLine();
|
||||
// // LogMessage($"谱仪原始数据: {response}");
|
||||
// spectrometerPort.DiscardInBuffer();
|
||||
// spectrometerPort.Write("$start\r");
|
||||
// await Task.Delay(50, token); // 等待刷新完成
|
||||
spectrometerPort.DiscardInBuffer();
|
||||
spectrometerPort.Write("$clear\r\n");
|
||||
await Task.Delay(50, token); // 等待刷新完成
|
||||
int interval = (int)(numericUpDownRefreshInterval.Value * 1000);
|
||||
spectrometerPort.Write("$start\r\n");
|
||||
// spectrometerPort.ReadTimeout = 1500;
|
||||
// response = spectrometerPort.ReadLine();
|
||||
// LogMessage($"谱仪原始数据: {response}");
|
||||
await Task.Delay(interval, token); // 等待刷新完成
|
||||
// // 先发送刷新指令
|
||||
// spectrometerPort.Write("$refresh\r\n");
|
||||
// await Task.Delay(500, token); // 等待刷新完成
|
||||
|
||||
// response = spectrometerPort.ReadLine();
|
||||
// LogMessage($"谱仪原始数据: {response}");
|
||||
// spectrometerPort.DiscardInBuffer();
|
||||
// spectrometerPort.Write("$start\r\n\r\n");
|
||||
// spectrometerPort.ReadTimeout = 1500;
|
||||
// response = spectrometerPort.ReadLine();
|
||||
// LogMessage($"谱仪原始数据: {response}");
|
||||
// await Task.Delay(50, token); // 等待刷新完成
|
||||
LogMessage("谱仪端口已打开");
|
||||
// 先发送刷新指令
|
||||
spectrometerPort.Write("$refresh\r\n");
|
||||
await Task.Delay(500, token); // 等待刷新完成
|
||||
|
||||
// 再发送获取结果指令
|
||||
spectrometerPort.Write("$getSperesult\r\n");
|
||||
await Task.Delay(50, token); // 等待刷新完成
|
||||
}
|
||||
|
||||
int interval = (int)(numericUpDownRefreshInterval.Value * 1000);
|
||||
await Task.Delay(interval, token);
|
||||
|
||||
await Task.Delay(50, token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -453,16 +611,16 @@ namespace sscom_sender
|
||||
private async void MQTTDataSender(CancellationToken token)
|
||||
{
|
||||
// 在数据发送线程中初始化MQTT连接
|
||||
InitializeMQTT();
|
||||
// InitializeMQTT();
|
||||
|
||||
while (!token.IsCancellationRequested && isRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (spectrometerDataQueue.TryDequeue(out SpectrometerData spectData))
|
||||
if (spectrometerDataQueue.TryDequeue(out SpectrometerData? spectData) && spectData != null)
|
||||
{
|
||||
// 查找最近的GPS数据
|
||||
GPSData nearestGPS = FindNearestGPSData(spectData.Timestamp);
|
||||
GPSData? nearestGPS = FindNearestGPSData(spectData.Timestamp);
|
||||
|
||||
if (nearestGPS != null)
|
||||
{
|
||||
@ -475,11 +633,11 @@ namespace sscom_sender
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(mqttData);
|
||||
string topic = $"/{textBoxTopicRoot.Text}/{textBoxDeviceName.Text}/user/update";
|
||||
string? topic = mqttConfig?.Topic;
|
||||
|
||||
if (mqttClient != null && mqttClient.IsConnected)
|
||||
{
|
||||
mqttClient.Publish(topic, Encoding.UTF8.GetBytes(json));
|
||||
_ = mqttClient.Publish(topic, Encoding.UTF8.GetBytes(json));
|
||||
LogMessage($"MQTT发送: {json}");
|
||||
}
|
||||
else
|
||||
@ -499,9 +657,9 @@ namespace sscom_sender
|
||||
}
|
||||
}
|
||||
|
||||
private GPSData FindNearestGPSData(DateTime targetTime)
|
||||
private GPSData? FindNearestGPSData(DateTime targetTime)
|
||||
{
|
||||
GPSData nearest = null;
|
||||
GPSData? nearest = null;
|
||||
TimeSpan minDiff = TimeSpan.MaxValue;
|
||||
|
||||
var gpsDataList = gpsDataQueue.ToArray();
|
||||
@ -526,7 +684,7 @@ namespace sscom_sender
|
||||
{
|
||||
try
|
||||
{
|
||||
if (logQueue.TryDequeue(out string logMessage))
|
||||
if (logQueue.TryDequeue(out string? logMessage) && logMessage != null && !string.IsNullOrEmpty(logFileName))
|
||||
{
|
||||
await File.AppendAllTextAsync(logFileName, logMessage + Environment.NewLine, token);
|
||||
}
|
||||
@ -542,25 +700,34 @@ namespace sscom_sender
|
||||
}
|
||||
}
|
||||
|
||||
private void LogMessage(string message)
|
||||
private void LogMessage(string message, bool screenOutput = true)
|
||||
{
|
||||
|
||||
// 处理日志消息
|
||||
|
||||
message = message.Replace("\r", "RR");
|
||||
message = message.Replace("\n", "NN");
|
||||
string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {message}";
|
||||
|
||||
// 添加到日志队列
|
||||
logQueue.Enqueue(logEntry);
|
||||
|
||||
// 更新UI
|
||||
if (textBoxLog.InvokeRequired)
|
||||
if (screenOutput)
|
||||
{
|
||||
textBoxLog.Invoke(new Action(() => {
|
||||
|
||||
// 更新UI
|
||||
if (textBoxLog.InvokeRequired)
|
||||
{
|
||||
textBoxLog.Invoke(new Action(() =>
|
||||
{
|
||||
textBoxLog.AppendText(logEntry + Environment.NewLine);
|
||||
textBoxLog.ScrollToCaret();
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
textBoxLog.AppendText(logEntry + Environment.NewLine);
|
||||
textBoxLog.ScrollToCaret();
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
textBoxLog.AppendText(logEntry + Environment.NewLine);
|
||||
textBoxLog.ScrollToCaret();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
9
mqtt_config.json
Normal file
9
mqtt_config.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ProductKey": "gfcq950RDqt",
|
||||
"Topic": "/a10inDdCRS6/PubDevice/user/update",
|
||||
"DeviceName": "PubDevice",
|
||||
"DeviceSecret": "1031a49a4f61c29a086f79b41ed971c7",
|
||||
"Broker": "iot-06z00jfiubx584v.mqtt.iothub.aliyuncs.com",
|
||||
"Port": 1883,
|
||||
"UseSsl": true
|
||||
}
|
24
sscom-sender.sln
Normal file
24
sscom-sender.sln
Normal file
@ -0,0 +1,24 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sscom-sender", "sscom-sender.csproj", "{F03C6C53-8989-99E6-D747-EC03449AD20F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F03C6C53-8989-99E6-D747-EC03449AD20F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F03C6C53-8989-99E6-D747-EC03449AD20F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F03C6C53-8989-99E6-D747-EC03449AD20F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F03C6C53-8989-99E6-D747-EC03449AD20F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {150E6FAC-712F-4139-BDF9-8AC813D4C86F}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Loading…
x
Reference in New Issue
Block a user