记录信号强度数据

This commit is contained in:
2025-09-24 21:53:18 +08:00
parent f764ad8962
commit 21fb9c7e57
8 changed files with 284 additions and 145 deletions

View File

@@ -1,30 +0,0 @@
package models
import (
"time"
"gorm.io/datatypes"
)
// SensorData 存储所有类型的传感器数据,对应数据库中的 'sensor_data' 表。
type SensorData struct {
// Time 是数据记录的时间戳,作为复合主键的一部分。
// GORM 会将其映射到 'time' TIMESTAMPTZ 列。
Time time.Time `gorm:"primaryKey" json:"time"`
// DeviceID 是传感器的唯一标识符,作为复合主键的另一部分。
// GORM 会将其映射到 'device_id' VARCHAR(50) 列。
DeviceID uint `gorm:"primaryKey" json:"device_id"`
// RegionalControllerID 是上报此数据的区域主控的ID。
// 我们为其添加了数据库索引以优化按区域查询的性能。
RegionalControllerID uint `json:"regional_controller_id"`
// Data 存储一个或多个传感器读数,格式为 JSON。
// GORM 会使用 'jsonb' 类型来创建此列。
Data datatypes.JSON `gorm:"type:jsonb" json:"data"`
}
func (SensorData) TableName() string {
return "sensor_data"
}

View File

@@ -0,0 +1,56 @@
package models
import (
"time"
"gorm.io/datatypes"
)
// SensorDataType 定义了 SensorData 记录中 Data 字段的整体类型
type SensorDataType string
const (
SensorDataTypeSignalMetrics SensorDataType = "signal_metrics" // 信号强度
SensorDataTypeBatteryLevel SensorDataType = "battery_level" // 电池电量
)
// SignalMetrics 存储信号强度数据
type SignalMetrics struct {
RSSI int `json:"rssi"` // 绝对信号强度dBm受距离、障碍物影响
SNR float64 `json:"snr"` // 信号与噪声的相对比率dB由 RSSI 减去噪声地板Noise Floor
Sensitivity int `json:"sensitivity"` // 网关的最低检测阈值(dBm)
Margin int `json:"margin"` // SNR 相对于接收器灵敏度的余量, Margin = SNR - Sensitivity
}
// BatteryLevel 存储电池电量数据
type BatteryLevel struct {
BatteryLevel float32 `json:"battery_level"` // 电量剩余百分比
BatteryLevelUnavailable bool `json:"battery_level_unavailable"` // 电量数据不可用
ExternalPower bool `json:"external_power"` // 是否使用外部电源
}
// SensorData 存储所有类型的传感器数据,对应数据库中的 'sensor_data' 表。
type SensorData struct {
// Time 是数据记录的时间戳,作为复合主键的一部分。
// GORM 会将其映射到 'time' TIMESTAMPTZ 列。
Time time.Time `gorm:"primaryKey" json:"time"`
// DeviceID 是传感器的唯一标识符,作为复合主键的另一部分。
// GORM 会将其映射到 'device_id' VARCHAR(50) 列。
DeviceID uint `gorm:"primaryKey" json:"device_id"`
// RegionalControllerID 是上报此数据的区域主控的ID。
// 我们为其添加了数据库索引以优化按区域查询的性能。
RegionalControllerID uint `json:"regional_controller_id"`
// SensorDataType 是传感数据的类型
SensorDataType SensorDataType `gorm:"not null;index" json:"sensor_data_type"`
// Data 存储一个或多个传感器读数,格式为 JSON。
// GORM 会使用 'jsonb' 类型来创建此列。
Data datatypes.JSON `gorm:"type:jsonb" json:"data"`
}
func (SensorData) TableName() string {
return "sensor_data"
}

View File

@@ -32,6 +32,9 @@ type DeviceRepository interface {
// Delete 根据主键 ID 删除一个设备
Delete(id uint) error
// FindByDevEui 根据 DevEui (存储在 properties JSONB 中的 lora_address) 查找设备 (新增)
FindByDevEui(devEui string) (*models.Device, error)
}
// gormDeviceRepository 是 DeviceRepository 的 GORM 实现
@@ -108,3 +111,13 @@ func (r *gormDeviceRepository) Update(device *models.Device) error {
func (r *gormDeviceRepository) Delete(id uint) error {
return r.db.Delete(&models.Device{}, id).Error
}
// FindByDevEui 根据 DevEui (存储在 properties JSONB 中的 lora_address) 查找设备
func (r *gormDeviceRepository) FindByDevEui(devEui string) (*models.Device, error) {
var device models.Device
// 使用 GORM 的 JSONB 查询语法: properties->>'lora_address'
if err := r.db.Where("properties->>'lora_address' = ?", devEui).First(&device).Error; err != nil {
return nil, err // 如果找不到或发生其他错误GORM 会返回错误
}
return &device, nil
}

View File

@@ -0,0 +1,27 @@
package repository
import (
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"gorm.io/gorm"
)
// SensorDataRepository 定义了与传感器数据相关的数据库操作接口。
type SensorDataRepository interface {
Create(sensorData *models.SensorData) error
}
// gormSensorDataRepository 是 SensorDataRepository 的 GORM 实现。
type gormSensorDataRepository struct {
db *gorm.DB
}
// NewGormSensorDataRepository 创建一个新的 SensorDataRepository GORM 实现实例。
// 它直接接收一个 *gorm.DB 实例作为依赖,完全遵循项目中的既定模式。
func NewGormSensorDataRepository(db *gorm.DB) SensorDataRepository {
return &gormSensorDataRepository{db: db}
}
// Create 将一条新的传感器数据记录插入数据库。
func (r *gormSensorDataRepository) Create(sensorData *models.SensorData) error {
return r.db.Create(sensorData).Error
}