From 4829c67d1689e422bd2c9049c4030202837472da Mon Sep 17 00:00:00 2001 From: Rushikesh Nimkar Date: Thu, 18 Jul 2024 03:24:18 +0530 Subject: [PATCH] add dwifi api --- api/v1/nodeDwifi/nodeDwifi.go | 143 ++++++++++++++++++++++++++++++++++ api/v1/v1.go | 3 + config/dbconfig/dbconfig.go | 2 +- models/nodeDwifi.go | 34 ++++++++ 4 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 api/v1/nodeDwifi/nodeDwifi.go create mode 100644 models/nodeDwifi.go diff --git a/api/v1/nodeDwifi/nodeDwifi.go b/api/v1/nodeDwifi/nodeDwifi.go new file mode 100644 index 0000000..f494cfe --- /dev/null +++ b/api/v1/nodeDwifi/nodeDwifi.go @@ -0,0 +1,143 @@ +package api + +import ( + "encoding/json" + "net/http" + "sync" + "time" + + "github.com/NetSepio/erebrus-gateway/config/dbconfig" + "github.com/NetSepio/erebrus-gateway/models" + "github.com/NetSepio/erebrus-gateway/util/pkg/logwrapper" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" +) + +var ( + upgrader = websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, + CheckOrigin: func(r *http.Request) bool { + // Allow all connections by default + return true + }, + } + + subscribers = make(map[*websocket.Conn]bool) + mutex = &sync.Mutex{} +) + +func ApplyRoutes(r *gin.RouterGroup) { + g := r.Group("/nodedwifi") + { + g.GET("/all", FetchAllNodeDwifi) + g.GET("/stream", StreamNodeDwifi) + } + + // Start the CheckForUpdates function in a separate goroutine + go CheckForUpdates() +} + +func FetchAllNodeDwifi(c *gin.Context) { + db := dbconfig.GetDb() + var nodeDwifis []models.NodeDwifi + + if err := db.Find(&nodeDwifis).Error; err != nil { + logwrapper.Errorf("failed to get NodeDwifi from DB: %s", err) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch NodeDwifi data"}) + return + } + + var responses []models.NodeDwifiResponse + + for _, nd := range nodeDwifis { + var deviceInfos []models.DeviceInfo + if len(nd.Status) > 0 { + err := json.Unmarshal([]byte(nd.Status), &deviceInfos) + if err != nil { + logwrapper.Errorf("failed to unmarshal NodeDwifi Status: %s", err) + continue + } + } + + response := models.NodeDwifiResponse{ + ID: nd.ID, + Gateway: nd.Gateway, + CreatedAt: nd.CreatedAt, + UpdatedAt: nd.UpdatedAt, + Status: deviceInfos, + } + + responses = append(responses, response) + } + + c.JSON(http.StatusOK, gin.H{"data": responses}) +} + +func StreamNodeDwifi(c *gin.Context) { + // Upgrade HTTP connection to WebSocket + conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + logwrapper.Errorf("websocket upgrade error: %v", err) + return + } + defer conn.Close() + + mutex.Lock() + subscribers[conn] = true + mutex.Unlock() + + // Listen for WebSocket closure + for { + _, _, err := conn.ReadMessage() + if err != nil { + mutex.Lock() + delete(subscribers, conn) + mutex.Unlock() + break + } + } +} + +func CheckForUpdates() { + db := dbconfig.GetDb() + for { + var nodeDwifis []models.NodeDwifi + if err := db.Find(&nodeDwifis).Error; err != nil { + logwrapper.Errorf("Error fetching updates: %v", err) + continue + } + + for _, nd := range nodeDwifis { + var deviceInfos []models.DeviceInfo + if len(nd.Status) > 0 { + err := json.Unmarshal([]byte(nd.Status), &deviceInfos) + if err != nil { + logwrapper.Errorf("failed to unmarshal NodeDwifi Status: %s", err) + continue + } + } + + response := models.NodeDwifiResponse{ + ID: nd.ID, + Gateway: nd.Gateway, + CreatedAt: nd.CreatedAt, + UpdatedAt: nd.UpdatedAt, + Status: deviceInfos, + } + + mutex.Lock() + for conn := range subscribers { + err := conn.WriteJSON(response) + if err != nil { + logwrapper.Errorf("error writing to WebSocket: %v", err) + conn.Close() + delete(subscribers, conn) + } + } + mutex.Unlock() + } + + time.Sleep(5 * time.Second) + } +} diff --git a/api/v1/v1.go b/api/v1/v1.go index 0b5875a..d1b3a42 100644 --- a/api/v1/v1.go +++ b/api/v1/v1.go @@ -3,7 +3,9 @@ package apiv1 import ( "github.com/NetSepio/erebrus-gateway/api/status" "github.com/NetSepio/erebrus-gateway/api/v1/client" + nodedwifi "github.com/NetSepio/erebrus-gateway/api/v1/nodeDwifi" "github.com/NetSepio/erebrus-gateway/api/v1/nodeOperatorForm" + "github.com/NetSepio/erebrus-gateway/api/v1/nodes" "github.com/NetSepio/erebrus-gateway/api/v1/registerDwifi" "github.com/NetSepio/erebrus-gateway/api/v1/subscription" @@ -19,5 +21,6 @@ func ApplyRoutes(r *gin.RouterGroup) { subscription.ApplyRoutes(v1) nodeOperatorForm.ApplyRoutes(v1) registerDwifi.ApplyRoutes(v1) + nodedwifi.ApplyRoutes(v1) } } diff --git a/config/dbconfig/dbconfig.go b/config/dbconfig/dbconfig.go index e66a3d0..1eb00fc 100644 --- a/config/dbconfig/dbconfig.go +++ b/config/dbconfig/dbconfig.go @@ -51,7 +51,7 @@ func GetDb() *gorm.DB { func DbInit() error { db := GetDb() - if err := db.AutoMigrate(&models.User{}, &models.Erebrus{}, &models.Node{}, &models.Subscription{}, &models.FormData{}, &models.FlowId{}, &models.UserFeedback{}, &models.WifiNode{}); err != nil { + if err := db.AutoMigrate(&models.User{}, &models.Erebrus{}, &models.Node{}, &models.Subscription{}, &models.FormData{}, &models.FlowId{}, &models.UserFeedback{}, &models.WifiNode{}, &models.NodeDwifi{}); err != nil { log.Fatal(err) } return nil diff --git a/models/nodeDwifi.go b/models/nodeDwifi.go new file mode 100644 index 0000000..e09053a --- /dev/null +++ b/models/nodeDwifi.go @@ -0,0 +1,34 @@ +package models + +import ( + "time" +) + +type NodeDwifi struct { + ID uint `json:"id" gorm:"primaryKey"` + Gateway string `json:"gateway"` + Status string `json:"-"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +type NodeDwifiResponse struct { + ID uint `json:"id"` + Gateway string `json:"gateway"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Status []DeviceInfo `json:"status"` +} + +type DeviceInfo struct { + MACAddress string `json:"macAddress"` + IPAddress string `json:"ipAddress"` + ConnectedAt time.Time `json:"connectedAt"` + TotalConnectedTime time.Duration `json:"totalConnectedTime"` + Connected bool `json:"connected"` + LastChecked time.Time `json:"lastChecked"` + DefaultGateway string `json:"defaultGateway"` + Manufacturer string `json:"manufacturer"` + InterfaceName string `json:"interfaceName"` + HostSSID string `json:"hostSSID"` +}