diff --git a/cmd/location/main.go b/cmd/location/main.go index 5ab6362..53842da 100644 --- a/cmd/location/main.go +++ b/cmd/location/main.go @@ -203,7 +203,6 @@ func assignBeaconToList(adv model.BeaconAdvertisement, appState *appcontext.AppS id := adv.MAC ok := appState.BeaconExists(id) now := time.Now().Unix() - fmt.Printf("beacon id: %s\n", id) if !ok { appState.UpdateLatestBeacon(id, model.Beacon{ID: id, BeaconType: adv.BeaconType, LastSeen: now, IncomingJSON: adv, BeaconLocation: adv.Hostname, Distance: utils.CalculateDistance(adv)}) diff --git a/cmd/location/server.log b/cmd/location/server.log deleted file mode 100644 index 9f17c45..0000000 --- a/cmd/location/server.log +++ /dev/null @@ -1,17 +0,0 @@ -{"time":"2025-12-04T12:58:07.198978987+01:00","level":"INFO","msg":"Locations algorithm initialized, subscribed to Kafka topics"} -{"time":"2025-12-04T12:58:31.095680248+01:00","level":"INFO","msg":"broken out of the main event loop"} -{"time":"2025-12-04T12:58:31.095860131+01:00","level":"INFO","msg":"All go routines have stopped, Beggining to close Kafka connections"} -{"time":"2025-12-04T12:58:48.509999563+01:00","level":"INFO","msg":"Locations algorithm initialized, subscribed to Kafka topics"} -{"time":"2025-12-04T13:00:19.083141862+01:00","level":"INFO","msg":"broken out of the main event loop"} -{"time":"2025-12-04T13:00:19.083262279+01:00","level":"INFO","msg":"All go routines have stopped, Beggining to close Kafka connections"} -{"time":"2025-12-11T20:57:46.752992493+01:00","level":"INFO","msg":"Locations algorithm initialized, subscribed to Kafka topics"} -{"time":"2025-12-11T20:58:32.221403094+01:00","level":"INFO","msg":"Beacon added to lookup: C83F8F17DB35"} -{"time":"2025-12-11T20:58:49.013687369+01:00","level":"INFO","msg":"broken out of the main event loop"} -{"time":"2025-12-11T20:58:49.01380182+01:00","level":"INFO","msg":"All go routines have stopped, Beggining to close Kafka connections"} -{"time":"2025-12-11T22:16:33.000113327+01:00","level":"INFO","msg":"Locations algorithm initialized, subscribed to Kafka topics"} -{"time":"2025-12-11T22:16:56.930565092+01:00","level":"INFO","msg":"Beacon added to lookup: C83F8F17DB35"} -{"time":"2025-12-11T22:17:01.230339099+01:00","level":"INFO","msg":"Beacon added to lookup: C83F8F17DB35"} -{"time":"2025-12-11T22:17:13.636880745+01:00","level":"INFO","msg":"Beacon added to lookup: C83F8F17DB35"} -{"time":"2025-12-11T22:17:23.816515709+01:00","level":"INFO","msg":"Beacon added to lookup: C83F8F17DB35"} -{"time":"2025-12-11T22:17:41.981977922+01:00","level":"INFO","msg":"broken out of the main event loop"} -{"time":"2025-12-11T22:17:41.98203123+01:00","level":"INFO","msg":"All go routines have stopped, Beggining to close Kafka connections"} diff --git a/cmd/server/main.go b/cmd/server/main.go index c7d5adf..00a0caa 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -80,8 +80,12 @@ func main() { r.HandleFunc("/api/beacons/{beacon_id}", controller.BeaconsDeleteController(writer, ctx, appState)).Methods("DELETE") r.HandleFunc("/api/beacons", controller.BeaconsListController(appState)).Methods("GET") r.HandleFunc("/api/beacons/{beacon_id}", controller.BeaconsListSingleController(appState)).Methods("GET") - r.HandleFunc("/api/beacons", controller.BeaconsAddController(writer, ctx)).Methods("POST") - r.HandleFunc("/api/beacons", controller.BeaconsAddController(writer, ctx)).Methods("PUT") + r.HandleFunc("/api/beacons", controller.BeaconsAddController(writer, ctx, appState)).Methods("POST") + r.HandleFunc("/api/beacons", controller.BeaconsAddController(writer, ctx, appState)).Methods("PUT") + + r.HandleFunc("/api/addbeacons", controller.AddListOfBeaconsController(writer, ctx, appState)).Methods("POST") + + r.HandleFunc("/api/beaconids", controller.GetBeaconIds(appState)).Methods("GET") r.HandleFunc("/api/settings", controller.SettingsListController(appState, client, ctx)).Methods("GET") r.HandleFunc("/api/settings", controller.SettingsEditController(settingsWriter, appState, client, ctx)).Methods("POST") diff --git a/internal/pkg/controller/beacons_controller.go b/internal/pkg/controller/beacons_controller.go index 975ff1b..68a961d 100644 --- a/internal/pkg/controller/beacons_controller.go +++ b/internal/pkg/controller/beacons_controller.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "net/http" - "strings" "github.com/AFASystems/presence/internal/pkg/common/appcontext" "github.com/AFASystems/presence/internal/pkg/model" @@ -13,6 +12,21 @@ import ( "github.com/segmentio/kafka-go" ) +func GetBeaconIds(appstate *appcontext.AppState) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + beacons := appstate.GetAllHttpResults() + bIds := make([]string, len(beacons)) + i := 0 + for k := range beacons { + bIds[i] = k + i++ + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(bIds) + } +} + func BeaconsListSingleController(appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -34,9 +48,18 @@ func BeaconsListSingleController(appstate *appcontext.AppState) http.HandlerFunc func BeaconsListController(appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { beacons := appstate.GetAllHttpResults() + values := make([]model.HTTPResult, len(beacons)) + i := 0 + for k, v := range beacons { + if k == "" { + continue + } + values[i] = v + i++ + } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(beacons) + json.NewEncoder(w).Encode(values) } } @@ -82,10 +105,26 @@ func BeaconsDeleteController(writer *kafka.Writer, ctx context.Context, appstate } } -func BeaconsAddController(writer *kafka.Writer, ctx context.Context) http.HandlerFunc { +func BeaconAddService(writer *kafka.Writer, ctx context.Context, appstate *appcontext.AppState, beacon model.HTTPResult) error { + id := beacon.ID + appstate.UpdateHTTPResult(id, beacon) + + apiUpdate := model.ApiUpdate{ + Method: "POST", + Beacon: beacon, + } + + if err := sendKafkaMessage(writer, &apiUpdate, ctx); err != nil { + return err + } + + return nil +} + +func BeaconsAddController(writer *kafka.Writer, ctx context.Context, appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) - var inBeacon model.Beacon + var inBeacon model.HTTPResult err := decoder.Decode(&inBeacon) if err != nil { @@ -93,17 +132,12 @@ func BeaconsAddController(writer *kafka.Writer, ctx context.Context) http.Handle return } - if (len(strings.TrimSpace(inBeacon.Name)) == 0) || (len(strings.TrimSpace(inBeacon.ID)) == 0) { - http.Error(w, "name and beacon_id cannot be blank", 400) + if inBeacon.ID == "" { + http.Error(w, "Beacon needs to include MAC addr", 400) return } - apiUpdate := model.ApiUpdate{ - Method: "POST", - Beacon: inBeacon, - } - - if err := sendKafkaMessage(writer, &apiUpdate, ctx); err != nil { + if err := BeaconAddService(writer, ctx, appstate, inBeacon); err != nil { fmt.Println("error in sending Kafka POST message") http.Error(w, "Error in sending kafka message", 500) return @@ -112,3 +146,30 @@ func BeaconsAddController(writer *kafka.Writer, ctx context.Context) http.Handle w.Write([]byte("ok")) } } + +func AddListOfBeaconsController(writer *kafka.Writer, ctx context.Context, appstate *appcontext.AppState) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + decoder := json.NewDecoder(r.Body) + var inBeacons []model.HTTPResult + if err := decoder.Decode(&inBeacons); err != nil { + http.Error(w, err.Error(), 400) + return + } + + for _, v := range inBeacons { + if v.ID == "" { + fmt.Println("One of the beacons is missing MAC address") + http.Error(w, "One of the beacons is missing MAC address", 400) + return + } + + if err := BeaconAddService(writer, ctx, appstate, v); err != nil { + fmt.Println("error in sending Kafka POST message") + http.Error(w, "Error in sending kafka message", 500) + return + } + } + + w.Write([]byte("ok")) + } +} diff --git a/internal/pkg/model/types.go b/internal/pkg/model/types.go index c4af9d5..ccafa68 100644 --- a/internal/pkg/model/types.go +++ b/internal/pkg/model/types.go @@ -112,11 +112,20 @@ type BeaconEvent struct { } type HTTPResult struct { - ID string `json:"ID"` + BeaconId string `json:"id"` + Name string `json:"name"` + ID string `json:"MAC"` + Status string `json:"status"` + Model string `json:"model"` + Position string `json:"position"` + Notes string `json:"notes"` + X float32 `json:"x"` + Y float32 `json:"y"` + Zone string `json:"zone"` + Building string `json:"building"` BeaconType string `json:"type"` Battery int64 `json:"battery"` Event int `json:"event"` - Location string `json:"location"` Distance float64 `json:"distance"` LastSeen int64 `json:"timestamp"` PreviousConfidentLocation string `json:"previous_confident_location"` @@ -160,7 +169,7 @@ type LatestBeaconsList struct { type ApiUpdate struct { Method string - Beacon Beacon + Beacon HTTPResult ID string } diff --git a/internal/pkg/service/beacon_service.go b/internal/pkg/service/beacon_service.go index a6b6260..9023212 100644 --- a/internal/pkg/service/beacon_service.go +++ b/internal/pkg/service/beacon_service.go @@ -36,10 +36,10 @@ func LocationToBeaconService(msg model.HTTPLocation, appState *appcontext.AppSta id := msg.ID beacon, ok := appState.GetHTTPResult(id) if !ok { - appState.UpdateHTTPResult(id, model.HTTPResult{ID: id, Location: msg.Location, Distance: msg.Distance, LastSeen: msg.LastSeen, PreviousConfidentLocation: msg.PreviousConfidentLocation}) + appState.UpdateHTTPResult(id, model.HTTPResult{ID: id, Position: msg.Location, Distance: msg.Distance, LastSeen: msg.LastSeen, PreviousConfidentLocation: msg.PreviousConfidentLocation}) } else { beacon.ID = id - beacon.Location = msg.Location + beacon.Position = msg.Location beacon.Distance = msg.Distance beacon.LastSeen = msg.LastSeen beacon.PreviousConfidentLocation = msg.PreviousConfidentLocation diff --git a/scripts/testAPI.sh b/scripts/testAPI.sh index 0611905..a6a03b0 100755 --- a/scripts/testAPI.sh +++ b/scripts/testAPI.sh @@ -3,13 +3,17 @@ URL="http://127.0.0.1:1902/api/beacons" BEACON_ID="C83F8F17DB35" echo "POST (create)" -curl -s -X POST $URL \ +curl -s -X POST "http://127.0.0.1:1902/api/addbeacons" \ -H "Content-Type: application/json" \ - -d '{"Beacon_id":"'"$BEACON_ID"'","Name":"Beacon1","tx_power":-59,"rssi":-70}' + -d '[{"id":"a3c1b2e4-9f73-4c1f-8c87-52e4d9cf9a01","name":"INGICS-TASTO","mac":"C83F8F17DB35","status":"1","model":"MNBT01G","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"d91a7b4f-02f6-44b6-9fa0-ff6df1c2e7b3","name":"RUSSI","mac":"C300003947DF","status":"1","model":"B7","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"5f1a9c3d-4b6f-4f88-9c92-df5c2d37c2aa","name":"PETRELLA","mac":"C300003B1E20","status":"1","model":"MWC01","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"8b7d42e9-4db5-4f42-a6c1-4e9f0c3e7d12","name":"AMOROSA-S","mac":"C300003946B5","status":"1","model":"MWB01","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"1e93b3fd-7d67-4a53-9c7a-0f0a8e7e41c6","name":"GALLO","mac":"C300003946AC","status":"1","model":"MWB01","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"e2b9d6cc-7d89-46bb-9e45-2b7f71e4a4d0","name":"SMISEK","mac":"C300003946B1","status":"1","model":"MWB01","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"6cfdeab2-03c4-41d7-9c1d-5f7bcb8c0b6b","name":"ROMAGNUOLO","mac":"C300003B1E21","status":"1","model":"MWC01","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"fa73b6dd-9941-4d25-8a9a-8df3b09a9d77","name":"BC-43","mac":"C300003947C4","status":"1","model":"B7","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"9c55d03e-2db1-4b0a-b1ac-8b60f60e712d","name":"AMOROSA-F","mac":"C300003947E2","status":"1","model":"B7","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"2a00e3b4-4a12-4f70-a4c4-408a1779e251","name":"DINONNO","mac":"C300003B1E1F","status":"1","model":"MWC01","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"bf6d6c84-5e1a-4b83-a10f-0e9cf2a198c3","name":"ismarch-X6","mac":"C7AE561E38B7","status":"1","model":"B7","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null},{"id":"41c4c6b2-9c3d-48d6-aea6-7c1bcfdfb2b7","name":"ismarch-C2","mac":"E01F9A7A47D2","status":"1","model":"B7","position":"","notes":"","x":0.0,"y":0.0,"zone":null,"building":null}]' echo -e "\n" sleep 1 curl -X GET $URL +sleep 1 + +curl -X GET "http://127.0.0.1:1902/api/beaconids" + sleep 1 \ No newline at end of file