hdsv2.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package hdsv2
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "io/ioutil"
  6. "net/http"
  7. "strconv"
  8. "strings"
  9. "imuslab.com/arozos/mod/iot"
  10. "imuslab.com/arozos/mod/network/mdns"
  11. )
  12. /*
  13. Home Dynamic 2 Controller
  14. This is a module that handles HDSv2 protocol devices scannings
  15. */
  16. type Handler struct {
  17. scanner *mdns.MDNSHost
  18. historyList []*iot.Device
  19. lastScanTime int64
  20. }
  21. //Create a new HDSv2 Protocol Handler
  22. func NewProtocolHandler(scanner *mdns.MDNSHost) *Handler {
  23. //Create a new MDNS Host
  24. return &Handler{
  25. scanner,
  26. []*iot.Device{},
  27. 0,
  28. }
  29. }
  30. //Scan the devices within the LAN
  31. func (h *Handler) Scan() ([]*iot.Device, error) {
  32. foundDevices := []*iot.Device{}
  33. hosts := h.scanner.Scan(3, "hds.arozos.com")
  34. for _, host := range hosts {
  35. thisDevice := iot.Device{
  36. Name: host.HostName,
  37. Port: host.Port,
  38. Model: host.Model,
  39. Version: host.BuildVersion + "-" + host.MinorVersion,
  40. Manufacturer: host.Vendor,
  41. DeviceUUID: host.UUID,
  42. IPAddr: host.IPv4[0].String(),
  43. RequireAuth: false,
  44. RequireConnect: false,
  45. Status: map[string]interface{}{},
  46. }
  47. //Try to get the device status
  48. status, err := getStatusForDevice(&thisDevice)
  49. if err != nil {
  50. //This might be not a valid HDSv2 device. Skip this
  51. continue
  52. }
  53. thisDevice.Status = status
  54. //Get the device content endpoints
  55. eps, err := getEndpoints(&thisDevice)
  56. if err != nil {
  57. //This might be not a valid HDSv2 device. Skip this
  58. continue
  59. }
  60. thisDevice.ControlEndpoints = eps
  61. //Push this host into found device list
  62. foundDevices = append(foundDevices, &thisDevice)
  63. }
  64. h.historyList = foundDevices
  65. return foundDevices, nil
  66. }
  67. //Return the history scan list from the handler
  68. func (h *Handler) List() ([]*iot.Device, error) {
  69. return h.historyList, nil
  70. }
  71. //Home Dynamic system's devices no need to established conenction before executing anything
  72. func (h *Handler) Connect(device *iot.Device) error {
  73. return nil
  74. }
  75. //Same rules also apply to disconnect
  76. func Disconnect(device *iot.Device) error {
  77. return nil
  78. }
  79. //Get the status of the device
  80. func (h *Handler) Status(device *iot.Device) (map[string]interface{}, error) {
  81. return getStatusForDevice(device)
  82. }
  83. //Get the status of the device
  84. func (h *Handler) Execute(device *iot.Device, endpoint *iot.Endpoint, payload interface{}) (interface{}, error) {
  85. var result interface{}
  86. return result, nil
  87. }
  88. //Get endpoint of the given device object
  89. func getEndpoints(device *iot.Device) ([]*iot.Endpoint, error) {
  90. //Parse the URL of the endpoint apis location (eps)
  91. requestURL := "http://" + device.IPAddr + ":" + strconv.Itoa(device.Port) + "/eps"
  92. resp, err := http.Get(requestURL)
  93. if err != nil {
  94. return nil, err
  95. }
  96. //Get the body content
  97. content, err := ioutil.ReadAll(resp.Body)
  98. if err != nil {
  99. return nil, err
  100. }
  101. //Check if the resp is json
  102. if !isJSON(strings.TrimSpace(string(content))) {
  103. return nil, errors.New("Invalid HDSv2 protocol")
  104. }
  105. //Convert the results to Endpoints
  106. endpoints := []*iot.Endpoint{}
  107. err = json.Unmarshal(content, &endpoints)
  108. if err != nil {
  109. return nil, err
  110. }
  111. return endpoints, nil
  112. }
  113. //Get status given the device object.
  114. func getStatusForDevice(device *iot.Device) (map[string]interface{}, error) {
  115. //Parse the URL for its status api endpoint
  116. requestURL := "http://" + device.IPAddr + ":" + strconv.Itoa(device.Port) + "/status"
  117. resp, err := http.Get(requestURL)
  118. if err != nil {
  119. return map[string]interface{}{}, err
  120. }
  121. //Get the body content
  122. content, err := ioutil.ReadAll(resp.Body)
  123. if err != nil {
  124. return map[string]interface{}{}, err
  125. }
  126. //Check if the resp is json
  127. if !isJSON(strings.TrimSpace(string(content))) {
  128. return map[string]interface{}{}, errors.New("Invalid HDSv2 protocol")
  129. }
  130. //Ok. Parse it
  131. status := map[string]interface{}{}
  132. err = json.Unmarshal(content, &status)
  133. if err != nil {
  134. return map[string]interface{}{}, err
  135. }
  136. return status, nil
  137. }