| @@ -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)}) | |||
| @@ -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"} | |||
| @@ -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") | |||
| @@ -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")) | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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 | |||
| @@ -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 | |||