Bläddra i källkod

后端对接mqtt、开关继电器、单灯控制器控制灯控、策略完善等

chengqian 1 dag sedan
förälder
incheckning
0b93cbb058

+ 4 - 4
config/config.yaml

@@ -11,8 +11,8 @@ nums:
     envNum: 1
     optNum: 1
 policy:
-    control: regulateLight
-    endTime: "00:50"
+    control: regulateSwitch
+    endTime: "15:55"
     id: 1
-    startTime: "00:50"
-tunnelId: LC12312312
+    startTime: "15:50"
+tunnelId: LC20250328150559

+ 1 - 1
config/serial.json

@@ -7,7 +7,7 @@
       "BaudRate":9600,
       "DataBits":8,
       "StopBits":1,
-      "Parity":"E",
+      "Parity":"N",
       "Timeout":3000
     }
   }

+ 11 - 2
dev/devs.json

@@ -1,7 +1,7 @@
 {
   "envDev": [
     {
-      "Sn": "ddd",
+      "Sn": "LC1742785166039",
       "Address": "01",
       "Name": "环境传感器",
       "TaskTime":5,
@@ -9,7 +9,7 @@
       "SerialId": 1
     },
     {
-      "Sn": "xxx",
+      "Sn": "LC1742806333179",
       "Address": "02",
       "Name": "光传感器",
       "TaskTime":5,
@@ -25,5 +25,14 @@
       "RadarId": 1,
       "SerialId": 1
     }
+  ],
+  "switchDev": [
+    {
+      "Sn": "zzz",
+      "Address": "01",
+      "Name": "开关继电器",
+      "RadarId": 1,
+      "SerialId": 1
+    }
   ]
 }

+ 0 - 4
log/info.20250324.log

