actions.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "sparrow/pkg/productconfig"
  7. "sparrow/pkg/rpcs"
  8. "github.com/opentracing/opentracing-go/ext"
  9. "github.com/opentracing/opentracing-go"
  10. "net/http"
  11. "sparrow/pkg/models"
  12. "sparrow/pkg/server"
  13. "github.com/go-martini/martini"
  14. "github.com/martini-contrib/render"
  15. )
  16. const (
  17. ErrOK = 0
  18. ErrSystemFault = 10001
  19. ErrProductNotFound = 10002
  20. ErrDeviceNotFound = 10003
  21. ErrDeviceNotOnline = 10004
  22. ErrWrongRequestFormat = 10005
  23. ErrWrongProductConfig = 10006
  24. ErrWrongQueryFormat = 10007
  25. ErrAccessDenied = 10008
  26. ErrIllegalityAction = 10009 //非法操作
  27. )
  28. var (
  29. // ErrBadRequestString 参数不全错误
  30. errBadRequestString = errors.New("请求参数不全")
  31. errIllegalityString = errors.New("非法操作")
  32. )
  33. const (
  34. defaultTimeOut = 3 // seconds
  35. )
  36. func renderError(code int, err error) Common {
  37. result := Common{}
  38. result.Code = code
  39. result.Message = err.Error()
  40. server.Log.Error(err.Error())
  41. return result
  42. }
  43. func done(result interface{}) Common {
  44. return Common{
  45. Code: ErrOK,
  46. Message: "success",
  47. Result: result,
  48. }
  49. }
  50. // GetDeviceInfoByKey get device info with device key
  51. func GetDeviceInfoByKey(params martini.Params, req *http.Request, r render.Render) {
  52. key := req.URL.Query().Get("device_key")
  53. server.Log.Printf("ACTION GetDeviceInfoByKey, key:: %v", key)
  54. device := &models.Device{}
  55. span, ctx := opentracing.StartSpanFromContext(context.Background(), "GetDeviceInfoByKey")
  56. defer span.Finish()
  57. ext.SpanKindRPCClient.Set(span)
  58. span.SetTag("device_key", key)
  59. err := server.RPCCallByName(ctx, "registry", "Registry.ValidateDevice", key, device)
  60. if err != nil {
  61. r.JSON(http.StatusOK, renderError(ErrDeviceNotFound, err))
  62. return
  63. }
  64. result := DeviceInfoResponse{
  65. Data: DeviceInfoData{
  66. Identifier: device.DeviceIdentifier,
  67. Name: device.DeviceName,
  68. Description: device.DeviceDescription,
  69. Version: device.DeviceVersion,
  70. },
  71. }
  72. r.JSON(http.StatusOK, result)
  73. return
  74. }
  75. // GetDeviceInfoByIdentifier get device info with device identifier
  76. func GetDeviceInfoByIdentifier(urlparams martini.Params, r render.Render) {
  77. identifier := urlparams["identifier"]
  78. server.Log.Printf("ACTION GetDeviceInfoByIdentifier, identifier:: %v", identifier)
  79. device := &models.Device{}
  80. span, ctx := opentracing.StartSpanFromContext(context.Background(), "GetDeviceInfoByIdentifier")
  81. defer span.Finish()
  82. ext.SpanKindRPCClient.Set(span)
  83. span.SetTag("identifier", identifier)
  84. err := server.RPCCallByName(ctx, "registry", "Registry.FindDeviceByIdentifier", identifier, device)
  85. if err != nil {
  86. r.JSON(http.StatusOK, renderError(ErrDeviceNotFound, err))
  87. return
  88. }
  89. result := DeviceInfoResponse{
  90. Data: DeviceInfoData{
  91. Identifier: device.DeviceIdentifier,
  92. Name: device.DeviceName,
  93. Description: device.DeviceDescription,
  94. Version: device.DeviceVersion,
  95. },
  96. }
  97. r.JSON(http.StatusOK, result)
  98. return
  99. }
  100. func GetDeviceCurrentStatus(device *models.Device, config *productconfig.ProductConfig,
  101. urlparams martini.Params, r render.Render) {
  102. server.Log.Printf("ACTION GetDeviceCurrentStatus, identifier:: %v", device.DeviceIdentifier)
  103. statusargs := rpcs.ArgsGetStatus{
  104. Id: uint64(device.ID),
  105. }
  106. statusreply := rpcs.ReplyGetStatus{}
  107. //opentracing
  108. span, ctx := opentracing.StartSpanFromContext(context.Background(), "GetDeviceCurrentStatus")
  109. defer span.Finish()
  110. ext.SpanKindRPCClient.Set(span)
  111. err := server.RPCCallByName(ctx, "controller", "Controller.GetStatus", statusargs, &statusreply)
  112. if err != nil {
  113. server.Log.Errorf("get devie status error: %v", err)
  114. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  115. return
  116. }
  117. status, err := config.StatusToMap(statusreply.Status)
  118. if err != nil {
  119. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  120. return
  121. }
  122. result := DeviceStatusResponse{
  123. Data: status,
  124. }
  125. r.JSON(http.StatusOK, result)
  126. return
  127. }
  128. // GetDeviceLatestStatus get device latest status
  129. func GetDeviceLatestStatus() {
  130. }
  131. // SetDeviceStatus set device status
  132. func SetDeviceStatus(device *models.Device, config *productconfig.ProductConfig,
  133. urlparams martini.Params, req *http.Request, r render.Render) {
  134. server.Log.Printf("ACTION GetDeviceCurrentStatus, identifier:: %v,request: %v", device.DeviceIdentifier, req.Body)
  135. var args interface{}
  136. decoder := json.NewDecoder(req.Body)
  137. err := decoder.Decode(&args)
  138. if err != nil {
  139. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  140. return
  141. }
  142. m, ok := args.(map[string]interface{})
  143. if !ok {
  144. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  145. return
  146. }
  147. status, err := config.MapToStatus(m)
  148. if err != nil {
  149. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  150. return
  151. }
  152. statusargs := rpcs.ArgsSetStatus{
  153. DeviceId: uint64(device.ID),
  154. Status: status,
  155. }
  156. statusreply := rpcs.ReplySetStatus{}
  157. //opentracing
  158. span, ctx := opentracing.StartSpanFromContext(context.Background(), "SetDeviceStatus")
  159. defer span.Finish()
  160. ext.SpanKindRPCClient.Set(span)
  161. err = server.RPCCallByName(ctx, "controller", "Controller.SetStatus", statusargs, &statusreply)
  162. if err != nil {
  163. server.Log.Errorf("set devie status error: %v", err)
  164. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  165. return
  166. }
  167. r.JSON(http.StatusOK, Common{})
  168. return
  169. }
  170. // SendCommandToDevice send command to device
  171. func SendCommandToDevice(device *models.Device, config *productconfig.ProductConfig,
  172. urlparams martini.Params, req *http.Request, r render.Render) {
  173. timeout := req.URL.Query().Get("timeout")
  174. server.Log.Printf("ACTION SendCommandToDevice, identifier:: %v, request: %v, timeout: %v",
  175. device.DeviceIdentifier, req.Body, timeout)
  176. var args interface{}
  177. decoder := json.NewDecoder(req.Body)
  178. err := decoder.Decode(&args)
  179. if err != nil {
  180. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  181. return
  182. }
  183. m, ok := args.(map[string]interface{})
  184. if !ok {
  185. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  186. return
  187. }
  188. command, err := config.MapToCommand(m)
  189. if err != nil {
  190. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  191. return
  192. }
  193. cmdargs := rpcs.ArgsSendCommand{
  194. DeviceId: uint64(device.ID),
  195. SubDevice: uint16(command.Head.SubDeviceid),
  196. No: uint16(command.Head.No),
  197. WaitTime: uint32(defaultTimeOut),
  198. Params: command.Params,
  199. }
  200. cmdreply := rpcs.ReplySendCommand{}
  201. //opentracing
  202. span, ctx := opentracing.StartSpanFromContext(context.Background(), "SendCommandToDevice")
  203. defer span.Finish()
  204. ext.SpanKindRPCClient.Set(span)
  205. err = server.RPCCallByName(ctx, "controller", "Controller.SendCommand", cmdargs, &cmdreply)
  206. if err != nil {
  207. server.Log.Errorf("send devie command error: %v", err)
  208. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  209. return
  210. }
  211. r.JSON(http.StatusOK, Common{})
  212. return
  213. }
  214. // AddRule 增加设备规则
  215. func AddRule(device *models.Device, req *http.Request, r render.Render) {
  216. var ruleReq CreateRuleRequest
  217. decoder := json.NewDecoder(req.Body)
  218. err := decoder.Decode(&ruleReq)
  219. if err != nil {
  220. r.JSON(http.StatusOK, renderError(ErrWrongRequestFormat, err))
  221. return
  222. }
  223. rule := &models.Rule{
  224. DeviceID: int64(device.ID),
  225. RuleType: ruleReq.Type,
  226. Trigger: ruleReq.Trigger,
  227. Target: ruleReq.Target,
  228. Action: ruleReq.Action,
  229. }
  230. reply := &rpcs.ReplyEmptyResult{}
  231. //opentracing
  232. span, ctx := opentracing.StartSpanFromContext(context.Background(), "AddRule")
  233. defer span.Finish()
  234. ext.SpanKindRPCClient.Set(span)
  235. err = server.RPCCallByName(ctx, "registry", "Registry.CreateRule", rule, reply)
  236. if err != nil {
  237. server.Log.Errorf("create device rule error: %v", err)
  238. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  239. return
  240. }
  241. r.JSON(http.StatusOK, Common{})
  242. return
  243. }