zzConn.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. package zz
  2. import (
  3. "encoding/json"
  4. "eps/models/statusMgr"
  5. "eps/tcp/mdbs"
  6. "eps/tcp/tc"
  7. "eps/tcp/tcpserver"
  8. "fmt"
  9. "github.com/astaxie/beego"
  10. "net"
  11. "reflect"
  12. "strings"
  13. "time"
  14. "wb/cs"
  15. "wb/lg"
  16. "wb/ut"
  17. )
  18. const (
  19. ZMethod = "method"
  20. ZParams = "params"
  21. ZHeartBeat = "now"
  22. )
  23. const (
  24. MLogin = "login"
  25. MNowData = "nowdata"
  26. )
  27. type ZZConn struct {
  28. tc.TConn
  29. PosX float64
  30. PosY float64
  31. }
  32. func newZZConn(conn net.Conn) *ZZConn {
  33. o := ZZConn{}
  34. o.Typo = "ZZ"
  35. o.ReadBuf = make([]byte, 4096)
  36. o.Conn = conn
  37. o.StatusMgr = statusMgr.GSStatusMgr
  38. return &o
  39. }
  40. func (this *ZZConn) Read() (bs []byte, err error) {
  41. i, err := this.Conn.Read(this.ReadBuf)
  42. if err != nil {
  43. //this.LogError(this.Typo + " Read error:", err.Error())
  44. return bs, err
  45. } else {
  46. bs := this.ReadBuf[:i]
  47. this.LogRecv(string(bs))
  48. return bs, err
  49. }
  50. }
  51. func (this *ZZConn) Write(req []byte) (n int, err error) {
  52. n, err = this.Conn.Write(req)
  53. this.LogSend(string(req))
  54. return n, err
  55. }
  56. func (this *ZZConn) ParseNowData(recvMap map[string]interface{}) bool {
  57. //this.LogInfo("ZZConn.ParseNowData data:", recvMap)
  58. this.parseP(recvMap)
  59. this.parseBinMap(recvMap, "m_mode")
  60. this.parseBinMap(recvMap, "a_sd")
  61. this.parseBinMap(recvMap, "a_et")
  62. this.parseBinMap(recvMap, "a_trip")
  63. this.parseBinMap(recvMap, "a_trip")
  64. this.parseBinMap(recvMap, "a_warn")
  65. this.parseBinMap(recvMap, "Indica")
  66. this.parseBinMap(recvMap, "IO_s")
  67. this.parseBinMap(recvMap, "main_s")
  68. //this.LogInfo("status", reflect.TypeOf(iMap)this.StatusMap["rmp"])
  69. //this.LogInfo("StatusMap", this.StatusMap)
  70. if rpm, ok := ut.Maps.GetFloat64(this.StatusMap, "rpm"); ok {
  71. if rpm > 0 {
  72. this.StatusMap["status"] = "running"
  73. } else {
  74. this.StatusMap["status"] = "online"
  75. }
  76. } else {
  77. this.LogError("rpm is not float64!")
  78. }
  79. if this.createAlarm() {
  80. this.StatusMap["status"] = "alarm"
  81. }
  82. this.StatusMgr.AddStatus(ut.Maps.Copy(this.StatusMap))
  83. this.parsePosition(recvMap)
  84. if this.PosX != 0 && this.PosY != 0 {
  85. this.LogInfo("[POS]:x = ", this.PosX, " y = ", this.PosY)
  86. this.StatusMgr.AddPosition(this.TermId, this.PosX, this.PosY)
  87. }
  88. return true
  89. }
  90. func (this *ZZConn) createAlarm() bool {
  91. has := false
  92. warn := ""
  93. for _, r := range zzWarnList {
  94. if v, ok := this.StatusMap[r.Key]; ok {
  95. if v == 1 {
  96. warn = warn + " " + r.Name
  97. has = true
  98. }
  99. }
  100. }
  101. this.StatusMap["warn"] = warn
  102. return has
  103. }
  104. func (this *ZZConn) parseP(recvMap map[string]interface{}) bool {
  105. pList, ok := ut.Maps.GetDeepInMap(recvMap, ZParams, "p")
  106. if ok {
  107. //lg.Debug("ZZConn.ParseNowData pList:", pList)
  108. rPlist, ok := pList.([]interface{})
  109. if !ok {
  110. //lg.Debug("ZZConn.ParseNowData pList: not ok", pList)
  111. return false
  112. }
  113. for _, rMap := range rPlist {
  114. //lg.Debug("ZZConn.ParseNowData rMap:", rMap)
  115. for k, v := range rMap.(map[string]interface{}) {
  116. //lg.Debug("ZZConn.ParseNowData rMap k:", k, " v:", v)
  117. if vStr, ok := v.(string); ok {
  118. valList := strings.Split(vStr, "|")
  119. if len(valList) == 0 {
  120. continue
  121. }
  122. valStr := valList[0]
  123. val, err := ut.StrTo(valStr).Float64()
  124. // 特殊处理下油压的单位换算
  125. if err != nil {
  126. //this.LogError("parse p convert to float64 error", err.Error())
  127. continue
  128. }
  129. if zzReg, ok := zzRegMap[k]; ok {
  130. this.StatusMap[zzReg.Key] = zzReg.GetValue(val)
  131. }
  132. }
  133. }
  134. }
  135. status := strings.TrimSpace(ut.Maps.GetStringDeepInMap(recvMap, ZParams, "status"))
  136. status = strings.ToLower(status)
  137. switch status {
  138. case "online":
  139. this.StatusMap["status"] = "online"
  140. default:
  141. this.StatusMap["status"] = "offline"
  142. }
  143. return true
  144. } else {
  145. return false
  146. }
  147. }
  148. func (this *ZZConn) parseBinMap(recvMap map[string]interface{}, mapKey string) bool {
  149. // 判断是否存在
  150. iMapList, ok := ut.Maps.GetDeepInMap(recvMap, ZParams, mapKey)
  151. if !ok {
  152. //this.LogDebug("parseBinMap mapKey not exist: ", mapKey)
  153. return false
  154. }
  155. // 判断是否为列表
  156. mapList, lok := iMapList.([]interface{})
  157. if !lok {
  158. this.LogError(mapKey, " iMapList type error:", reflect.TypeOf(iMapList))
  159. return false
  160. }
  161. // 循环取列表里的map
  162. for _, iMap := range mapList {
  163. // 判断列表中是否是map列表
  164. rMap, rok := iMap.(map[string]interface{})
  165. if !rok {
  166. this.LogError(mapKey, " iMap type error:", reflect.TypeOf(iMap))
  167. continue
  168. }
  169. // 取列表中的map值
  170. for k, v := range rMap {
  171. // 判断key是否已经定义
  172. reg, kok := zzBinMap[k]
  173. if !kok {
  174. continue
  175. }
  176. // 判断value是否为float
  177. fv, vok := v.(float64)
  178. if !vok {
  179. this.LogError(mapKey, " type error:", reflect.TypeOf(v))
  180. continue
  181. }
  182. // 根据值设置结果
  183. if fv == 0 {
  184. this.StatusMap[reg.Key] = 0
  185. } else {
  186. this.StatusMap[reg.Key] = 1
  187. }
  188. }
  189. }
  190. return true
  191. }
  192. func (this *ZZConn) parsePosition(recvMap map[string]interface{}) bool {
  193. if longitude, ok := this.getPosition(recvMap, "longitude"); ok {
  194. //this.LogDebug("[POS]:x = ", this.PosX, " y = ", this.PosY)
  195. this.PosX = longitude
  196. } else {
  197. //this.LogDebug("[POS]: no langitude.")
  198. }
  199. if latitude, ok := this.getPosition(recvMap, "latitude"); ok {
  200. //this.LogDebug("[POS]:x = ", this.PosX, " y = ", this.PosY)
  201. this.PosY = latitude
  202. } else {
  203. //this.LogDebug("[POS]: no latitude.")
  204. return false
  205. }
  206. return true
  207. }
  208. func (this *ZZConn) getPosition(req map[string]interface{}, k string) (float64, bool) {
  209. pos := ut.Maps.GetStringDeepInMap(req, ZParams, k)
  210. if pos == "" {
  211. return 0, false
  212. }
  213. if p, err := ut.StrTo(pos).Float64(); err == nil {
  214. return p, true
  215. } else {
  216. this.LogError("getPosition", err.Error())
  217. return 0, false
  218. }
  219. }
  220. func (this *ZZConn) SendCmd(cmd string) {
  221. this.LogInfo("[CMD]:", cmd)
  222. var cmdStr string
  223. switch cmd {
  224. case mdbs.StartCmd:
  225. cmdStr = `{"deviceid":1,"cmd":4}`
  226. bb := []byte(cmdStr)
  227. bb = append(bb, 10)
  228. this.Write(bb)
  229. time.Sleep(10 * time.Second)
  230. cmdStr = `{"deviceid":1,"cmd":0}`
  231. case mdbs.StopCmd:
  232. cmdStr = `{"deviceid":1,"cmd":1}`
  233. case "test":
  234. cmdStr = `{"deviceid":1,"cmd":2}`
  235. case "auto":
  236. cmdStr = `{"deviceid":1,"cmd":3}`
  237. case "manual":
  238. cmdStr = `{"deviceid":1,"cmd":4}`
  239. case "msenable":
  240. cmdStr = `{"deviceid":1,"cmd":5}`
  241. case "msdisable":
  242. cmdStr = `{"deviceid":1,"cmd":5}`
  243. case "gsenable":
  244. cmdStr = `{"deviceid":1,"cmd":6}`
  245. case "gsdisable":
  246. cmdStr = `{"deviceid":1,"cmd":6}`
  247. case "faultreset":
  248. cmdStr = `{"deviceid":1,"cmd":7}`
  249. default:
  250. return
  251. }
  252. bb := []byte(cmdStr)
  253. bb = append(bb, 10)
  254. this.Write(bb)
  255. }
  256. func EchoFunc(conn net.Conn) {
  257. lg.Info("ZZ CONNECT FROM: ", conn.RemoteAddr())
  258. defer conn.Close()
  259. zzConn := newZZConn(conn)
  260. defer func() {
  261. if zzConn.TermId != "" {
  262. tc.DeleteConn(zzConn)
  263. //statusMgr.Remove(zzConn.TermId)
  264. }
  265. if err := recover(); err != nil {
  266. zzConn.LogError("EchoFunc panic", err)
  267. }
  268. }()
  269. for {
  270. msg, err := zzConn.Read()
  271. if err != nil {
  272. zzConn.LogInfo("ZZ EchoFunc Read error:", err.Error())
  273. return
  274. }
  275. var msgJson cs.MObject
  276. jsonErr := json.Unmarshal(msg, &msgJson)
  277. if jsonErr != nil {
  278. zzConn.LogInfo("zz.EchoFunc read json error:", jsonErr.Error())
  279. continue
  280. }
  281. // 判断是否为心跳包{"now":1}
  282. if _, ok := msgJson[ZHeartBeat]; ok {
  283. zzConn.Write([]byte("{\"now\":1}"))
  284. continue
  285. }
  286. method := msgJson.GetString(ZMethod)
  287. switch msgJson.GetString(ZMethod) {
  288. case MLogin:
  289. retBs := createLoginResp()
  290. zzConn.Write(retBs)
  291. return
  292. case MNowData:
  293. if zzConn.TermId == "" {
  294. if termId := msgJson.GetTrimStringDeep(ZParams, "hostid"); termId != "" {
  295. zzConn.Init(termId)
  296. zzConn.StatusMap = zzConn.StatusMgr.GetDefaultStatusMap(termId)
  297. tc.AddMConn(zzConn)
  298. } else {
  299. continue
  300. }
  301. }
  302. if packetnum, nok := msgJson.GetInt64Deep(ZParams, "packetnum"); nok {
  303. zzConn.LogDebug("ZZ EchoFunc get packetnum:", packetnum)
  304. retBs := createSuccessResp(packetnum)
  305. zzConn.Write(retBs)
  306. zzConn.ParseNowData(msgJson)
  307. } else {
  308. zzConn.LogError("ZZ EchoFunc get packetnum error")
  309. }
  310. default:
  311. zzConn.LogInfo("Recv other msg", method)
  312. }
  313. }
  314. }
  315. func createLoginResp() []byte {
  316. bs := fmt.Sprintf(`{"result":{"register":1,"liveData":"%s","UTC":%v},"retcode":"000000"}`, ZZLivedata, time.Now().Unix())
  317. bb := []byte(bs)
  318. bb = append(bb, 10)
  319. return bb
  320. }
  321. func createSuccessResp(packetnum int64) []byte {
  322. str := fmt.Sprintf(`{"message":"ok","retcode":"000000","packetnum":%v}`, packetnum)
  323. bb := []byte(str)
  324. return append(bb, 10)
  325. }
  326. var (
  327. ZZPort string
  328. ZZLivedata string
  329. )
  330. func init() {
  331. ZZLivedata = beego.AppConfig.String("zzlivedata")
  332. ZZPort = beego.AppConfig.String("zzport")
  333. }
  334. func ServerRun() {
  335. server.Run(ZZPort, EchoFunc)
  336. }