diff --git a/bridge b/bridge index 056a60b..32a6031 100755 Binary files a/bridge and b/bridge differ diff --git a/decoder b/decoder index b09eb79..f2a061b 100755 Binary files a/decoder and b/decoder differ diff --git a/internal/app/server/routes.go b/internal/app/server/routes.go index 6240d97..b30fdc8 100644 --- a/internal/app/server/routes.go +++ b/internal/app/server/routes.go @@ -57,6 +57,11 @@ func (a *ServerApp) RegisterRoutes() http.Handler { r.HandleFunc("/reslevis/alerts/{id}", controller.AlertUpdateStatusController(a.DB, a.ctx)).Methods("PATCH") r.HandleFunc("/reslevis/alerts/{id}", controller.AlertDeleteController(a.DB, a.ctx)).Methods("DELETE") + r.HandleFunc("/reslevis/getFloors", controller.FloorListController(a.DB, a.ctx)).Methods("GET") + r.HandleFunc("/reslevis/postFloor", controller.FloorAddController(a.DB, a.ctx)).Methods("POST") + r.HandleFunc("/reslevis/updateFloor", controller.FloorUpdateController(a.DB, a.ctx)).Methods("PUT") + r.HandleFunc("/reslevis/removeFloor/{id}", controller.FloorDeleteController(a.DB, a.ctx)).Methods("DELETE") + // Tracks r.HandleFunc("/reslevis/getTracks/{id}", controller.TracksListController(a.DB, a.ctx)).Methods("GET") r.HandleFunc("/reslevis/getTracks", controller.TracksListAllController(a.DB, a.ctx)).Methods("GET") diff --git a/internal/pkg/controller/floor_controller.go b/internal/pkg/controller/floor_controller.go new file mode 100644 index 0000000..93521e3 --- /dev/null +++ b/internal/pkg/controller/floor_controller.go @@ -0,0 +1,75 @@ +package controller + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/AFASystems/presence/internal/pkg/api/response" + "github.com/AFASystems/presence/internal/pkg/model" + "github.com/AFASystems/presence/internal/pkg/validation" + "github.com/gorilla/mux" + "gorm.io/gorm" +) + +func FloorAddController(db *gorm.DB, context context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var floor model.Floor + if err := json.NewDecoder(r.Body).Decode(&floor); err != nil { + response.BadRequest(w, "invalid request body") + return + } + if err := validation.Struct(&floor); err != nil { + response.BadRequest(w, err.Error()) + return + } + if err := db.WithContext(context).Create(&floor).Error; err != nil { + response.InternalError(w, "failed to create floor", err) + return + } + + response.JSON(w, http.StatusCreated, map[string]string{"status": "created"}) + } +} + +func FloorListController(db *gorm.DB, context context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var floors []model.Floor + if err := db.WithContext(context).Find(&floors).Error; err != nil { + response.InternalError(w, "failed to list floors", err) + return + } + if err := db.WithContext(context).Find(&floors).Error; err != nil { + response.InternalError(w, "failed to list floors", err) + return + } + response.JSON(w, http.StatusOK, floors) + } +} + +func FloorUpdateController(db *gorm.DB, context context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var floor model.Floor + if err := json.NewDecoder(r.Body).Decode(&floor); err != nil { + response.BadRequest(w, "invalid request body") + return + } + } +} + +func FloorDeleteController(db *gorm.DB, context context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + id := mux.Vars(r)["id"] + res := db.WithContext(context).Delete(&model.Floor{}, "id = ?", id) + if res.RowsAffected == 0 { + response.NotFound(w, "floor not found") + return + } + if res.Error != nil { + response.InternalError(w, "failed to delete floor", res.Error) + return + } + + response.JSON(w, http.StatusOK, map[string]string{"status": "deleted"}) + } +} diff --git a/internal/pkg/database/database.go b/internal/pkg/database/database.go index 70aee1e..d9495fd 100644 --- a/internal/pkg/database/database.go +++ b/internal/pkg/database/database.go @@ -26,7 +26,7 @@ func Connect(cfg *config.Config) (*gorm.DB, error) { return nil, err } - if err := db.AutoMigrate(&model.Gateway{}, model.Zone{}, model.TrackerZones{}, model.Tracker{}, model.Config{}, appcontext.Settings{}, model.Tracks{}, &model.Alert{}); err != nil { + if err := db.AutoMigrate(&model.Gateway{}, model.Zone{}, model.TrackerZones{}, model.Tracker{}, model.Config{}, appcontext.Settings{}, model.Tracks{}, &model.Alert{}, model.Floor{}); err != nil { return nil, err } diff --git a/internal/pkg/model/floor.go b/internal/pkg/model/floor.go new file mode 100644 index 0000000..beea49c --- /dev/null +++ b/internal/pkg/model/floor.go @@ -0,0 +1,11 @@ +package model + +type Floor struct { + ID string `gorm:"unique;primaryKey"` + Name string `json:"name"` + FloorNumber int `json:"floornumber"` + Image string `json:"image"` + Description string `json:"description"` + Scale int `json:"scale"` + Building string `json:"building"` +} diff --git a/internal/pkg/model/tracks.go b/internal/pkg/model/tracks.go index f4aa1e8..ff64f3e 100644 --- a/internal/pkg/model/tracks.go +++ b/internal/pkg/model/tracks.go @@ -17,4 +17,7 @@ type Tracks struct { Floor string `json:"floor"` Signal int64 `json:"signal"` Building string `json:"building"` + X float32 `json:"x"` + Y float32 `json:"y"` + Z float32 `json:"z"` } diff --git a/internal/pkg/service/beacon_service.go b/internal/pkg/service/beacon_service.go index c1823ce..e11540a 100644 --- a/internal/pkg/service/beacon_service.go +++ b/internal/pkg/service/beacon_service.go @@ -75,7 +75,29 @@ func LocationToBeaconService(msg model.HTTPLocation, db *gorm.DB, writer *kafka. return } - if err := db.Create(&model.Tracks{UUID: msg.ID, Timestamp: time.Now(), Gateway: gw.ID, GatewayMac: gw.MAC, Tracker: msg.ID, Floor: gw.Floor, Building: gw.Building, TrackerMac: tracker.MAC, Signal: msg.RSSI}).Error; err != nil { + var floor model.Floor + if err := db.Where("id = ?", gw.Floor).First(&floor).Error; err != nil { + msg := fmt.Sprintf("Floor not found for ID: %s", gw.Floor) + slog.Error(msg) + return + } + + fmt.Printf("floor: %d\n", floor.FloorNumber) + + if err := db.Create(&model.Tracks{ + UUID: msg.ID, + Timestamp: time.Now(), + Gateway: gw.ID, + GatewayMac: gw.MAC, + Tracker: msg.ID, + Floor: gw.Floor, + Building: gw.Building, + TrackerMac: tracker.MAC, + Signal: msg.RSSI, + X: gw.X, + Y: gw.Y, + Z: float32(floor.FloorNumber), + }).Error; err != nil { msg := fmt.Sprintf("Error in saving distance for beacon: %v", err) slog.Error(msg) return @@ -92,6 +114,7 @@ func LocationToBeaconService(msg model.HTTPLocation, db *gorm.DB, writer *kafka. } func LocationToBeaconServiceAI(msg model.HTTPLocation, db *gorm.DB, writer *kafka.Writer, ctx context.Context) { + fmt.Printf("msg: %+v\n", msg) tracker, err := findTracker(msg, db) if err != nil { msg := fmt.Sprintf("Error in finding tracker: %v", err) @@ -113,7 +136,9 @@ func LocationToBeaconServiceAI(msg model.HTTPLocation, db *gorm.DB, writer *kafk return } - if err := db.Create(&model.Tracks{UUID: tracker.ID, Timestamp: time.Now(), Gateway: gw.ID, GatewayMac: gw.MAC, Tracker: tracker.ID, Floor: gw.Floor, Building: gw.Building, TrackerMac: tracker.MAC}).Error; err != nil { + // fmt.Printf("gw: %+v\n", gw) + + if err := db.Create(&model.Tracks{UUID: tracker.ID, Timestamp: time.Now(), Gateway: gw.ID, GatewayMac: gw.MAC, Tracker: tracker.ID, Floor: gw.Floor, Building: gw.Building, TrackerMac: tracker.MAC, X: msg.X, Y: msg.Y, Z: msg.Z}).Error; err != nil { msg := fmt.Sprintf("Error in saving distance for beacon: %v", err) slog.Error(msg) return diff --git a/location b/location index 8d6739e..c7021a6 100755 Binary files a/location and b/location differ diff --git a/server b/server index 826371b..5c35b69 100755 Binary files a/server and b/server differ