//windows  Linux系统通用
//本代码使用的编译环境为:golang-go
//运行指令:go run tcpServerDemoDO.go
package main

import (
	"fmt"
	"net"
	"strings"
	"time"
)

var buf []byte = make([]byte, 4096)
var serverIp = "192.168.10.173"
var serverPort = "6000"

func main() {
	//参数连接 --> https://www.jianshu.com/p/325ac02fc31c
	fmt.Println("本机作为服务端")
	fmt.Println("本机IP：" + serverIp + "端口：" + serverPort)
	localAddress, _ := net.ResolveTCPAddr("tcp4", serverIp + ":" + serverPort) //定义一个本机IP和端口。
	var tcpListener, err = net.ListenTCP("tcp", localAddress)           //在刚定义好的地址上进监听请求。
	if err != nil {
		fmt.Println("监听出错：", err)
		return
	}
	defer func() { //担心return之前忘记关闭连接，因此在defer中先约定好关它。
		tcpListener.Close()
	}()

	fmt.Println("等待客户机的连接")
	var conn, err2 = tcpListener.AcceptTCP() //接受连接。
	if err2 != nil {
		fmt.Println("接受连接失败：", err2)
		return
	}
	fmt.Println("连接成功")

	var remoteAddr = conn.RemoteAddr() //获取连接到的对像的IP地址。
	fmt.Println("客户端IP与端口 --> ", remoteAddr)
		
	fmt.Println("DO 继电器输出接口测试：")
	
	//控制 DO 继电器输出接口 OUT1 吸合
	fmt.Println("发送开机指令：AT+STACH1=1\\r\\n")
	conn.Write([]byte("AT+STACH1=1\r\n"))
	a, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:a]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")
	time.Sleep(500000000) //0.5秒
	//================================================

	//时间单位改成 秒
	fmt.Println("发送时间单位改成 秒指令：AT+DLYUNIT=0\\r\\n")
	conn.Write([]byte("AT+DLYUNIT=0\r\n"))
	b, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:b]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")
	time.Sleep(500000000) //0.5秒
	//================================================

	//控制 DO 继电器输出接口 OUT1 点动开 OUT1开启后延时5秒再关闭
	fmt.Println("控制 DO 继电器输出接口 OUT1 点动开 OUT1开启后延时5秒再关闭指令：AT+STACH1=3,5,100000,1000000\\r\\n")
	conn.Write([]byte("AT+STACH1=3,5,100000,1000000\r\n"))
	c, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:c]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")
	time.Sleep(500000000)
	//================================================

	//控制 DO 继电器输出接口 OUT1~OUT4 间隔 1 秒轮流吸合
	fmt.Println("控制 DO 继电器输出接口 OUT1~OUT4 间隔 1 秒轮流吸合：AT+DODLY=1,1,4,1,1\\r\\n")
	conn.Write([]byte("AT+DODLY=1,1,4,1,1\r\n"))
	d, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:d]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")	
	time.Sleep(500000000) //0.5秒
	//================================================
	
	//继电器 OUT1 每天早上 8 点定时吸合
	fmt.Println("发送继电器 OUT1 每天早上 8 点定时吸合指令：AT+AUTOCONT=2,TASK1,[CYC:1],[T:3,0|1|2|3|4|5|6,08:00:00],[DO:0,1,1,100000,100000,1000000],[N:1,0]\\r\\n ")
	conn.Write([]byte("AT+AUTOCONT=2,TASK1,[CYC:1],[T:3,0|1|2|3|4|5|6,08:00:00],[DO:0,1,1,100000,100000,1000000],[N:1,0]\r\n"))
	e, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:e]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")
	time.Sleep(500000000) //0.5秒
	//================================================
	
	//N1/DI1 联动控制继电器 OUT1 点动输出 5 秒
	fmt.Println("发送 //N1/DI1 联动控制继电器 OUT1 点动输出 5 秒指令：AT+LINKAGE1=3,5,100000,1,1000000\\r\\n")
	conn.Write([]byte("AT+LINKAGE1=3,5,100000,1,1000000\r\n"))
	f, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:f]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")
	time.Sleep(500000000) //0.5秒
	
	//上电默认状态设置为吸合
	fmt.Println("发送上电默认状态设置为吸合指令：AT+DODEFSTA=1\\r\\n")
	conn.Write([]byte("AT+DODEFSTA=1\r\n"))
	g, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:g]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")
	time.Sleep(500000000) //0.5秒
	
	//使能状态主动上传
	fmt.Println("发送使能状态主动上传指令：AT+KPUPLOAD=1\\r\\n")
	conn.Write([]byte("AT+KPUPLOAD=1\r\n"))
	h, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:h]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")
	time.Sleep(500000000) //0.5秒
	
	//使能掉电保存
	fmt.Println("发送使能掉电保存指令：AT+KPKEEP=1\\r\\n")
	conn.Write([]byte("AT+KPKEEP=1\r\n"))
	i, err := conn.Read(buf)
	fmt.Println("指令应答：", strings.Replace(string(buf[:i]), "\r\n", "\\r\\n", 1))
	fmt.Println("指令执行成功！")
	time.Sleep(500000000) //0.5秒
	
	fmt.Println("测试完成！")

	fmt.Println("更多控制指令的详细解释请查阅《网络控制器AT指令手册V2.9.PDF》")
	fmt.Println("本Demo仅用于开发参考，不能直接用于商业项目实施！")
}
