From 37680572036adc50e731cce306b8ef785b8f2310 Mon Sep 17 00:00:00 2001 From: yarnom Date: Thu, 21 Aug 2025 00:08:48 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E6=AD=A3udp=E6=8E=A5?= =?UTF-8?q?=E5=8F=97=E7=9A=84=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- angle.go | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++ udp_server.go | 34 ++++++++++---- 2 files changed, 151 insertions(+), 8 deletions(-) create mode 100644 angle.go diff --git a/angle.go b/angle.go new file mode 100644 index 0000000..532b82d --- /dev/null +++ b/angle.go @@ -0,0 +1,125 @@ +package main + +import ( + "fmt" + "log" + "regexp" + "strconv" + "strings" +) + +// 单个传感器数据结构 +type SensorReading struct { + SerialNumber string // 传感器序列号,如 8513343-01 + GroupID int // 组ID,如 1 + SensorID int // 传感器ID,如 1-16 + Temperature float64 // 温度值,如 32.9 + X float64 // X轴值,如 0.848 + Y float64 // Y轴值,如 2.100 + Z float64 // Z轴默认为0 +} + +// 解析批量传感器数据 +func parseBatchData(data string) ([]SensorReading, error) { + // 检查是否是批量数据格式 + if !strings.Contains(data, "#{") || !strings.Contains(data, "}!") { + return nil, fmt.Errorf("不是批量数据格式") + } + + // 提取批量数据部分 - 使用非贪婪匹配确保正确捕获内容 + batchPattern := regexp.MustCompile(`#\{([\s\S]*?)\}!`) + batchMatches := batchPattern.FindStringSubmatch(data) + if len(batchMatches) != 2 { + return nil, fmt.Errorf("批量数据格式不正确") + } + + // 获取批量数据内容 + batchContent := batchMatches[1] + + // 记录原始批量数据内容,用于调试 + log.Printf("解析批量数据内容: %s", batchContent) + + // 按行分割 + lines := strings.Split(batchContent, "\n") + + var readings []SensorReading + + // 行解析正则表达式 - 匹配格式如: 8513343-01,1,1,32.9,0.848,2.100 + linePattern := regexp.MustCompile(`([^,]+),(\d+),(\d+),([-]?\d+\.\d+),([-]?\d+\.\d+),([-]?\d+\.\d+)`) + + for _, line := range lines { + // 清理行 + line = strings.TrimSpace(line) + if line == "" { + continue + } + + // 处理可能存在的回车符 + line = strings.ReplaceAll(line, "\r", "") + + // 解析行 + matches := linePattern.FindStringSubmatch(line) + if len(matches) != 7 { + // 记录不匹配的行 + log.Printf("无法匹配行: %s", line) + continue // 跳过不匹配的行 + } + + // 解析各个字段 + serialNumber := matches[1] + groupID, err := strconv.Atoi(matches[2]) + if err != nil { + continue + } + + sensorID, err := strconv.Atoi(matches[3]) + if err != nil { + continue + } + + temperature, err := strconv.ParseFloat(matches[4], 64) + if err != nil { + continue + } + + x, err := strconv.ParseFloat(matches[5], 64) + if err != nil { + continue + } + + y, err := strconv.ParseFloat(matches[6], 64) + if err != nil { + continue + } + + // 创建传感器读数对象 + reading := SensorReading{ + SerialNumber: serialNumber, + GroupID: groupID, + SensorID: sensorID, + Temperature: temperature, + X: x, + Y: y, + Z: 0.0, // Z轴默认为0 + } + + readings = append(readings, reading) + } + + if len(readings) == 0 { + return nil, fmt.Errorf("未找到有效的传感器数据") + } + + return readings, nil +} + +// 保存批量传感器数据到数据库 +func SaveBatchSensorData(readings []SensorReading) error { + for _, reading := range readings { + // 使用现有的SaveSensorData函数保存每个传感器的数据 + if err := SaveSensorData(reading.SensorID, reading.X, reading.Y, reading.Z, reading.Temperature); err != nil { + return fmt.Errorf("保存传感器 %d 数据失败: %v", reading.SensorID, err) + } + } + return nil +} diff --git a/udp_server.go b/udp_server.go index ed650d5..63797f3 100644 --- a/udp_server.go +++ b/udp_server.go @@ -44,17 +44,35 @@ func handleUDPPacket(conn *net.UDPConn, addr *net.UDPAddr, data []byte) { rawData := string(data) TCPDataLogger.Printf("从UDP客户端 %s 接收到原始数据: %s", remoteAddr, rawData) - sensorID, x, y, z, temperature, err := parseData(rawData) + // 尝试解析批量数据 + readings, err := parseBatchData(rawData) + if err == nil && len(readings) > 0 { + // 批量数据解析成功 + TCPDataLogger.Printf("批量解析成功 - UDP客户端: %s, 传感器数量: %d", remoteAddr, len(readings)) - if err == nil { - TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f, 温度=%.1f°C", - remoteAddr, sensorID, x, y, z, temperature) - - if err := SaveSensorData(sensorID, x, y, z, temperature); err != nil { - Logger.Printf("保存传感器数据失败: %v", err) + // 保存所有传感器数据 + if err := SaveBatchSensorData(readings); err != nil { + Logger.Printf("保存批量传感器数据失败: %v", err) } + + // 记录第一个传感器的数据(用于兼容现有日志格式) + firstSensor := readings[0] + TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f, 温度=%.1f°C", + remoteAddr, firstSensor.SensorID, firstSensor.X, firstSensor.Y, firstSensor.Z, firstSensor.Temperature) } else { - TCPDataLogger.Printf("无法解析从UDP客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, err) + // 尝试传统解析方法 + sensorID, x, y, z, temperature, parseErr := parseData(rawData) + + if parseErr == nil { + TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f, 温度=%.1f°C", + remoteAddr, sensorID, x, y, z, temperature) + + if err := SaveSensorData(sensorID, x, y, z, temperature); err != nil { + Logger.Printf("保存传感器数据失败: %v", err) + } + } else { + TCPDataLogger.Printf("无法解析从UDP客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, parseErr) + } } resp := "OK\n"