1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024 |
- package comm
- import (
- "bytes"
- "encoding/binary"
- "encoding/hex"
- "fmt"
- MQTT "github.com/eclipse/paho.mqtt.golang"
- "github.com/jacobsa/go-serial/serial"
- "github.com/kptyun/KPTCOMM/pkg/setting"
- "github.com/kptyun/KPTCOMM/routers/restful"
- "github.com/recoilme/slowpoke"
- "github.com/siddontang/go-log/log"
- "math"
- //"github.com/xormplus/xorm"
- "io"
- "net"
- "strings"
- "sync"
- "time"
- )
- // 一个已经被关闭的channel不会阻塞,已经被关闭的channel会实时返回
- // goroutine退出,关闭done来进行广播
- var needEscape int
- var my_comport io.ReadWriteCloser
- var my_Controlcomport io.ReadWriteCloser
- var SrcAdd []byte
- var commop string = ""
- var delaysendcommop int = 0
- var Boastaddr *net.UDPAddr
- var Logger *log.Logger
- var StopCharP chan int
- // var ProcessKeyP chan []byte
- var ProcessKeyPstr chan []string
- var BroadcastBuf chan []byte
- var file string
- var RunTMRList sync.Map
- var MbTable = []uint16{
- 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
- 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
- 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
- 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
- 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
- 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
- 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
- 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
- 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
- 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
- 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
- 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
- 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
- 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
- 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
- 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
- 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
- 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
- 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
- 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
- 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
- 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
- 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
- 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
- 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
- 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
- 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
- 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
- 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
- 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
- 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
- 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040}
- func CheckSum(data []byte) uint16 {
- var crc16 uint16
- crc16 = 0xffff
- for _, v := range data {
- n := uint8(uint16(v) ^ crc16)
- crc16 >>= 8
- crc16 ^= MbTable[n]
- }
- return crc16
- }
- func getBoastaddr() *net.UDPAddr {
- tempaddr, err := net.ResolveUDPAddr("udp4", "255.255.255.255:8800")
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- return tempaddr
- }
- if strings.TrimSpace(setting.ServerSetting.Netcard) != "" {
- interfaces, err := net.Interfaces()
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- return tempaddr
- }
- for _, i := range interfaces {
- byName, err := net.InterfaceByName(i.Name)
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- return tempaddr
- }
- if byName.Name == strings.TrimSpace(setting.ServerSetting.Netcard) {
- addresses, _ := byName.Addrs()
- for _, v := range addresses {
- if ipnet, ok := v.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
- if ipnet.IP.To4() != nil {
- ipmask := fmt.Sprintf("%d.%d.%d.%d:%d",
- ipnet.IP[12], ipnet.IP[13], ipnet.IP[14], 255, setting.ServerSetting.Broadcast)
- tempaddr, err = net.ResolveUDPAddr("udp4", ipmask)
- if err != nil {
- tempaddr, err = net.ResolveUDPAddr("udp4", "255.255.255.255:8800")
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- return tempaddr
- }
- } else {
- //Logger.Infof("%s %s \r\n", "发现本机IP:", fmt.Sprintf("%d.%d.%d.%d", ipnet.IP[12], ipnet.IP[13], ipnet.IP[14], ipnet.IP[15]))
- return tempaddr
- break
- }
- }
- }
- }
- }
- }
- }
- return tempaddr
- }
- func CommStrValidate(rebus []byte) bool {
- var ResI byte
- ResI = 0
- for i, value := range rebus {
- if i < len(rebus)-1 {
- ResI = ResI + value
- }
- }
- ResI = 0xFF - ResI
- return ResI == rebus[len(rebus)-1]
- }
- func getDateTime(buf []byte) time.Time {
- dataTime := time.Date(2000+int(buf[0]>>2),
- time.Month(((buf[0]&0x03)<<2)|(buf[1]>>6)),
- int((buf[1]&0x3E)>>1),
- int(((buf[1]&0x01)<<4)|(buf[2]>>4)),
- int(((buf[2]&0x0F)<<2)|(buf[3]>>6)),
- int(buf[3]&0x3F),
- 0,
- time.Local)
- return dataTime
- }
- func getWeight(buf1, byte2, byte3 byte) float64 {
- ws := int16((byte3 & 96) >> 5)
- x := int16(buf1)<<8 | int16(byte2)
- if (byte3 >> 7) == 1 {
- x = -1 * x
- }
- s := float64(x)
- for i := int16(0); i < ws; i++ {
- s = s / 10
- }
- return s
- }
- func getSendTailer() byte {
- key := []byte("SendTailer")
- val, err := slowpoke.Get(file, key)
- if err != nil {
- val, err = slowpoke.Get(file, key)
- }
- if val == nil {
- val = make([]byte, 1)
- val[0] = 1
- } else {
- val[0] = val[0] + 1
- if val[0] > 0x0F {
- val[0] = 0
- }
- }
- err = slowpoke.Set(file, key, val)
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- }
- return val[0]
- }
- func getF8(InSrcAddr byte, OriSendId byte) []byte {
- var p1, p2, p3, p4, temps byte
- year := byte(time.Now().Local().Year() % 2000)
- month := byte(time.Now().Local().Month())
- day := byte(time.Now().Local().Day())
- hour := byte(time.Now().Local().Hour())
- minute := byte(time.Now().Local().Minute())
- second := byte(time.Now().Local().Second())
- p1 = (year << 2) | (month >> 2)
- p2 = ((month & 0x03) << 6) | ((day & 0x1F) << 1) | ((hour & 0x3F) >> 4)
- p3 = ((hour & 0x0F) << 4) | ((minute & 0x3F) >> 2)
- p4 = ((minute & 0x03) << 6) | (second & 0x3F)
- buf := make([]byte, 0)
- buf = append(buf, 0x7e)
- buf = append(buf, 0x08)
- buf = append(buf, InSrcAddr)
- buf = append(buf, 0x18)
- buf = append(buf, p1)
- buf = append(buf, p2)
- buf = append(buf, p3)
- buf = append(buf, p4)
- tempTailer := getSendTailer()
- buf = append(buf, ((OriSendId&0x0F)<<8)|(tempTailer&0x0F))
- temps = 0
- for _, i2 := range buf {
- temps = temps + i2
- }
- buf = append(buf, 0xFF-temps)
- return buf
- }
- func duplicateValidate(recbuf []byte) ([]byte, []byte, bool) {
- key := make([]byte, 1)
- val := make([]byte, 2)
- key[0] = recbuf[2]
- if recbuf[3] < 240 {
- val[1] = recbuf[3] + 16
- } else {
- val[1] = recbuf[3]
- }
- if recbuf[1] < byte(len(recbuf)) {
- val[0] = recbuf[recbuf[1]]
- }
- oldval, err := slowpoke.Get(file, key)
- if err != nil {
- Logger.Errorf("%s %s\r\n", file, err)
- oldval, err = slowpoke.Get(file, key)
- }
- if oldval == nil {
- val[0] = 0
- val[1] = 0
- return key, val, true
- }
- return key, val, (oldval[0] != val[0]) || (oldval[1] != val[1])
- }
- func saveduplicateValidate(key []byte, val []byte) {
- err := slowpoke.Set(file, key, val)
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- }
- }
- func processWeight(InSrcAddr byte, recbuf []byte) error {
- sParams := make([]interface{}, 0)
- sParams = append(sParams, InSrcAddr)
- sParams = append(sParams, getDateTime(recbuf[:4]))
- sParams = append(sParams, getWeight(recbuf[4], recbuf[5], recbuf[6]))
- _, err := restful.ExecQuerySqlx("select ProcTimeWeight(?,?,?)", sParams)
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- }
- return err
- }
- func RunsendBuf() {
- defer func() {
- // 发生宕机时,获取panic传递的上下文并打印
- if err := recover(); err != nil {
- fmt.Println("RunsendBuf出错:", err)
- StopCharP <- 1
- }
- }()
- for {
- tmpstr := <-ProcessKeyPstr
- if len(tmpstr[0]) > 0 {
- err := sendBuf(tmpstr, nil)
- //println("recbuf",tmpstr)
- if err != nil {
- //goto openSerial
- StopCharP <- 1
- time.Sleep(10 * time.Millisecond)
- //RunTMRList = make(map[byte]int, 200)
- go OpenComm()
- }
- }
- }
- }
- func RunbroadBuf() {
- var err error
- var conn *net.UDPConn
- var intvalue int
- errT := 0
- for {
- recbuf := <-BroadcastBuf
- if setting.ServerSetting.ControlComm > 0 {
- my_Controlcomport, err = serial.Open(*setting.ControlCommSetting)
- if err != nil {
- Logger.Errorf("%s %s %s %s\r\n", setting.ControlCommSetting.PortName, "打开继电器串口错误: ", setting.CommSetting.PortName, err)
- if setting.DatabaseSetting.Showlog {
- fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "打开继电器串口错误: ", setting.CommSetting.PortName, err)
- }
- } else {
- // Logger.Infof("%s %s\r\n", setting.ControlCommSetting.PortName, "打开继电器成功")
- if (recbuf[6] == 0xCB) && (recbuf[7] == 0xAE) {
- intvalue = 0
- for i := 0; i <= 5; i++ {
- if recbuf[21-i] != 0x20 {
- intvalue = intvalue + int(recbuf[21-i]-0x30)*int(math.Floor(math.Pow10(i)))
- } else {
- break
- }
- }
- _, err = my_Controlcomport.Write(SetCoil(1, recbuf[2]-1,
- (recbuf[14] == 0xC9) && (recbuf[15] == 0xD9) && (intvalue > setting.ServerSetting.RelayDev)))
- if err != nil {
- Logger.Errorf("%s %s: %s\r\n", "写继电器串口错误: ", setting.ControlCommSetting.PortName, err)
- if setting.DatabaseSetting.Showlog {
- fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "写继电器串口错误: ", setting.ControlCommSetting.PortName, err)
- }
- }
- if setting.DatabaseSetting.Showlog {
- fmt.Println(time.Now().Format("2006-01-02 15:04:05"), recbuf[2]-1, " ", intvalue, " ", setting.ServerSetting.RelayDev, " ",
- (recbuf[14] == 0xC9) && (recbuf[15] == 0xD9) && (intvalue > setting.ServerSetting.RelayDev))
- }
- } else {
- _, err = my_Controlcomport.Write(SetCoil(1, recbuf[2]-1, false))
- if err != nil {
- Logger.Errorf("%s %s: %s\r\n", "写继电器串口错误: ", setting.ControlCommSetting.PortName, err)
- if setting.DatabaseSetting.Showlog {
- fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "写继电器串口错误: ", setting.ControlCommSetting.PortName, err)
- }
- }
- }
- _ = my_Controlcomport.Close()
- }
- }
- if setting.ServerSetting.Broadcast > 0 {
- Boastaddr, err = net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%d", setting.ServerSetting.BroadcastAddr, setting.ServerSetting.Broadcast))
- if err != nil && errT == 0 {
- Boastaddr = getBoastaddr()
- }
- }
- if Boastaddr != nil {
- if errT == 0 {
- conn, err = net.DialUDP("udp4", nil, Boastaddr)
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- errT = 1
- } else {
- if len(recbuf) > 0 {
- _, err := conn.Write(recbuf)
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- errT = 1
- _ = conn.Close()
- }
- }
- }
- }
- }
- }
- }
- func processKey0(recbuf []byte) error {
- var err error
- InSrcAddr := recbuf[2]
- s := time.Now()
- if recbuf[3] == 0xF0 || recbuf[3] == 0xE0 {
- for i := 0; i < int((recbuf[1]-4)/7); i++ {
- err = processWeight(InSrcAddr, recbuf[4+(i*7):4+(i+1)*7])
- // break
- }
- }
- if setting.DatabaseSetting.ShowXormlog {
- println("processKey0=================", time.Now().Sub(s).Milliseconds())
- }
- return err
- }
- func processKey1(recbuf []byte) (string, error) {
- sParams := make([]interface{}, 0)
- s := time.Now()
- InSrcAddr := recbuf[2]
- InTime := getDateTime(recbuf[4:8])
- BeginWeight := getWeight(recbuf[8], recbuf[9], recbuf[12])
- endWeight := getWeight(recbuf[10], recbuf[11], recbuf[12])
- InButtonType := recbuf[3]
- OriSendId := recbuf[15]
- LastSortID := recbuf[13]
- LastInorOut := recbuf[14]
- sParams = append(sParams, InSrcAddr)
- sParams = append(sParams, InTime)
- sParams = append(sParams, endWeight)
- _, err := restful.ExecQuerySqlx("select ProcTimeWeight(?,?,?)", sParams)
- if err != nil {
- Logger.Errorf("%s \r\n", err)
- }
- sParams = append(sParams[:0])
- sParams = append(sParams, InSrcAddr)
- sParams = append(sParams, InTime)
- sParams = append(sParams, InButtonType)
- sParams = append(sParams, OriSendId)
- sParams = append(sParams, BeginWeight)
- sParams = append(sParams, endWeight)
- sParams = append(sParams, LastSortID)
- sParams = append(sParams, LastInorOut)
- //InObjAddr INTEGER, InSrcAddr INTEGER,InTime DATETIME,InButtonType INTEGER,OriSendId INTEGER,
- // OldWeight DOUBLE,NewestWeight DOUBLE,LastSortID INTEGER,LastInorOut INTEGER
- queryResult, err := restful.QueryByListv2Sqlx("select ProcNewButton(0,?,?,?,?,?,?,?,?) as resultstr", 0, 1, sParams)
- if err == nil {
- returnmsgmap, _ := queryResult.(map[string]interface{})
- returnmsgmap1, _ := returnmsgmap["rows"].([]map[string]interface{})
- if len(returnmsgmap1) > 0 {
- switch returnmsgmap1[0]["resultstr"].(type) {
- case string:
- if setting.DatabaseSetting.ShowXormlog {
- println("processKey1=================", time.Now().Sub(s).Milliseconds())
- }
- return returnmsgmap1[0]["resultstr"].(string), nil
- }
- }
- }
- return "", err
- }
- func delcommop(lastCommop string) error {
- tx, err := restful.Dbs.Beginx()
- if err != nil {
- fmt.Println("GetT error:", err)
- }
- defer func() {
- switch {
- case err != nil:
- fmt.Println("__error:", err)
- if tx != nil {
- tx.Rollback()
- }
- default:
- if tx != nil {
- err = tx.Commit()
- }
- }
- }()
- sParams := make([]interface{}, 0)
- sParams = append(sParams, lastCommop)
- _, err = restful.ExecQueryT("delete from `commop` where `Cont`= ?", sParams, tx)
- if err == nil {
- commop = ""
- }
- return err
- }
- func getcommop() string {
- queryResult, err := restful.QueryByListSqlx("SELECT `Cont` as resultstr,ID FROM `commop` ", 0, 1, nil)
- if err == nil {
- returnmsgmap, _ := queryResult.(map[string]interface{})
- returnmsgmap1, _ := returnmsgmap["rows"].(map[string][]interface{})
- if len(returnmsgmap1["resultstr"]) > 0 {
- sParams := make([]interface{}, 0)
- sParams = append(sParams, returnmsgmap1["ID"][0])
- //restful.ExecQuery("update commop set `SendTimes`=`SendTimes` + 1 where id = ?", sParams)
- //restful.ExecQuery("delete from commop where `SendTimes`>= 5 and id = ?", sParams)
- restful.ExecQuerySqlx("update commop set `SendTimes`=`SendTimes` + 1 where id = ?", sParams)
- restful.ExecQuerySqlx("delete from commop where `SendTimes`>= 5 and id = ?", sParams)
- return returnmsgmap1["resultstr"][0].(string)
- }
- } else {
- Logger.Errorf("%s \r\n", err)
- }
- return ""
- }
- func getnextOperate() string {
- queryResult, err := restful.QueryByListSqlx("SELECT `Cont` as resultstr,ID FROM `commop` ", 0, 1, nil)
- if err == nil {
- returnmsgmap, _ := queryResult.(map[string]interface{})
- returnmsgmap1, _ := returnmsgmap["lists"].(map[string][]interface{})
- if len(returnmsgmap1["resultstr"]) > 0 {
- sParams := make([]interface{}, 0)
- sParams = append(sParams, returnmsgmap1["ID"][0])
- return returnmsgmap1["resultstr"][0].(string)
- }
- } else {
- Logger.Errorf("%s \r\n", err)
- }
- return ""
- }
- func processChar(inbyte byte, recLength, dataLength, state uint8, recbuf []byte) (uint8, uint8, uint8, bool, []byte) {
- //7E 15 01 F1 7E 45 C8 AB CC EC BD E1 CA F8 20 20 20 20 20 20 20 30 1C
- switch state {
- case 0: //头判断
- if inbyte == 0x7E {
- state = 1
- recLength = 1
- recbuf = recbuf[:0]
- recbuf = append(recbuf, inbyte)
- }
- case 1: //接收长度数据
- if inbyte == 0x7E {
- state = 1
- recLength = 1
- recbuf = recbuf[:0]
- recbuf = append(recbuf, inbyte)
- } else {
- state = 2
- recLength = 2
- dataLength = inbyte + 2
- recbuf = append(recbuf, inbyte)
- }
- case 2: //接收数据中
- recbuf = append(recbuf, inbyte)
- recLength++
- if recLength == dataLength {
- state = 0
- recLength = 0
- return recLength, dataLength, state, true, recbuf
- }
- }
- return recLength, dataLength, state, false, recbuf
- }
- func processCharApi(inbyte byte, recLength, dataLength, state uint8, recbuf []byte) (uint8, uint8, uint8, bool, []byte) {
- //7E 15 01 F1 7E 45 C8 AB CC EC BD E1 CA F8 20 20 20 20 20 20 20 30 1C
- switch state {
- case 0: //头判断
- if inbyte == 0x7E {
- state = 1
- recLength = 1
- recbuf = recbuf[:0]
- recbuf = append(recbuf, inbyte)
- }
- case 1: //头判断
- if inbyte == 0x7E {
- state = 1
- recLength = 1
- recbuf = recbuf[:0]
- recbuf = append(recbuf, inbyte)
- } else if inbyte == 0x00 {
- state = 2
- recLength = 2
- recbuf = append(recbuf, inbyte)
- } else {
- state = 0
- recLength = 0
- recbuf = recbuf[:0]
- }
- case 2: //接收数据中
- if inbyte == 0x7E {
- state = 1
- recLength = 1
- recbuf = recbuf[:0]
- recbuf = append(recbuf, inbyte)
- } else {
- if inbyte == 0x7D {
- needEscape = 1
- } else {
- state = 3
- recLength = 3
- dataLength = inbyte + 4
- if needEscape == 1 {
- needEscape = 0
- recbuf = append(recbuf, inbyte^0x20)
- } else {
- recbuf = append(recbuf, inbyte)
- }
- }
- }
- case 3: //接收数据中
- if inbyte == 0x7D {
- needEscape = 1
- } else {
- recLength++
- if needEscape == 1 {
- needEscape = 0
- recbuf = append(recbuf, inbyte^0x20)
- } else {
- recbuf = append(recbuf, inbyte)
- }
- }
- if recLength == dataLength {
- state = 0
- recLength = 0
- if recbuf[3] == 0x90 && len(recbuf) > 16 && len(recbuf) > int(recbuf[16]+17) {
- SrcAdd = recbuf[4:12]
- recbuf = recbuf[15 : recbuf[16]+17]
- //recbuf = append(recbuf[4:12], recbuf[15:recbuf[16]+17]...)
- }
- return recLength, dataLength, state, true, recbuf
- }
- }
- return recLength, dataLength, state, false, recbuf
- }
- func getOutbytes(inbuf string, srcAdd string) ([]byte, error) {
- var tmpsum byte
- inbuf = strings.ToLower(inbuf)
- d, err := hex.DecodeString(inbuf)
- if err != nil {
- return nil, err
- }
- for i, i2 := range d {
- if i < len(d)-1 {
- tmpsum = tmpsum + i2
- } else {
- d[len(d)-1] = 0xFF - tmpsum
- }
- }
- if d[3] != 0xAA {
- Logger.Infof("O:\t% X \r\n", d)
- }
- if setting.DatabaseSetting.Showlog && (d[3] != 0xAA) {
- fmt.Printf("%s O:\t% X \r\n", time.Now().Format("2006-01-02 15:04:05"), d)
- }
- if setting.ServerSetting.UseAPI == 1 {
- if d[3] == 0x18 {
- Logger.Infof("sent to:\t% X \r\n", SrcAdd)
- }
- d = XbeeMake(d, srcAdd, d[3] == 0xA2)
- //d = XbeeMake(d, srcAdd, true)
- }
- return d, nil
- }
- // 保护方式允许一个函数
- func ProtectRun() {
- CurrentPath, _ := setting.GetCurrentPath()
- h, _ := log.NewRotatingFileHandler(CurrentPath+"Plog.log", 40*1024*1024, 10)
- if setting.DatabaseSetting.Showline {
- Logger = log.New(h, log.Ltime|log.Lfile)
- } else {
- Logger = log.New(h, log.Ltime)
- }
- Logger.SetLevelByName("info")
- //ProcessKeyP = make(chan []byte, 100)
- ProcessKeyPstr = make(chan []string, 100)
- BroadcastBuf = make(chan []byte, 100)
- //RunTMRList = make(map[byte]int, 200)
- go RunsendBuf()
- //if setting.ServerSetting.Broadcast > 0 {
- go RunbroadBuf()
- //}
- for {
- err := OpenComm()
- if err != nil {
- if strings.Compare(err.Error(), "一分钟未收到数据") < 0 {
- Logger.Errorln(err)
- }
- }
- time.Sleep(1 * time.Second)
- }
- }
- func XbeeMake(inbuf []byte, srcAdd string, boast bool) []byte {
- //7E 00 0F 10 01 00 00 00 00 00 00 FF FF FF FE 00 C0 01 32
- var CheckSum byte
- var localSrcAdd []byte
- var er error
- buf := make([]byte, 0)
- buf1 := make([]byte, 0)
- inbuflen := len(inbuf) + 14
- if len(srcAdd) > 0 {
- localSrcAdd, er = hex.DecodeString(srcAdd)
- }
- if er != nil || len(srcAdd) == 0 {
- localSrcAdd = localSrcAdd[:0]
- localSrcAdd = append(buf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF)
- }
- buf = append(buf, 0x7e, 0x00, byte(inbuflen&0xFF), 0x10, 0x01)
- if boast {
- buf = append(buf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF)
- } else {
- for _, i2 := range localSrcAdd {
- buf = append(buf, i2)
- }
- }
- buf = append(buf, 0xFF, 0xFE, 0x00, 0xC0)
- for _, i2 := range inbuf {
- buf = append(buf, i2)
- }
- CheckSum = 0x00
- for i := 3; i < len(buf); i++ {
- CheckSum = CheckSum + buf[i]
- }
- buf = append(buf, 0xFF-CheckSum)
- buf1 = append(buf1, 0x7E)
- for i := 1; i < len(buf); i++ {
- if buf[i] == 0x7E || buf[i] == 0x7D || buf[i] == 0x11 || buf[i] == 0x13 {
- buf1 = append(buf1, 0x7D, buf[i]^0x20)
- } else {
- buf1 = append(buf1, buf[i])
- }
- }
- return buf1
- }
- func writeComm(tempstr string, srcAdd string) error {
- if len(tempstr) == 0 {
- return nil
- }
- buftmp, err := getOutbytes(tempstr, srcAdd)
- if err == nil {
- _, err = my_comport.Write(buftmp)
- if err != nil {
- Logger.Errorf("%s %s\r\n", "串口写入错误: ", err)
- time.Sleep(1 * time.Second)
- _ = my_comport.Close()
- return err
- }
- }
- return nil
- }
- func sendBuf(tmpstr []string, client MQTT.Client) error {
- var tmepstr2, tempstr1 string
- tmepstr2 = ""
- d, err := hex.DecodeString(tmpstr[0])
- if err == nil {
- mylength1 := int(d[1] + 2)
- if len(d) > mylength1 {
- tempstr1 = hex.EncodeToString(d[0:mylength1])
- tmepstr2 = hex.EncodeToString(d[mylength1:])
- } else {
- tempstr1 = tmpstr[0]
- }
- if client != nil {
- MQPublish(client, tempstr1)
- MQPublish(client, tmepstr2)
- } else {
- if len(tempstr1) > 0 {
- err = writeComm(tempstr1, tmpstr[1])
- if err != nil {
- return err
- }
- }
- if len(tmepstr2) > 0 {
- err = writeComm(tmepstr2, tmpstr[1])
- if err != nil {
- return err
- }
- }
- }
- }
- return nil
- }
- func ProcessBuf(rebuff []byte) string {
- var err error
- var tmpstr string
- tmpstr = ""
- if CommStrValidate(rebuff) {
- if rebuff[3] == 0xA4 {
- if setting.DatabaseSetting.Showlog {
- fmt.Printf("%s I:\t% X \n", time.Now().Format("2006-01-02 15:04:05"), rebuff)
- }
- Logger.Infof("I:\t% X \r\n", rebuff)
- tmpcommop_, err := hex.DecodeString(commop)
- if err == nil && len(tmpcommop_) > 5 {
- if rebuff[2]&0x1F == tmpcommop_[2]&0x1F {
- delcommop(commop)
- }
- }
- } else if rebuff[3] == 0xA1 {
- // if setting.ServerSetting.Broadcast > 0 {
- select {
- case BroadcastBuf <- rebuff:
- default:
- Logger.Errorf("%s\r\n", "BroadcastBuf通道已满")
- }
- // }
- } else if rebuff[3]&0xF0 == 0xA0 {
- if setting.DatabaseSetting.Showlog {
- fmt.Printf("%s A0:\t% X \n", time.Now().Format("2006-01-02 15:04:05"), rebuff)
- }
- } else {
- if setting.DatabaseSetting.Showlog {
- fmt.Printf("%s I:\t% X \n", time.Now().Format("2006-01-02 15:04:05"), rebuff)
- }
- Logger.Infof("I:\t% X \r\n", rebuff)
- key, val, valresul := duplicateValidate(rebuff)
- if valresul {
- if rebuff[3]&0xF0 == 0xE0 {
- rebuff[3] = rebuff[3] + 0x10
- }
- if rebuff[3] == 0xF0 {
- err = processKey0(rebuff)
- if err == nil {
- tmpstr = fmt.Sprintf("7E04%02x10%02x00", rebuff[2], rebuff[rebuff[1]])
- }
- } else if rebuff[3] == 0xF1 || rebuff[3] == 0xF2 || rebuff[3] == 0xF3 ||
- rebuff[3] == 0xF4 || rebuff[3] == 0xF5 {
- // err = processKey0(rebuff)
- tmpstr, err = processKey1(rebuff)
- } else if rebuff[3] == 0xF8 {
- tmpstr = hex.EncodeToString(getF8(rebuff[2], rebuff[4]))
- }
- } else {
- fmt.Printf("%s duplicateValidate:\t%s \n", time.Now().Format("2006-01-02 15:04:05"), "重复数据")
- if rebuff[3] == 0xE1 || rebuff[3] == 0xE2 || rebuff[3] == 0xE3 {
- //tmpstr = fmt.Sprintf("7E04%02x11%02x00", rebuff[2], rebuff[rebuff[1]])
- tmpstr, _ = processKey1(rebuff)
- } else if rebuff[3] == 0xE0 {
- tmpstr = fmt.Sprintf("7E04%02x10%02x00", rebuff[2], rebuff[rebuff[1]])
- } else if rebuff[3] == 0xF8 || rebuff[3] == 0xE8 {
- tmpstr = hex.EncodeToString(getF8(rebuff[2], rebuff[4]))
- } else if rebuff[3] == 0xF4 || rebuff[3] == 0xE4 || rebuff[3] == 0xF5 || rebuff[3] == 0xE5 {
- if rebuff[3]&0xF0 == 0xE0 {
- rebuff[3] = rebuff[3] + 0x10
- }
- tmpstr, _ = processKey1(rebuff)
- }
- }
- if len(tmpstr) > 0 {
- saveduplicateValidate(key, val)
- }
- }
- }
- return tmpstr
- }
- func SetCoil(Addr byte, KAddr byte, State bool) []byte {
- m_data := []byte{0x01, 0x05, 0x00, 0x01, 0x00, 0x00}
- m_data[0] = Addr
- m_data[3] = KAddr
- if State {
- m_data[4] = 0xFF
- }
- checksum := CheckSum(m_data)
- int16buf := new(bytes.Buffer)
- binary.Write(int16buf, binary.LittleEndian, checksum)
- m_data = append(m_data, int16buf.Bytes()...)
- //fmt.Printf("output-after:%X \n",m_data)
- return m_data
- }
- func SetMulCoil(Addr byte, value int16) []byte {
- m_data := []byte{0x01, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00}
- m_data[0] = Addr
- m_data[3] = 0
- m_data[5] = 16
- m_data[7] = byte(value & 0xFF)
- m_data[8] = byte((value >> 8) & 0xFF)
- checksum := CheckSum(m_data)
- int16buf := new(bytes.Buffer)
- binary.Write(int16buf, binary.LittleEndian, checksum)
- m_data = append(m_data, int16buf.Bytes()...)
- fmt.Printf("output-after:%X \n", m_data)
- return m_data
- }
- func coil(i int) int16 {
- return 1 << (i - 1)
- }
- func OpenComm() (err error) {
- var monitorBegin, monitorend time.Time
- var recLength, dataLength, state uint8
- var processok bool
- SrcAdd = make([]byte, 8)
- defer slowpoke.CloseAll()
- defer func() {
- // 发生宕机时,获取panic传递的上下文并打印
- if err := recover(); err != nil {
- fmt.Println("OpenComm出错:", err)
- }
- }()
- //a := 0
- //
- //b :=1/a
- //println(b)
- fmt.Println("启动时间:", time.Now().Local().Format("2006-01-02 15:04:05")) //2019-07-31 13:57:52
- file = setting.CurrentPath + "rectailer"
- buf := make([]byte, 32)
- recbuf := make([]byte, 1)
- SrcAdd = make([]byte, 8)
- openserial:
- my_comport, err = serial.Open(*setting.CommSetting)
- recLength = 0
- dataLength = 0
- state = 0
- if err != nil {
- Logger.Errorf("%s %s %s %s\r\n", setting.CommSetting.PortName, "打开错误: ", setting.CommSetting.PortName, err)
- if setting.DatabaseSetting.Showlog {
- fmt.Println(time.Now().Format("2006-01-02 15:04:05"), setting.CommSetting.PortName, "打开错误: ", setting.CommSetting.PortName, err)
- }
- time.Sleep(1 * time.Second)
- goto openserial
- }
- Logger.Infof("%s %s\r\n", setting.CommSetting.PortName, "打开成功")
- // my_comport.Write(SetCoil(1,1, true))
- // my_comport.Write(SetMulCoil(1,(coil(1)|coil(3)|coil(5)|coil(7))))
- // my_comport.Write(SetMulCoil(1,(coil(2)|coil(4)|coil(6)|coil(8))))
- if setting.DatabaseSetting.Showlog {
- fmt.Println(time.Now().Format("2006-01-02 15:04:05"), setting.CommSetting.PortName, "打开成功")
- }
- sendcommopBegin := time.Now()
- sendLoraBegin := time.Now()
- monitorBegin = time.Now()
- defer my_comport.Close()
- for {
- select {
- case <-StopCharP:
- Logger.Infof("%s\r\n", "服务被停止")
- break
- default:
- n, err := my_comport.Read(buf)
- if (err != io.EOF) && (err != nil) {
- Logger.Errorf("%s %s\r\n", "串口读写错误: ", err)
- time.Sleep(1 * time.Second)
- _ = my_comport.Close()
- panic(err)
- } else if n > 0 {
- monitorBegin = time.Now()
- buf = buf[:n]
- //fmt.Printf("% X ",buf)
- for _, value := range buf {
- if setting.ServerSetting.UseAPI == 1 {
- recLength, dataLength, state, processok, recbuf = processCharApi(value, recLength, dataLength, state, recbuf)
- } else {
- recLength, dataLength, state, processok, recbuf = processChar(value, recLength, dataLength, state, recbuf)
- }
- if processok {
- var recbuftem = make([]byte, len(recbuf))
- copy(recbuftem, recbuf)
- go func(recbuftem []byte, tempSrcAdd string) {
- if (len(recbuftem) > 3) && (recbuftem[2] < 30) {
- b := recbuftem[2]
- key, mapok := RunTMRList.Load(b)
- if !mapok {
- key = 0
- }
- if key == 0 {
- tmpstr := make([]string, 2)
- begin := time.Now()
- RunTMRList.Store(b, 1)
- tmpstr[0] = ProcessBuf(recbuftem)
- tmpstr[1] = tempSrcAdd
- end := time.Now()
- // fmt.Printf(tmpstr[0])
- if len(tmpstr) > 0 && end.Sub(begin).Seconds() < 30 {
- select {
- case ProcessKeyPstr <- tmpstr:
- default:
- Logger.Errorf("%s\r\n", "ProcessKeyPstr通道已满")
- }
- } else {
- Logger.Errorf("%s\r\n", "ProcessBuf 为空或超过30秒")
- }
- RunTMRList.Store(b, 0)
- }
- recbuftem = recbuftem[:0]
- }
- }(recbuftem, hex.EncodeToString(SrcAdd))
- }
- }
- } else {
- sendcommopEnd := time.Now()
- if (sendcommopEnd.Sub(sendLoraBegin).Milliseconds() > setting.ServerSetting.SendRoute) && (setting.ServerSetting.SendRoute > 0) {
- sendLoraBegin = time.Now()
- tempsend := make([]string, 2)
- tempsend[0] = "7E03FFAA00"
- tempsend[1] = ""
- select {
- case ProcessKeyPstr <- tempsend:
- default:
- Logger.Errorf("%s\r\n", "commop_ProcessKeyPstr通道已满")
- }
- } else if sendcommopEnd.Sub(sendcommopBegin).Seconds() > 1 {
- sendcommopBegin = time.Now()
- delaysendcommop = 0
- commop = getcommop()
- if len(commop) > 0 {
- tempTailer := getSendTailer()
- tempCommopstr, er := hex.DecodeString(commop)
- if er == nil {
- tempCommopstr[tempCommopstr[1]] = (tempCommopstr[tempCommopstr[1]] & 0xF0) | (tempTailer & 0x0F)
- tempsend := make([]string, 2)
- tempsend[0] = hex.EncodeToString(tempCommopstr)
- tempsend[1] = ""
- select {
- case ProcessKeyPstr <- tempsend:
- default:
- Logger.Errorf("%s\r\n", "commop_ProcessKeyPstr通道已满")
- }
- }
- }
- } else {
- monitorend = time.Now()
- if monitorend.Sub(monitorBegin).Minutes() > 1 {
- time.Sleep(1 * time.Second)
- _ = my_comport.Close()
- panic("一分钟未收到数据")
- }
- time.Sleep(10 * time.Microsecond)
- }
- }
- }
- }
- }
|