diff --git a/internal/handler/sensor.go b/internal/handler/sensor.go index eda30a6..0cd20d6 100644 --- a/internal/handler/sensor.go +++ b/internal/handler/sensor.go @@ -2,6 +2,7 @@ package handler import ( "encoding/json" + "fmt" "net/http" "time" @@ -183,3 +184,25 @@ func (h *SensorHandler) GetLatestSensorRawData(w http.ResponseWriter, r *http.Re return } } + +// TriggerManualQuery 手动触发向所有设备发送查询指令 +func (h *SensorHandler) TriggerManualQuery(w http.ResponseWriter, r *http.Request) { + count := tcp.TriggerManualQuery() + + response := struct { + Success bool `json:"success"` + Message string `json:"message"` + Count int `json:"count"` + }{ + Success: count > 0, + Message: fmt.Sprintf("成功向%d个设备发送查询指令", count), + Count: count, + } + + w.Header().Set("Content-Type", "application/json") + encoder := json.NewEncoder(w) + if err := encoder.Encode(response); err != nil { + logger.Logger.Printf("JSON编码失败: %v", err) + http.Error(w, "服务器内部错误", http.StatusInternalServerError) + } +} diff --git a/internal/tcp/sensor.go b/internal/tcp/sensor.go index c1fab75..a2d10ca 100644 --- a/internal/tcp/sensor.go +++ b/internal/tcp/sensor.go @@ -349,3 +349,24 @@ func hexCharToByte(c byte) (byte, bool) { } return 0, false } + +// TriggerManualQuery 手动触发向所有设备发送查询 +func TriggerManualQuery() int { + activeConnections.mu.RLock() + defer activeConnections.mu.RUnlock() + + count := 0 + for addr, conn := range activeConnections.conns { + // 只有活跃的连接才发送查询 + if time.Since(conn.lastActivity) < time.Minute*10 { + if err := conn.sendQuery(); err != nil { + logger.Logger.Printf("手动触发查询失败 [%s]: %v", addr, err) + } else { + logger.Logger.Printf("手动触发查询成功 [%s]", addr) + count++ + } + } + } + + return count +} diff --git a/main.go b/main.go index e62843b..474fc16 100644 --- a/main.go +++ b/main.go @@ -55,6 +55,7 @@ func main() { http.HandleFunc("/api/latest", sensorHandler.GetLatestData) http.HandleFunc("/api/status", sensorHandler.GetConnectionStatus) http.HandleFunc("/api/raw/latest", sensorHandler.GetLatestSensorRawData) + http.HandleFunc("/api/trigger-query", sensorHandler.TriggerManualQuery) http.HandleFunc("/", sensorHandler.ServeStatic) // 启动TCP服务器 diff --git a/static/index.html b/static/index.html index 315e487..6b4c779 100644 --- a/static/index.html +++ b/static/index.html @@ -361,6 +361,29 @@ }); } + // 触发设备进行数据查询 + function triggerDeviceQuery() { + return fetch('/api/trigger-query') + .then(response => response.json()) + .then(data => { + console.log('触发设备查询结果:', data); + if (data.success) { + // 如果成功触发查询,等待3秒后获取新数据 + return new Promise(resolve => { + setTimeout(() => { + console.log('等待3秒后获取新数据'); + resolve(data); + }, 3000); + }); + } + return data; + }) + .catch(error => { + console.error('触发设备查询失败:', error); + return { success: false, message: '触发设备查询失败' }; + }); + } + // 查询最新数据 function queryLatestData() { const interval = document.getElementById('interval').value; @@ -388,11 +411,22 @@ // 加载状态指示 document.getElementById('mainChart').style.opacity = 0.5; + const latestDataElement = document.querySelector('.latest-data'); + latestDataElement.style.opacity = 0.5; - // 同时获取最新的传感器原始数据 - fetchLatestSensorData(); - - fetch(`/api/latest?interval=${interval}&start=${startDateTime}&end=${endDateTime}`) + // 首先触发设备查询 + triggerDeviceQuery() + .then(() => { + // 获取最新传感器数据 + return fetchLatestSensorData(); + }) + .then(() => { + // 恢复最新数据区域的不透明度 + latestDataElement.style.opacity = 1; + + // 获取聚合数据 + return fetch(`/api/latest?interval=${interval}&start=${startDateTime}&end=${endDateTime}`); + }) .then(response => response.json()) .then(data => { updateChart(data); @@ -410,6 +444,7 @@ alert('获取最新数据失败,请检查网络连接'); // 恢复正常显示 document.getElementById('mainChart').style.opacity = 1; + latestDataElement.style.opacity = 1; }); }