comm.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. package comm
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "encoding/hex"
  6. "fmt"
  7. MQTT "github.com/eclipse/paho.mqtt.golang"
  8. "github.com/jacobsa/go-serial/serial"
  9. "github.com/kptyun/KPTCOMM/pkg/setting"
  10. "github.com/kptyun/KPTCOMM/routers/restful"
  11. "github.com/recoilme/slowpoke"
  12. "github.com/siddontang/go-log/log"
  13. "math"
  14. //"github.com/xormplus/xorm"
  15. "io"
  16. "net"
  17. "strings"
  18. "sync"
  19. "time"
  20. )
  21. // 一个已经被关闭的channel不会阻塞,已经被关闭的channel会实时返回
  22. // goroutine退出,关闭done来进行广播
  23. var needEscape int
  24. var my_comport io.ReadWriteCloser
  25. var my_Controlcomport io.ReadWriteCloser
  26. var SrcAdd []byte
  27. var commop string = ""
  28. var delaysendcommop int = 0
  29. var Boastaddr *net.UDPAddr
  30. var Logger *log.Logger
  31. var StopCharP chan int
  32. // var ProcessKeyP chan []byte
  33. var ProcessKeyPstr chan []string
  34. var BroadcastBuf chan []byte
  35. var file string
  36. var RunTMRList sync.Map
  37. var MbTable = []uint16{
  38. 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
  39. 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
  40. 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
  41. 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
  42. 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
  43. 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
  44. 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
  45. 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
  46. 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
  47. 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
  48. 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
  49. 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
  50. 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
  51. 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
  52. 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
  53. 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
  54. 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
  55. 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
  56. 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
  57. 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
  58. 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
  59. 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
  60. 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
  61. 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
  62. 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
  63. 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
  64. 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
  65. 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
  66. 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
  67. 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
  68. 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
  69. 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040}
  70. func CheckSum(data []byte) uint16 {
  71. var crc16 uint16
  72. crc16 = 0xffff
  73. for _, v := range data {
  74. n := uint8(uint16(v) ^ crc16)
  75. crc16 >>= 8
  76. crc16 ^= MbTable[n]
  77. }
  78. return crc16
  79. }
  80. func getBoastaddr() *net.UDPAddr {
  81. tempaddr, err := net.ResolveUDPAddr("udp4", "255.255.255.255:8800")
  82. if err != nil {
  83. Logger.Errorf("%s \r\n", err)
  84. return tempaddr
  85. }
  86. if strings.TrimSpace(setting.ServerSetting.Netcard) != "" {
  87. interfaces, err := net.Interfaces()
  88. if err != nil {
  89. Logger.Errorf("%s \r\n", err)
  90. return tempaddr
  91. }
  92. for _, i := range interfaces {
  93. byName, err := net.InterfaceByName(i.Name)
  94. if err != nil {
  95. Logger.Errorf("%s \r\n", err)
  96. return tempaddr
  97. }
  98. if byName.Name == strings.TrimSpace(setting.ServerSetting.Netcard) {
  99. addresses, _ := byName.Addrs()
  100. for _, v := range addresses {
  101. if ipnet, ok := v.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
  102. if ipnet.IP.To4() != nil {
  103. ipmask := fmt.Sprintf("%d.%d.%d.%d:%d",
  104. ipnet.IP[12], ipnet.IP[13], ipnet.IP[14], 255, setting.ServerSetting.Broadcast)
  105. tempaddr, err = net.ResolveUDPAddr("udp4", ipmask)
  106. if err != nil {
  107. tempaddr, err = net.ResolveUDPAddr("udp4", "255.255.255.255:8800")
  108. if err != nil {
  109. Logger.Errorf("%s \r\n", err)
  110. return tempaddr
  111. }
  112. } else {
  113. 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]))
  114. return tempaddr
  115. break
  116. }
  117. }
  118. }
  119. }
  120. }
  121. }
  122. }
  123. return tempaddr
  124. }
  125. func CommStrValidate(rebus []byte) bool {
  126. var ResI byte
  127. ResI = 0
  128. for i, value := range rebus {
  129. if i < len(rebus)-1 {
  130. ResI = ResI + value
  131. }
  132. }
  133. ResI = 0xFF - ResI
  134. return ResI == rebus[len(rebus)-1]
  135. }
  136. func getDateTime(buf []byte) time.Time {
  137. dataTime := time.Date(2000+int(buf[0]>>2),
  138. time.Month(((buf[0]&0x03)<<2)|(buf[1]>>6)),
  139. int((buf[1]&0x3E)>>1),
  140. int(((buf[1]&0x01)<<4)|(buf[2]>>4)),
  141. int(((buf[2]&0x0F)<<2)|(buf[3]>>6)),
  142. int(buf[3]&0x3F),
  143. 0,
  144. time.Local)
  145. return dataTime
  146. }
  147. func getWeight(buf1, byte2, byte3 byte) float64 {
  148. ws := int16((byte3 & 96) >> 5)
  149. x := int16(buf1)<<8 | int16(byte2)
  150. if (byte3 >> 7) == 1 {
  151. x = -1 * x
  152. }
  153. s := float64(x)
  154. for i := int16(0); i < ws; i++ {
  155. s = s / 10
  156. }
  157. return s
  158. }
  159. func getSendTailer() byte {
  160. key := []byte("SendTailer")
  161. val, err := slowpoke.Get(file, key)
  162. if err != nil {
  163. val, err = slowpoke.Get(file, key)
  164. }
  165. if val == nil {
  166. val = make([]byte, 1)
  167. val[0] = 1
  168. } else {
  169. val[0] = val[0] + 1
  170. if val[0] > 0x0F {
  171. val[0] = 0
  172. }
  173. }
  174. err = slowpoke.Set(file, key, val)
  175. if err != nil {
  176. Logger.Errorf("%s \r\n", err)
  177. }
  178. return val[0]
  179. }
  180. func getF8(InSrcAddr byte, OriSendId byte) []byte {
  181. var p1, p2, p3, p4, temps byte
  182. year := byte(time.Now().Local().Year() % 2000)
  183. month := byte(time.Now().Local().Month())
  184. day := byte(time.Now().Local().Day())
  185. hour := byte(time.Now().Local().Hour())
  186. minute := byte(time.Now().Local().Minute())
  187. second := byte(time.Now().Local().Second())
  188. p1 = (year << 2) | (month >> 2)
  189. p2 = ((month & 0x03) << 6) | ((day & 0x1F) << 1) | ((hour & 0x3F) >> 4)
  190. p3 = ((hour & 0x0F) << 4) | ((minute & 0x3F) >> 2)
  191. p4 = ((minute & 0x03) << 6) | (second & 0x3F)
  192. buf := make([]byte, 0)
  193. buf = append(buf, 0x7e)
  194. buf = append(buf, 0x08)
  195. buf = append(buf, InSrcAddr)
  196. buf = append(buf, 0x18)
  197. buf = append(buf, p1)
  198. buf = append(buf, p2)
  199. buf = append(buf, p3)
  200. buf = append(buf, p4)
  201. tempTailer := getSendTailer()
  202. buf = append(buf, ((OriSendId&0x0F)<<8)|(tempTailer&0x0F))
  203. temps = 0
  204. for _, i2 := range buf {
  205. temps = temps + i2
  206. }
  207. buf = append(buf, 0xFF-temps)
  208. return buf
  209. }
  210. func duplicateValidate(recbuf []byte) ([]byte, []byte, bool) {
  211. key := make([]byte, 1)
  212. val := make([]byte, 2)
  213. key[0] = recbuf[2]
  214. if recbuf[3] < 240 {
  215. val[1] = recbuf[3] + 16
  216. } else {
  217. val[1] = recbuf[3]
  218. }
  219. if recbuf[1] < byte(len(recbuf)) {
  220. val[0] = recbuf[recbuf[1]]
  221. }
  222. oldval, err := slowpoke.Get(file, key)
  223. if err != nil {
  224. Logger.Errorf("%s %s\r\n", file, err)
  225. oldval, err = slowpoke.Get(file, key)
  226. }
  227. if oldval == nil {
  228. val[0] = 0
  229. val[1] = 0
  230. return key, val, true
  231. }
  232. return key, val, (oldval[0] != val[0]) || (oldval[1] != val[1])
  233. }
  234. func saveduplicateValidate(key []byte, val []byte) {
  235. err := slowpoke.Set(file, key, val)
  236. if err != nil {
  237. Logger.Errorf("%s \r\n", err)
  238. }
  239. }
  240. func processWeight(InSrcAddr byte, recbuf []byte) error {
  241. sParams := make([]interface{}, 0)
  242. sParams = append(sParams, InSrcAddr)
  243. sParams = append(sParams, getDateTime(recbuf[:4]))
  244. sParams = append(sParams, getWeight(recbuf[4], recbuf[5], recbuf[6]))
  245. _, err := restful.ExecQuerySqlx("select ProcTimeWeight(?,?,?)", sParams)
  246. if err != nil {
  247. Logger.Errorf("%s \r\n", err)
  248. }
  249. return err
  250. }
  251. func RunsendBuf() {
  252. defer func() {
  253. // 发生宕机时,获取panic传递的上下文并打印
  254. if err := recover(); err != nil {
  255. fmt.Println("RunsendBuf出错:", err)
  256. StopCharP <- 1
  257. }
  258. }()
  259. for {
  260. tmpstr := <-ProcessKeyPstr
  261. if len(tmpstr[0]) > 0 {
  262. err := sendBuf(tmpstr, nil)
  263. //println("recbuf",tmpstr)
  264. if err != nil {
  265. //goto openSerial
  266. StopCharP <- 1
  267. time.Sleep(10 * time.Millisecond)
  268. //RunTMRList = make(map[byte]int, 200)
  269. go OpenComm()
  270. }
  271. }
  272. }
  273. }
  274. func RunbroadBuf() {
  275. var err error
  276. var conn *net.UDPConn
  277. var intvalue int
  278. errT := 0
  279. for {
  280. recbuf := <-BroadcastBuf
  281. if setting.ServerSetting.ControlComm > 0 {
  282. my_Controlcomport, err = serial.Open(*setting.ControlCommSetting)
  283. if err != nil {
  284. Logger.Errorf("%s %s %s %s\r\n", setting.ControlCommSetting.PortName, "打开继电器串口错误: ", setting.CommSetting.PortName, err)
  285. if setting.DatabaseSetting.Showlog {
  286. fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "打开继电器串口错误: ", setting.CommSetting.PortName, err)
  287. }
  288. } else {
  289. // Logger.Infof("%s %s\r\n", setting.ControlCommSetting.PortName, "打开继电器成功")
  290. if (recbuf[6] == 0xCB) && (recbuf[7] == 0xAE) {
  291. intvalue = 0
  292. for i := 0; i <= 5; i++ {
  293. if recbuf[21-i] != 0x20 {
  294. intvalue = intvalue + int(recbuf[21-i]-0x30)*int(math.Floor(math.Pow10(i)))
  295. } else {
  296. break
  297. }
  298. }
  299. _, err = my_Controlcomport.Write(SetCoil(1, recbuf[2]-1,
  300. (recbuf[14] == 0xC9) && (recbuf[15] == 0xD9) && (intvalue > setting.ServerSetting.RelayDev)))
  301. if err != nil {
  302. Logger.Errorf("%s %s: %s\r\n", "写继电器串口错误: ", setting.ControlCommSetting.PortName, err)
  303. if setting.DatabaseSetting.Showlog {
  304. fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "写继电器串口错误: ", setting.ControlCommSetting.PortName, err)
  305. }
  306. }
  307. if setting.DatabaseSetting.Showlog {
  308. fmt.Println(time.Now().Format("2006-01-02 15:04:05"), recbuf[2]-1, " ", intvalue, " ", setting.ServerSetting.RelayDev, " ",
  309. (recbuf[14] == 0xC9) && (recbuf[15] == 0xD9) && (intvalue > setting.ServerSetting.RelayDev))
  310. }
  311. } else {
  312. _, err = my_Controlcomport.Write(SetCoil(1, recbuf[2]-1, false))
  313. if err != nil {
  314. Logger.Errorf("%s %s: %s\r\n", "写继电器串口错误: ", setting.ControlCommSetting.PortName, err)
  315. if setting.DatabaseSetting.Showlog {
  316. fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "写继电器串口错误: ", setting.ControlCommSetting.PortName, err)
  317. }
  318. }
  319. }
  320. _ = my_Controlcomport.Close()
  321. }
  322. }
  323. if setting.ServerSetting.Broadcast > 0 && errT == 0 {
  324. Boastaddr = getBoastaddr()
  325. }
  326. if Boastaddr != nil {
  327. if errT == 0 {
  328. conn, err = net.DialUDP("udp4", nil, Boastaddr)
  329. if err != nil {
  330. Logger.Errorf("%s \r\n", err)
  331. errT = 1
  332. } else {
  333. if len(recbuf) > 0 {
  334. _, err := conn.Write(recbuf)
  335. if err != nil {
  336. Logger.Errorf("%s \r\n", err)
  337. errT = 1
  338. _ = conn.Close()
  339. }
  340. }
  341. }
  342. }
  343. }
  344. }
  345. }
  346. func processKey0(recbuf []byte) error {
  347. var err error
  348. InSrcAddr := recbuf[2]
  349. s := time.Now()
  350. if recbuf[3] == 0xF0 || recbuf[3] == 0xE0 {
  351. for i := 0; i < int((recbuf[1]-4)/7); i++ {
  352. err = processWeight(InSrcAddr, recbuf[4+(i*7):4+(i+1)*7])
  353. // break
  354. }
  355. }
  356. if setting.DatabaseSetting.ShowXormlog {
  357. println("processKey0=================", time.Now().Sub(s).Milliseconds())
  358. }
  359. return err
  360. }
  361. func processKey1(recbuf []byte) (string, error) {
  362. sParams := make([]interface{}, 0)
  363. s := time.Now()
  364. InSrcAddr := recbuf[2]
  365. InTime := getDateTime(recbuf[4:8])
  366. BeginWeight := getWeight(recbuf[8], recbuf[9], recbuf[12])
  367. endWeight := getWeight(recbuf[10], recbuf[11], recbuf[12])
  368. InButtonType := recbuf[3]
  369. OriSendId := recbuf[15]
  370. LastSortID := recbuf[13]
  371. LastInorOut := recbuf[14]
  372. sParams = append(sParams, InSrcAddr)
  373. sParams = append(sParams, InTime)
  374. sParams = append(sParams, endWeight)
  375. _, err := restful.ExecQuerySqlx("select ProcTimeWeight(?,?,?)", sParams)
  376. if err != nil {
  377. Logger.Errorf("%s \r\n", err)
  378. }
  379. sParams = append(sParams[:0])
  380. sParams = append(sParams, InSrcAddr)
  381. sParams = append(sParams, InTime)
  382. sParams = append(sParams, InButtonType)
  383. sParams = append(sParams, OriSendId)
  384. sParams = append(sParams, BeginWeight)
  385. sParams = append(sParams, endWeight)
  386. sParams = append(sParams, LastSortID)
  387. sParams = append(sParams, LastInorOut)
  388. //InObjAddr INTEGER, InSrcAddr INTEGER,InTime DATETIME,InButtonType INTEGER,OriSendId INTEGER,
  389. // OldWeight DOUBLE,NewestWeight DOUBLE,LastSortID INTEGER,LastInorOut INTEGER
  390. queryResult, err := restful.QueryByListv2Sqlx("select ProcNewButton(0,?,?,?,?,?,?,?,?) as resultstr", 0, 1, sParams)
  391. if err == nil {
  392. returnmsgmap, _ := queryResult.(map[string]interface{})
  393. returnmsgmap1, _ := returnmsgmap["lists"].([]map[string]interface{})
  394. if len(returnmsgmap1) > 0 {
  395. switch returnmsgmap1[0]["resultstr"].(type) {
  396. case string:
  397. if setting.DatabaseSetting.ShowXormlog {
  398. println("processKey1=================", time.Now().Sub(s).Milliseconds())
  399. }
  400. return returnmsgmap1[0]["resultstr"].(string), nil
  401. }
  402. }
  403. }
  404. return "", err
  405. }
  406. func delcommop(lastCommop string) error {
  407. tx, err := restful.Dbs.Beginx()
  408. if err != nil {
  409. fmt.Println("GetT error:", err)
  410. }
  411. defer func() {
  412. switch {
  413. case err != nil:
  414. fmt.Println("__error:", err)
  415. if tx != nil {
  416. tx.Rollback()
  417. }
  418. default:
  419. if tx != nil {
  420. err = tx.Commit()
  421. }
  422. }
  423. }()
  424. sParams := make([]interface{}, 0)
  425. sParams = append(sParams, lastCommop)
  426. _, err = restful.ExecQueryT("delete from `commop` where `Cont`= ?", sParams, tx)
  427. if err == nil {
  428. commop = ""
  429. }
  430. return err
  431. }
  432. func getcommop() string {
  433. queryResult, err := restful.QueryByListSqlx("SELECT `Cont` as resultstr,ID FROM `commop` ", 0, 1, nil)
  434. if err == nil {
  435. returnmsgmap, _ := queryResult.(map[string]interface{})
  436. returnmsgmap1, _ := returnmsgmap["lists"].(map[string][]interface{})
  437. if len(returnmsgmap1["resultstr"]) > 0 {
  438. sParams := make([]interface{}, 0)
  439. sParams = append(sParams, returnmsgmap1["ID"][0])
  440. //restful.ExecQuery("update commop set `SendTimes`=`SendTimes` + 1 where id = ?", sParams)
  441. //restful.ExecQuery("delete from commop where `SendTimes`>= 5 and id = ?", sParams)
  442. restful.ExecQuerySqlx("update commop set `SendTimes`=`SendTimes` + 1 where id = ?", sParams)
  443. restful.ExecQuerySqlx("delete from commop where `SendTimes`>= 5 and id = ?", sParams)
  444. return returnmsgmap1["resultstr"][0].(string)
  445. }
  446. } else {
  447. Logger.Errorf("%s \r\n", err)
  448. }
  449. return ""
  450. }
  451. func processChar(inbyte byte, recLength, dataLength, state uint8, recbuf []byte) (uint8, uint8, uint8, bool, []byte) {
  452. //7E 15 01 F1 7E 45 C8 AB CC EC BD E1 CA F8 20 20 20 20 20 20 20 30 1C
  453. switch state {
  454. case 0: //头判断
  455. if inbyte == 0x7E {
  456. state = 1
  457. recLength = 1
  458. recbuf = recbuf[:0]
  459. recbuf = append(recbuf, inbyte)
  460. }
  461. case 1: //接收长度数据
  462. if inbyte == 0x7E {
  463. state = 1
  464. recLength = 1
  465. recbuf = recbuf[:0]
  466. recbuf = append(recbuf, inbyte)
  467. } else {
  468. state = 2
  469. recLength = 2
  470. dataLength = inbyte + 2
  471. recbuf = append(recbuf, inbyte)
  472. }
  473. case 2: //接收数据中
  474. recbuf = append(recbuf, inbyte)
  475. recLength++
  476. if recLength == dataLength {
  477. state = 0
  478. recLength = 0
  479. return recLength, dataLength, state, true, recbuf
  480. }
  481. }
  482. return recLength, dataLength, state, false, recbuf
  483. }
  484. func processCharApi(inbyte byte, recLength, dataLength, state uint8, recbuf []byte) (uint8, uint8, uint8, bool, []byte) {
  485. //7E 15 01 F1 7E 45 C8 AB CC EC BD E1 CA F8 20 20 20 20 20 20 20 30 1C
  486. switch state {
  487. case 0: //头判断
  488. if inbyte == 0x7E {
  489. state = 1
  490. recLength = 1
  491. recbuf = recbuf[:0]
  492. recbuf = append(recbuf, inbyte)
  493. }
  494. case 1: //头判断
  495. if inbyte == 0x7E {
  496. state = 1
  497. recLength = 1
  498. recbuf = recbuf[:0]
  499. recbuf = append(recbuf, inbyte)
  500. } else if inbyte == 0x00 {
  501. state = 2
  502. recLength = 2
  503. recbuf = append(recbuf, inbyte)
  504. } else {
  505. state = 0
  506. recLength = 0
  507. recbuf = recbuf[:0]
  508. }
  509. case 2: //接收数据中
  510. if inbyte == 0x7E {
  511. state = 1
  512. recLength = 1
  513. recbuf = recbuf[:0]
  514. recbuf = append(recbuf, inbyte)
  515. } else {
  516. if inbyte == 0x7D {
  517. needEscape = 1
  518. } else {
  519. state = 3
  520. recLength = 3
  521. dataLength = inbyte + 4
  522. if needEscape == 1 {
  523. needEscape = 0
  524. recbuf = append(recbuf, inbyte^0x20)
  525. } else {
  526. recbuf = append(recbuf, inbyte)
  527. }
  528. }
  529. }
  530. case 3: //接收数据中
  531. if inbyte == 0x7D {
  532. needEscape = 1
  533. } else {
  534. recLength++
  535. if needEscape == 1 {
  536. needEscape = 0
  537. recbuf = append(recbuf, inbyte^0x20)
  538. } else {
  539. recbuf = append(recbuf, inbyte)
  540. }
  541. }
  542. if recLength == dataLength {
  543. state = 0
  544. recLength = 0
  545. if recbuf[3] == 0x90 && len(recbuf) > 16 && len(recbuf) > int(recbuf[16]+17) {
  546. SrcAdd = recbuf[4:12]
  547. recbuf = recbuf[15 : recbuf[16]+17]
  548. //recbuf = append(recbuf[4:12], recbuf[15:recbuf[16]+17]...)
  549. }
  550. return recLength, dataLength, state, true, recbuf
  551. }
  552. }
  553. return recLength, dataLength, state, false, recbuf
  554. }
  555. func getOutbytes(inbuf string, srcAdd string) ([]byte, error) {
  556. var tmpsum byte
  557. inbuf = strings.ToLower(inbuf)
  558. d, err := hex.DecodeString(inbuf)
  559. if err != nil {
  560. return nil, err
  561. }
  562. for i, i2 := range d {
  563. if i < len(d)-1 {
  564. tmpsum = tmpsum + i2
  565. } else {
  566. d[len(d)-1] = 0xFF - tmpsum
  567. }
  568. }
  569. Logger.Infof("O:\t% X \r\n", d)
  570. if setting.DatabaseSetting.Showlog {
  571. fmt.Printf("%s O:\t% X \r\n", time.Now().Format("2006-01-02 15:04:05"), d)
  572. }
  573. if setting.ServerSetting.UseAPI == 1 {
  574. if d[3] == 0x18 {
  575. Logger.Infof("sent to:\t% X \r\n", SrcAdd)
  576. }
  577. d = XbeeMake(d, srcAdd, d[3] == 0xA2)
  578. //d = XbeeMake(d, srcAdd, true)
  579. }
  580. return d, nil
  581. }
  582. // 保护方式允许一个函数
  583. func ProtectRun() {
  584. CurrentPath, _ := setting.GetCurrentPath()
  585. h, _ := log.NewRotatingFileHandler(CurrentPath+"Plog.log", 40*1024*1024, 10)
  586. if setting.DatabaseSetting.Showline {
  587. Logger = log.New(h, log.Ltime|log.Lfile)
  588. } else {
  589. Logger = log.New(h, log.Ltime)
  590. }
  591. Logger.SetLevelByName("info")
  592. //ProcessKeyP = make(chan []byte, 100)
  593. ProcessKeyPstr = make(chan []string, 100)
  594. BroadcastBuf = make(chan []byte, 100)
  595. //RunTMRList = make(map[byte]int, 200)
  596. go RunsendBuf()
  597. //if setting.ServerSetting.Broadcast > 0 {
  598. go RunbroadBuf()
  599. //}
  600. for {
  601. err := OpenComm()
  602. if err != nil {
  603. if strings.Compare(err.Error(), "一分钟未收到数据") < 0 {
  604. Logger.Errorln(err)
  605. }
  606. }
  607. time.Sleep(1 * time.Second)
  608. }
  609. }
  610. func XbeeMake(inbuf []byte, srcAdd string, boast bool) []byte {
  611. //7E 00 0F 10 01 00 00 00 00 00 00 FF FF FF FE 00 C0 01 32
  612. var CheckSum byte
  613. var localSrcAdd []byte
  614. var er error
  615. buf := make([]byte, 0)
  616. buf1 := make([]byte, 0)
  617. inbuflen := len(inbuf) + 14
  618. if len(srcAdd) > 0 {
  619. localSrcAdd, er = hex.DecodeString(srcAdd)
  620. }
  621. if er != nil || len(srcAdd) == 0 {
  622. localSrcAdd = localSrcAdd[:0]
  623. localSrcAdd = append(buf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF)
  624. }
  625. buf = append(buf, 0x7e, 0x00, byte(inbuflen&0xFF), 0x10, 0x01)
  626. if boast {
  627. buf = append(buf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF)
  628. } else {
  629. for _, i2 := range localSrcAdd {
  630. buf = append(buf, i2)
  631. }
  632. }
  633. buf = append(buf, 0xFF, 0xFE, 0x00, 0xC0)
  634. for _, i2 := range inbuf {
  635. buf = append(buf, i2)
  636. }
  637. CheckSum = 0x00
  638. for i := 3; i < len(buf); i++ {
  639. CheckSum = CheckSum + buf[i]
  640. }
  641. buf = append(buf, 0xFF-CheckSum)
  642. buf1 = append(buf1, 0x7E)
  643. for i := 1; i < len(buf); i++ {
  644. if buf[i] == 0x7E || buf[i] == 0x7D || buf[i] == 0x11 || buf[i] == 0x13 {
  645. buf1 = append(buf1, 0x7D, buf[i]^0x20)
  646. } else {
  647. buf1 = append(buf1, buf[i])
  648. }
  649. }
  650. return buf1
  651. }
  652. func writeComm(tempstr string, srcAdd string) error {
  653. if len(tempstr) == 0 {
  654. return nil
  655. }
  656. buftmp, err := getOutbytes(tempstr, srcAdd)
  657. if err == nil {
  658. _, err = my_comport.Write(buftmp)
  659. if err != nil {
  660. Logger.Errorf("%s %s\r\n", "串口写入错误: ", err)
  661. time.Sleep(1 * time.Second)
  662. _ = my_comport.Close()
  663. return err
  664. }
  665. }
  666. return nil
  667. }
  668. func sendBuf(tmpstr []string, client MQTT.Client) error {
  669. var tmepstr2, tempstr1 string
  670. tmepstr2 = ""
  671. d, err := hex.DecodeString(tmpstr[0])
  672. if err == nil {
  673. mylength1 := int(d[1] + 2)
  674. if len(d) > mylength1 {
  675. tempstr1 = hex.EncodeToString(d[0:mylength1])
  676. tmepstr2 = hex.EncodeToString(d[mylength1:])
  677. } else {
  678. tempstr1 = tmpstr[0]
  679. }
  680. if client != nil {
  681. MQPublish(client, tempstr1)
  682. MQPublish(client, tmepstr2)
  683. } else {
  684. if len(tempstr1) > 0 {
  685. err = writeComm(tempstr1, tmpstr[1])
  686. if err != nil {
  687. return err
  688. }
  689. }
  690. if len(tmepstr2) > 0 {
  691. err = writeComm(tmepstr2, tmpstr[1])
  692. if err != nil {
  693. return err
  694. }
  695. }
  696. }
  697. }
  698. return nil
  699. }
  700. func ProcessBuf(rebuff []byte) string {
  701. var err error
  702. var tmpstr string
  703. tmpstr = ""
  704. if CommStrValidate(rebuff) {
  705. if rebuff[3] == 0xA4 {
  706. if setting.DatabaseSetting.Showlog {
  707. fmt.Printf("%s I:\t% X \n", time.Now().Format("2006-01-02 15:04:05"), rebuff)
  708. }
  709. Logger.Infof("I:\t% X \r\n", rebuff)
  710. tmpcommop_, err := hex.DecodeString(commop)
  711. if err == nil && len(tmpcommop_) > 5 {
  712. if rebuff[2]&0x1F == tmpcommop_[2]&0x1F {
  713. delcommop(commop)
  714. }
  715. }
  716. } else if rebuff[3] == 0xA1 {
  717. // if setting.ServerSetting.Broadcast > 0 {
  718. select {
  719. case BroadcastBuf <- rebuff:
  720. default:
  721. Logger.Errorf("%s\r\n", "BroadcastBuf通道已满")
  722. }
  723. // }
  724. } else if rebuff[3]&0xF0 == 0xA0 {
  725. if setting.DatabaseSetting.Showlog {
  726. fmt.Printf("%s A0:\t% X \n", time.Now().Format("2006-01-02 15:04:05"), rebuff)
  727. }
  728. } else {
  729. if setting.DatabaseSetting.Showlog {
  730. fmt.Printf("%s I:\t% X \n", time.Now().Format("2006-01-02 15:04:05"), rebuff)
  731. }
  732. Logger.Infof("I:\t% X \r\n", rebuff)
  733. key, val, valresul := duplicateValidate(rebuff)
  734. if valresul {
  735. if rebuff[3]&0xF0 == 0xE0 {
  736. rebuff[3] = rebuff[3] + 0x10
  737. }
  738. if rebuff[3] == 0xF0 {
  739. err = processKey0(rebuff)
  740. if err == nil {
  741. tmpstr = fmt.Sprintf("7E04%02x10%02x00", rebuff[2], rebuff[rebuff[1]])
  742. }
  743. } else if rebuff[3] == 0xF1 || rebuff[3] == 0xF2 || rebuff[3] == 0xF3 ||
  744. rebuff[3] == 0xF4 || rebuff[3] == 0xF5 {
  745. // err = processKey0(rebuff)
  746. tmpstr, err = processKey1(rebuff)
  747. } else if rebuff[3] == 0xF8 {
  748. tmpstr = hex.EncodeToString(getF8(rebuff[2], rebuff[4]))
  749. }
  750. } else {
  751. fmt.Printf("%s duplicateValidate:\t%s \n", time.Now().Format("2006-01-02 15:04:05"), "重复数据")
  752. if rebuff[3] == 0xE1 || rebuff[3] == 0xE2 || rebuff[3] == 0xE3 {
  753. //tmpstr = fmt.Sprintf("7E04%02x11%02x00", rebuff[2], rebuff[rebuff[1]])
  754. tmpstr, _ = processKey1(rebuff)
  755. } else if rebuff[3] == 0xE0 {
  756. tmpstr = fmt.Sprintf("7E04%02x10%02x00", rebuff[2], rebuff[rebuff[1]])
  757. } else if rebuff[3] == 0xF8 || rebuff[3] == 0xE8 {
  758. tmpstr = hex.EncodeToString(getF8(rebuff[2], rebuff[4]))
  759. } else if rebuff[3] == 0xF4 || rebuff[3] == 0xE4 || rebuff[3] == 0xF5 || rebuff[3] == 0xE5 {
  760. if rebuff[3]&0xF0 == 0xE0 {
  761. rebuff[3] = rebuff[3] + 0x10
  762. }
  763. tmpstr, _ = processKey1(rebuff)
  764. }
  765. }
  766. if len(tmpstr) > 0 {
  767. saveduplicateValidate(key, val)
  768. }
  769. }
  770. }
  771. return tmpstr
  772. }
  773. func SetCoil(Addr byte, KAddr byte, State bool) []byte {
  774. m_data := []byte{0x01, 0x05, 0x00, 0x01, 0x00, 0x00}
  775. m_data[0] = Addr
  776. m_data[3] = KAddr
  777. if State {
  778. m_data[4] = 0xFF
  779. }
  780. checksum := CheckSum(m_data)
  781. int16buf := new(bytes.Buffer)
  782. binary.Write(int16buf, binary.LittleEndian, checksum)
  783. m_data = append(m_data, int16buf.Bytes()...)
  784. //fmt.Printf("output-after:%X \n",m_data)
  785. return m_data
  786. }
  787. func SetMulCoil(Addr byte, value int16) []byte {
  788. m_data := []byte{0x01, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00}
  789. m_data[0] = Addr
  790. m_data[3] = 0
  791. m_data[5] = 16
  792. m_data[7] = byte(value & 0xFF)
  793. m_data[8] = byte((value >> 8) & 0xFF)
  794. checksum := CheckSum(m_data)
  795. int16buf := new(bytes.Buffer)
  796. binary.Write(int16buf, binary.LittleEndian, checksum)
  797. m_data = append(m_data, int16buf.Bytes()...)
  798. fmt.Printf("output-after:%X \n", m_data)
  799. return m_data
  800. }
  801. func coil(i int) int16 {
  802. return 1 << (i - 1)
  803. }
  804. func OpenComm() (err error) {
  805. var monitorBegin, monitorend time.Time
  806. var recLength, dataLength, state uint8
  807. var processok bool
  808. SrcAdd = make([]byte, 8)
  809. defer slowpoke.CloseAll()
  810. defer func() {
  811. // 发生宕机时,获取panic传递的上下文并打印
  812. if err := recover(); err != nil {
  813. fmt.Println("OpenComm出错:", err)
  814. }
  815. }()
  816. //a := 0
  817. //
  818. //b :=1/a
  819. //println(b)
  820. fmt.Println("启动时间:", time.Now().Local().Format("2006-01-02 15:04:05")) //2019-07-31 13:57:52
  821. file = setting.CurrentPath + "rectailer"
  822. buf := make([]byte, 32)
  823. recbuf := make([]byte, 1)
  824. SrcAdd = make([]byte, 8)
  825. openserial:
  826. my_comport, err = serial.Open(*setting.CommSetting)
  827. recLength = 0
  828. dataLength = 0
  829. state = 0
  830. if err != nil {
  831. Logger.Errorf("%s %s %s %s\r\n", setting.CommSetting.PortName, "打开错误: ", setting.CommSetting.PortName, err)
  832. if setting.DatabaseSetting.Showlog {
  833. fmt.Println(time.Now().Format("2006-01-02 15:04:05"), setting.CommSetting.PortName, "打开错误: ", setting.CommSetting.PortName, err)
  834. }
  835. time.Sleep(1 * time.Second)
  836. goto openserial
  837. }
  838. Logger.Infof("%s %s\r\n", setting.CommSetting.PortName, "打开成功")
  839. // my_comport.Write(SetCoil(1,1, true))
  840. // my_comport.Write(SetMulCoil(1,(coil(1)|coil(3)|coil(5)|coil(7))))
  841. // my_comport.Write(SetMulCoil(1,(coil(2)|coil(4)|coil(6)|coil(8))))
  842. if setting.DatabaseSetting.Showlog {
  843. fmt.Println(time.Now().Format("2006-01-02 15:04:05"), setting.CommSetting.PortName, "打开成功")
  844. }
  845. sendcommopBegin := time.Now()
  846. monitorBegin = time.Now()
  847. defer my_comport.Close()
  848. for {
  849. select {
  850. case <-StopCharP:
  851. Logger.Infof("%s\r\n", "服务被停止")
  852. break
  853. default:
  854. n, err := my_comport.Read(buf)
  855. if (err != io.EOF) && (err != nil) {
  856. Logger.Errorf("%s %s\r\n", "串口读写错误: ", err)
  857. time.Sleep(1 * time.Second)
  858. _ = my_comport.Close()
  859. panic(err)
  860. } else if n > 0 {
  861. monitorBegin = time.Now()
  862. buf = buf[:n]
  863. //fmt.Printf("% X ",buf)
  864. for _, value := range buf {
  865. if setting.ServerSetting.UseAPI == 1 {
  866. recLength, dataLength, state, processok, recbuf = processCharApi(value, recLength, dataLength, state, recbuf)
  867. } else {
  868. recLength, dataLength, state, processok, recbuf = processChar(value, recLength, dataLength, state, recbuf)
  869. }
  870. if processok {
  871. var recbuftem = make([]byte, len(recbuf))
  872. copy(recbuftem, recbuf)
  873. go func(recbuftem []byte, tempSrcAdd string) {
  874. if (len(recbuftem) > 3) && (recbuftem[2] < 30) {
  875. b := recbuftem[2]
  876. key, mapok := RunTMRList.Load(b)
  877. if !mapok {
  878. key = 0
  879. }
  880. if key == 0 {
  881. tmpstr := make([]string, 2)
  882. begin := time.Now()
  883. RunTMRList.Store(b, 1)
  884. tmpstr[0] = ProcessBuf(recbuftem)
  885. tmpstr[1] = tempSrcAdd
  886. end := time.Now()
  887. // fmt.Printf(tmpstr[0])
  888. if len(tmpstr) > 0 && end.Sub(begin).Seconds() < 30 {
  889. select {
  890. case ProcessKeyPstr <- tmpstr:
  891. default:
  892. Logger.Errorf("%s\r\n", "ProcessKeyPstr通道已满")
  893. }
  894. } else {
  895. Logger.Errorf("%s\r\n", "ProcessBuf 为空或超过30秒")
  896. }
  897. RunTMRList.Store(b, 0)
  898. }
  899. recbuftem = recbuftem[:0]
  900. }
  901. }(recbuftem, hex.EncodeToString(SrcAdd))
  902. }
  903. }
  904. } else {
  905. sendcommopEnd := time.Now()
  906. if sendcommopEnd.Sub(sendcommopBegin).Seconds() > 1 {
  907. sendcommopBegin = time.Now()
  908. delaysendcommop = 0
  909. commop = getcommop()
  910. if len(commop) > 0 {
  911. tempTailer := getSendTailer()
  912. tempCommopstr, er := hex.DecodeString(commop)
  913. if er == nil {
  914. tempCommopstr[tempCommopstr[1]] = (tempCommopstr[tempCommopstr[1]] & 0xF0) | (tempTailer & 0x0F)
  915. tempsend := make([]string, 2)
  916. tempsend[0] = hex.EncodeToString(tempCommopstr)
  917. tempsend[1] = ""
  918. select {
  919. case ProcessKeyPstr <- tempsend:
  920. default:
  921. Logger.Errorf("%s\r\n", "commop_ProcessKeyPstr通道已满")
  922. }
  923. }
  924. }
  925. } else {
  926. monitorend = time.Now()
  927. if monitorend.Sub(monitorBegin).Minutes() > 1 {
  928. time.Sleep(1 * time.Second)
  929. _ = my_comport.Close()
  930. panic("一分钟未收到数据")
  931. }
  932. time.Sleep(10 * time.Microsecond)
  933. }
  934. }
  935. }
  936. }
  937. }