@@ -1,4 +0,0 @@
-{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-24 16:16:29.607"}
-{"level":"error","msg":"parseTopic err","time":"2025-03-24 16:16:41.159"}
-{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-24 16:17:32.628"}
-{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-24 17:04:39.512"}

+ 0 - 3
log/info.20250326.log

@@ -1,3 +0,0 @@
-{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-26 09:25:14.630"}
-{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-26 16:27:34.081"}
-{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-26 17:07:35.499"}

+ 49 - 0
log/info.20250331.log

@@ -0,0 +1,49 @@
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 15:54:04.515"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 15:55:25.754"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 15:56:07.139"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 15:56:41.761"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 15:57:25.635"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 15:58:43.659"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 15:59:28.788"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:00:27.654"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:00:56.712"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:01:09.977"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:01:52.044"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:06:37.920"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:07:06.921"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:07:37.756"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:10:28.058"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:11:22.531"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:12:00.623"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:12:45.141"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:13:16.490"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:13:23.835"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:13:40.322"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:13:56.433"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:15:19.454"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:15:30.302"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:15:39.797"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:16:07.135"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:16:34.506"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:16:44.144"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:37:53.507"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:38:35.281"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:46:11.069"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:46:39.987"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:46:47.786"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:47:35.542"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:48:28.066"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:48:37.971"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:48:52.331"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:49:24.690"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:49:38.736"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 16:50:31.699"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 17:17:05.627"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 17:18:56.520"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 17:19:03.471"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 17:19:15.946"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 17:19:30.343"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 17:19:38.740"}
+{"level":"error","msg":"无法打开串口 CO3: The system cannot find the file specified.","time":"2025-03-31 17:19:38.747"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 17:19:48.859"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-03-31 17:20:06.164"}

+ 16 - 0
log/info.20250402.log

@@ -0,0 +1,16 @@
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 10:25:13.101"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 11:33:39.236"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 11:34:44.729"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 11:54:15.049"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 11:56:33.241"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 11:58:29.792"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 13:34:05.303"}
+{"level":"error","msg":"无法打开串口 COM3: The system cannot find the file specified.","time":"2025-04-02 13:34:05.314"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 13:48:03.291"}
+{"level":"info","msg":"获取串口失败,设备编号:zzz,错误:serial port not found","time":"2025-04-02 13:48:03.304"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 13:48:34.824"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 13:53:26.827"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 13:55:12.137"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 13:55:29.124"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 14:22:49.292"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-02 14:24:23.908"}

+ 31 - 0
log/info.20250403.log

@@ -0,0 +1,31 @@
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 10:39:31.372"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 10:40:23.281"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 10:43:36.655"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 10:44:38.053"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 10:47:50.234"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 10:58:16.533"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 11:04:53.082"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 13:41:32.142"}
+{"level":"error","msg":"MClient.ConnectionLostHandler:MQTT连接已经断开,原因: read tcp 198.18.0.1:61047-\u003e118.253.180.18:1883: wsarecv: An existing connection was forcibly closed by the remote host.","time":"2025-04-03 13:57:53.973"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 13:57:54.004"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 14:34:52.209"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 14:40:00.846"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 14:40:41.248"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:04:23.362"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:07:11.754"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:07:46.032"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:08:11.363"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:08:53.946"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:09:45.884"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:10:56.937"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:11:33.566"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:12:03.709"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:14:20.329"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:14:39.684"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:22:33.178"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:29:33.405"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:29:46.922"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:30:04.535"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:37:53.121"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:43:58.755"}
+{"level":"info","msg":"MClient.OnConnectHandler:MQTT连接成功","time":"2025-04-03 15:46:07.427"}

+ 7 - 6
main.go

@@ -2,8 +2,8 @@ package main
 
 import (
 	"fmt"
-	"smart_tunnel_edge/mqtt"
-	"smart_tunnel_edge/util"
+	"smart_tunnel_edge/service"
+	"smart_tunnel_edge/timer"
 	"smart_tunnel_edge/util/config"
 	"smart_tunnel_edge/util/logger"
 )
@@ -11,7 +11,7 @@ import (
 func main() {
 	logger.InitLog() //初始化日志
 
-	mqtt.InitMqtt() //初始化mqtt
+	service.InitMqtt() //初始化mqtt
 
 	err := config.LoadSerialConfig()
 	if err != nil {
@@ -19,7 +19,7 @@ func main() {
 		return
 	}
 	//打开串口并监听
-	if err := util.OpenSerialPort(config.SerialConfig.SerialMap); err != nil {
+	if err := service.OpenSerialPort(config.SerialConfig.SerialMap); err != nil {
 		fmt.Printf("处理串口时发生错误: %v", err)
 		return
 	}
@@ -30,10 +30,11 @@ func main() {
 		return
 	}
 	for _, dev := range config.DevConfig.EnvDevs { //循环设备制定采集任务
-		go util.StartDeviceCollection(dev)
+		go service.StartDeviceCollection(dev)
 	}
 
-	go util.TimeTasks()
+	service.InitControl()
+	go timer.TimeTasks()
 
 	select {}
 

+ 17 - 0
protocol/switchRelay/model.go

@@ -1 +1,18 @@
 package switchRelay
+
+type DataPack struct {
+	Address  string //地址码
+	Function byte   //功能码
+	Way      int    //操作路数
+	Command  int    //控制指令
+	Crc      uint16 //Crc校验码
+}
+
+type MultiLoopDataPack struct {
+	Address  string //地址码
+	Function byte   //功能码
+	TurnOff  int    //开关指令
+	State    []int  //回路状态
+	Command  []byte //控制指令
+	Crc      uint16 //Crc校验码
+}

+ 68 - 2
protocol/switchRelay/service.go

@@ -1,5 +1,71 @@
 package switchRelay
 
-//开指令
+import (
+	"encoding/hex"
+	"github.com/valyala/bytebufferpool"
+)
 
-//关指令
+func (x DataPack) GetSwitchRelayCommand() *bytebufferpool.ByteBuffer {
+	buf := bytebufferpool.Get()
+	x.Function = 0x05
+	decodeAddress, _ := hex.DecodeString(x.Address)
+	buf.Write(decodeAddress)
+	buf.WriteByte(x.Function)
+	buf.Write([]byte{0x00, byte(x.Way - 1)})
+	if x.Command == 1 {
+		buf.Write([]byte{0xFF, 0x00})
+	} else {
+		buf.Write([]byte{0x00, 0x00})
+	}
+
+	x.Crc = calculateCRC16Modbus(buf.Bytes())
+	buf.Write([]byte{byte(x.Crc & 0xFF), byte(x.Crc >> 8)})
+	return buf
+}
+
+func (x MultiLoopDataPack) GetControlMuchSwitchRelayCommand() *bytebufferpool.ByteBuffer {
+	buf := bytebufferpool.Get()
+	x.Function = 0x10
+	decodeAddress, _ := hex.DecodeString(x.Address)
+	buf.Write(decodeAddress)
+	buf.WriteByte(x.Function)
+	if x.TurnOff == 1 {
+		buf.Write([]byte{0x04, 0x1A, 0x00, 0x02, 0x04, 0x00})
+	} else {
+		buf.Write([]byte{0x04, 0x1C, 0x00, 0x02, 0x04, 0x00})
+	}
+	buf.Write(generateHexSwitchState(x.State))
+	x.Command = []byte{0x00, 0x00}
+	buf.Write(x.Command)
+	x.Crc = calculateCRC16Modbus(buf.Bytes())
+	buf.Write([]byte{byte(x.Crc & 0xFF), byte(x.Crc >> 8)})
+	return buf
+}
+
+func calculateCRC16Modbus(data []byte) uint16 {
+	var crc uint16 = 0xFFFF // CRC-16 初始化值
+	for _, byteVal := range data {
+		crc ^= uint16(byteVal) // 对字节进行异或操作
+		for i := 0; i < 8; i++ {
+			if crc&0x0001 != 0 {
+				crc >>= 1
+				crc ^= 0xA001 // 多项式 0xA001
+			} else {
+				crc >>= 1
+			}
+		}
+	}
+	return crc
+}
+
+func generateHexSwitchState(switches []int) []byte {
+	var state int
+
+	// 遍历切片,设置对应位置的开关为 1
+	for _, s := range switches {
+		state |= 1 << (s - 1) // 设置第s位为1,s从1开始
+	}
+
+	// 返回字节切片,使用 []byte{} 来包裹十六进制值
+	return []byte{byte(state)}
+}

+ 26 - 10
radar_test.go

@@ -3,7 +3,6 @@ package main
 import (
 	"encoding/hex"
 	"fmt"
-	"smart_tunnel_edge/util/config"
 	"testing"
 )
 
@@ -43,16 +42,22 @@ func Test_verify(t *testing.T) {
 	//command := dataPack.GetEnvGatherCommand()
 	//fmt.Println("+++++", hex.EncodeToString(command.Bytes()))
 
-	updates := map[string]interface{}{
-		"id":        1,
-		"startTime": "00:30",
-		"endTime":   "00:20",
-	}
-	err := config.UpdateYAMLConfig(updates)
-	if err != nil {
-		fmt.Println(err)
-	}
+	//updates := map[string]interface{}{
+	//	"id":        1,
+	//	"startTime": "00:30",
+	//	"endTime":   "00:20",
+	//}
+	//err := config.UpdateYAMLConfig(updates)
+	//if err != nil {
+	//	fmt.Println(err)
+	//}
 
+	//pack := switchRelay.DataPack{Address: "fe", Way: 2, Command: 0}
+	//command := pack.GetSwitchRelayCommand()
+	//fmt.Println("MingLing。。。", hex.EncodeToString(command.Bytes()))
+	ints := []int{1, 2, 3}
+	state := generateHexSwitchState(ints)
+	fmt.Println("转换后:", hex.EncodeToString(state))
 }
 
 func parseHexString(hexStr string) string {
@@ -66,5 +71,16 @@ func parseHexString(hexStr string) string {
 	// 将字节数组转换为对应的字符
 	return string(bytes)
 }
+func generateHexSwitchState(switches []int) []byte {
+	var state int
+
+	// 遍历切片,设置对应位置的开关为 1
+	for _, s := range switches {
+		state |= 1 << (s - 1) // 设置第s位为1,s从1开始
+	}
+
+	// 返回字节切片,使用 []byte{} 来包裹十六进制值
+	return []byte{byte(state)}
+}
 
 // UpdateYAMLConfig 用于更新 YAML 配置文件中的多个值

+ 67 - 7
util/devmgr.go

@@ -1,8 +1,9 @@
-package util
+package service
 
 import (
 	"smart_tunnel_edge/protocol/envSensor"
 	"smart_tunnel_edge/protocol/lampControl"
+	"smart_tunnel_edge/protocol/switchRelay"
 	"smart_tunnel_edge/util/config"
 	"smart_tunnel_edge/util/logger"
 	"sync"
@@ -14,8 +15,21 @@ var mu sync.Mutex
 const (
 	RegulateLight  = "regulateLight"
 	RegulateSwitch = "regulateSwitch"
+	LowLightLevel  = 30
+	HighLightLevel = 60
 )
 
+// 初始化时单灯或者开关继电器
+func InitControl() {
+	if config.Instance().Policy.Control == RegulateLight {
+		go SetLampBright(1, LowLightLevel)
+		go SetLampBright(2, LowLightLevel)
+	} else {
+		go SetSwitchRelay(1, 1, 1)
+		go SetSwitchRelay(2, 1, 1)
+	}
+}
+
 func StartDeviceCollection(dev *config.EnvDev) {
 	coverTime := dev.TaskTime
 	ticker := time.NewTicker(time.Duration(coverTime) * time.Minute)
@@ -49,14 +63,11 @@ func StartDeviceCollection(dev *config.EnvDev) {
 	}
 }
 
-// 采集方法
-//func EnvGather(address string) {
-//
-//}
-
-func OperationLampSwitchJudge(radarId int8, brightness int) {
+func OperationLampSwitchJudge(radarId int8, brightness, way, turnOf int) {
 	if config.Instance().Policy.Control == RegulateLight {
 		SetLampBright(radarId, brightness)
+	} else {
+		SetSwitchRelay(radarId, way, turnOf)
 	}
 }
 
@@ -88,6 +99,55 @@ func SetLampBright(radarId int8, brightness int) {
 				return
 			}
 		}()
+		time.Sleep(time.Millisecond * 150)
 	}
 	wg.Wait()
 }
+
+// 开关继电器开关方法(单路)
+func SetSwitchRelay(radarId int8, way, turnOf int) {
+	for _, dev := range config.DevConfig.SwitchDevs {
+		if dev.RadarId != radarId {
+			continue
+		}
+		port, err := GetSerialPort(dev.SerialId)
+		if err != nil {
+			logger.Logger.Infof("获取串口失败,设备编号:%v,错误:%v", dev.Sn, err)
+			return
+		}
+		command := switchRelay.DataPack{Address: dev.Address, Way: way, Command: turnOf}.GetSwitchRelayCommand()
+		mu.Lock() // 锁定串口操作
+		write, err := port.Write(command.Bytes())
+		mu.Unlock() // 锁定串口操作
+
+		if write < 0 || err != nil {
+			logger.Logger.Errorf("控制单路开关继电器:%v操作失败,错误:%v", dev.Sn, err)
+			continue
+		}
+		time.Sleep(time.Millisecond * 150)
+	}
+}
+
+// 开关继电器开关方法(多路)
+func SetSwitchMultiRelay(radarId int8, turnOf int, ways []int) {
+	for _, dev := range config.DevConfig.SwitchDevs {
+		if dev.RadarId != radarId {
+			continue
+		}
+		port, err := GetSerialPort(dev.SerialId)
+		if err != nil {
+			logger.Logger.Infof("获取串口失败,设备编号:%v,错误:%v", dev.Sn, err)
+			return
+		}
+		command := switchRelay.MultiLoopDataPack{Address: dev.Address, TurnOff: turnOf, State: ways}.GetControlMuchSwitchRelayCommand()
+		mu.Lock() // 锁定串口操作
+		write, err := port.Write(command.Bytes())
+		mu.Unlock() // 锁定串口操作
+
+		if write < 0 || err != nil {
+			logger.Logger.Errorf("控制多路开关继电器:%v操作失败,错误:%v", dev.Sn, err)
+			continue
+		}
+		time.Sleep(time.Millisecond * 150)
+	}
+}

+ 1 - 1
util/model.go

@@ -1,4 +1,4 @@
-package util
+package service
 
 type EnvData struct {
 	Sn          string  `json:"sn"`

+ 28 - 11
mqtt/mqtt_handle.go

@@ -1,4 +1,4 @@
-package mqtt
+package service
 
 import (
 	"encoding/json"
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"runtime"
 	"runtime/debug"
+	"smart_tunnel_edge/mqtt"
 	"smart_tunnel_edge/util/config"
 	"smart_tunnel_edge/util/logger"
 	"strconv"
@@ -23,7 +24,7 @@ func InitMqtt() {
 var MqttService *MqttHandler
 
 type MqttHandler struct {
-	queue *MlQueue
+	queue *mqtt.MlQueue
 }
 
 var _handlerOnce sync.Once
@@ -32,17 +33,17 @@ var _handlerSingle *MqttHandler
 func GetHandler() *MqttHandler {
 	_handlerOnce.Do(func() {
 		_handlerSingle = &MqttHandler{
-			queue: NewQueue(10000),
+			queue: mqtt.NewQueue(10000),
 		}
 	})
 	return _handlerSingle
 }
 
 func (o *MqttHandler) SubscribeTopics() {
-	GetMQTTMgr().Subscribe("smart_tunnel/#", AtLeastOnce, o.HandlerData)
+	mqtt.GetMQTTMgr().Subscribe("smart_tunnel/#", mqtt.AtLeastOnce, o.HandlerData)
 }
 
-func (o *MqttHandler) HandlerData(m Message) {
+func (o *MqttHandler) HandlerData(m mqtt.Message) {
 	for {
 		ok, cnt := o.queue.Put(&m)
 		if ok {
@@ -69,20 +70,35 @@ func (o *MqttHandler) Handler() interface{} {
 		} else if quantity > 1000 {
 			logger.Logger.Warnf("数据队列累积过多,请注意优化,当前队列条数:%d", quantity)
 		}
-		m, ok := msg.(*Message)
-		fmt.Println("主题:", m.Topic())
+		m, ok := msg.(*mqtt.Message)
 		if !ok {
 			continue
 		}
-		_, topic, err := ParseTopic(m.Topic())
+		tunnelId, topic, err := ParseTopic(m.Topic())
 		if err != nil {
 			logger.Logger.Errorf("parseTopic err")
 			continue
 		}
-
+		if tunnelId != config.Instance().TunnelId {
+			continue
+		}
 		switch topic {
 		case TopicLampControl:
-
+			data := m.PayloadString()
+			data1 := data[0:1]
+			data2 := data[1:]
+			radarId, _ := strconv.Atoi(data1)
+			brightNess, _ := strconv.Atoi(data2)
+			SetLampBright(int8(radarId), brightNess)
+		case TopicSwitchControl:
+			data := m.PayloadString()
+			data1 := data[0:1]
+			data2 := data[1:2]
+			data3 := data[2:3]
+			radarId, _ := strconv.Atoi(data1)
+			way, _ := strconv.Atoi(data2)
+			turnOf, _ := strconv.Atoi(data3)
+			SetSwitchRelay(int8(radarId), way, turnOf)
 		case TopicTunnelTactics:
 			// 修改策略
 			num, _ := strconv.Atoi(m.PayloadString())
@@ -113,7 +129,7 @@ func (o *MqttHandler) Handler() interface{} {
 }
 
 func (o *MqttHandler) Publish(topic string, data interface{}) error {
-	return GetMQTTMgr().Publish(topic, data, AtLeastOnce)
+	return mqtt.GetMQTTMgr().Publish(topic, data, mqtt.AtLeastOnce)
 }
 
 func (o *MqttHandler) GetTopic(operation string) string {
@@ -146,4 +162,5 @@ const (
 	TopicTunnelTactics = "tunnelTactics"
 	TopicTunnelTiming  = "tunnelTiming"
 	TopicLampControl   = "lampControl"
+	TopicSwitchControl = "switchControl"
 )

+ 37 - 19
util/serialmgr.go

@@ -1,4 +1,4 @@
-package util
+package service
 
 import (
 	"encoding/hex"
@@ -7,7 +7,6 @@ import (
 	"fmt"
 	"github.com/tarm/serial"
 	"log"
-	"smart_tunnel_edge/mqtt"
 	"smart_tunnel_edge/util/config"
 	"smart_tunnel_edge/util/logger"
 	"strconv"
@@ -82,14 +81,14 @@ func listenPort(portCode int8, port *serial.Port) {
 		n, err := port.Read(buf)
 		if err != nil {
 			log.Printf("读取串口数据失败: %v", err)
-			continue
+			return
 		}
 		if n > 0 {
 			dataString := hex.EncodeToString(buf[:n])
-			fmt.Println("数据:", dataString)
+			//fmt.Println("数据:", dataString)
 			switch {
 			case len(dataString) == 42 && dataString[2:6] == "0310": //环境传感器数据
-				fmt.Print("环境传感:")
+				//fmt.Print("环境传感:")
 				shiDu, _ := strconv.ParseInt(dataString[6:10], 16, 0)
 				wenDu, _ := strconv.ParseInt(dataString[10:14], 16, 0)
 				gz, _ := strconv.ParseInt(dataString[30:38], 16, 0)
@@ -106,15 +105,15 @@ func listenPort(portCode int8, port *serial.Port) {
 				}
 
 				jsonData, _ := json.Marshal(data)
-				topic := mqtt.MqttService.GetTopic(mqtt.TopicGatherDataEnv)
-				err := mqtt.MqttService.Publish(topic, jsonData)
+				topic := MqttService.GetTopic(TopicGatherDataEnv)
+				err := MqttService.Publish(topic, jsonData)
 				if err != nil {
 					logger.Logger.Errorf("MQTT Publish err = %s", err.Error())
 					continue
 				}
 
 			case len(dataString) == 14 && dataString[2:6] == "0302": //光照传感器数据
-				fmt.Printf("光传感:")
+				//fmt.Printf("光传感:")
 				gz, _ := strconv.ParseInt(dataString[6:10], 16, 0)
 
 				if _, exists := env[dataString[0:2]]; !exists {
@@ -130,8 +129,8 @@ func listenPort(portCode int8, port *serial.Port) {
 				}
 
 				jsonData, _ := json.Marshal(data)
-				topic := mqtt.MqttService.GetTopic(mqtt.TopicGatherDataOpt)
-				err := mqtt.MqttService.Publish(topic, jsonData)
+				topic := MqttService.GetTopic(TopicGatherDataOpt)
+				err := MqttService.Publish(topic, jsonData)
 				if err != nil {
 					logger.Logger.Errorf("MQTT Publish err = %s", err.Error())
 					continue
@@ -151,10 +150,10 @@ func listenPort(portCode int8, port *serial.Port) {
 							timer.Reset(lightDuration)
 						}
 					} else {
-						OperationLampSwitchJudge(portCode, 100)
+						OperationLampSwitchJudge(portCode, HighLightLevel, 2, 1) //brightness代表亮度,way代表开关继电器回路数,turnOf代表开还是关,1代表开,0代表关
 						isLightOperate = true
 						timer = time.AfterFunc(lightDuration, func() {
-							OperationLampSwitchJudge(portCode, 20)
+							OperationLampSwitchJudge(portCode, LowLightLevel, 2, 0)
 							isLightOperate = false
 						})
 					}
@@ -171,14 +170,33 @@ func listenPort(portCode int8, port *serial.Port) {
 				envAverage := calculateAverage(env)
 				optAverage := calculateAverage(opt)
 
-				fmt.Println("环境平均值:", envAverage)
-				fmt.Println("光照平均值:", optAverage)
-
-				//TODO 作比较,进行灯控操作并清空切片
-				if envAverage-6 >= 0 {
-
+				control := config.Instance().Policy.Control
+				if envAverage-optAverage >= 20000 { //如果相差20000Lux开两路或者调节亮度为90%
+					if control == RegulateLight {
+						go SetLampBright(1, 90)
+						go SetLampBright(2, 90)
+					} else if control == RegulateSwitch {
+						go SetSwitchMultiRelay(1, 1, []int{1, 2, 3}) //int[]{}表达控制的回路
+						go SetSwitchMultiRelay(2, 1, []int{1, 2, 3})
+					}
+				} else if envAverage-optAverage >= 10000 { //如果相差10000Lux开两路或者调节亮度为60%
+					if control == RegulateLight {
+						go SetLampBright(1, 60)
+						go SetLampBright(2, 60)
+					} else if control == RegulateSwitch {
+						go SetSwitchRelay(1, 3, 0) //不管如何先将第三路关闭
+						go SetSwitchRelay(2, 3, 0)
+						go SetSwitchMultiRelay(1, 1, []int{1, 2})
+						go SetSwitchMultiRelay(2, 1, []int{1, 2})
+					}
 				} else {
-
+					if control == RegulateLight {
+						go SetLampBright(1, 30)
+						go SetLampBright(2, 30)
+					} else if control == RegulateSwitch {
+						go SetSwitchMultiRelay(1, 0, []int{2, 3})
+						go SetSwitchMultiRelay(2, 0, []int{2, 3})
+					}
 				}
 
 				env = make(map[string]int64)

+ 31 - 0
timer/task.go

@@ -0,0 +1,31 @@
+package timer
+
+import (
+	"github.com/robfig/cron"
+	"smart_tunnel_edge/service"
+	"smart_tunnel_edge/util/config"
+	"time"
+)
+
+var commandQueue = make(chan []byte, 5)
+
+func TimeTasks() {
+	c := cron.New()
+	_ = c.AddFunc("0 */5 * * * ?", func() { //0/5 * * * * ?
+		if config.Instance().Policy.Id == 3 { //如果当前策略是定时改变光照亮度
+			endTime := config.Instance().Policy.EndTime
+			startTime := config.Instance().Policy.StartTime
+			currentTime := time.Now().Format("15:04")
+			if currentTime == startTime {
+				//开灯,将两条路亮度调高
+				go service.OperationLampSwitchJudge(1, service.HighLightLevel, 2, 1)
+				go service.OperationLampSwitchJudge(2, service.HighLightLevel, 2, 1)
+			} else if currentTime == endTime {
+				//关灯,将两条路亮度调低
+				go service.OperationLampSwitchJudge(1, service.LowLightLevel, 2, 0)
+				go service.OperationLampSwitchJudge(2, service.LowLightLevel, 2, 0)
+			}
+		}
+	})
+	c.Start()
+}

+ 11 - 2
util/config/config.go

@@ -126,8 +126,9 @@ func LoadDevConfig() error {
 }
 
 type Devs struct {
-	EnvDevs  []*EnvDev  `json:"envDev"`
-	LampDevs []*LampDev `json:"lampDev"`
+	EnvDevs    []*EnvDev    `json:"envDev"`
+	LampDevs   []*LampDev   `json:"lampDev"`
+	SwitchDevs []*SwitchDev `json:"switchDev"`
 }
 
 type EnvDev struct {
@@ -147,6 +148,14 @@ type LampDev struct {
 	SerialId int8   `json:"serialId"` // 串口id
 }
 
+type SwitchDev struct {
+	Sn       string `json:"sn"`       //设备SN
+	Address  string `json:"address"`  //设备地址
+	Name     string `json:"name"`     //设备名称
+	RadarId  int8   `json:"radarId"`  //雷达id
+	SerialId int8   `json:"serialId"` // 串口id
+}
+
 // 读取、更新并保存配置的统一方法
 func UpdateYAMLConfig(updates map[string]interface{}) error {
 	data, err := ioutil.ReadFile("./config/config.yaml")

+ 0 - 52
util/task.go

@@ -1,52 +0,0 @@
-package util
-
-import (
-	"github.com/robfig/cron"
-)
-
-var commandQueue = make(chan []byte, 5)
-
-func TimeTasks() {
-	c := cron.New()
-	//每3分钟监测状态
-	//_ = c.AddFunc("0 0/5 * * * ? ", func() {
-	_ = c.AddFunc("0/5 * * * * ?", func() {
-		//for _, dev := range config.DevConfig.LampDevs {
-		//	pack := lampControl.DataPack{Addr: dev.Address, Data: []byte{0x01}}
-		//	command := pack.GetLampTurnOnOffCommand()
-		//	//dataPack := lampControl.DataPack{Addr: dev.Address}
-		//	//command := dataPack.GetLampSetBrightCommand(10)
-		//	fmt.Println("命令:", hex.EncodeToString(command.Bytes()))
-		//	port, err := GetSerialPort(dev.SerialId)
-		//	if err != nil {
-		//		logger.Logger.Infof(err.Error())
-		//		continue
-		//	}
-		//	write, err := port.Write(command.Bytes())
-		//	fmt.Println("write.....,", write)
-		//	if err != nil {
-		//		fmt.Println(err.Error())
-		//	}
-		//}
-		//data := EnvData{Temperature: float64(98) / 10.0, Humidity: float64(345) / 10.0, Illuminance: 666}
-		//
-		//jsonData, _ := json.Marshal(data)
-		//topic := mqtt.MqttService.GetTopic(mqtt.TopicGatherDataEnv)
-		//err := mqtt.MqttService.Publish(topic, jsonData)
-		//if err != nil {
-		//	logger.Logger.Errorf("MQTT Publish err = %s", err.Error())
-		//}
-		//parseTopic, s, _ := mqtt.ParseTopic("smart_tunnel/xyzSuiDao/gatherDataEnv")
-		//fmt.Println("====", parseTopic)
-		//fmt.Println("====", s)
-		//
-		//fmt.Println("主题:", topic)
-
-		//fmt.Println("实时更新。。。", config.Instance().Policy.StartTime)
-		//fmt.Println("实时更新。。。", config.Instance().Mqtt.Server)
-		//config.ReloadConfig()
-		//fmt.Println(config.Instance().Policy.Id == 2)
-		//fmt.Println(config.Instance().Policy.Control == "regulateSwitch")
-	})
-	c.Start()
-}