actions.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "sparrow/pkg/productconfig"
  7. "sparrow/pkg/rpcs"
  8. "strings"
  9. "github.com/gogf/gf/encoding/gjson"
  10. "github.com/opentracing/opentracing-go/ext"
  11. "github.com/opentracing/opentracing-go"
  12. "net/http"
  13. "sparrow/pkg/models"
  14. "sparrow/pkg/server"
  15. "github.com/go-martini/martini"
  16. "github.com/martini-contrib/render"
  17. )
  18. const (
  19. ErrOK = 0
  20. ErrSystemFault = 10001
  21. ErrProductNotFound = 10002
  22. ErrDeviceNotFound = 10003
  23. ErrDeviceNotOnline = 10004
  24. ErrWrongRequestFormat = 10005
  25. ErrWrongProductConfig = 10006
  26. ErrWrongQueryFormat = 10007
  27. ErrAccessDenied = 10008
  28. ErrIllegalityAction = 10009 //非法操作
  29. ErrWrongSecret = 10010 //
  30. )
  31. var (
  32. // ErrBadRequestString 参数不全错误
  33. errBadRequestString = errors.New("请求参数不全")
  34. errIllegalityString = errors.New("非法操作")
  35. )
  36. const (
  37. defaultTimeOut = 0 // seconds
  38. )
  39. func renderError(code int, err error) Common {
  40. result := Common{}
  41. result.Code = code
  42. result.Message = err.Error()
  43. server.Log.Error(err.Error())
  44. return result
  45. }
  46. func done(result interface{}) Common {
  47. return Common{
  48. Code: ErrOK,
  49. Message: "success",
  50. Result: result,
  51. }
  52. }
  53. // GetDeviceInfoByKey get device info with device key
  54. func GetDeviceInfoByKey(params martini.Params, req *http.Request, r render.Render) {
  55. key := req.URL.Query().Get("device_key")
  56. server.Log.Printf("ACTION GetDeviceInfoByKey, key:: %v", key)
  57. device := &models.Device{}
  58. span, ctx := opentracing.StartSpanFromContext(context.Background(), "GetDeviceInfoByKey")
  59. defer span.Finish()
  60. ext.SpanKindRPCClient.Set(span)
  61. span.SetTag("device_key", key)
  62. err := server.RPCCallByName(ctx, rpcs.RegistryServerName, "Registry.ValidateDevice", key, device)
  63. if err != nil {
  64. r.JSON(http.StatusOK, renderError(ErrDeviceNotFound, err))
  65. return
  66. }
  67. result := DeviceInfoResponse{
  68. Data: DeviceInfoData{
  69. Identifier: device.DeviceIdentifier,
  70. Name: device.DeviceName,
  71. Description: device.DeviceDescription,
  72. Version: device.DeviceVersion,
  73. },
  74. }
  75. r.JSON(http.StatusOK, result)
  76. return
  77. }
  78. // GetDeviceInfoByIdentifier get device info with device identifier
  79. func GetDeviceInfoByIdentifier(urlparams martini.Params, r render.Render) {
  80. identifier := urlparams["identifier"]
  81. server.Log.Printf("ACTION GetDeviceInfoByIdentifier, identifier:: %v", identifier)
  82. device := &models.Device{}
  83. err := server.RPCCallByName(context.Background(), rpcs.RegistryServerName, "Registry.FindDeviceByIdentifier2", identifier, device)
  84. if err != nil {
  85. r.JSON(http.StatusOK, renderError(ErrDeviceNotFound, err))
  86. return
  87. }
  88. result := DeviceInfoResponse{
  89. Data: DeviceInfoData{
  90. Identifier: device.DeviceIdentifier,
  91. Name: device.DeviceName,
  92. Description: device.DeviceDescription,
  93. Version: device.DeviceVersion,
  94. },
  95. }
  96. r.JSON(http.StatusOK, result)
  97. return
  98. }
  99. func GetDeviceCurrentStatus(device *models.Device, config *productconfig.ProductConfig,
  100. urlparams martini.Params, r render.Render) {
  101. server.Log.Printf("ACTION GetDeviceCurrentStatus, identifier:: %v", device.DeviceIdentifier)
  102. // 1. 触发设备上报状态(下发指令,不等待返回)
  103. triggerArgs := rpcs.ArgsGetStatus{Id: device.DeviceIdentifier}
  104. triggerReply := rpcs.ReplyGetStatus{}
  105. err := server.RPCCallByName(context.Background(), rpcs.ControllerName, "Controller.GetStatus", triggerArgs, &triggerReply)
  106. if err != nil {
  107. server.Log.Errorf("trigger device status error: %v", err)
  108. }
  109. // 2. 从 DeviceManager 获取实际存储的状态数据
  110. args := rpcs.ArgsGetStatus{Id: device.DeviceIdentifier}
  111. reply := rpcs.ReplyStatus{}
  112. err = server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetDeviceStatus", args, &reply)
  113. if err != nil {
  114. server.Log.Errorf("获取设备状态数据失败: %v", err)
  115. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  116. return
  117. }
  118. if reply.Status == "" {
  119. r.JSON(http.StatusOK, DeviceStatusResponse{Data: map[string]interface{}{}})
  120. return
  121. }
  122. // 3. 解析 JSON 字符串
  123. var status map[string]interface{}
  124. if err := json.Unmarshal([]byte(reply.Status), &status); err != nil {
  125. server.Log.Errorf("解析设备状态数据失败: %v", err)
  126. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  127. return
  128. }
  129. r.JSON(http.StatusOK, DeviceStatusResponse{Data: status})
  130. return
  131. }
  132. func GetDeviceStatusByFields(device *models.Device, config *productconfig.ProductConfig,
  133. urlparams martini.Params, req *http.Request, r render.Render) {
  134. server.Log.Printf("ACTION GetDeviceStatusByFields, identifier:: %v", device.DeviceIdentifier)
  135. fieldsParam := req.URL.Query().Get("fields")
  136. if fieldsParam == "" {
  137. r.JSON(http.StatusOK, renderError(ErrWrongQueryFormat, errBadRequestString))
  138. return
  139. }
  140. requestFields := strings.Split(fieldsParam, ",")
  141. // 触发设备上报状态
  142. triggerArgs := rpcs.ArgsGetStatus{Id: device.DeviceIdentifier}
  143. triggerReply := rpcs.ReplyGetStatus{}
  144. err := server.RPCCallByName(context.Background(), rpcs.ControllerName, "Controller.GetStatus", triggerArgs, &triggerReply)
  145. if err != nil {
  146. server.Log.Errorf("trigger device status error: %v", err)
  147. }
  148. // 从 DeviceManager 获取实际存储的状态数据
  149. args := rpcs.ArgsGetStatus{Id: device.DeviceIdentifier}
  150. reply := rpcs.ReplyStatus{}
  151. err = server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetDeviceStatus", args, &reply)
  152. if err != nil {
  153. server.Log.Errorf("获取设备状态数据失败: %v", err)
  154. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  155. return
  156. }
  157. if reply.Status == "" {
  158. r.JSON(http.StatusOK, DeviceStatusFieldResponse{Data: map[string]interface{}{}})
  159. return
  160. }
  161. // 解析 JSON 字符串
  162. var status map[string]interface{}
  163. if err := json.Unmarshal([]byte(reply.Status), &status); err != nil {
  164. server.Log.Errorf("解析设备状态数据失败: %v", err)
  165. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  166. return
  167. }
  168. server.Log.Debugf("GetDeviceStatusByFields status keys: %v", func() []string {
  169. keys := make([]string, 0, len(status))
  170. for k := range status {
  171. keys = append(keys, k)
  172. }
  173. return keys
  174. }())
  175. // 按指定字段过滤
  176. filtered := make(map[string]interface{})
  177. for _, field := range requestFields {
  178. if val, ok := status[field]; ok {
  179. filtered[field] = val
  180. }
  181. }
  182. r.JSON(http.StatusOK, DeviceStatusFieldResponse{Data: filtered})
  183. return
  184. }
  185. // GetDeviceLatestStatus 获取设备最新状态(直接查询,不触发上报)
  186. func GetDeviceLatestStatus(device *models.Device, config *productconfig.ProductConfig,
  187. urlparams martini.Params, r render.Render) {
  188. server.Log.Printf("ACTION GetDeviceLatestStatus, identifier:: %v", device.DeviceIdentifier)
  189. // 直接从 DeviceManager 获取存储的状态数据
  190. args := rpcs.ArgsGetStatus{Id: device.DeviceIdentifier}
  191. reply := rpcs.ReplyStatus{}
  192. err := server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetDeviceStatus", args, &reply)
  193. if err != nil {
  194. server.Log.Errorf("获取设备状态数据失败: %v", err)
  195. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  196. return
  197. }
  198. if reply.Status == "" {
  199. r.JSON(http.StatusOK, DeviceStatusResponse{Data: map[string]interface{}{}})
  200. return
  201. }
  202. var status map[string]interface{}
  203. if err := json.Unmarshal([]byte(reply.Status), &status); err != nil {
  204. server.Log.Errorf("解析设备状态数据失败: %v", err)
  205. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  206. return
  207. }
  208. r.JSON(http.StatusOK, DeviceStatusResponse{Data: status})
  209. return
  210. }
  211. // DeviceUpgrade 设备OTA升级
  212. func DeviceUpgrade(device *models.Device, urlparams martini.Params, req *http.Request, r render.Render) {
  213. var param DeviceUpgradeReq
  214. decoder := json.NewDecoder(req.Body)
  215. err := decoder.Decode(&param)
  216. if err != nil {
  217. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  218. return
  219. }
  220. server.Log.Infof("设备OTA升级:%s, %s", param.DeviceId, param.Version)
  221. //var args rpcs.ArgsDeviceUpgrade
  222. //args.DeviceId = param.DeviceId
  223. //args.SudDeviceId = param.SubDeviceId
  224. //args.Url = param.Url
  225. //args.Md5 = param.MD5
  226. //args.Version = param.Version
  227. //args.FileSize = param.FileSize
  228. var reply rpcs.ReplyEmptyResult
  229. args := rpcs.ArgsSendCommand{
  230. DeviceId: param.DeviceId,
  231. SubDevice: param.SubDeviceId,
  232. Cmd: "devUpgrade",
  233. Params: map[string]interface{}{
  234. "md5": param.MD5,
  235. "url": param.Url,
  236. "version": param.Version,
  237. "file_size": param.FileSize,
  238. },
  239. }
  240. err = server.RPCCallByName(nil, rpcs.ControllerName, "Controller.SendCommand", args, &reply)
  241. //err = server.RPCCallByName(context.Background(), rpcs.MQTTAccessName, "Access.Upgrade", args, &reply)
  242. if err != nil {
  243. server.Log.Errorf("设备OTA升级失败:", err)
  244. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  245. return
  246. }
  247. r.JSON(http.StatusOK, Common{})
  248. return
  249. }
  250. // SetDeviceStatus set device status
  251. func SetDeviceStatus(device *models.Device, config *productconfig.ProductConfig,
  252. urlparams martini.Params, req *http.Request, r render.Render) {
  253. server.Log.Printf("ACTION GetDeviceCurrentStatus, identifier:: %v,request: %v", device.DeviceIdentifier, req.Body)
  254. var args interface{}
  255. decoder := json.NewDecoder(req.Body)
  256. err := decoder.Decode(&args)
  257. if err != nil {
  258. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  259. return
  260. }
  261. m, ok := args.(map[string]interface{})
  262. if !ok {
  263. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  264. return
  265. }
  266. status, err := config.MapToStatus(m)
  267. if err != nil {
  268. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  269. return
  270. }
  271. statusargs := rpcs.ArgsSetStatus{
  272. DeviceId: device.RecordId,
  273. Status: status,
  274. }
  275. statusreply := rpcs.ReplySetStatus{}
  276. //opentracing
  277. span, ctx := opentracing.StartSpanFromContext(context.Background(), "SetDeviceStatus")
  278. defer span.Finish()
  279. ext.SpanKindRPCClient.Set(span)
  280. err = server.RPCCallByName(ctx, rpcs.ControllerName, "Controller.SetStatus", statusargs, &statusreply)
  281. if err != nil {
  282. server.Log.Errorf("set devie status error: %v", err)
  283. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  284. return
  285. }
  286. r.JSON(http.StatusOK, Common{})
  287. return
  288. }
  289. // SendCommandToDevice send command to device
  290. /*
  291. {
  292. "deviceCode": "5566",
  293. "subDeviceId": "1",
  294. "data": {
  295. "cmd": "powerControl",
  296. "params": {
  297. "power": 1,
  298. "temp":2
  299. }
  300. }
  301. }
  302. */
  303. func SendCommandToDevice(device *models.Device, config *productconfig.ProductConfig,
  304. urlparams martini.Params, req *http.Request, r render.Render) {
  305. timeout := req.URL.Query().Get("timeout")
  306. server.Log.Printf("ACTION SendCommandToDevice, identifier:: %v, request: %v, timeout: %v",
  307. device.DeviceIdentifier, req.Body, timeout)
  308. var args map[string]interface{}
  309. decoder := json.NewDecoder(req.Body)
  310. err := decoder.Decode(&args)
  311. if err != nil {
  312. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  313. return
  314. }
  315. j := gjson.New(args)
  316. cmdargs := rpcs.ArgsSendCommand{
  317. DeviceId: device.DeviceIdentifier,
  318. SubDevice: j.GetString("subDeviceId"),
  319. WaitTime: uint32(defaultTimeOut),
  320. Params: j.GetMap("data.params"),
  321. Cmd: j.GetString("data.cmd"),
  322. }
  323. cmdreply := rpcs.ReplySendCommand{}
  324. err = server.RPCCallByName(context.Background(), rpcs.ControllerName, "Controller.SendCommand", cmdargs, &cmdreply)
  325. if err != nil {
  326. server.Log.Errorf("send devie command error: %v", err)
  327. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  328. return
  329. }
  330. r.JSON(http.StatusOK, Common{})
  331. return
  332. }
  333. func SendCommandToDeviceV2(device *models.Device, config *productconfig.ProductConfig,
  334. urlparams martini.Params, req *http.Request, r render.Render) {
  335. timeout := req.URL.Query().Get("timeout")
  336. server.Log.Printf("ACTION SendCommandToDevice, identifier:: %v, request: %v, timeout: %v",
  337. device.DeviceIdentifier, req.Body, timeout)
  338. var args map[string]interface{}
  339. decoder := json.NewDecoder(req.Body)
  340. err := decoder.Decode(&args)
  341. if err != nil {
  342. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  343. return
  344. }
  345. j := gjson.New(args)
  346. cmdargs := rpcs.ArgsSendCommand{
  347. DeviceId: device.DeviceIdentifier,
  348. SubDevice: j.GetString("subDeviceId"),
  349. WaitTime: uint32(defaultTimeOut),
  350. Params: j.GetMap("data.params"),
  351. Cmd: j.GetString("data.cmd"),
  352. }
  353. cmdreply := rpcs.ReplySendCommand{}
  354. err = server.RPCCallByName(context.Background(), rpcs.ControllerName, "Controller.SendCommandV2", cmdargs, &cmdreply)
  355. if err != nil {
  356. server.Log.Errorf("send devie command error: %v", err)
  357. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  358. return
  359. }
  360. r.JSON(http.StatusOK, Common{})
  361. return
  362. }
  363. // AddRule 增加设备规则
  364. func AddRule(device *models.Device, req *http.Request, r render.Render) {
  365. var ruleReq CreateRuleRequest
  366. decoder := json.NewDecoder(req.Body)
  367. err := decoder.Decode(&ruleReq)
  368. if err != nil {
  369. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  370. return
  371. }
  372. rule := &models.Rule{
  373. DeviceID: device.RecordId,
  374. RuleType: ruleReq.Type,
  375. Trigger: ruleReq.Trigger,
  376. Target: ruleReq.Target,
  377. Action: ruleReq.Action,
  378. }
  379. reply := &rpcs.ReplyEmptyResult{}
  380. //opentracing
  381. span, ctx := opentracing.StartSpanFromContext(context.Background(), "AddRule")
  382. defer span.Finish()
  383. ext.SpanKindRPCClient.Set(span)
  384. err = server.RPCCallByName(ctx, rpcs.RegistryServerName, "Registry.CreateRule", rule, reply)
  385. if err != nil {
  386. server.Log.Errorf("create device rule error: %v", err)
  387. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  388. return
  389. }
  390. r.JSON(http.StatusOK, Common{})
  391. return
  392. }
  393. func AppAuth(req *http.Request, r render.Render) {
  394. var ruleReq rpcs.ArgsAppAuth
  395. decoder := json.NewDecoder(req.Body)
  396. err := decoder.Decode(&ruleReq)
  397. if err != nil {
  398. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  399. return
  400. }
  401. app := &models.Application{}
  402. err = server.RPCCallByName(nil, rpcs.RegistryServerName, "Registry.FindApplicationByAppKey", ruleReq, app)
  403. if err != nil {
  404. r.JSON(http.StatusOK, renderError(ErrWrongSecret, errors.New("invalid secret key")))
  405. return
  406. }
  407. if app.SecretKey != ruleReq.Secretkey {
  408. // device secret is wrong.
  409. r.JSON(http.StatusOK, renderError(ErrWrongSecret, errors.New("wrong application secret")))
  410. return
  411. }
  412. token, timeSnap := TokenMaker(app)
  413. result := AppAuthDataResponse{
  414. AccessToken: token,
  415. ExpireAt: timeSnap,
  416. }
  417. r.JSON(http.StatusOK, Common{
  418. Result: result,
  419. })
  420. return
  421. }
  422. func CheckDeviceNetConfig(req *http.Request, r render.Render) {
  423. var params rpcs.ArgsCheckDeviceNetConfig
  424. params.DeviceCode = req.URL.Query().Get("device_code")
  425. params.Md5 = req.URL.Query().Get("md5")
  426. var reply rpcs.ReplyCheckDeviceNetConfig
  427. err := server.RPCCallByName(nil, rpcs.RegistryServerName, "Registry.CheckDeviceNetConfig", &params, &reply)
  428. if err != nil {
  429. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  430. return
  431. }
  432. r.JSON(http.StatusOK, Common{
  433. Result: reply.Result,
  434. })
  435. }
  436. func CheckDeviceIsOnline(req *http.Request, r render.Render) {
  437. identifier := req.URL.Query().Get("device_code")
  438. device := &models.Device{}
  439. err := server.RPCCallByName(nil, rpcs.RegistryServerName, "Registry.FindDeviceByIdentifier", identifier, device)
  440. if err != nil {
  441. r.JSON(http.StatusOK, renderError(ErrDeviceNotFound, err))
  442. return
  443. }
  444. onlineargs := rpcs.ArgsGetDeviceOnlineStatus{
  445. Id: device.DeviceIdentifier,
  446. }
  447. onlinereply := rpcs.ReplyGetDeviceOnlineStatus{}
  448. err = server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetDeviceOnlineStatus", onlineargs, &onlinereply)
  449. if err != nil || onlinereply.ClientIP == "" {
  450. r.JSON(http.StatusOK, Common{
  451. Result: 2,
  452. })
  453. }
  454. r.JSON(http.StatusOK, Common{
  455. Result: 1,
  456. })
  457. }
  458. func SubmitSceneTask(req *http.Request, r render.Render) {
  459. var ruleReq rpcs.ArgsSubmitTask
  460. decoder := json.NewDecoder(req.Body)
  461. err := decoder.Decode(&ruleReq)
  462. if err != nil {
  463. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  464. return
  465. }
  466. reply := rpcs.ReplySubmitTask{}
  467. server.Log.Debugf("submit sceneTask %v", ruleReq)
  468. err = server.RPCCallByName(nil, rpcs.SceneAccessServiceName, "SceneService.SubmitTask", ruleReq, &reply)
  469. if err != nil {
  470. server.Log.Errorf("submit sceneTask error: %v", err)
  471. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  472. return
  473. }
  474. r.JSON(http.StatusOK, Common{})
  475. return
  476. }
  477. func SubmitTaskLifecycle(req *http.Request, r render.Render) {
  478. var ruleReq rpcs.ArgsSubmitTaskLifecycle
  479. decoder := json.NewDecoder(req.Body)
  480. err := decoder.Decode(&ruleReq)
  481. if err != nil {
  482. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  483. return
  484. }
  485. reply := rpcs.ReplySubmitTask{}
  486. err = server.RPCCallByName(nil, rpcs.SceneAccessServiceName, "SceneService.SubmitTaskLifecycle", ruleReq, &reply)
  487. if err != nil {
  488. r.JSON(http.StatusOK, renderError(ErrWrongSecret, errors.New("invalid secret key")))
  489. server.Log.Errorf("submit taskLifecycle error: %v", err)
  490. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  491. return
  492. }
  493. r.JSON(http.StatusOK, Common{})
  494. return
  495. }
  496. func SubmitSceneAction(req *http.Request, r render.Render) {
  497. var ruleReq rpcs.ArgsSubmitSceneAction
  498. decoder := json.NewDecoder(req.Body)
  499. err := decoder.Decode(&ruleReq)
  500. if err != nil {
  501. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  502. return
  503. }
  504. reply := rpcs.ReplySubmitSceneAction{}
  505. err = server.RPCCallByName(nil, rpcs.SceneServiceName, "SceneService.SubmitAction", ruleReq, &reply)
  506. if err != nil {
  507. r.JSON(http.StatusOK, renderError(ErrWrongSecret, errors.New("invalid secret key")))
  508. server.Log.Errorf("submit scene-manager error: %v", err)
  509. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  510. return
  511. }
  512. r.JSON(http.StatusOK, Common{})
  513. return
  514. }