command_service.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. package service
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "reflect"
  8. "rtzh_elec_temperature/conf"
  9. "rtzh_elec_temperature/global"
  10. "rtzh_elec_temperature/logger"
  11. "rtzh_elec_temperature/models/bo"
  12. "rtzh_elec_temperature/mqtt"
  13. "rtzh_elec_temperature/rtelec_app_public_lib/utils"
  14. "rtzh_elec_temperature/tools"
  15. "time"
  16. "github.com/astaxie/beego/orm"
  17. "git.rtzhtech.cn/iss/public-lib/logic"
  18. "github.com/spf13/cast"
  19. )
  20. //命令执行服务
  21. type CommandService struct {
  22. BaseService
  23. //当前操作的设备ID
  24. DeviceId int
  25. //命令信息模型对象
  26. CommandData CommandParameter
  27. }
  28. type CommandMgr struct {
  29. DeviceId int
  30. AttrName string
  31. State int
  32. ModelId int
  33. Mpname string
  34. Actid int64
  35. }
  36. /**
  37. 2022-11-1修改http访问海康硬件的接口为modbus模式
  38. */
  39. type CommandParameter struct {
  40. CommandMgr
  41. DeviceId int
  42. Condition map[string]interface{}
  43. MessageId string
  44. CommandType int
  45. ValueType string
  46. }
  47. //执行次数、总次数、间隔周期
  48. var ExecuteIndex = 0
  49. var ExecuteTimer = 0
  50. var interval, _ = time.ParseDuration("0s")
  51. //下发控制指令
  52. func (t *CommandService) PushCommand(cmdParameter CommandMgr) (string, error) {
  53. if RtelecManageApp().AppToken == "" {
  54. return "", errors.New("发送指令时Token不允许为空!")
  55. }
  56. //获取设备信息
  57. //-----2022-12-08--------
  58. devinfo := new(DeviceService)
  59. devinfo.DeviceId = cmdParameter.DeviceId
  60. devlst, err2 := devinfo.GetCommandRestart()
  61. if err2 != nil {
  62. return "", err2
  63. }
  64. if len(devlst) == 0 {
  65. return "", errors.New("无效的设备ID" + tools.IsEmpty(cmdParameter.DeviceId))
  66. }
  67. devicename := tools.IsEmpty(devlst[0]["devicename"])
  68. //-----------------------------
  69. sendCount, _ := bo.GetSysParamValue("sendCount", "3")
  70. ExecuteTimer = cast.ToInt(sendCount)
  71. sendInterval, _ := bo.GetSysParamValue("sendInterval", "3")
  72. interval, _ = time.ParseDuration(sendInterval + "s")
  73. var ExecuteState = false
  74. var message = "远端设备无响应!"
  75. resultvalue := ""
  76. timeout, _ := bo.GetSysParamValue("timeout", "5")
  77. for ExecuteIndex = 0; ExecuteIndex < ExecuteTimer; ExecuteIndex++ {
  78. var messageId = tools.GetUid()
  79. msgObj := new(utils.MsgStateManage)
  80. msgObj.SetMessageStateValue(messageId, utils.MsgState{Success: false, State: false, Message: ""})
  81. logger.Logger.Debug(fmt.Sprintf("====发送id为%s指令:%+v", messageId, cmdParameter))
  82. t.Command(cmdParameter, messageId, 1)
  83. Result := msgObj.HanderMesage(messageId, cast.ToInt(timeout)) //2022-11-04修改:把延迟秒数变为一个变量,从配置文件或者数据库中读取
  84. logger.Logger.Debug(fmt.Sprintf("====接收ID为%s结果:%+v", messageId, Result))
  85. if Result.Success {
  86. //控制命令下发成功
  87. //获取控制点关联的采集点状态值。如果未关联,则获取控制点本身的状态值(需要控制点的寄存器地址支持读)
  88. ExecuteState, resultvalue = t.CheckState(cmdParameter)
  89. if ExecuteState {
  90. //状态值获取成功,并且与下发值完全匹配时,进入控制点联动控制处理
  91. //注:控制点可能没有配置联动策略,此时无需任何处理
  92. t.Handle_Link_Event(cmdParameter)
  93. //此处是否应该记录一次操作成功的操作日志????
  94. new(LogService).SaveLog(fmt.Sprintf("控制成功。设备名称:%s 操作:%s 操作时间:%s", devicename, "控制", tools.NowTime()))
  95. return resultvalue, nil
  96. } else {
  97. continue
  98. }
  99. } else {
  100. //如果执行命令失败直接返回结果。[!!该逻辑已废弃!!]
  101. //如果执行命令失败,尝试重新执行
  102. logger.Logger.Debug(fmt.Sprintf("执行命令%s[%v]失败,结果为:%v,尝试重新执行...", messageId, cmdParameter, Result))
  103. new(LogService).SaveLog(fmt.Sprintf("设备%s执行命令%s[%v]失败,结果为:%v,操作时间:%s", devicename, messageId, cmdParameter, Result, tools.NowTime()))
  104. //return errors.New(Result.Message)
  105. ExecuteState = false
  106. message = Result.Message
  107. continue
  108. }
  109. }
  110. //此处是否应该记录一次操作失败的操作日志????
  111. if !ExecuteState {
  112. return "", errors.New(message)
  113. } else {
  114. return resultvalue, nil
  115. }
  116. }
  117. //处理联动事件
  118. func (field *CommandService) Handle_Link_Event(parameter CommandMgr) {
  119. var Field = new(HistoryService)
  120. Field.Model.Deviceid = int32(parameter.DeviceId)
  121. //接收数据后设置设备为在线状态
  122. new(DeviceService).SetDeviceState(parameter.DeviceId, 2)
  123. Field.Model.Date = tools.NowTime()
  124. var AttrInfo = make(map[string]interface{})
  125. AttrInfo[parameter.AttrName] = float64(parameter.State)
  126. Field.AttrInfo = AttrInfo
  127. go new(LinkEventService).HandleLinkEvent(Field)
  128. }
  129. //判断状态
  130. func (field *CommandService) CheckState(cmdParameter CommandMgr) (bool, string) {
  131. appId := cast.ToInt(RtelecManageApp().RegAppID)
  132. time.Sleep(interval)
  133. var messageId = tools.GetUid()
  134. var sendStatus = cmdParameter.State //保存下发的命令值
  135. msgObj := new(utils.MsgStateManage)
  136. msgObj.SetMessageStateValue(messageId, utils.MsgState{Success: false, State: false, Message: ""})
  137. //2022-11-4判断状态通过发送的dev_cpinfo的attrname去获取对应采集点的属性attrname
  138. //--start--
  139. type ControlMpname struct {
  140. Mpid int64
  141. Mpname string
  142. Successval float64
  143. }
  144. var mpobj ControlMpname
  145. l := logic.NewDeviceLogic()
  146. var sqlCommandText = "select ifnull(mp.attrname,'') mpname,ifnull(a.mpid,0) mpid,ifnull(t1.successval,t1.value) successval from dev_cpinfo a inner join dev_devinfo b on a.deviceid=b.deviceid left join dev_mpinfo mp on a.mpid=mp.mpid inner join dev_cpaction t1 on a.cpid=t1.cpid where 1=1"
  147. sqlCommandText += fmt.Sprintf(" and a.attrname='%s'", cmdParameter.AttrName)
  148. sqlCommandText += fmt.Sprintf(" and a.deviceid=%d", cmdParameter.DeviceId)
  149. if cmdParameter.Actid > 0 {
  150. sqlCommandText += fmt.Sprintf(" and t1.actid=%d", cmdParameter.Actid)
  151. }
  152. sqlCommandText += fmt.Sprintf(" and b.appid=%d limit 1", appId)
  153. logger.Logger.Debug("=====CheckState sqlCommandText:" + sqlCommandText)
  154. err := l.SvcCtx.AlarmStrategy.Base.Raw(sqlCommandText, &mpobj)
  155. logger.Logger.Debug(fmt.Sprintf("=====CheckState mpobj:%+v", mpobj))
  156. if err == nil && mpobj.Mpname != "" {
  157. // if mpobj.Mpid != 0 {
  158. // //获取优化测点的信息
  159. // var tmp = ControlMpname{}
  160. // sqlCommandText = fmt.Sprintf("SELECT d.refid mpid,m.attrname mpname from dev_data_optimize d,dev_mpinfo m where d.refid = m.mpid and d.mpid=%d", mpobj.Mpid)
  161. // err = l.SvcCtx.AlarmStrategy.Base.Raw(sqlCommandText, &tmp)
  162. // if err == nil {
  163. // if tmp.Mpname != "" {
  164. // cmdParameter.Mpname = tmp.Mpname //这因为command函数里面还要用这个去找采集点的attrname
  165. // }
  166. // }
  167. // }
  168. cmdParameter.Mpname = mpobj.Mpname //这因为command函数里面还要用这个去找采集点的attrname
  169. }
  170. //如果单独设置了关联测点的控制成功值:successval,采用该值与采集结果进行一致性比对
  171. sendStatus = cast.ToInt(mpobj.Successval)
  172. //--end--
  173. logger.Logger.Debug(fmt.Sprintf("===CheckState===发送id为%s采集命令:%+v", messageId, cmdParameter))
  174. gatherInter, _ := bo.GetSysParamValue("gatherInterval", "2")
  175. gatherInterval, _ := time.ParseDuration(cast.ToString(gatherInter + "s"))
  176. //计数读取15秒
  177. gatherCount, _ := bo.GetSysParamValue("gatherCount", "15")
  178. var countDown = cast.ToInt(gatherCount) //从数据库中读取配置周期
  179. field.Command(cmdParameter, messageId, 0)
  180. timeout, _ := bo.GetSysParamValue("timeout", "3")
  181. Result := msgObj.HanderMesage(messageId, cast.ToInt(timeout)) //先读1次
  182. //控制结果状态。只有硬件进行了动作并且动作结果与预期相同时才算控制成功
  183. controlSuccess := false
  184. for {
  185. logger.Logger.Debug(fmt.Sprintf("第%d次===CheckState==接收ID为%s采集结果:%+v 控制成功值:%d", countDown, messageId, Result, sendStatus))
  186. if Result.Success && Result.State && sendStatus == cast.ToInt(Result.Value) {
  187. controlSuccess = true
  188. break
  189. }
  190. time.Sleep(gatherInterval) //每次读取间隔时间
  191. messageId = tools.GetUid()
  192. field.Command(cmdParameter, messageId, 0)
  193. Result = msgObj.HanderMesage(messageId, cast.ToInt(timeout))
  194. countDown -= 1
  195. if countDown < 1 {
  196. break
  197. }
  198. }
  199. var state = false
  200. if controlSuccess {
  201. //如果状态读取成功则写入历史表
  202. //--start--
  203. type fields struct {
  204. Appid int
  205. Deviceid int
  206. Devicename string
  207. Mpid string
  208. Mpname string
  209. Attrname string
  210. Val string
  211. Date int64
  212. }
  213. var field = fields{}
  214. var sql = ""
  215. if tools.IsEmpty(conf.GlobalConfig["DoorWay"]) == "http" {
  216. sql = fmt.Sprintf("SELECT a.appid,a.deviceid,a.devicename,m.mpid,m.cpname mpname,m.attrname FROM dev_devinfo a INNER JOIN dev_cpinfo m ON a.deviceid = m.deviceid AND m.cpname='%s' WHERE a.appid =%d AND a.deviceid =%d LIMIT 1;", cmdParameter.Mpname, appId, cmdParameter.DeviceId)
  217. } else {
  218. sql = fmt.Sprintf("select a.appid,a.deviceid,a.devicename,m.mpid,m.mpname,m.attrname from dev_devinfo a left join dev_mpinfo m on a.deviceid=m.deviceid and m.mpname='%s' where a.appid=%d and a.deviceid=%d limit 1;", cmdParameter.Mpname, appId, cmdParameter.DeviceId)
  219. }
  220. err = l.SvcCtx.AlarmStrategy.Base.Raw(sql, &field)
  221. if err == nil {
  222. field.Val = cast.ToString(Result.Value)
  223. field.Date = time.Now().Unix()
  224. } else {
  225. logger.Logger.Debug(err)
  226. return false, ""
  227. }
  228. o := orm.NewOrm()
  229. var sqlParamber []interface{}
  230. var sqlCommandText = "insert into dev_history(appid,deviceid,devicename,mpid,mpname,attrname,val,date)values(?,?,?,?,?,?,?,from_unixtime(?));"
  231. //因为采集硬件方式的不同,采集点和控制点是同一个寄存器的时候,历史数据写入控制点的attrname,如果是分开的则写入采集点的attrname
  232. if field.Mpid == "" {
  233. field.Mpid = "0"
  234. }
  235. if tools.IsEmpty(conf.GlobalConfig["DoorWay"]) == "http" {
  236. sqlParamber = []interface{}{appId, field.Deviceid, field.Devicename, field.Mpid, field.Mpname, cmdParameter.AttrName, field.Val, field.Date}
  237. } else {
  238. sqlParamber = []interface{}{appId, field.Deviceid, field.Devicename, field.Mpid, field.Mpname, cmdParameter.Mpname, field.Val, field.Date}
  239. }
  240. _, err := o.Raw(sqlCommandText, sqlParamber).Exec()
  241. if err != nil {
  242. logger.Logger.Debug(err)
  243. return false, ""
  244. }
  245. //--end--
  246. new(LogService).SaveLog(fmt.Sprintf("采集成功。设备名称:%s 操作:%s 操作时间:%s", field.Devicename, "采集", tools.NowTime()))
  247. if Result.Success && sendStatus == cast.ToInt(Result.Value) {
  248. state = true
  249. }
  250. logger.Logger.Debug(fmt.Sprintf("==CheckState==本次%s控制结果:%v", messageId, state))
  251. return state, tools.IsEmpty(Result.Value)
  252. }
  253. return state, Result.Message
  254. }
  255. //获取状态信息
  256. func (field *CommandService) GetCommandState(cmdParameter CommandMgr) (interface{}, string) {
  257. AppId := cast.ToInt(RtelecManageApp().RegAppID)
  258. var messageId = tools.GetUid()
  259. msgObj := new(utils.MsgStateManage)
  260. msgObj.SetMessageStateValue(messageId, utils.MsgState{Success: false, State: false, Message: ""})
  261. //2022-11-4判断状态通过发送的dev_cpinfo的attrname去获取对应mpname
  262. type ControlMpname struct {
  263. Mpid int
  264. Mpname string
  265. }
  266. var mpobj ControlMpname
  267. l := logic.NewDeviceLogic()
  268. var sqlCommandText = "select ifnull(mp.attrname,'') mpname,ifnull(a.mpid,0) mpid from dev_cpinfo a inner join dev_devinfo b on a.deviceid=b.deviceid left join dev_mpinfo mp on a.mpid=mp.mpid where 1=1"
  269. sqlCommandText += fmt.Sprintf(" and a.attrname='%s'", cmdParameter.AttrName)
  270. sqlCommandText += fmt.Sprintf(" and a.deviceid=%d", cmdParameter.DeviceId)
  271. sqlCommandText += fmt.Sprintf(" and b.appid=%d limit 1", AppId)
  272. err := l.SvcCtx.AlarmStrategy.Base.Raw(sqlCommandText, &mpobj)
  273. if err == nil {
  274. if mpobj.Mpid != 0 {
  275. //获取优化测点的信息
  276. var tmp = ControlMpname{}
  277. sqlCommandText = fmt.Sprintf("SELECT d.refid mpid,m.attrname mpname from dev_data_optimize d,dev_mpinfo m where d.refid = m.mpid and d.mpid=%d", mpobj.Mpid)
  278. err = l.SvcCtx.AlarmStrategy.Base.Raw(sqlCommandText, &tmp)
  279. if err == nil {
  280. if tmp.Mpname != "" {
  281. cmdParameter.Mpname = tmp.Mpname
  282. }
  283. }
  284. }
  285. }
  286. field.Command(cmdParameter, messageId, 0)
  287. timeout, _ := bo.GetSysParamValue("timeout", "3")
  288. Result := msgObj.HanderMesage(messageId, cast.ToInt(timeout))
  289. if Result.Success {
  290. return Result.Value, ""
  291. } else {
  292. return -1, Result.Message
  293. }
  294. }
  295. //命令管理
  296. func (field *CommandService) Command(Field CommandMgr, messageId string, commandType int) {
  297. var deviceObject = new(DeviceService)
  298. deviceObject.DeviceId = Field.DeviceId
  299. deviceObject.Model.AttrName = Field.AttrName
  300. list, err := deviceObject.GetCommandParameter()
  301. if err == nil && len(list) > 0 {
  302. apptoken := RtelecManageApp().AppToken
  303. for _, record := range list {
  304. var parameter = make(map[string]interface{})
  305. parameter["mid"] = messageId
  306. parameter["token"] = apptoken
  307. utils.MessageIds.Set(messageId, messageId)
  308. //mqtt消息中的message数据处理
  309. var para = make(map[string]interface{})
  310. para["timestamp"] = time.Now().Unix()
  311. para["deviceName"] = record.Devicename
  312. para["modelId"] = record.Modelid
  313. para["attrName"] = record.AttrName
  314. //这里的mpname其实是采集点的attrname,在CheckState函数中的sql查询的时候,查询的字段是attrname别名为mpname
  315. if commandType == 0 && Field.Mpname != "" {
  316. para["attrName"] = Field.Mpname
  317. }
  318. para["commandType"] = commandType
  319. para["valueType"] = "number"
  320. para["value"] = Field.State
  321. Message, _ := json.Marshal(para)
  322. msg, _ := new(utils.ToolsLogic).EncryptMsg(Message, []byte(conf.GlobalConfig["rtelec_manage_password"]), true)
  323. parameter["message"] = msg
  324. value, _ := json.Marshal(parameter)
  325. mqtt.PublishMessage(global.Rtelec_Topics["command"], string(value))
  326. }
  327. }
  328. }
  329. //设备重启
  330. func (c *CommandService) DeviceRestart() error {
  331. var deviceObject = new(DeviceService)
  332. deviceObject.DeviceId = c.DeviceId
  333. var modelId float64
  334. modellist := new(ModelService).GetModelListObj()
  335. if len(modellist) > 0 {
  336. for _, record := range modellist {
  337. row := record.(map[string]interface{})
  338. if row["model_name"].(string) == "lightcontorller" {
  339. modelId = cast.ToFloat64(row["id"])
  340. }
  341. }
  342. }
  343. if modelId == 0 {
  344. return errors.New("模型id不允许为空!")
  345. }
  346. list, err := deviceObject.GetCommandRestart()
  347. if err == nil && len(list) > 0 {
  348. for _, record := range list {
  349. logger.Logger.Debug(record)
  350. var parameter = make(map[string]interface{})
  351. var mid = tools.GetUid()
  352. parameter["mid"] = mid
  353. parameter["token"] = RtelecManageApp().AppToken
  354. utils.MessageIds.Set(mid, mid)
  355. //mqtt消息中的message数据处理
  356. var para = make(map[string]interface{})
  357. para["timestamp"] = time.Now().Unix()
  358. para["deviceName"] = tools.IsEmpty(record["devicename"])
  359. para["modelId"] = modelId
  360. para["attrName"] = "isrest"
  361. para["commandType"] = 1
  362. para["valueType"] = "number"
  363. para["value"] = 1
  364. Message, _ := json.Marshal(para)
  365. msg, _ := new(utils.ToolsLogic).EncryptMsg(Message, []byte(conf.GlobalConfig["rtelec_manage_password"]), true)
  366. parameter["message"] = msg
  367. value, _ := json.Marshal(parameter)
  368. mqtt.PublishMessage(global.Rtelec_Topics["command"], string(value))
  369. new(LogService).SaveLog(fmt.Sprintf("命令发送成功。设备名称:%+v 操作:%s 操作时间:%s", para["deviceName"], "重启", tools.NowTime()))
  370. }
  371. }
  372. if len(list) == 0 {
  373. return errors.New("未查询到需要发送指令对应的设备!")
  374. }
  375. return nil
  376. }
  377. //处理命令执行后的返回结果
  378. func (field *CommandService) HandleCommandResult(data map[string]interface{}, MessageId string) {
  379. logger.Logger.Debug("接收控制结果数据:")
  380. logger.Logger.Debug(data)
  381. if message, ok := data["message"]; ok && tools.IsEmpty(message) != "" {
  382. var tempData map[string]interface{}
  383. if reflect.TypeOf(message).Kind() == reflect.String {
  384. bytes := []byte(message.(string))
  385. err := json.Unmarshal(bytes, &tempData)
  386. if err == nil {
  387. if cast.ToInt(tempData["code"]) == 200 {
  388. new(utils.MsgStateManage).SetMessageStateValue(MessageId, utils.MsgState{Success: true, State: true, Message: "操作成功", Value: tempData["value"]})
  389. } else {
  390. logger.Logger.Debug(fmt.Sprintf("指令%s执行返回失败:%+v", MessageId, data))
  391. new(utils.MsgStateManage).SetMessageStateObj(MessageId, utils.MsgState{Success: true, State: false, Message: tools.IsEmpty(tempData["msg"]), Value: -1})
  392. }
  393. } else {
  394. logger.Logger.Debug("接收到数据不是有效的JSON格式:")
  395. logger.Logger.Debug(data)
  396. }
  397. }
  398. }
  399. if MessageId != "" { //对比使用后删除map中的key
  400. utils.MessageIds.Remove(MessageId)
  401. new(utils.MsgStateManage).RemoveMessageStateObj(MessageId)
  402. }
  403. }
  404. //调用命令公共接口
  405. //attrname:向指定属性(测点)发送指令,未指定时向所有属性发送
  406. func (field *CommandService) CommonInterface(attrname ...string) error {
  407. staticAttrName := ""
  408. if attrname != nil && len(attrname) > 0 {
  409. staticAttrName = attrname[0]
  410. }
  411. var deviceObject = new(DeviceService)
  412. deviceObject.DeviceId = field.DeviceId
  413. list, err := deviceObject.GetCmdParameter()
  414. if err == nil {
  415. if len(list) == 0 {
  416. return errors.New("指定的设备不正确")
  417. }
  418. var messageId = field.CommandData.MessageId
  419. for _, record := range list {
  420. if staticAttrName == "" || staticAttrName == record.AttrName {
  421. var parameter = make(map[string]interface{})
  422. parameter["mid"] = messageId
  423. parameter["token"] = RtelecManageApp().AppToken
  424. utils.MessageIds.Set(messageId, messageId)
  425. var para = make(map[string]interface{})
  426. para["timestamp"] = time.Now().Unix()
  427. para["deviceName"] = record.Devicename
  428. para["modelId"] = record.Modelid
  429. para["attrName"] = record.AttrName
  430. para["commandType"] = field.CommandData.CommandType
  431. if field.CommandData.ValueType == "" {
  432. para["valueType"] = "string"
  433. } else {
  434. para["valueType"] = field.CommandData.ValueType
  435. }
  436. field.CommandData.Condition["mid"] = messageId
  437. msgContent, _ := json.Marshal(field.CommandData.Condition)
  438. para["value"] = base64.StdEncoding.EncodeToString(msgContent)
  439. Message, _ := json.Marshal(para)
  440. msg, _ := new(utils.ToolsLogic).EncryptMsg(Message, []byte(conf.GlobalConfig["rtelec_manage_password"]), true)
  441. parameter["message"] = msg
  442. command_text, _ := json.Marshal(parameter)
  443. logger.Logger.Debug(fmt.Sprintf("控制操作,操作参数:%+v", para))
  444. mqtt.PublishMessage(global.Rtelec_Topics["command"], string(command_text))
  445. if staticAttrName != "" {
  446. //如果指定了定向属性时,发送后立即退出
  447. break
  448. }
  449. }
  450. }
  451. }
  452. return nil
  453. }
  454. //发送事件获取指令
  455. //需要订阅dataPush接口,解析查询返回结果数据 <---错误的订阅主题,应该订阅/iss_v1.0.0/isecurity/command/response 2022-11-24
  456. //消息value数据格式:
  457. //{
  458. // "code": "getEvent",
  459. // "pageNo": 1,
  460. // "pageSize": 20,
  461. // "startTime": "2022-09-07T00:00:00+08:00",
  462. // "endTime": "2022-09-07T23:59:59+08:00",
  463. // "mid": "1a41fd60-f393-4ff8-b1dd-8b9b8dc077e3"
  464. //}
  465. func (field *CommandService) SendGetEvent(comm_code string, attrname ...string) error {
  466. staticAttrName := ""
  467. if attrname != nil && len(attrname) > 0 {
  468. staticAttrName = attrname[0]
  469. }
  470. if comm_code == "" {
  471. comm_code = "getEvent"
  472. }
  473. if _, has := field.CommandData.Condition["pageNo"]; !has {
  474. field.CommandData.Condition["pageNo"] = 1
  475. }
  476. if _, has := field.CommandData.Condition["pageSize"]; !has {
  477. field.CommandData.Condition["pageSize"] = 20
  478. }
  479. field.CommandData.Condition["code"] = comm_code
  480. //field.Condition["starttime"] = starttime
  481. //field.Condition["endTime"] = tools.NowTime()
  482. if _, has := field.CommandData.Condition["startTime"]; !has {
  483. field.CommandData.Condition["startTime"] = time.Now().Add(-12 * time.Hour).Format("2006-01-02T15:04:05+08:00")
  484. }
  485. if _, has := field.CommandData.Condition["endTime"]; !has {
  486. field.CommandData.Condition["endTime"] = time.Now().Format("2006-01-02T15:04:05+08:00")
  487. }
  488. var deviceObject = new(DeviceService)
  489. deviceObject.DeviceId = field.DeviceId
  490. deviceInfo, _ := deviceObject.GetCommandRestart()
  491. if deviceInfo == nil || len(deviceInfo) == 0 {
  492. return errors.New(fmt.Sprintf("未查询到设备[ID:%d]对应的设备信息", field.DeviceId))
  493. }
  494. deviceSign := deviceInfo[0]
  495. var parameter = make(map[string]interface{})
  496. // parameter["code"] = comm_code //附加参数,用于解析结果时标识该数据为事件查询数据
  497. parameter["mid"] = field.CommandData.MessageId
  498. parameter["token"] = RtelecManageApp().AppToken
  499. utils.MessageIds.Set(field.CommandData.MessageId, field.CommandData.MessageId)
  500. var para = make(map[string]interface{})
  501. para["timestamp"] = time.Now().Unix()
  502. para["deviceName"] = tools.IsEmpty(deviceSign["devicename"])
  503. para["modelId"] = tools.IsEmpty(deviceSign["modelid"])
  504. para["attrName"] = "Contrl"
  505. para["valueType"] = "string"
  506. para["commandType"] = 0
  507. if staticAttrName != "" {
  508. para["attrName"] = staticAttrName
  509. }
  510. field.CommandData.Condition["mid"] = field.CommandData.MessageId
  511. msgContent, _ := json.Marshal(field.CommandData.Condition)
  512. para["value"] = base64.StdEncoding.EncodeToString(msgContent)
  513. Message, _ := json.Marshal(para)
  514. msg, _ := new(utils.ToolsLogic).EncryptMsg(Message, []byte(conf.GlobalConfig["rtelec_manage_password"]), true)
  515. parameter["message"] = msg
  516. command_text, _ := json.Marshal(parameter)
  517. logger.Logger.Debug(fmt.Sprintf("SendGetEvent操作,操作参数:%+v", para))
  518. mqtt.PublishMessage(global.Rtelec_Topics["command"], string(command_text))
  519. return nil
  520. }