|
@@ -6,16 +6,17 @@ import (
|
|
|
"encoding/json"
|
|
"encoding/json"
|
|
|
"errors"
|
|
"errors"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
|
|
+ "sort"
|
|
|
|
|
+ "strconv"
|
|
|
|
|
+ "strings"
|
|
|
|
|
+ "time"
|
|
|
|
|
+
|
|
|
"github.com/astaxie/beego/cache"
|
|
"github.com/astaxie/beego/cache"
|
|
|
_ "github.com/astaxie/beego/cache/redis"
|
|
_ "github.com/astaxie/beego/cache/redis"
|
|
|
"github.com/astaxie/beego/logs"
|
|
"github.com/astaxie/beego/logs"
|
|
|
"github.com/beego/beego/v2/adapter/orm"
|
|
"github.com/beego/beego/v2/adapter/orm"
|
|
|
orm2 "github.com/beego/beego/v2/client/orm"
|
|
orm2 "github.com/beego/beego/v2/client/orm"
|
|
|
_ "github.com/go-sql-driver/mysql"
|
|
_ "github.com/go-sql-driver/mysql"
|
|
|
- "sort"
|
|
|
|
|
- "strconv"
|
|
|
|
|
- "strings"
|
|
|
|
|
- "time"
|
|
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// 建表
|
|
// 建表
|
|
@@ -79,6 +80,20 @@ type DeviceData_R2 struct {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 模板
|
|
// 模板
|
|
|
|
|
+type DeviceData_ChartShow struct {
|
|
|
|
|
+ T_sn string // sn
|
|
|
|
|
+ T_id int // 传感器id
|
|
|
|
|
+ T_name string // 传感器名称
|
|
|
|
|
+ T_t float32 // 温度
|
|
|
|
|
+ T_rh float32 // 湿度
|
|
|
|
|
+ T_tl float32 // 温度下限
|
|
|
|
|
+ T_tu float32 // 温度上限
|
|
|
|
|
+ T_rhl float32 // 湿度下限
|
|
|
|
|
+ T_rhu float32 // 湿度上限
|
|
|
|
|
+ T_time string // 采集时间
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 模板
|
|
|
type DeviceData_Docking struct {
|
|
type DeviceData_Docking struct {
|
|
|
T_monitor int // 监控状态 0 未监控 1 监控
|
|
T_monitor int // 监控状态 0 未监控 1 监控
|
|
|
T_online int // 在线状态 0 未启用 1 在线 2 离线
|
|
T_online int // 在线状态 0 未启用 1 在线 2 离线
|
|
@@ -181,6 +196,22 @@ func DeviceDataToDeviceData_R2(d Device, sp DeviceSensorParameter_R, r DeviceDat
|
|
|
return t
|
|
return t
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func DeviceData_ToDeviceData_ChartShow(d Device, r DeviceData_) (t DeviceData_ChartShow) {
|
|
|
|
|
+
|
|
|
|
|
+ t.T_id = r.T_id
|
|
|
|
|
+ t.T_t = r.T_t
|
|
|
|
|
+ t.T_rh = r.T_rh
|
|
|
|
|
+ t.T_time = r.T_time.Format("2006-01-02 15:04:05")
|
|
|
|
|
+ sp := Read_DeviceSensorParameter_Map_Get(r.T_sp)
|
|
|
|
|
+ t.T_name = sp.T_name
|
|
|
|
|
+ t.T_tl = sp.T_Tlower
|
|
|
|
|
+ t.T_tu = sp.T_Tupper
|
|
|
|
|
+ t.T_rhl = sp.T_RHlower
|
|
|
|
|
+ t.T_rhu = sp.T_RHupper
|
|
|
|
|
+
|
|
|
|
|
+ return t
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// ---------------- Redis -------------------
|
|
// ---------------- Redis -------------------
|
|
|
// Redis_Device_Set(m.T_sn,m) // Redis 更新缓存
|
|
// Redis_Device_Set(m.T_sn,m) // Redis 更新缓存
|
|
|
func RedisDeviceData_Set(key string, r DeviceData_) (err error) {
|
|
func RedisDeviceData_Set(key string, r DeviceData_) (err error) {
|
|
@@ -260,6 +291,46 @@ func AssistedPositioning_Get(T_sn string, T_id int) (r DeviceData_R1, is bool) {
|
|
|
return DeviceData_R1{}, false
|
|
return DeviceData_R1{}, false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// Redis_DeviceDataStatistics_Set 设置统计数据缓存
|
|
|
|
|
+func Redis_DeviceDataStatistics_Set(SN string, T_id int, Time_start string, Time_end string, stats DeviceDataStatistics) error {
|
|
|
|
|
+ // 构建缓存key: device_data_stats:SN:T_id:Time_start:Time_end
|
|
|
|
|
+ key := fmt.Sprintf("device_data_stats:%s:%d:%s:%s", SN, T_id, Time_start, Time_end)
|
|
|
|
|
+
|
|
|
|
|
+ // json序列化
|
|
|
|
|
+ str, err := json.Marshal(stats)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logs.Error(lib.FuncName(), err)
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 缓存10分钟
|
|
|
|
|
+ err = redis_DeviceData.Put(key, str, 10*time.Minute)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logs.Error("Redis_DeviceDataStatistics_Set", "set key:", key, err)
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Redis_DeviceDataStatistics_Get 获取统计数据缓存
|
|
|
|
|
+func Redis_DeviceDataStatistics_Get(SN string, T_id int, Time_start string, Time_end string) (stats DeviceDataStatistics, found bool) {
|
|
|
|
|
+ // 构建缓存key
|
|
|
|
|
+ key := fmt.Sprintf("device_data_stats:%s:%d:%s:%s", SN, T_id, Time_start, Time_end)
|
|
|
|
|
+
|
|
|
|
|
+ if !redis_DeviceData.IsExist(key) {
|
|
|
|
|
+ return DeviceDataStatistics{}, false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ v := redis_DeviceData.Get(key)
|
|
|
|
|
+ err := json.Unmarshal(v.([]byte), &stats)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logs.Error(lib.FuncName(), err)
|
|
|
|
|
+ return DeviceDataStatistics{}, false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return stats, true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// -------------------------------------------------------
|
|
// -------------------------------------------------------
|
|
|
// 创建数据库 Device.CREATE_DeviceData("")
|
|
// 创建数据库 Device.CREATE_DeviceData("")
|
|
|
func CREATE_DeviceData(SN string) bool {
|
|
func CREATE_DeviceData(SN string) bool {
|
|
@@ -445,6 +516,116 @@ func Read_DeviceData_ById_List(SN string, T_id int, Time_start_ string, Time_end
|
|
|
|
|
|
|
|
return r, key
|
|
return r, key
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+func Read_DeviceData_ById_List_ChartShow(SN string, T_id int, Time_start_ string, Time_end_ string) ([]DeviceData_ChartShow, int) {
|
|
|
|
|
+ o := orm.NewOrm()
|
|
|
|
|
+ var maps []DeviceData_
|
|
|
|
|
+
|
|
|
|
|
+ sql_time := ""
|
|
|
|
|
+
|
|
|
|
|
+ if len(Time_start_) > 1 {
|
|
|
|
|
+ sql_time += " t_time >= '" + Time_start_ + "' AND "
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if len(Time_end_) > 1 {
|
|
|
|
|
+ sql_time += " t_time <= '" + Time_end_ + "' AND "
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 优化:移除不必要的 COUNT 查询,直接查询数据
|
|
|
|
|
+ sql := "SELECT t_id,t_sp,t_t,t_rh,t_site,DATE_FORMAT(t_time,'%Y-%m-%d %H:%i:%s') AS t_time,t_time AS t_time1 FROM z_device_data_" + SN + " WHERE " + sql_time + " t_id = " + strconv.Itoa(T_id) + " ORDER BY t_time1 DESC,t_id DESC "
|
|
|
|
|
+
|
|
|
|
|
+ logs.Debug(sql)
|
|
|
|
|
+ _, err := o.Raw(sql).QueryRows(&maps)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logs.Error(lib.FuncName(), err)
|
|
|
|
|
+ return []DeviceData_ChartShow{}, 0
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果没有数据,直接返回
|
|
|
|
|
+ if len(maps) == 0 {
|
|
|
|
|
+ return []DeviceData_ChartShow{}, 0
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 优化:预分配结果切片容量,减少内存重新分配
|
|
|
|
|
+ r := make([]DeviceData_ChartShow, 0, len(maps))
|
|
|
|
|
+
|
|
|
|
|
+ // 获取传感器名称和参数(只查询一次)
|
|
|
|
|
+ deviceSensor, _ := Read_DeviceSensor_ByT_sn(SN, T_id)
|
|
|
|
|
+ sp, _ := Read_DeviceSensorParameter(deviceSensor.T_sn, deviceSensor.T_id)
|
|
|
|
|
+
|
|
|
|
|
+ // 转换数据
|
|
|
|
|
+ for _, v := range maps {
|
|
|
|
|
+ item := DeviceData_ChartShow{
|
|
|
|
|
+ T_sn: SN,
|
|
|
|
|
+ T_id: v.T_id,
|
|
|
|
|
+ T_t: v.T_t,
|
|
|
|
|
+ T_rh: v.T_rh,
|
|
|
|
|
+ T_time: v.T_time.Format("2006-01-02 15:04:05"),
|
|
|
|
|
+ T_name: deviceSensor.T_name,
|
|
|
|
|
+ T_tl: sp.T_Tlower,
|
|
|
|
|
+ T_tu: sp.T_Tupper,
|
|
|
|
|
+ T_rhl: sp.T_RHlower,
|
|
|
|
|
+ T_rhu: sp.T_RHupper,
|
|
|
|
|
+ }
|
|
|
|
|
+ r = append(r, item)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return r, len(r)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Read_DeviceData_ById_List_ChartShow_WithCache 优化版本:接受预加载的传感器信息,避免重复查询
|
|
|
|
|
+func Read_DeviceData_ById_List_ChartShow_WithCache(SN string, T_id int, Time_start_ string, Time_end_ string, deviceSensor DeviceSensor, sp DeviceSensorParameter_R) ([]DeviceData_ChartShow, int) {
|
|
|
|
|
+ o := orm.NewOrm()
|
|
|
|
|
+ var maps []DeviceData_
|
|
|
|
|
+
|
|
|
|
|
+ sql_time := ""
|
|
|
|
|
+
|
|
|
|
|
+ if len(Time_start_) > 1 {
|
|
|
|
|
+ sql_time += " t_time >= '" + Time_start_ + "' AND "
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if len(Time_end_) > 1 {
|
|
|
|
|
+ sql_time += " t_time <= '" + Time_end_ + "' AND "
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 优化:移除不必要的 COUNT 查询,直接查询数据
|
|
|
|
|
+ sql := "SELECT t_id,t_sp,t_t,t_rh,t_site,DATE_FORMAT(t_time,'%Y-%m-%d %H:%i:%s') AS t_time,t_time AS t_time1 FROM z_device_data_" + SN + " WHERE " + sql_time + " t_id = " + strconv.Itoa(T_id) + " ORDER BY t_time1 DESC,t_id DESC "
|
|
|
|
|
+
|
|
|
|
|
+ logs.Debug(sql)
|
|
|
|
|
+ _, err := o.Raw(sql).QueryRows(&maps)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logs.Error(lib.FuncName(), err)
|
|
|
|
|
+ return []DeviceData_ChartShow{}, 0
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果没有数据,直接返回
|
|
|
|
|
+ if len(maps) == 0 {
|
|
|
|
|
+ return []DeviceData_ChartShow{}, 0
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 优化:预分配结果切片容量,减少内存重新分配
|
|
|
|
|
+ r := make([]DeviceData_ChartShow, 0, len(maps))
|
|
|
|
|
+
|
|
|
|
|
+ // 使用传入的传感器信息,无需再次查询
|
|
|
|
|
+ for _, v := range maps {
|
|
|
|
|
+ item := DeviceData_ChartShow{
|
|
|
|
|
+ T_sn: SN,
|
|
|
|
|
+ T_id: v.T_id,
|
|
|
|
|
+ T_t: v.T_t,
|
|
|
|
|
+ T_rh: v.T_rh,
|
|
|
|
|
+ T_time: v.T_time.Format("2006-01-02 15:04:05"),
|
|
|
|
|
+ T_name: deviceSensor.T_name,
|
|
|
|
|
+ T_tl: sp.T_Tlower,
|
|
|
|
|
+ T_tu: sp.T_Tupper,
|
|
|
|
|
+ T_rhl: sp.T_RHlower,
|
|
|
|
|
+ T_rhu: sp.T_RHupper,
|
|
|
|
|
+ }
|
|
|
|
|
+ r = append(r, item)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return r, len(r)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func Read_DeviceData_ById_List_OrderByTimeAes(SN string, T_id int, Time_start_ string, Time_end_ string, page int, page_z int) ([]DeviceData_R, int) {
|
|
func Read_DeviceData_ById_List_OrderByTimeAes(SN string, T_id int, Time_start_ string, Time_end_ string, page int, page_z int) ([]DeviceData_R, int) {
|
|
|
o := orm.NewOrm()
|
|
o := orm.NewOrm()
|
|
|
var maps []DeviceData_
|
|
var maps []DeviceData_
|
|
@@ -623,7 +804,7 @@ func Read_DeviceData_By_T_snid_List(T_snid string, Time_start_ string, Time_end_
|
|
|
if len(sn_id) == 3 {
|
|
if len(sn_id) == 3 {
|
|
|
Read_DeviceSensorParameter_All_Map(sn_id[0], lib.To_int(sn_id[1]))
|
|
Read_DeviceSensorParameter_All_Map(sn_id[0], lib.To_int(sn_id[1]))
|
|
|
r_maps, r_maps_num := Read_DeviceData_ById_List(sn_id[0], lib.To_int(sn_id[1]), Time_start_, Time_end_, 0, 9999)
|
|
r_maps, r_maps_num := Read_DeviceData_ById_List(sn_id[0], lib.To_int(sn_id[1]), Time_start_, Time_end_, 0, 9999)
|
|
|
- for i, _ := range r_maps {
|
|
|
|
|
|
|
+ for i := range r_maps {
|
|
|
atoi, _ := strconv.Atoi(sn_id[2])
|
|
atoi, _ := strconv.Atoi(sn_id[2])
|
|
|
r_maps[i].Sorts = atoi
|
|
r_maps[i].Sorts = atoi
|
|
|
}
|
|
}
|
|
@@ -675,6 +856,200 @@ func Read_DeviceData_By_T_snid_List(T_snid string, Time_start_ string, Time_end_
|
|
|
return maps[offset:offset_z], maps_num
|
|
return maps[offset:offset_z], maps_num
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func Read_DeviceData_By_T_snid_List_ChartShow(T_snid string, Time_start_ string, Time_end_ string) ([]DeviceData_ChartShow, int64) {
|
|
|
|
|
+ T_snid_list := strings.Split(strings.Trim(T_snid, "|"), "|")
|
|
|
|
|
+
|
|
|
|
|
+ // 优化:批量预加载所有传感器信息和参数,避免 N+1 查询问题
|
|
|
|
|
+ sensorMap := make(map[string]DeviceSensor) // key: "SN_T_id"
|
|
|
|
|
+ parameterMap := make(map[string]DeviceSensorParameter_R) // key: "SN_T_id"
|
|
|
|
|
+
|
|
|
|
|
+ for _, v := range T_snid_list {
|
|
|
|
|
+ sn_id := strings.Split(v, ",")
|
|
|
|
|
+ if len(sn_id) < 2 {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ sn := sn_id[0]
|
|
|
|
|
+ sensorId := lib.To_int(sn_id[1])
|
|
|
|
|
+ key := fmt.Sprintf("%s_%d", sn, sensorId)
|
|
|
|
|
+
|
|
|
|
|
+ // 预加载传感器信息
|
|
|
|
|
+ if sensor, ok := Read_DeviceSensor_ByT_sn(sn, sensorId); ok {
|
|
|
|
|
+ sensorMap[key] = sensor
|
|
|
|
|
+ // 预加载传感器参数
|
|
|
|
|
+ if param, ok := Read_DeviceSensorParameter(sn, sensorId); ok {
|
|
|
|
|
+ parameterMap[key] = param
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 预估容量以减少内存重新分配
|
|
|
|
|
+ estimatedCapacity := len(T_snid_list) * 100
|
|
|
|
|
+ maps := make([]DeviceData_ChartShow, 0, estimatedCapacity)
|
|
|
|
|
+ var maps_num int64
|
|
|
|
|
+
|
|
|
|
|
+ // 遍历所有传感器,加载数据
|
|
|
|
|
+ for _, v := range T_snid_list {
|
|
|
|
|
+ sn_id := strings.Split(v, ",")
|
|
|
|
|
+ if len(sn_id) < 2 {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取 SN 和传感器 ID
|
|
|
|
|
+ sn := sn_id[0]
|
|
|
|
|
+ sensorId := lib.To_int(sn_id[1])
|
|
|
|
|
+
|
|
|
|
|
+ // 使用优化后的函数,传入预加载的传感器信息
|
|
|
|
|
+ key := fmt.Sprintf("%s_%d", sn, sensorId)
|
|
|
|
|
+ sensor, hasSensor := sensorMap[key]
|
|
|
|
|
+ param, hasParam := parameterMap[key]
|
|
|
|
|
+
|
|
|
|
|
+ if !hasSensor || !hasParam {
|
|
|
|
|
+ logs.Debug("跳过传感器(未找到信息):", sn, sensorId)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取数据列表(使用新的优化函数)
|
|
|
|
|
+ r_maps, r_maps_num := Read_DeviceData_ById_List_ChartShow_WithCache(sn, sensorId, Time_start_, Time_end_, sensor, param)
|
|
|
|
|
+
|
|
|
|
|
+ maps = append(maps, r_maps...)
|
|
|
|
|
+ maps_num += int64(r_maps_num)
|
|
|
|
|
+
|
|
|
|
|
+ logs.Debug("加载数据:", sn, sensorId, r_maps_num)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果没有数据,直接返回
|
|
|
|
|
+ if maps_num == 0 {
|
|
|
|
|
+ return maps, maps_num
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 按时间倒序排序
|
|
|
|
|
+ sort.Slice(maps, func(i, j int) bool {
|
|
|
|
|
+ return maps[i].T_time > maps[j].T_time
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ logs.Debug("总数据:", maps_num, " 导出全部")
|
|
|
|
|
+ return maps, maps_num
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// DeviceDataStatistics 设备数据统计结构(单个传感器)
|
|
|
|
|
+type DeviceDataStatistics struct {
|
|
|
|
|
+ SN string `json:"sn"` // 设备SN
|
|
|
|
|
+ SensorId int `json:"sensor_id"` // 传感器ID
|
|
|
|
|
+ SensorName string `json:"sensor_name"` // 传感器名称
|
|
|
|
|
+ TempMax float32 `json:"temp_max"` // 最高温度
|
|
|
|
|
+ TempMin float32 `json:"temp_min"` // 最低温度
|
|
|
|
|
+ TempAvg float32 `json:"temp_avg"` // 平均温度
|
|
|
|
|
+ HumidityMax float32 `json:"humidity_max"` // 最高湿度
|
|
|
|
|
+ HumidityMin float32 `json:"humidity_min"` // 最低湿度
|
|
|
|
|
+ HumidityAvg float32 `json:"humidity_avg"` // 平均湿度
|
|
|
|
|
+ DataCount int64 `json:"data_count"` // 数据条数
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// DeviceDataStatisticsTotal 所有传感器数据统计汇总结构
|
|
|
|
|
+type DeviceDataStatisticsTotal struct {
|
|
|
|
|
+ TempMax float32 `json:"temp_max"` // 所有传感器中的最高温度
|
|
|
|
|
+ TempMin float32 `json:"temp_min"` // 所有传感器中的最低温度
|
|
|
|
|
+ TempAvg float32 `json:"temp_avg"` // 所有传感器温度平均值
|
|
|
|
|
+ HumidityMax float32 `json:"humidity_max"` // 所有传感器中的最高湿度
|
|
|
|
|
+ HumidityMin float32 `json:"humidity_min"` // 所有传感器中的最低湿度
|
|
|
|
|
+ HumidityAvg float32 `json:"humidity_avg"` // 所有传感器湿度平均值
|
|
|
|
|
+ DataCount int64 `json:"data_count"` // 总数据条数
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Read_DeviceData_Statistics 获取设备数据统计信息
|
|
|
|
|
+func Read_DeviceData_Statistics(SN string, T_id int, Time_start_ string, Time_end_ string) (DeviceDataStatistics, error) {
|
|
|
|
|
+ // 先尝试从缓存获取
|
|
|
|
|
+ if cachedStats, found := Redis_DeviceDataStatistics_Get(SN, T_id, Time_start_, Time_end_); found {
|
|
|
|
|
+ logs.Debug("从缓存获取统计数据: SN=%s, T_id=%d", SN, T_id)
|
|
|
|
|
+ return cachedStats, nil
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ o := orm.NewOrm()
|
|
|
|
|
+ var stats DeviceDataStatistics
|
|
|
|
|
+ var result []orm2.ParamsList
|
|
|
|
|
+
|
|
|
|
|
+ // 构建时间条件
|
|
|
|
|
+ sql_time := ""
|
|
|
|
|
+ if len(Time_start_) > 1 {
|
|
|
|
|
+ sql_time += " t_time >= '" + Time_start_ + "' AND "
|
|
|
|
|
+ }
|
|
|
|
|
+ if len(Time_end_) > 1 {
|
|
|
|
|
+ sql_time += " t_time <= '" + Time_end_ + "' AND "
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查询统计数据:最大值、最小值、平均值、数据条数
|
|
|
|
|
+ sql := "SELECT " +
|
|
|
|
|
+ "MAX(t_t) AS temp_max, " +
|
|
|
|
|
+ "MIN(t_t) AS temp_min, " +
|
|
|
|
|
+ "AVG(t_t) AS temp_avg, " +
|
|
|
|
|
+ "MAX(t_rh) AS humidity_max, " +
|
|
|
|
|
+ "MIN(t_rh) AS humidity_min, " +
|
|
|
|
|
+ "AVG(t_rh) AS humidity_avg, " +
|
|
|
|
|
+ "COUNT(*) AS data_count " +
|
|
|
|
|
+ "FROM z_device_data_" + SN + " " +
|
|
|
|
|
+ "WHERE " + sql_time + " t_id = " + strconv.Itoa(T_id)
|
|
|
|
|
+
|
|
|
|
|
+ logs.Debug(sql)
|
|
|
|
|
+ _, err := o.Raw(sql).ValuesList(&result)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logs.Error(lib.FuncName(), err)
|
|
|
|
|
+ return stats, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if len(result) == 0 || result[0][0] == nil {
|
|
|
|
|
+ return stats, errors.New("没有查询到数据")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 填充统计数据
|
|
|
|
|
+ stats.SN = SN
|
|
|
|
|
+ stats.SensorId = T_id
|
|
|
|
|
+
|
|
|
|
|
+ // 解析统计结果
|
|
|
|
|
+ if result[0][0] != nil {
|
|
|
|
|
+ if val, err := strconv.ParseFloat(result[0][0].(string), 32); err == nil {
|
|
|
|
|
+ stats.TempMax = float32(val)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if result[0][1] != nil {
|
|
|
|
|
+ if val, err := strconv.ParseFloat(result[0][1].(string), 32); err == nil {
|
|
|
|
|
+ stats.TempMin = float32(val)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if result[0][2] != nil {
|
|
|
|
|
+ if val, err := strconv.ParseFloat(result[0][2].(string), 32); err == nil {
|
|
|
|
|
+ stats.TempAvg = float32(val)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if result[0][3] != nil {
|
|
|
|
|
+ if val, err := strconv.ParseFloat(result[0][3].(string), 32); err == nil {
|
|
|
|
|
+ stats.HumidityMax = float32(val)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if result[0][4] != nil {
|
|
|
|
|
+ if val, err := strconv.ParseFloat(result[0][4].(string), 32); err == nil {
|
|
|
|
|
+ stats.HumidityMin = float32(val)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if result[0][5] != nil {
|
|
|
|
|
+ if val, err := strconv.ParseFloat(result[0][5].(string), 32); err == nil {
|
|
|
|
|
+ stats.HumidityAvg = float32(val)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if result[0][6] != nil {
|
|
|
|
|
+ if val, err := strconv.ParseInt(result[0][6].(string), 10, 64); err == nil {
|
|
|
|
|
+ stats.DataCount = val
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 将统计数据存入缓存(10分钟有效期)
|
|
|
|
|
+ if err := Redis_DeviceDataStatistics_Set(SN, T_id, Time_start_, Time_end_, stats); err != nil {
|
|
|
|
|
+ logs.Error("缓存统计数据失败: ", err)
|
|
|
|
|
+ // 即使缓存失败也继续返回数据
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return stats, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func Read_DeviceData_ById_Year_List(SN string) []orm2.ParamsList {
|
|
func Read_DeviceData_ById_Year_List(SN string) []orm2.ParamsList {
|
|
|
o := orm.NewOrm()
|
|
o := orm.NewOrm()
|
|
|
|
|
|