129 lines
2.8 KiB
Go
129 lines
2.8 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/hex"
|
||
"net"
|
||
"time"
|
||
)
|
||
|
||
// 传感器通信相关结构和函数
|
||
type SensorComm struct {
|
||
conn net.Conn
|
||
address string
|
||
lastQueryTime time.Time
|
||
lastResetTime time.Time
|
||
querySuccess bool
|
||
responseRecv chan bool
|
||
queryCmd []byte
|
||
resetCmd []byte
|
||
}
|
||
|
||
// 创建新的传感器通信实例
|
||
func newSensorComm(conn net.Conn) *SensorComm {
|
||
sc := &SensorComm{
|
||
conn: conn,
|
||
address: conn.RemoteAddr().String(),
|
||
lastQueryTime: time.Time{},
|
||
lastResetTime: time.Time{},
|
||
querySuccess: false,
|
||
responseRecv: make(chan bool, 1), // 带缓冲的通道,避免阻塞
|
||
queryCmd: prepareQueryCommand(),
|
||
resetCmd: prepareResetCommand(),
|
||
}
|
||
return sc
|
||
}
|
||
|
||
// 准备查询命令
|
||
func prepareQueryCommand() []byte {
|
||
queryHexData := "01 03 01 F4 00 10 04 08"
|
||
queryHexData = removeSpaces(queryHexData)
|
||
queryData, err := hex.DecodeString(queryHexData)
|
||
if err != nil {
|
||
logger.Printf("解析查询命令错误: %v", err)
|
||
return nil
|
||
}
|
||
return queryData
|
||
}
|
||
|
||
// 准备重置命令
|
||
func prepareResetCommand() []byte {
|
||
resetHexData := "01 06 60 02 00 5A B6 31"
|
||
resetHexData = removeSpaces(resetHexData)
|
||
resetData, err := hex.DecodeString(resetHexData)
|
||
if err != nil {
|
||
logger.Printf("解析重置命令错误: %v", err)
|
||
return nil
|
||
}
|
||
return resetData
|
||
}
|
||
|
||
// 发送查询命令
|
||
func (sc *SensorComm) sendQuery() bool {
|
||
sc.querySuccess = false
|
||
_, err := sc.conn.Write(sc.queryCmd)
|
||
if err != nil {
|
||
logger.Printf("发送查询命令错误: %v", err)
|
||
return false
|
||
}
|
||
|
||
sc.lastQueryTime = time.Now()
|
||
logger.Printf("发送查询命令: %s", time.Now().Format("15:04:05"))
|
||
return true
|
||
}
|
||
|
||
// 发送整点重置命令,在查询成功后执行
|
||
func (sc *SensorComm) resetHourly() bool {
|
||
// 检查是否在过去5分钟内已经重置过
|
||
if time.Since(sc.lastResetTime) < 5*time.Minute {
|
||
logger.Printf("最近5分钟内已重置过雨量,跳过本次重置")
|
||
return false
|
||
}
|
||
|
||
// 直接发送重置命令
|
||
_, err := sc.conn.Write(sc.resetCmd)
|
||
if err != nil {
|
||
logger.Printf("发送重置命令错误: %v", err)
|
||
return false
|
||
}
|
||
|
||
logger.Printf("发送雨量重置命令: %s", time.Now().Format("15:04:05"))
|
||
sc.lastResetTime = time.Now()
|
||
return true
|
||
}
|
||
// 处理接收到的数据
|
||
func (sc *SensorComm) handleData(data []byte) *SensorData {
|
||
sensorData := parseData(data)
|
||
if sensorData != nil {
|
||
sc.querySuccess = true
|
||
|
||
// 通知已收到响应
|
||
select {
|
||
case sc.responseRecv <- true:
|
||
default:
|
||
// 通道已满或无接收者,这里不阻塞
|
||
}
|
||
|
||
return sensorData
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// 关闭连接
|
||
func (sc *SensorComm) close() {
|
||
if sc.conn != nil {
|
||
sc.conn.Close()
|
||
}
|
||
close(sc.responseRecv)
|
||
}
|
||
|
||
// 移除字符串中的空格
|
||
func removeSpaces(s string) string {
|
||
var result []rune
|
||
for _, r := range s {
|
||
if r != ' ' {
|
||
result = append(result, r)
|
||
}
|
||
}
|
||
return string(result)
|
||
}
|