handlerManager.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package iot
  2. import (
  3. "encoding/json"
  4. "log"
  5. "net/http"
  6. "imuslab.com/arozos/mod/database"
  7. )
  8. /*
  9. IoT Handler Manager
  10. Author: tobychui
  11. This manager mange all the existsing / registered ioT Manager.
  12. This allow a much more abstract usage in the main code
  13. */
  14. type Manager struct {
  15. RegisteredHandler []ProtocolHandler
  16. cachedDeviceList []*Device
  17. db *database.Database
  18. }
  19. func NewIoTManager(sysdb *database.Database) *Manager {
  20. //Create the iot database if it doesn't exists
  21. if !sysdb.TableExists("iot") {
  22. sysdb.NewTable("iot")
  23. }
  24. //Return a new iot manager
  25. return &Manager{
  26. RegisteredHandler: []ProtocolHandler{},
  27. cachedDeviceList: []*Device{},
  28. db: sysdb,
  29. }
  30. }
  31. //Register the handler as one of the IoT Protocol Handler.
  32. func (m *Manager) RegisterHandler(h ProtocolHandler) error {
  33. //Try to start the handler
  34. err := h.Start()
  35. if err != nil {
  36. //Handler startup failed
  37. log.Println("*IoT* Protocol Handler Startup Failed: ", err.Error())
  38. return err
  39. }
  40. //Add it to the handlers
  41. m.RegisteredHandler = append(m.RegisteredHandler, h)
  42. return nil
  43. }
  44. //Handle listing of all avaible scanner and its stats
  45. func (m *Manager) HandleScannerList(w http.ResponseWriter, r *http.Request) {
  46. stats := []Stats{}
  47. for _, scanner := range m.RegisteredHandler {
  48. thisScannerStat := scanner.Stats()
  49. stats = append(stats, thisScannerStat)
  50. }
  51. js, _ := json.Marshal(stats)
  52. sendJSONResponse(w, string(js))
  53. }
  54. //Get the device object by id
  55. func (m *Manager) GetDeviceByID(devid string) *Device {
  56. for _, dev := range m.cachedDeviceList {
  57. if dev.DeviceUUID == devid {
  58. return dev
  59. }
  60. }
  61. return nil
  62. }
  63. //Handle listing of all avaible scanner and its stats
  64. func (m *Manager) HandleIconLoad(w http.ResponseWriter, r *http.Request) {
  65. devid, err := mv(r, "devid", false)
  66. if err != nil {
  67. sendErrorResponse(w, "Invalid device id")
  68. return
  69. }
  70. //Get device icon from handler
  71. targetDevice := m.GetDeviceByID(devid)
  72. iconName := targetDevice.Handler.Icon(targetDevice)
  73. iconFilePath := "./web/SystemAO/iot/hub/img/devices/" + iconName + ".png"
  74. if fileExists(iconFilePath) {
  75. http.ServeFile(w, r, iconFilePath)
  76. } else {
  77. http.ServeFile(w, r, "./web/SystemAO/iot/hub/img/devices/unknown.png")
  78. }
  79. }
  80. //Handle listing of all avaible scanner and its stats
  81. func (m *Manager) HandleExecute(w http.ResponseWriter, r *http.Request) {
  82. devid, err := mv(r, "devid", true)
  83. if err != nil {
  84. sendErrorResponse(w, "Invalid device id")
  85. return
  86. }
  87. eptname, err := mv(r, "eptname", true)
  88. if err != nil {
  89. sendErrorResponse(w, "Invalid endpoint name")
  90. return
  91. }
  92. payload, _ := mv(r, "payload", true)
  93. //Get device by device id
  94. dev := m.GetDeviceByID(devid)
  95. if dev == nil {
  96. sendErrorResponse(w, "Given device id not found")
  97. return
  98. }
  99. //Get its endpoint
  100. var targetEndpoint Endpoint
  101. for _, ept := range dev.ControlEndpoints {
  102. if ept.Name == eptname {
  103. //This is the endpoint we are looking for
  104. targetEndpoint = *ept
  105. break
  106. }
  107. }
  108. //log.Println(dev.IPAddr, targetEndpoint, payload)
  109. //Send request to the target IoT device
  110. result, err := dev.Handler.Execute(dev, &targetEndpoint, payload)
  111. if err != nil {
  112. sendErrorResponse(w, err.Error())
  113. return
  114. }
  115. js, _ := json.Marshal(result)
  116. sendJSONResponse(w, string(js))
  117. }
  118. //Get status of the given device ID
  119. func (m *Manager) HandleGetDeviceStatus(w http.ResponseWriter, r *http.Request) {
  120. devid, err := mv(r, "devid", true)
  121. if err != nil {
  122. sendErrorResponse(w, "Invalid device id")
  123. return
  124. }
  125. //Search for that device ID
  126. for _, dev := range m.cachedDeviceList {
  127. if dev.DeviceUUID == devid {
  128. //Found. Get it status and return
  129. status, err := dev.Handler.Status(dev)
  130. if err != nil {
  131. sendErrorResponse(w, err.Error())
  132. return
  133. }
  134. //Return the status
  135. js, _ := json.Marshal(status)
  136. sendJSONResponse(w, string(js))
  137. return
  138. }
  139. }
  140. //Not found
  141. sendErrorResponse(w, "Given device ID does not match any scanned devices")
  142. }
  143. //Handle IoT Scanning Request
  144. func (m *Manager) HandleScanning(w http.ResponseWriter, r *http.Request) {
  145. //Scan the devices
  146. scannedDevices := m.ScanDevices()
  147. js, _ := json.Marshal(scannedDevices)
  148. sendJSONResponse(w, string(js))
  149. }
  150. //Handle IoT Listing Request
  151. func (m *Manager) HandleListing(w http.ResponseWriter, r *http.Request) {
  152. if m.cachedDeviceList == nil || len(m.cachedDeviceList) == 0 {
  153. m.ScanDevices()
  154. }
  155. js, _ := json.Marshal(m.cachedDeviceList)
  156. sendJSONResponse(w, string(js))
  157. }
  158. func (m *Manager) GetCachedDeviceList() []*Device {
  159. if m.cachedDeviceList == nil {
  160. m.ScanDevices()
  161. }
  162. return m.cachedDeviceList
  163. }
  164. func (m *Manager) ScanDevices() []*Device {
  165. scannedDevices := []*Device{}
  166. for _, ph := range m.RegisteredHandler {
  167. //Scan devices using this handler
  168. thisProtcolDeviceList, err := ph.Scan()
  169. if err != nil {
  170. log.Println("*IoT* Scan Error: " + err.Error())
  171. continue
  172. }
  173. //Append it to list
  174. for _, dev := range thisProtcolDeviceList {
  175. scannedDevices = append(scannedDevices, dev)
  176. }
  177. }
  178. //Cache the scan record
  179. m.cachedDeviceList = scannedDevices
  180. return scannedDevices
  181. }