diff --git a/Form1.Designer.cs b/Form1.Designer.cs index ca1d4c3..2585be4 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -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 // diff --git a/Form1.cs b/Form1.cs index fcf7531..0b61c5f 100644 --- a/Form1.cs +++ b/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 gpsDataQueue = new ConcurrentQueue(); @@ -32,11 +43,11 @@ namespace sscom_sender private ConcurrentQueue logQueue = new ConcurrentQueue(); // 线程控制 - 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() + .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(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(); + } } } diff --git a/mqtt_config.json b/mqtt_config.json new file mode 100644 index 0000000..c12db41 --- /dev/null +++ b/mqtt_config.json @@ -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 +} \ No newline at end of file diff --git a/sscom-sender.sln b/sscom-sender.sln new file mode 100644 index 0000000..918a6ea --- /dev/null +++ b/sscom-sender.sln @@ -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