212 lines
5.8 KiB
Go
212 lines
5.8 KiB
Go
package business
|
||
|
||
import (
|
||
"encoding/hex"
|
||
"fmt"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"Dynamic_environmental_detection/logger"
|
||
)
|
||
|
||
// DebugHandler 调试处理器
|
||
type DebugHandler struct {
|
||
modbusConfig *ModbusConfig
|
||
}
|
||
|
||
// NewDebugHandler 创建调试处理器
|
||
func NewDebugHandler() *DebugHandler {
|
||
return &DebugHandler{
|
||
modbusConfig: DefaultModbusConfig(),
|
||
}
|
||
}
|
||
|
||
// TestDevice 测试单个设备
|
||
func (dh *DebugHandler) TestDevice(slaveIDStr, sensorTypeStr string) error {
|
||
// 解析参数
|
||
slaveID, err := strconv.ParseUint(slaveIDStr, 10, 8)
|
||
if err != nil {
|
||
return fmt.Errorf("Invalid slave address: %s", slaveIDStr)
|
||
}
|
||
|
||
sensorTypeInt, err := strconv.Atoi(sensorTypeStr)
|
||
if err != nil {
|
||
return fmt.Errorf("Invalid sensor type: %s", sensorTypeStr)
|
||
}
|
||
|
||
sensorType := SensorType(sensorTypeInt)
|
||
if sensorType < 1 || sensorType > 3 {
|
||
return fmt.Errorf("Sensor type must be between 1-3")
|
||
}
|
||
|
||
logger.Logger.Printf("=== Starting Debug Mode ===")
|
||
logger.Logger.Printf("Slave ID: %d, Sensor Type: %s", slaveID, GetSensorTypeName(sensorType))
|
||
|
||
// 获取寄存器配置
|
||
registerConfig, err := GetRegisterConfig(sensorType)
|
||
if err != nil {
|
||
return fmt.Errorf("Failed to get register configuration: %v", err)
|
||
}
|
||
|
||
// 创建调试客户端
|
||
client, err := NewDebugModbusClient(dh.modbusConfig, byte(slaveID))
|
||
if err != nil {
|
||
return fmt.Errorf("Failed to create Modbus client: %v", err)
|
||
}
|
||
defer client.Close()
|
||
|
||
// 读取数据
|
||
logger.Logger.Printf("Reading registers - Address: %d, Count: %d", registerConfig.RegisterAddress, registerConfig.RegisterCount)
|
||
|
||
rawData, err := client.ReadHoldingRegisters(
|
||
registerConfig.RegisterAddress,
|
||
registerConfig.RegisterCount,
|
||
)
|
||
|
||
if err != nil {
|
||
return fmt.Errorf("Read failed: %v", err)
|
||
}
|
||
|
||
// 显示原始响应
|
||
dh.printRawResponse(rawData, byte(slaveID))
|
||
|
||
// 解析数据
|
||
processedData, err := dh.parseSensorData(rawData, sensorType, byte(slaveID))
|
||
if err != nil {
|
||
return fmt.Errorf("Data parsing failed: %v", err)
|
||
}
|
||
|
||
// 显示解析结果
|
||
dh.printParsedData(processedData, sensorType)
|
||
|
||
logger.Logger.Printf("=== Debug Completed ===")
|
||
return nil
|
||
}
|
||
|
||
// TestRawCommand 测试原始Modbus命令(简化版)
|
||
func (dh *DebugHandler) TestRawCommand(hexCommand string) error {
|
||
logger.Logger.Printf("=== Raw Command Debug Mode ===")
|
||
logger.Logger.Printf("Sending command: %s", hexCommand)
|
||
|
||
// 解码十六进制命令
|
||
command, err := hex.DecodeString(hexCommand)
|
||
if err != nil {
|
||
return fmt.Errorf("Command format error: %v", err)
|
||
}
|
||
|
||
if len(command) < 6 {
|
||
return fmt.Errorf("Command length insufficient, minimum 6 bytes required")
|
||
}
|
||
|
||
slaveID := command[0]
|
||
functionCode := command[1]
|
||
|
||
// 只支持读保持寄存器功能码
|
||
if functionCode != 0x03 {
|
||
return fmt.Errorf("Only read holding registers function code (0x03) is supported, current: 0x%02X", functionCode)
|
||
}
|
||
|
||
address := uint16(command[2])<<8 | uint16(command[3])
|
||
quantity := uint16(command[4])<<8 | uint16(command[5])
|
||
|
||
logger.Logger.Printf("Parsed command - SlaveID: %d, Function Code: 0x%02X, Address: %d, Quantity: %d",
|
||
slaveID, functionCode, address, quantity)
|
||
|
||
// 创建调试客户端
|
||
client, err := NewDebugModbusClient(dh.modbusConfig, slaveID)
|
||
if err != nil {
|
||
return fmt.Errorf("Failed to create Modbus client: %v", err)
|
||
}
|
||
defer client.Close()
|
||
|
||
// 读取寄存器
|
||
rawData, err := client.ReadHoldingRegisters(address, quantity)
|
||
if err != nil {
|
||
return fmt.Errorf("Read failed: %v", err)
|
||
}
|
||
|
||
// 显示原始响应
|
||
dh.printRawResponse(rawData, slaveID)
|
||
|
||
logger.Logger.Printf("=== Raw Command Debug Completed ===")
|
||
return nil
|
||
}
|
||
|
||
// printRawResponse 打印原始响应
|
||
func (dh *DebugHandler) printRawResponse(rawData []byte, slaveID byte) {
|
||
logger.Logger.Printf("Response received (%d bytes):", len(rawData))
|
||
|
||
// 格式化的十六进制输出
|
||
hexParts := make([]string, len(rawData))
|
||
for i, b := range rawData {
|
||
hexParts[i] = fmt.Sprintf("%02X", b)
|
||
}
|
||
logger.Logger.Printf("Hexadecimal: %s", strings.Join(hexParts, " "))
|
||
|
||
// ASCII显示
|
||
asciiParts := make([]string, len(rawData))
|
||
for i, b := range rawData {
|
||
if b >= 32 && b <= 126 {
|
||
asciiParts[i] = string(b)
|
||
} else {
|
||
asciiParts[i] = "."
|
||
}
|
||
}
|
||
logger.Logger.Printf("ASCII: %s", strings.Join(asciiParts, ""))
|
||
}
|
||
|
||
// parseSensorData 解析传感器数据
|
||
func (dh *DebugHandler) parseSensorData(rawData []byte, sensorType SensorType, slaveID byte) (*ProcessedSensorData, error) {
|
||
// 创建临时的SensorData用于处理
|
||
sensorData := &SensorData{
|
||
DeviceUUID: fmt.Sprintf("debug_device_%d", slaveID),
|
||
TaskID: "debug",
|
||
Address: "Debug Location",
|
||
SensorType: sensorType,
|
||
Facility: "00",
|
||
RawData: rawData,
|
||
Timestamp: time.Now(),
|
||
}
|
||
|
||
// 使用数据处理器
|
||
processor := NewDataProcessor()
|
||
processedData, err := processor.ProcessSensorData(sensorData)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return processedData, nil
|
||
}
|
||
|
||
// printParsedData 打印解析结果
|
||
func (dh *DebugHandler) printParsedData(data *ProcessedSensorData, sensorType SensorType) {
|
||
logger.Logger.Printf("=== Data Parsing Results ===")
|
||
logger.Logger.Printf("Sensor Type: %s", GetSensorTypeName(sensorType))
|
||
logger.Logger.Printf("Timestamp: %s", time.Unix(data.Timestamp, 0).Format("2006-01-02 15:04:05"))
|
||
|
||
switch sensorType {
|
||
case SensorTypeTemperatureHumidity:
|
||
if len(data.Values) >= 2 {
|
||
logger.Logger.Printf("Temperature: %.1f°C", data.Values[0])
|
||
logger.Logger.Printf("Humidity: %.1f%%", data.Values[1])
|
||
}
|
||
case SensorTypeWaterLeak:
|
||
statusText := "Normal"
|
||
if data.Status == 1 {
|
||
statusText = "Alarm"
|
||
}
|
||
logger.Logger.Printf("Water Leak Status: %d (%s)", data.Status, statusText)
|
||
case SensorTypeSmoke:
|
||
statusText := "Normal"
|
||
if data.Status == 1 {
|
||
statusText = "Alarm"
|
||
}
|
||
logger.Logger.Printf("Smoke Status: %d (%s)", data.Status, statusText)
|
||
}
|
||
|
||
if data.Error != "" {
|
||
logger.Logger.Printf("Parsing Error: %s", data.Error)
|
||
}
|
||
}
|