123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- package iot
- import (
- "encoding/json"
- "log"
- "net/http"
- "imuslab.com/arozos/mod/database"
- "imuslab.com/arozos/mod/utils"
- )
- /*
- IoT Handler Manager
- Author: tobychui
- This manager mange all the existsing / registered ioT Manager.
- This allow a much more abstract usage in the main code
- */
- type Manager struct {
- RegisteredHandler []ProtocolHandler
- cachedDeviceList []*Device
- db *database.Database
- }
- func NewIoTManager(sysdb *database.Database) *Manager {
- //Create the iot database if it doesn't exists
- if !sysdb.TableExists("iot") {
- sysdb.NewTable("iot")
- }
- //Return a new iot manager
- return &Manager{
- RegisteredHandler: []ProtocolHandler{},
- cachedDeviceList: []*Device{},
- db: sysdb,
- }
- }
- //Register the handler as one of the IoT Protocol Handler.
- func (m *Manager) RegisterHandler(h ProtocolHandler) error {
- //Try to start the handler
- err := h.Start()
- if err != nil {
- //Handler startup failed
- log.Println("[IoT] *ERROR* Protocol Handler Startup Failed: ", err.Error())
- return err
- }
- //Add it to the handlers
- m.RegisteredHandler = append(m.RegisteredHandler, h)
- return nil
- }
- //Handle listing of all avaible scanner and its stats
- func (m *Manager) HandleScannerList(w http.ResponseWriter, r *http.Request) {
- stats := []Stats{}
- for _, scanner := range m.RegisteredHandler {
- thisScannerStat := scanner.Stats()
- stats = append(stats, thisScannerStat)
- }
- js, _ := json.Marshal(stats)
- utils.SendJSONResponse(w, string(js))
- }
- //Get the device object by id
- func (m *Manager) GetDeviceByID(devid string) *Device {
- for _, dev := range m.cachedDeviceList {
- if dev.DeviceUUID == devid {
- return dev
- }
- }
- return nil
- }
- //Handle listing of all avaible scanner and its stats
- func (m *Manager) HandleIconLoad(w http.ResponseWriter, r *http.Request) {
- devid, err := utils.Mv(r, "devid", false)
- if err != nil {
- utils.SendErrorResponse(w, "Invalid device id")
- return
- }
- //Get device icon from handler
- targetDevice := m.GetDeviceByID(devid)
- iconName := targetDevice.Handler.Icon(targetDevice)
- iconFilePath := "./web/SystemAO/iot/hub/img/devices/" + iconName + ".png"
- //fmt.Println(iconFilePath)
- if utils.FileExists(iconFilePath) {
- http.ServeFile(w, r, iconFilePath)
- } else {
- http.ServeFile(w, r, "./web/SystemAO/iot/hub/img/devices/unknown.png")
- }
- }
- //Handle listing of all avaible scanner and its stats
- func (m *Manager) HandleExecute(w http.ResponseWriter, r *http.Request) {
- devid, err := utils.Mv(r, "devid", true)
- if err != nil {
- utils.SendErrorResponse(w, "Invalid device id")
- return
- }
- eptname, err := utils.Mv(r, "eptname", true)
- if err != nil {
- utils.SendErrorResponse(w, "Invalid endpoint name")
- return
- }
- payload, _ := utils.Mv(r, "payload", true)
- //Get device by device id
- dev := m.GetDeviceByID(devid)
- if dev == nil {
- utils.SendErrorResponse(w, "Given device id not found")
- return
- }
- //Get its endpoint
- var targetEndpoint Endpoint
- for _, ept := range dev.ControlEndpoints {
- if ept.Name == eptname {
- //This is the endpoint we are looking for
- targetEndpoint = *ept
- break
- }
- }
- //log.Println(dev.IPAddr, targetEndpoint, payload)
- //Send request to the target IoT device
- result, err := dev.Handler.Execute(dev, &targetEndpoint, payload)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- js, _ := json.Marshal(result)
- utils.SendJSONResponse(w, string(js))
- }
- //Get status of the given device ID
- func (m *Manager) HandleGetDeviceStatus(w http.ResponseWriter, r *http.Request) {
- devid, err := utils.Mv(r, "devid", true)
- if err != nil {
- utils.SendErrorResponse(w, "Invalid device id")
- return
- }
- //Search for that device ID
- for _, dev := range m.cachedDeviceList {
- if dev.DeviceUUID == devid {
- //Found. Get it status and return
- status, err := dev.Handler.Status(dev)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- //Return the status
- js, _ := json.Marshal(status)
- utils.SendJSONResponse(w, string(js))
- return
- }
- }
- //Not found
- utils.SendErrorResponse(w, "Given device ID does not match any scanned devices")
- }
- //Handle IoT Scanning Request
- func (m *Manager) HandleScanning(w http.ResponseWriter, r *http.Request) {
- //Scan the devices
- scannedDevices := m.ScanDevices()
- js, _ := json.Marshal(scannedDevices)
- utils.SendJSONResponse(w, string(js))
- }
- //Handle IoT Listing Request
- func (m *Manager) HandleListing(w http.ResponseWriter, r *http.Request) {
- if m.cachedDeviceList == nil || len(m.cachedDeviceList) == 0 {
- m.ScanDevices()
- }
- js, _ := json.Marshal(m.cachedDeviceList)
- utils.SendJSONResponse(w, string(js))
- }
- func (m *Manager) GetCachedDeviceList() []*Device {
- if m.cachedDeviceList == nil {
- m.ScanDevices()
- }
- return m.cachedDeviceList
- }
- func (m *Manager) ScanDevices() []*Device {
- scannedDevices := []*Device{}
- for _, ph := range m.RegisteredHandler {
- //Scan devices using this handler
- thisProtcolDeviceList, err := ph.Scan()
- if err != nil {
- log.Println("[IoT] *ERROR* Scan Error: " + err.Error())
- continue
- }
- //Append it to list
- for _, dev := range thisProtcolDeviceList {
- scannedDevices = append(scannedDevices, dev)
- }
- }
- //Cache the scan record
- m.cachedDeviceList = scannedDevices
- return scannedDevices
- }
|