From 441ce2c5ecc15a257fad09095064d0287ac6c4cc Mon Sep 17 00:00:00 2001 From: huang <1724659546@qq.com> Date: Tue, 30 Sep 2025 00:30:46 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=20ChirpStackListener?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/service/transport/chirp_stack.go | 78 ++++++++++--------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/internal/app/service/transport/chirp_stack.go b/internal/app/service/transport/chirp_stack.go index 2573429..bf5779e 100644 --- a/internal/app/service/transport/chirp_stack.go +++ b/internal/app/service/transport/chirp_stack.go @@ -32,7 +32,7 @@ type ChirpStackListener struct { logger *logs.Logger sensorDataRepo repository.SensorDataRepository deviceRepo repository.DeviceRepository - areaControllerRepo repository.AreaControllerRepository // 新增 + areaControllerRepo repository.AreaControllerRepository deviceCommandLogRepo repository.DeviceCommandLogRepository pendingCollectionRepo repository.PendingCollectionRepository } @@ -42,7 +42,7 @@ func NewChirpStackListener( logger *logs.Logger, sensorDataRepo repository.SensorDataRepository, deviceRepo repository.DeviceRepository, - areaControllerRepo repository.AreaControllerRepository, // 新增 + areaControllerRepo repository.AreaControllerRepository, deviceCommandLogRepo repository.DeviceCommandLogRepository, pendingCollectionRepo repository.PendingCollectionRepository, ) ListenHandler { // 返回接口类型 @@ -50,7 +50,7 @@ func NewChirpStackListener( logger: logger, sensorDataRepo: sensorDataRepo, deviceRepo: deviceRepo, - areaControllerRepo: areaControllerRepo, // 新增 + areaControllerRepo: areaControllerRepo, deviceCommandLogRepo: deviceCommandLogRepo, pendingCollectionRepo: pendingCollectionRepo, } @@ -151,14 +151,6 @@ func (c *ChirpStackListener) handler(data []byte, eventType string) { // --- 业务处理函数 --- -// GenericSensorReading 表示单个传感器读数,包含设备ID、类型和值。 -// 此结构体已不再使用,但保留以供参考或兼容旧代码。 -type GenericSensorReading struct { - DeviceID uint `json:"device_id"` // 传感器设备的ID - Type string `json:"type"` // 传感器类型 (现在直接使用 ValueDescriptor.Name) - Value float64 `json:"value"` // 传感器读数 -} - // handleUpEvent 处理上行数据事件 func (c *ChirpStackListener) handleUpEvent(event *UpEvent) { c.logger.Infof("开始处理 'up' 事件, DevEui: %s", event.DeviceInfo.DevEui) @@ -187,9 +179,9 @@ func (c *ChirpStackListener) handleUpEvent(event *UpEvent) { RssiDbm: rx.Rssi, SnrDb: rx.Snr, } - // 记录信号强度,使用 ValueDescriptor 的 Name 作为 sensorName - // 简化处理,只记录 RSSI,如果需要记录 SNR,可以再添加一个 ValueDescriptor - c.recordSensorData(regionalController.ID, regionalController.ID, event.Time, "signal_strength", float64(signalMetrics.RssiDbm)) + + // 记录信号强度 + c.recordSensorData(regionalController.ID, regionalController.ID, event.Time, models.SensorTypeSignalMetrics, signalMetrics) c.logger.Infof("已记录区域主控 (ID: %d) 的信号强度: RSSI=%d, SNR=%.2f", regionalController.ID, rx.Rssi, rx.Snr) } else { c.logger.Warnf("处理 'up' 事件时未找到 RxInfo,无法记录信号数据。DevEui: %s", event.DeviceInfo.DevEui) @@ -292,9 +284,24 @@ func (c *ChirpStackListener) handleUpEvent(event *UpEvent) { // 5.3 应用乘数和偏移量计算最终值 parsedValue := float64(rawSensorValue)*valueDescriptor.Multiplier + valueDescriptor.Offset - // 5.4 记录传感器数据 - c.recordSensorData(regionalController.ID, dev.ID, event.Time, valueDescriptor.Name, parsedValue) - c.logger.Infof("成功记录传感器数据: 设备ID=%d, 类型=%s, 原始值=%d, 解析值=%.2f", dev.ID, valueDescriptor.Name, rawSensorValue, parsedValue) + // 5.4 根据传感器类型构建具体的数据结构 + var dataToRecord interface{} + switch valueDescriptor.Type { + case models.SensorTypeTemperature: + dataToRecord = models.TemperatureData{TemperatureCelsius: parsedValue} + case models.SensorTypeHumidity: + dataToRecord = models.HumidityData{HumidityPercent: parsedValue} + case models.SensorTypeWeight: + dataToRecord = models.WeightData{WeightKilograms: parsedValue} + default: + // TODO 未知传感器的数据需要记录吗 + c.logger.Warnf("未知的传感器类型 '%s',将使用通用格式记录", valueDescriptor.Type) + dataToRecord = map[string]float64{"value": parsedValue} + } + + // 5.5 记录传感器数据 + c.recordSensorData(regionalController.ID, dev.ID, event.Time, valueDescriptor.Type, dataToRecord) + c.logger.Infof("成功记录传感器数据: 设备ID=%d, 类型=%s, 原始值=%f, 解析值=%.2f", dev.ID, valueDescriptor.Type, rawSensorValue, parsedValue) } // 6. 更新请求状态为“已完成” @@ -309,28 +316,28 @@ func (c *ChirpStackListener) handleUpEvent(event *UpEvent) { func (c *ChirpStackListener) handleStatusEvent(event *StatusEvent) { c.logger.Infof("处接收到理 'status' 事件: %+v", event) - // 记录信号强度 - signalMetrics := models.SignalMetrics{ - MarginDb: event.Margin, - } - // 这里的 event.DeviceInfo.DevEui 对应的是区域主控的 DevEui + // 查找区域主控设备 regionalController, err := c.areaControllerRepo.FindByNetworkID(event.DeviceInfo.DevEui) if err != nil { c.logger.Errorf("处理 'status' 事件失败:无法通过 DevEui '%s' 找到区域主控设备: %v", event.DeviceInfo.DevEui, err) return } - // 记录区域主控的信号强度 - c.recordSensorData(regionalController.ID, regionalController.ID, event.Time, "signal_metrics", float64(signalMetrics.RssiDbm)) - // 记录 电量 + // 记录信号强度 + signalMetrics := models.SignalMetrics{ + MarginDb: event.Margin, + } + c.recordSensorData(regionalController.ID, regionalController.ID, event.Time, models.SensorTypeSignalMetrics, signalMetrics) + c.logger.Infof("已记录区域主控 (ID: %d) 的信号状态: %+v", regionalController.ID, signalMetrics) + + // 记录电量 batteryLevel := models.BatteryLevel{ BatteryLevelRatio: event.BatteryLevel, BatteryLevelUnavailable: event.BatteryLevelUnavailable, ExternalPower: event.ExternalPower, } - // 记录区域主控的电池电量 - c.recordSensorData(regionalController.ID, regionalController.ID, event.Time, "battery_level", float64(batteryLevel.BatteryLevelRatio)) - + c.recordSensorData(regionalController.ID, regionalController.ID, event.Time, models.SensorTypeBatteryLevel, batteryLevel) + c.logger.Infof("已记录区域主控 (ID: %d) 的电池状态: %+v", regionalController.ID, batteryLevel) } // handleAckEvent 处理下行确认事件 @@ -397,14 +404,11 @@ func (c *ChirpStackListener) handleIntegrationEvent(event *IntegrationEvent) { // recordSensorData 是一个通用方法,用于将传感器数据存入数据库。 // regionalControllerID: 区域主控设备的ID // sensorDeviceID: 实际产生传感器数据的普通设备的ID -// sensorName: 传感器值的名称 (例如 "temperature", "weight") -// parsedValue: 已经解析并应用了乘数和偏移量的浮点数值 -func (c *ChirpStackListener) recordSensorData(regionalControllerID uint, sensorDeviceID uint, eventTime time.Time, sensorName string, parsedValue float64) { - // 1. 将解析后的值封装成一个简单的 JSON 对象 - dataToMarshal := map[string]float64{ - "value": parsedValue, - } - jsonData, err := json.Marshal(dataToMarshal) +// sensorType: 传感器值的类型 (例如 models.SensorTypeTemperature) +// data: 具体的传感器数据结构体实例 (例如 models.TemperatureData) +func (c *ChirpStackListener) recordSensorData(regionalControllerID uint, sensorDeviceID uint, eventTime time.Time, sensorType models.SensorType, data interface{}) { + // 1. 将传入的结构体序列化为 JSON + jsonData, err := json.Marshal(data) if err != nil { c.logger.Errorf("记录传感器数据失败:序列化数据为 JSON 时出错: %v", err) return @@ -415,7 +419,7 @@ func (c *ChirpStackListener) recordSensorData(regionalControllerID uint, sensorD Time: eventTime, DeviceID: sensorDeviceID, RegionalControllerID: regionalControllerID, - SensorDataType: sensorName, // 直接使用 sensorName 作为数据类型 + SensorType: sensorType, Data: datatypes.JSON(jsonData), }