rain_monitor/api/api.go
2025-07-12 17:41:49 +08:00

203 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package api
import (
"encoding/json"
"log"
"net/http"
"rain_monitor/db"
"rain_monitor/modbus"
"rain_monitor/models"
"time"
)
func StartWebServer() {
http.HandleFunc("/api/status", handleStatus)
http.HandleFunc("/api/raw/latest", handleLatestRawData)
http.HandleFunc("/api/trigger-query", handleTriggerQuery)
http.HandleFunc("/api/data", handleQueryData)
http.HandleFunc("/api/latest", handleLatestData)
http.Handle("/", http.FileServer(http.Dir("static")))
log.Println("Web服务器已启动监听端口 10003")
err := http.ListenAndServe(":10003", nil)
if err != nil {
log.Fatalf("Web服务器启动失败: %v", err)
}
}
func handleStatus(w http.ResponseWriter, r *http.Request) {
status := modbus.GetConnectionStatus()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(status)
}
func handleLatestRawData(w http.ResponseWriter, r *http.Request) {
weatherData, err1 := db.GetLatestWeatherData()
rainData, err2 := db.GetLatestRainGaugeData()
if (weatherData == nil && rainData == nil) || (err1 != nil && err2 != nil) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusNotFound)
json.NewEncoder(w).Encode(map[string]interface{}{
"error": "没有可用的数据",
"details": map[string]interface{}{
"weather_error": err1,
"rain_error": err2,
},
})
return
}
result := map[string]interface{}{}
if weatherData != nil && !weatherData.Timestamp.IsZero() {
result["timestamp"] = weatherData.Timestamp.Format(time.RFC3339)
result["formatted_time"] = weatherData.Timestamp.Format("2006-01-02 15:04:05")
} else if rainData != nil && !rainData.Timestamp.IsZero() {
result["timestamp"] = rainData.Timestamp.Format(time.RFC3339)
result["formatted_time"] = rainData.Timestamp.Format("2006-01-02 15:04:05")
} else {
result["timestamp"] = time.Now().Format(time.RFC3339)
result["formatted_time"] = time.Now().Format("2006-01-02 15:04:05")
}
if weatherData != nil {
result["temperature"] = weatherData.Temperature
result["humidity"] = weatherData.Humidity
result["wind_speed"] = weatherData.WindSpeed
result["wind_direction_8"] = weatherData.WindDirection8
result["wind_direction_360"] = weatherData.WindDirection360
result["atm_pressure"] = weatherData.AtmPressure
result["solar_radiation"] = weatherData.SolarRadiation
result["weather_rainfall"] = weatherData.Rainfall
}
if rainData != nil {
result["total_rainfall"] = rainData.TotalRainfall
result["daily_rainfall"] = rainData.DailyRainfall
result["instant_rainfall"] = rainData.InstantRainfall
}
if rainData != nil {
result["rainfall"] = rainData.TotalRainfall
} else if weatherData != nil {
result["rainfall"] = weatherData.Rainfall
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(result)
}
func handleTriggerQuery(w http.ResponseWriter, r *http.Request) {
err1 := modbus.QueryDevice(modbus.DeviceWeatherStation)
err2 := modbus.QueryDevice(modbus.DeviceRainGauge)
result := map[string]interface{}{
"success": err1 == nil || err2 == nil,
"timestamp": time.Now().Format(time.RFC3339),
}
if err1 != nil {
result["weather_error"] = err1.Error()
}
if err2 != nil {
result["rain_error"] = err2.Error()
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(result)
}
func handleQueryData(w http.ResponseWriter, r *http.Request) {
startStr := r.URL.Query().Get("start")
endStr := r.URL.Query().Get("end")
interval := r.URL.Query().Get("interval")
log.Printf("handleQueryData - 请求参数: start=%s, end=%s, interval=%s", startStr, endStr, interval)
if startStr == "" || endStr == "" {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{"error": "缺少必要的时间参数"})
return
}
start, err := time.Parse(time.RFC3339, startStr)
if err != nil {
log.Printf("开始时间解析失败: %v", err)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{"error": "开始时间格式错误"})
return
}
end, err := time.Parse(time.RFC3339, endStr)
if err != nil {
log.Printf("结束时间解析失败: %v", err)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{"error": "结束时间格式错误"})
return
}
data, err := db.GetAggregatedData(start, end)
if err != nil {
log.Printf("查询聚合数据失败: %v", err)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode([]models.AggregatedData{})
return
}
log.Printf("查询成功,返回 %d 条记录", len(data))
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)
}
func handleLatestData(w http.ResponseWriter, r *http.Request) {
startStr := r.URL.Query().Get("start")
endStr := r.URL.Query().Get("end")
interval := r.URL.Query().Get("interval")
log.Printf("handleLatestData - 请求参数: start=%s, end=%s, interval=%s", startStr, endStr, interval)
if startStr == "" || endStr == "" {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{"error": "缺少必要的时间参数"})
return
}
start, err := time.Parse(time.RFC3339, startStr)
if err != nil {
log.Printf("开始时间解析失败: %v", err)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{"error": "开始时间格式错误"})
return
}
end, err := time.Parse(time.RFC3339, endStr)
if err != nil {
log.Printf("结束时间解析失败: %v", err)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{"error": "结束时间格式错误"})
return
}
data, err := db.GetAggregatedData(start, end)
if err != nil {
log.Printf("查询聚合数据失败: %v", err)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode([]models.AggregatedData{})
return
}
log.Printf("查询成功,返回 %d 条记录", len(data))
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)
}