linkevent_service.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. package service
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "rtzh_elec_temperature/datachannel"
  6. "rtzh_elec_temperature/global"
  7. "rtzh_elec_temperature/logger"
  8. "rtzh_elec_temperature/models/bo"
  9. "rtzh_elec_temperature/mqtt"
  10. "rtzh_elec_temperature/rtelec_app_public_lib/utils"
  11. "rtzh_elec_temperature/tools"
  12. "strconv"
  13. "strings"
  14. "sync"
  15. "time"
  16. "github.com/astaxie/beego/orm"
  17. "git.rtzhtech.cn/iss/public-lib/model"
  18. "git.rtzhtech.cn/iss/public-lib/logic"
  19. "github.com/spf13/cast"
  20. )
  21. type LinkEventService struct {
  22. BaseService
  23. }
  24. type LinkInfo struct {
  25. Deviceid int `json:"deviceid"`
  26. Modelid int `json:"modelid"`
  27. Strategyid int64 `json:"strategyid"`
  28. Strategyname string `json:"strategyname"`
  29. Srcappid int `json:"srcappid"`
  30. Dstappid int `json:"dstappid"` //联动目标Appid
  31. Linkfromid int64 `json:"linkfromid"`
  32. Linktoid int64 `json:"linktoid"`
  33. Fromdeviceid int `json:"fromdeviceid"`
  34. Actid int64 `json:"actid"`
  35. Fromattrname string `json:"fromattrname"`
  36. Linktype int `json:"linktype"`
  37. TargValue float64 `json:"targ_value"`
  38. Than int `json:"than"`
  39. Relation int `json:"relation"`
  40. Delay int `json:"delay"`
  41. Targetattrname string `json:"targetattrname"`
  42. //目标动作点的指令值
  43. Actvalue float64 `json:"actvalue"`
  44. //目标动作点的指令描述
  45. Actdesc string `json:"actdesc"`
  46. }
  47. //map[int][]LinkInfo
  48. var LinkData = sync.Map{} // make(map[int][]LinkInfo)
  49. //联动描述
  50. var LinkDescription = make(map[int64]string)
  51. //联动消息结构
  52. type LinkeBody struct {
  53. Srcappid int32
  54. Destappid int32
  55. Eventid int64
  56. Eventdesc string
  57. Linktype int
  58. Strategyid int64 `json:"strategyid"`
  59. Linktoid int64
  60. Actid int64
  61. Beforestatus string
  62. Afterstatus string
  63. Result string
  64. Reply int // 1- 动作执行成功 0-动作执行失败
  65. MessageId string
  66. }
  67. //发送消息
  68. type LinkRequest struct {
  69. Deviceid int `json:"deviceid"`
  70. Strategyid int64 `json:"strategyid"`
  71. Srcappid int `json:"srcappid"`
  72. Dstappid int `json:"dstappid"`
  73. Strategyname string `json:"strategyname"`
  74. Linktype int `json:"linktype"`
  75. Linkfromid int64 `json:"linkfromid"`
  76. Actid int64 `json:"actid"`
  77. }
  78. //初始化
  79. func init() {
  80. logger.Logger.Println("rtelec联动事件服务初始化")
  81. //等待应用注册结果
  82. go func() {
  83. for {
  84. data, ok := <-datachannel.Service_LinkEventReply_Chanl
  85. if ok {
  86. utils.MessageIds.Remove(tools.IsEmpty(data["mid"]))
  87. if destappid, ok := data["destappid"]; ok {
  88. insObj := RtelecManageApp()
  89. //只处理目标应用为当前应用的事件回复
  90. if destappid == insObj.RegAppID {
  91. logger.Logger.Debug(fmt.Sprintf("=======接收到联动事件回复结果:%+v", data))
  92. }
  93. }
  94. }
  95. }
  96. }()
  97. //等待联动策略更新通知
  98. go func() {
  99. _, ok := <-datachannel.Service_LinkInfoNotice_Chanl
  100. if ok {
  101. //重新加载联动策略
  102. isLoadLinkInfo = false
  103. new(LinkEventService).GetLinkInfo(0)
  104. }
  105. }()
  106. }
  107. //告警数据列表列表
  108. func (t *LinkEventService) LinkDataList(startDate, endDate int, source_address, targ_address, device_name string, pageIndex, pageSize int) (map[string]interface{}, error) {
  109. AppId := cast.ToInt(RtelecManageApp().RegAppID)
  110. l := logic.NewAlarmStrategyLogic()
  111. type linkData struct {
  112. id int `json:"id"`
  113. Eventid int64 `json:"eventid,string"`
  114. Eventdesc string `json:"eventdesc"`
  115. Date string `json:"date"`
  116. Beforestatus string `json:"beforestatus"`
  117. Afterstatus string `json:"afterstatus"`
  118. Result string `json:"result"`
  119. Create_at string `json:"create_at"`
  120. SourceAddress string `json:"source_address"`
  121. TargeAddress string `json:"targe_address"`
  122. Cpname string `json:"cpname"`
  123. Strategyname string `json:"strategyname"`
  124. Devicename string `json:"devicename"`
  125. Linktype string `json:"linktype"`
  126. }
  127. sqlCommandText := `select a.id,eventid,b.strategyname,eventdesc,from_unixtime(timestamp) date,beforestatus,afterstatus,result,a.create_at,concat(c.zonename,'/',c.positionname) source_address,concat(d.zonename,'/',d.positionname) targe_address,cpname,d.devicename,linktype from link_event a inner join (select a.strategyid,a.strategyname,linkfromid,linktoid,actid,case linktype when 1 then '测点联动' when 2 then '模拟IO量输入事件联动' when 3 then '数字量IO量输入联动' when 4 then '模拟IO量输出事件联动' when 5 then '数字量IO量输出联动' when 6 then '辅控事件联动' else null end linktype from
  128. link_strategy a inner join link_relation_obj b on a.strategyid=b.strategyid
  129. inner join link_relation_action c on a.strategyid=c.strategyid) b on a.strategyid=b.strategyid
  130. left join (select mpid,zonename,positionname from dev_mpinfo union select mpid,zonename,positionname from video_mpinfo) c on b.linkfromid=c.mpid
  131. left join (select p1.cpid,p1.cpname,p1.zonename,p1.positionname,p1.deviceid,p2.devicename from dev_cpinfo p1,dev_devinfo p2 where p1.deviceid=p2.deviceid union select p1.mpid cpid,p1.mpname cpname,p1.zonename,p1.positionname,p1.deviceid,p2.device_name devicename from video_mpinfo p1,video_devinfo p2 where p1.deviceid=p2.device_id )d on b.linktoid=d.cpid`
  132. totalSql := "select count(1) recordcount from link_event a inner join (select a.strategyid,a.strategyname,linkfromid,linktoid,actid from link_strategy a inner join link_relation_obj b on a.strategyid=b.strategyid inner join link_relation_action c on a.strategyid=c.strategyid) b on a.strategyid=b.strategyid " +
  133. " left join dev_mpinfo c on b.linkfromid=mpid left join dev_cpinfo d on b.linktoid=d.cpid left join dev_devinfo e on d.deviceid=e.deviceid"
  134. var sqlCondition []string
  135. if source_address != "" {
  136. sqlCondition = append(sqlCondition, fmt.Sprintf("concat(c.zonename,'/',c.positionname) like '%%%s%%'", source_address))
  137. }
  138. if targ_address != "" {
  139. sqlCondition = append(sqlCondition, fmt.Sprintf("concat(d.zonename,'/',d.positionname) like '%%%s%%'", targ_address))
  140. }
  141. if device_name != "" {
  142. sqlCondition = append(sqlCondition, fmt.Sprintf("e.devicename like '%%%s%%'", device_name))
  143. }
  144. if startDate > 0 && endDate > 0 {
  145. sqlCondition = append(sqlCondition, fmt.Sprintf("a.timestamp between %d and %d", startDate, endDate))
  146. } else if startDate > 0 {
  147. sqlCondition = append(sqlCondition, fmt.Sprintf("a.timestamp>=%d", startDate))
  148. } else if endDate > 0 {
  149. sqlCondition = append(sqlCondition, fmt.Sprintf("a.timestamp<=%d", endDate))
  150. }
  151. sqlCondition = append(sqlCondition, fmt.Sprintf("(a.dstappid=%d or a.srcappid=%d)", AppId, AppId))
  152. if len(sqlCondition) > 0 {
  153. sqlCommandText += " where " + strings.Join(sqlCondition, " and ")
  154. totalSql += " where " + strings.Join(sqlCondition, " and ")
  155. }
  156. sqlCommandText += fmt.Sprintf(" order by a.id desc limit %d,%d", (pageIndex-1)*pageSize, pageSize)
  157. var list []linkData
  158. err := l.SvcCtx.AlarmStrategy.Base.Raw(sqlCommandText, &list)
  159. var total Alarm_Total
  160. if err == nil {
  161. l.SvcCtx.AlarmStrategy.Base.Raw(totalSql, &total)
  162. }
  163. if len(list) == 0 {
  164. return map[string]interface{}{"list": []interface{}{}, "total": total.Recordcount}, err
  165. } else {
  166. return map[string]interface{}{"list": list, "total": total.Recordcount}, err
  167. }
  168. }
  169. //处理收到的联动消息
  170. func (t *LinkEventService) LinkMessage(data map[string]interface{}) {
  171. var parameter LinkeBody
  172. //解析消息
  173. if len(data) > 0 {
  174. if v, ok := data["srcappid"]; ok {
  175. parameter.Srcappid = cast.ToInt32(v)
  176. }
  177. if v, ok := data["destappid"]; ok {
  178. parameter.Destappid = cast.ToInt32(v)
  179. }
  180. if v, ok := data["eventid"]; ok {
  181. parameter.Eventid, _ = strconv.ParseInt(string(v.(json.Number)), 10, 64)
  182. }
  183. if v, ok := data["strategyid"]; ok {
  184. parameter.Strategyid, _ = strconv.ParseInt(string(v.(json.Number)), 10, 64)
  185. }
  186. if v, ok := data["linktoid"]; ok {
  187. parameter.Linktoid, _ = strconv.ParseInt(string(v.(json.Number)), 10, 64)
  188. }
  189. if v, ok := data["linktype"]; ok {
  190. parameter.Linktype = cast.ToInt(v)
  191. }
  192. if v, ok := data["eventdesc"]; ok {
  193. parameter.Eventdesc = cast.ToString(v)
  194. }
  195. if v, ok := data["actid"]; ok {
  196. parameter.Actid, _ = strconv.ParseInt(string(v.(json.Number)), 10, 64)
  197. }
  198. if messageId, ok := data["mid"]; ok {
  199. parameter.MessageId = cast.ToString(messageId)
  200. }
  201. } else {
  202. logger.Logger.Println("接收的联动消息为空!")
  203. return
  204. }
  205. if int(parameter.Destappid) == cast.ToInt(RtelecManageApp().RegAppID) {
  206. t.HandleLinkEventByMessage(parameter)
  207. }
  208. }
  209. //处理联动消息事件
  210. func (t *LinkEventService) HandleLinkEventByMessage(parameter LinkeBody) {
  211. appid := cast.ToInt64(RtelecManageApp().RegAppID)
  212. commandInfo, err := t.GetLinkByStrategyId(parameter.Strategyid, parameter.Linktoid, parameter.Actid)
  213. if err == nil {
  214. if len(commandInfo) > 0 {
  215. for _, info := range commandInfo {
  216. var commandField CommandMgr
  217. commandField.DeviceId = info.Deviceid
  218. commandField.AttrName = info.Targetattrname
  219. commandField.State = int(info.Actvalue)
  220. commandField.Actid = info.Actid
  221. var state = t.getBeforestatus(info.Deviceid, info.Targetattrname)
  222. //发送指令
  223. var messageId = tools.GetUid()
  224. msgObj := new(utils.MsgStateManage)
  225. msgObj.SetMessageStateObj(messageId, utils.MsgState{Success: false, State: false, Message: ""})
  226. Result := utils.MsgState{}
  227. raddelay, _ := bo.GetSysParamValue("readdelay", "5")
  228. commandObj := new(CommandService)
  229. for i := 0; i < 5; i++ {
  230. commandObj.Command(commandField, messageId, 1)
  231. Result = msgObj.HanderMesage(messageId, cast.ToInt(raddelay))
  232. if Result.Success {
  233. break
  234. }
  235. }
  236. eventObject := logic.NewLinkEventLogic()
  237. var field model.LinkEvent
  238. field.Eventid = new(utils.ToolsLogic).GetOnlyId(appid)
  239. stateText := info.Actdesc
  240. //判断成功状态
  241. if Result.Success {
  242. ExecuteState, _ := commandObj.CheckState(commandField)
  243. if ExecuteState {
  244. parameter.Reply = 1
  245. field.Result = fmt.Sprintf("%s成功", stateText)
  246. } else {
  247. parameter.Reply = 0
  248. field.Result = fmt.Sprintf("%s失败", stateText)
  249. }
  250. } else {
  251. parameter.Reply = 0
  252. field.Result = Result.Message
  253. }
  254. var desc = t.LinkDesc(info.Linktoid) + fmt.Sprintf("将设备控制状态更改为:%s,执行结果:%s", stateText, field.Result)
  255. field.Eventdesc = desc
  256. field.Strategyid = info.Strategyid
  257. field.Timestamp = time.Now().Local().Unix()
  258. field.Linktoid = info.Linktoid
  259. field.Beforestatus = tools.IsEmpty(state)
  260. field.Afterstatus = stateText
  261. field.Srcappid = parameter.Srcappid
  262. field.Dstappid = parameter.Destappid
  263. field.CreateAt = time.Now()
  264. field.UpdateAt = time.Now()
  265. parameter.Beforestatus = field.Beforestatus
  266. parameter.Afterstatus = field.Afterstatus
  267. parameter.Result = field.Result
  268. err := eventObject.AddLinkEvent(&field)
  269. filedByte, _ := json.Marshal(field)
  270. if err == nil {
  271. //进行联动消息处理后的回复
  272. go t.PublishLinkReply(parameter)
  273. new(LogService).SaveLog(fmt.Sprintf("添加联动事件成功,联动内容:%s", string(filedByte)))
  274. } else {
  275. new(LogService).SaveLog(fmt.Sprintf("添加联动事件失败,联动内容:%s,失败原因:%s", string(filedByte), err.Error()))
  276. }
  277. }
  278. } else {
  279. logger.Logger.Println("进行联动时未查询到联动对象")
  280. }
  281. } else {
  282. logger.Logger.Error(fmt.Sprintf("查询联动对象时出现错误:%s", err.Error()))
  283. }
  284. }
  285. //判断是否有联动配并触发联动事件
  286. func (t *LinkEventService) HandleLinkEvent(Field *HistoryService) {
  287. appid := cast.ToInt32(RtelecManageApp().RegAppID)
  288. Link_Info, err := t.GetLinkInfo(int(Field.Model.Deviceid))
  289. if err == nil && len(Link_Info) > 0 {
  290. var isLink = false //是否触发联动标识
  291. //前置测点运算关系,默认为无 1-与,2-或,3-无
  292. preRelation := 4
  293. currentLinkInfo := LinkInfo{}
  294. var linkdesc = ""
  295. logger.Logger.Debug(fmt.Sprintf("当前设备%d的联动配置:%+v", Field.Model.Deviceid, Link_Info))
  296. for AttrName, AttrValue := range Field.AttrInfo {
  297. attrvalue := AttrValue.(float64)
  298. for _, info := range Link_Info {
  299. if int(Field.Model.Deviceid) == info.Fromdeviceid && AttrName == info.Fromattrname {
  300. var tmpIsLink = false
  301. switch info.Than {
  302. case 1:
  303. if attrvalue > info.TargValue {
  304. tmpIsLink = true
  305. linkdesc = fmt.Sprintf("联动条件为>%d", int(info.TargValue))
  306. }
  307. case 2:
  308. if attrvalue == info.TargValue {
  309. tmpIsLink = true
  310. linkdesc = fmt.Sprintf("联动条件=%d", int(info.TargValue))
  311. }
  312. case 3:
  313. if attrvalue < info.TargValue {
  314. tmpIsLink = true
  315. linkdesc = fmt.Sprintf("联动条件<%d", int(info.TargValue))
  316. }
  317. case 4:
  318. if attrvalue >= info.TargValue {
  319. tmpIsLink = true
  320. linkdesc = fmt.Sprintf("联动条件>=%d", int(info.TargValue))
  321. }
  322. case 5:
  323. if attrvalue <= info.TargValue {
  324. tmpIsLink = true
  325. linkdesc = fmt.Sprintf("联动条件<=%d", int(info.TargValue))
  326. }
  327. }
  328. if preRelation == 2 {
  329. //或者
  330. isLink = isLink || tmpIsLink
  331. } else if preRelation == 1 {
  332. //与
  333. isLink = isLink && tmpIsLink
  334. }
  335. if isLink {
  336. //当前满足联动条件的配置信息
  337. currentLinkInfo = info
  338. }
  339. preRelation = info.Relation
  340. }
  341. }
  342. }
  343. if isLink {
  344. //内部处理不发消息
  345. if currentLinkInfo.Dstappid == int(appid) {
  346. logger.Logger.Debug(fmt.Sprintf("设备%d属性%s触发联动事件%s控制点%d动作%s,延时%d秒执行", currentLinkInfo.Fromdeviceid, currentLinkInfo.Fromattrname, currentLinkInfo.Strategyname, currentLinkInfo.Targetattrname, currentLinkInfo.Actdesc, currentLinkInfo.Delay))
  347. if currentLinkInfo.Delay > 0 {
  348. //当前联动事件延迟时长
  349. time.Sleep(time.Duration(currentLinkInfo.Delay) * time.Second)
  350. }
  351. var commandField CommandMgr
  352. //向目标设备及控制点发送控制指令
  353. commandField.DeviceId = currentLinkInfo.Deviceid
  354. commandField.AttrName = currentLinkInfo.Targetattrname
  355. commandField.State = int(currentLinkInfo.Actvalue)
  356. var state = t.getBeforestatus(currentLinkInfo.Deviceid, currentLinkInfo.Targetattrname)
  357. //发送指令
  358. var messageId = tools.GetUid()
  359. msgObj := new(utils.MsgStateManage)
  360. msgObj.SetMessageStateObj(messageId, utils.MsgState{Success: false, State: false, Message: ""})
  361. commandObj := new(CommandService)
  362. commandObj.Command(commandField, messageId, 1)
  363. Result := msgObj.HanderMesage(messageId, 10)
  364. eventObject := logic.NewLinkEventLogic()
  365. var field model.LinkEvent
  366. field.Eventid = new(utils.ToolsLogic).GetOnlyId(int64(appid))
  367. field.Beforestatus = tools.IsEmpty(state)
  368. field.Afterstatus = tools.IsEmpty(state)
  369. //判断成功状态
  370. if Result.Success {
  371. ExecuteState, _ := commandObj.CheckState(commandField)
  372. if ExecuteState {
  373. field.Afterstatus = strconv.Itoa(int(currentLinkInfo.Actvalue))
  374. field.Result = fmt.Sprintf("%s成功", currentLinkInfo.Actdesc)
  375. } else {
  376. field.Result = fmt.Sprintf("%s失败", currentLinkInfo.Actdesc)
  377. }
  378. } else {
  379. field.Result = Result.Message
  380. }
  381. desc := t.LinkDesc(currentLinkInfo.Linktoid) + fmt.Sprintf("触发条件:%s,将设备控制状态更改为:%s,执行结果:%s", linkdesc, currentLinkInfo.Actdesc, field.Result)
  382. field.Eventdesc = desc
  383. field.Strategyid = currentLinkInfo.Strategyid
  384. field.Timestamp = time.Now().Local().Unix()
  385. field.Linktoid = currentLinkInfo.Linktoid
  386. field.Srcappid = int32(currentLinkInfo.Srcappid)
  387. field.Dstappid = int32(appid)
  388. err := eventObject.AddLinkEvent(&field)
  389. filedByte, _ := json.Marshal(field)
  390. if err == nil {
  391. new(LogService).SaveLog(fmt.Sprintf("添加联动事件成功,联动内容:%s", string(filedByte)))
  392. } else {
  393. new(LogService).SaveLog(fmt.Sprintf("添加联动事件失败,联动内容:%s,失败原因:%s", string(filedByte), err.Error()))
  394. }
  395. } else {
  396. t.SendLinkMessage(currentLinkInfo)
  397. }
  398. }
  399. }
  400. }
  401. var isLoadLinkInfo = false
  402. //获取联动信息
  403. func (t *LinkEventService) GetLinkInfo(DeviceId int) ([]LinkInfo, error) {
  404. if DeviceId == 0 {
  405. if isLoadLinkInfo {
  406. return nil, nil
  407. }
  408. isLoadLinkInfo = true
  409. LinkData = sync.Map{}
  410. logger.Logger.Debug(fmt.Sprintf("====初始化联动策略===="))
  411. LinkObject := logic.NewLinkStrategyLogic()
  412. var AppId = RtelecManageApp().RegAppID
  413. var list []LinkInfo
  414. var sqlCommandText = "select b.deviceid,a.strategyid,a.appid srcappid,strategyname,linktype,linkfromid,value targ_value,than,relation,b.appid dstappid,linktoid,modelid,a.deviceid fromdeviceid,a.attrname fromattrname,b.actid,b.attrname targerattrname,b.actvalue,b.actdesc,b.delay " +
  415. fmt.Sprintf("from (select a.strategyid,a.appid,a.strategyname,a.linktype,b.linkfromid,b.value,b.than,b.relation,mp.deviceid,mp.attrname from link_strategy a inner join link_relation_obj b on a.strategyid=b.strategyid inner join dev_mpinfo mp on b.linkfromid=mp.mpid where a.disable=1 and a.appid=%s) a ", AppId) +
  416. fmt.Sprintf("left join (select strategyid,b.attrname,c.appid,c.deviceid,linktoid,c.modelid,a.actid,a.delay,cp.value actvalue,cp.actdesc from link_relation_action a inner join dev_cpinfo b on a.linktoid=b.cpid inner join dev_devinfo c on b.deviceid=c.deviceid inner join dev_cpaction cp on a.actid=cp.actid) b on a.strategyid=b.strategyid ")
  417. logger.Logger.Debug(sqlCommandText)
  418. err := LinkObject.SvcCtx.LinkStrategy.Base.Raw(sqlCommandText, &list)
  419. if err == nil {
  420. for _, val := range list {
  421. //var deviceList []LinkInfo
  422. //deviceList = append(deviceList, val)
  423. //LinkData[val.Deviceid] = deviceList
  424. if val.Dstappid == 0 {
  425. //尝试查询判断是否视频设备
  426. type VideoDeviceInfo struct {
  427. Dstappid int
  428. Deviceid int64
  429. Actid int64
  430. Linktoid int64
  431. Mpname string
  432. }
  433. sql := fmt.Sprintf(`select b.deviceid,a.strategyid,a.appid srcappid,strategyname,linktype,linkfromid,value targ_value,than,relation,b.appid dstappid,linktoid,modelid,a.deviceid fromdeviceid,a.attrname fromattrname,b.actid,b.attrname mpname,b.actvalue,b.actdesc,b.delay
  434. from (select a.strategyid,a.appid,a.strategyname,a.linktype,b.linkfromid,b.value,b.than,b.relation,mp.deviceid,mp.attrname from link_strategy a inner join link_relation_obj b on a.strategyid=b.strategyid inner join dev_mpinfo mp on b.linkfromid=mp.mpid where a.disable=1 and a.appid=%s and a.strategyid=%s) a
  435. left join (select a.strategyid,a.linktoid,b.mpname attrname,c.appid,c.device_id deviceid,c.model modelid,a.actid,a.delay,cp.acttype actvalue,cp.actdesc from link_relation_action a inner join video_mpinfo b on a.linktoid=b.mpid inner join video_devinfo c on b.deviceid=c.device_id left join video_action cp on a.actid=cp.actid where a.strategyid=%s) b on a.strategyid=b.strategyid`, AppId, tools.IsEmpty(val.Strategyid), tools.IsEmpty(val.Strategyid))
  436. var videoDeviceList []VideoDeviceInfo
  437. err := LinkObject.SvcCtx.LinkStrategy.Base.Raw(sql, &videoDeviceList)
  438. if err != nil {
  439. logger.Logger.Error(err)
  440. logger.Logger.Println(sql)
  441. continue
  442. }
  443. if len(videoDeviceList) == 0 {
  444. logger.Logger.Println(fmt.Sprintf("未发现测点%d关联的设备信息!", val.Linktoid))
  445. continue
  446. }
  447. val.Dstappid = videoDeviceList[0].Dstappid
  448. val.Deviceid = int(videoDeviceList[0].Deviceid)
  449. val.Targetattrname = videoDeviceList[0].Mpname
  450. val.Actid = videoDeviceList[0].Actid
  451. val.Linktoid = videoDeviceList[0].Linktoid
  452. }
  453. logger.Logger.Debug(fmt.Sprintf("====初始化加载联动策略:%+v", val))
  454. lst, has := LinkData.Load(val.Fromdeviceid)
  455. if has {
  456. lst2 := lst.([]LinkInfo)
  457. lst2 = append(lst2, val)
  458. LinkData.Store(val.Fromdeviceid, lst2)
  459. } else {
  460. lst := []LinkInfo{val}
  461. LinkData.Store(val.Fromdeviceid, lst)
  462. }
  463. }
  464. } else {
  465. logger.Logger.Error(err)
  466. logger.Logger.Println(sqlCommandText)
  467. }
  468. isLoadLinkInfo = false
  469. return list, err
  470. } else {
  471. lst, _ := LinkData.Load(DeviceId)
  472. if lst == nil {
  473. return []LinkInfo{}, nil
  474. }
  475. return lst.([]LinkInfo), nil
  476. }
  477. }
  478. func (t *LinkEventService) getBeforestatus(deviceId int, attrname string) int {
  479. deviceServiceIns := new(DeviceService)
  480. //获取设备的模型信息
  481. deviceModelInfo := deviceServiceIns.GetComboxListById(int32(deviceId))
  482. if deviceModelInfo == nil {
  483. logger.Logger.Error("未发现模型配置信息")
  484. return 0
  485. }
  486. ormrow, err := new(bo.Global).GetCodeInfo("model_table_mapping", cast.ToString(deviceModelInfo.Modelid))
  487. if err != nil || tools.IsEmpty(ormrow["name"]) == "" {
  488. logger.Logger.Error(fmt.Sprintf("未找到模型id=%d对应的数据表关系", deviceModelInfo.Modelid))
  489. return 0
  490. }
  491. localtablename := "t_data_" + tools.IsEmpty(ormrow["name"])
  492. var result = 0
  493. o := orm.NewOrm()
  494. var sqlCommandText = "select " + attrname + " val from " + localtablename + " where deviceid=? order by id desc limit 1 "
  495. var sqlparameter = []interface{}{deviceId}
  496. var table []orm.Params
  497. _, err = o.Raw(sqlCommandText, sqlparameter).Values(&table)
  498. if err == nil && len(table) > 0 {
  499. result, _ = strconv.Atoi(tools.IsEmpty(table[0]["val"]))
  500. } else {
  501. logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sqlCommandText, sqlparameter))
  502. }
  503. return result
  504. }
  505. //获取联动信息
  506. func (t *LinkEventService) GetLinkByStrategyId(strategyid, linktoid, actid int64) ([]LinkInfo, error) {
  507. LinkObject := logic.NewLinkStrategyLogic()
  508. var Result []LinkInfo
  509. var sqlCommandText = "select DISTINCT e.deviceid,e.modelid,e.attrname targetattrname,a.strategyid,linktoid,d.value actvalue,d.actdesc,d.actid " +
  510. " from link_strategy a inner join link_relation_obj b on a.strategyid=b.strategyid inner join link_relation_action c on a.strategyid=c.strategyid inner join dev_cpaction d on d.cpid=c.linktoid inner join dev_cpinfo e on d.cpid=e.cpid " +
  511. fmt.Sprintf("where a.disable=1 and a.strategyid=%d and linktoid=%d and d.actid=%d", strategyid, linktoid, actid)
  512. err := LinkObject.SvcCtx.LinkStrategy.Base.Raw(sqlCommandText, &Result)
  513. if err != nil {
  514. logger.Logger.Error(err)
  515. logger.Logger.Println(sqlCommandText)
  516. }
  517. return Result, err
  518. }
  519. //根据联动目标ID获得描述
  520. func (t *LinkEventService) LinkDesc(linktoId int64) string {
  521. if desc, ok := LinkDescription[linktoId]; ok {
  522. return desc
  523. } else {
  524. mpInfo := logic.NewMpInfoLogic()
  525. type Mpfield struct {
  526. Eventdesc string `json:"eventdesc"`
  527. }
  528. var list []Mpfield
  529. var sqlCommandText = fmt.Sprintf("select concat(c.name,',区域:',a.zonename,',位置:',a.positionname,',控制点名称:',a.cpname) eventdesc from dev_cpinfo a inner join dev_devinfo b on a.deviceid=b.deviceid inner join sys_station c on b.stationid=c.stationid where a.cpid=%d", linktoId)
  530. err := mpInfo.SvcCtx.DevMpinfo.Base.Raw(sqlCommandText, &list)
  531. if err == nil && len(list) > 0 {
  532. LinkDescription[linktoId] = list[0].Eventdesc + ","
  533. }
  534. return LinkDescription[linktoId]
  535. }
  536. }
  537. //联动消息回复
  538. func (t *LinkEventService) PublishLinkReply(replyContent LinkeBody) {
  539. var parameter = make(map[string]interface{})
  540. parameter["srcappid"] = replyContent.Srcappid
  541. parameter["destappid"] = replyContent.Destappid
  542. parameter["eventid"] = replyContent.Eventid
  543. parameter["eventdesc"] = replyContent.Eventdesc
  544. parameter["linktype"] = replyContent.Linktype
  545. parameter["strategyid"] = replyContent.Strategyid
  546. parameter["linktoid"] = replyContent.Linktoid
  547. parameter["actid"] = replyContent.Actid
  548. parameter["beforestatus"] = replyContent.Beforestatus
  549. parameter["afterstatus"] = replyContent.Afterstatus
  550. parameter["result"] = replyContent.Result
  551. parameter["reply"] = replyContent.Reply
  552. parameter["mid"] = replyContent.MessageId
  553. parameter["timestamp"] = time.Now().Unix()
  554. messageContent, _ := json.Marshal(parameter)
  555. logger.Logger.Debug(fmt.Sprintf("=====联动消息回复主题(%s)内容:%s", global.Rtelec_Topics["link_reply"], string(messageContent)))
  556. mqtt.PublishMessage(global.Rtelec_Topics["link_reply"], string(messageContent))
  557. }
  558. //发送联动消息
  559. func (t *LinkEventService) SendLinkMessage(record LinkInfo) {
  560. var parameter = make(map[string]interface{})
  561. parameter["srcappid"] = record.Srcappid
  562. parameter["destappid"] = record.Dstappid
  563. parameter["eventid"] = new(logic.ToolsLogic).GetOnlyId(cast.ToInt64(RtelecManageApp().RegAppID))
  564. parameter["eventdesc"] = record.Strategyname
  565. parameter["linktype"] = record.Linktype
  566. parameter["strategyid"] = record.Strategyid
  567. parameter["linktoid"] = record.Linktoid
  568. parameter["actid"] = record.Actid
  569. parameter["mid"] = tools.GetUid()
  570. messageContent, _ := json.Marshal(parameter)
  571. logger.Logger.Debug(fmt.Sprintf("=====发送联动消息主题(%s)内容:%s", global.Rtelec_Topics["link_request"], string(messageContent)))
  572. mqtt.PublishMessage(global.Rtelec_Topics["link_request"], string(messageContent))
  573. }