diff --git a/internal/dao/sensor.go b/internal/dao/sensor.go index 07a0743..220b2ab 100644 --- a/internal/dao/sensor.go +++ b/internal/dao/sensor.go @@ -219,3 +219,33 @@ func findNearestPoint(t time.Time, timestamps []int64, dataMap map[int64]model.A return dataMap[nearest] } + +// GetLatestSensorData 获取最新的一条传感器数据 +func (dao *SensorDAO) GetLatestSensorData() (*model.SensorData, error) { + query := ` + SELECT id, timestamp, wind_speed, wind_force, wind_direction_8, + wind_direction_360, humidity, temperature, atm_pressure, + solar_radiation, rainfall + FROM sensor_data + ORDER BY timestamp DESC + LIMIT 1 + ` + + var data model.SensorData + err := dao.db.QueryRow(query).Scan( + &data.ID, &data.Timestamp, &data.WindSpeed, &data.WindForce, &data.WindDirection8, + &data.WindDirection360, &data.Humidity, &data.Temperature, &data.AtmPressure, + &data.SolarRadiation, &data.Rainfall, + ) + + if err != nil { + if err == sql.ErrNoRows { + logger.Logger.Printf("未找到传感器数据") + return nil, nil + } + logger.Logger.Printf("获取最新传感器数据失败: %v", err) + return nil, err + } + + return &data, nil +} diff --git a/internal/handler/sensor.go b/internal/handler/sensor.go index d5c86a2..eda30a6 100644 --- a/internal/handler/sensor.go +++ b/internal/handler/sensor.go @@ -128,3 +128,58 @@ func (h *SensorHandler) GetLatestData(w http.ResponseWriter, r *http.Request) { return } } + +// GetLatestSensorRawData 获取最新的一条传感器原始数据 +func (h *SensorHandler) GetLatestSensorRawData(w http.ResponseWriter, r *http.Request) { + data, err := h.dao.GetLatestSensorData() + if err != nil { + logger.Logger.Printf("获取最新传感器数据失败: %v", err) + http.Error(w, "服务器内部错误", http.StatusInternalServerError) + return + } + + if data == nil { + // 没有数据,返回空对象 + w.Header().Set("Content-Type", "application/json") + w.Write([]byte("{}")) + return + } + + // 转换为前端友好的格式 + response := struct { + ID int64 `json:"id"` + Timestamp time.Time `json:"timestamp"` + FormattedTime string `json:"formatted_time"` + WindSpeed float64 `json:"wind_speed"` // 风速(m/s) + WindForce int `json:"wind_force"` // 风力(级) + WindDirection8 int `json:"wind_direction_8"` // 8方位风向 + WindDirection360 int `json:"wind_direction_360"` // 360度风向 + Humidity float64 `json:"humidity"` // 湿度(%) + Temperature float64 `json:"temperature"` // 温度(℃) + AtmPressure float64 `json:"atm_pressure"` // 大气压(kPa) + SolarRadiation int `json:"solar_radiation"` // 太阳辐射(W/m²) + Rainfall int `json:"rainfall"` // 累计雨量(mm) + }{ + ID: data.ID, + Timestamp: data.Timestamp, + FormattedTime: data.Timestamp.Format("2006-01-02 15:04:05"), + WindSpeed: float64(data.WindSpeed) / 100.0, + WindForce: data.WindForce, + WindDirection8: data.WindDirection8, + WindDirection360: data.WindDirection360, + Humidity: float64(data.Humidity) / 10.0, + Temperature: float64(data.Temperature) / 10.0, + AtmPressure: float64(data.AtmPressure) / 10.0, + SolarRadiation: data.SolarRadiation, + Rainfall: data.Rainfall, + } + + w.Header().Set("Content-Type", "application/json") + encoder := json.NewEncoder(w) + encoder.SetIndent("", " ") + if err := encoder.Encode(response); err != nil { + logger.Logger.Printf("JSON编码失败: %v", err) + http.Error(w, "服务器内部错误", http.StatusInternalServerError) + return + } +} diff --git a/main.go b/main.go index 6df05a0..e62843b 100644 --- a/main.go +++ b/main.go @@ -54,6 +54,7 @@ func main() { http.HandleFunc("/api/data", sensorHandler.GetAggregatedData) http.HandleFunc("/api/latest", sensorHandler.GetLatestData) http.HandleFunc("/api/status", sensorHandler.GetConnectionStatus) + http.HandleFunc("/api/raw/latest", sensorHandler.GetLatestSensorRawData) http.HandleFunc("/", sensorHandler.ServeStatic) // 启动TCP服务器 diff --git a/static/index.html b/static/index.html index 97a7a7a..315e487 100644 --- a/static/index.html +++ b/static/index.html @@ -41,6 +41,49 @@ gap: 5px; } + .latest-data { + margin-bottom: 20px; + padding: 15px; + border: 1px solid #ddd; + border-radius: 4px; + background-color: #f8f9fa; + } + + .latest-data h3 { + margin-top: 0; + margin-bottom: 10px; + color: #333; + } + + .data-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 10px; + } + + .data-item { + padding: 8px; + border: 1px solid #eee; + border-radius: 4px; + background-color: white; + } + + .data-label { + font-weight: bold; + color: #555; + font-size: 12px; + } + + .data-value { + font-size: 18px; + color: #007bff; + } + + .data-unit { + font-size: 12px; + color: #777; + } + select, input, button { padding: 5px 10px; border: 1px solid #ddd; @@ -128,7 +171,7 @@