From bfcd74640f4b43706b9f87046dc0bf2540a5b02e Mon Sep 17 00:00:00 2001 From: blazSmehov Date: Mon, 22 Dec 2025 14:21:28 +0100 Subject: [PATCH] feat: add pulling of configuration from server on start up, updates in db, cleanup in bridge on server startup --- cmd/bridge/main.go | 19 +- cmd/decoder/main.go | 3 +- cmd/location/log.txt | 994 ------------------ cmd/location/main.go | 5 +- cmd/server/main.go | 47 +- cmd/token-testbench/main.go | 161 +++ internal/pkg/apiclient/auth.go | 45 + internal/pkg/apiclient/data.go | 87 ++ internal/pkg/apiclient/updatedb.go | 79 ++ internal/pkg/common/appcontext/context.go | 20 +- internal/pkg/config/config.go | 10 + .../pkg/controller/trackers_controller.go | 12 +- .../pkg/controller/trackerzones_controller.go | 8 +- internal/pkg/model/gateway.go | 24 +- internal/pkg/model/trackers.go | 25 +- internal/pkg/model/types.go | 3 +- 16 files changed, 489 insertions(+), 1053 deletions(-) delete mode 100644 cmd/location/log.txt create mode 100644 cmd/token-testbench/main.go create mode 100644 internal/pkg/apiclient/auth.go create mode 100644 internal/pkg/apiclient/data.go create mode 100644 internal/pkg/apiclient/updatedb.go diff --git a/cmd/bridge/main.go b/cmd/bridge/main.go index c21a974..4bc654e 100644 --- a/cmd/bridge/main.go +++ b/cmd/bridge/main.go @@ -40,14 +40,15 @@ func mqtthandler(writer *kafka.Writer, topic string, message []byte, appState *a if reading.Type == "Gateway" { continue } + + val, ok := appState.BeaconExists(reading.MAC) // fmt.Printf("reading: %+v\n", reading) - if !appState.BeaconExists(reading.MAC) { + if !ok { continue } - fmt.Printf("Tracking beacon: %s\n", reading.MAC) - adv := model.BeaconAdvertisement{ + ID: val, Hostname: hostname, MAC: reading.MAC, RSSI: int64(reading.RSSI), @@ -63,6 +64,7 @@ func mqtthandler(writer *kafka.Writer, topic string, message []byte, appState *a msg := kafka.Message{ Value: encodedMsg, } + err = writer.WriteMessages(context.Background(), msg) if err != nil { fmt.Println("Error in writing to Kafka: ", err) @@ -167,12 +169,17 @@ eventloop: case msg := <-chApi: switch msg.Method { case "POST": - id := msg.Beacon.ID - appState.AddBeaconToLookup(id) + id := msg.ID + appState.AddBeaconToLookup(msg.MAC, id) lMsg := fmt.Sprintf("Beacon added to lookup: %s", id) slog.Info(lMsg) case "DELETE": - id := msg.Beacon.ID + id := msg.MAC + if id == "all" { + appState.CleanLookup() + fmt.Println("cleaned up lookup map") + continue + } appState.RemoveBeaconFromLookup(id) lMsg := fmt.Sprintf("Beacon removed from lookup: %s", id) slog.Info(lMsg) diff --git a/cmd/decoder/main.go b/cmd/decoder/main.go index dd97b6e..508943d 100644 --- a/cmd/decoder/main.go +++ b/cmd/decoder/main.go @@ -83,7 +83,7 @@ func processIncoming(adv model.BeaconAdvertisement, appState *appcontext.AppStat func decodeBeacon(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer) error { beacon := strings.TrimSpace(adv.Data) - id := adv.MAC + id := adv.ID if beacon == "" { return nil } @@ -109,6 +109,7 @@ func decodeBeacon(adv model.BeaconAdvertisement, appState *appcontext.AppState, } eMsg, err := event.ToJSON() + fmt.Printf("event: %+v\n", eMsg) if err != nil { return err } diff --git a/cmd/location/log.txt b/cmd/location/log.txt deleted file mode 100644 index a9a5673..0000000 --- a/cmd/location/log.txt +++ /dev/null @@ -1,994 +0,0 @@ -beacon id: 28EE7BA6E367beacon id: 65D48848F0B7beacon id: 001DA568988Cbeacon id: C83F8F17DB35beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: 001DA568988Cbeacon id: 001DA568988Cbeacon id: 001DA568988Cbeacon id: 4CD74B223734beacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: 4CD74B223734beacon id: 28EE7BA6E367beacon id: C3000057B9F3beacon id: 001DA568988Cbeacon id: C300003947E2beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: E01F9A7A47D2beacon id: 46602DE47FBDbeacon id: 17C8E5FAEBB8beacon id: 18C79055CB06beacon id: C83F8F17DB35beacon id: 18C79055CB06beacon id: C3000057A459beacon id: C300003947E2beacon id: F1C612AB9195beacon id: C3000057A45Abeacon id: 28EE7BA6E367beacon id: 17C8E5FAEBB8beacon id: 18C79055CB06beacon id: C300003947E2beacon id: 28EE7BA6E367beacon id: C3000057A45Abeacon id: 18C79055CB06beacon id: 46602DE47FBDbeacon id: C7AE561E38B7beacon id: 4CD74B223734beacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: C300003946ACbeacon id: C300003947E2beacon id: 17C8E5FAEBB8beacon id: 0BA3386F193Fbeacon id: C3000057A459beacon id: 28EE7BA6E367beacon id: 46602DE47FBDbeacon id: 46602DE47FBDbeacon id: C83F8F17DB35beacon id: 18C79055CB06beacon id: 18C79055CB06beacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 001DA568988Cbeacon id: C3000057A45Abeacon id: C3000057A459beacon id: C3000057A45Abeacon id: 18C79055CB06beacon id: 001DA568988Cbeacon id: C300003946ACbeacon id: C3000057A459beacon id: 46602DE47FBDbeacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: C300003947E2beacon id: DC1FB511DE9Ebeacon id: 28EE7BA6E367beacon id: C83F8F17DB35beacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: 18C79055CB06beacon id: 28EE7BA6E367beacon id: C3000057B9F3beacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: 18C79055CB06beacon id: C3000057B9F3beacon id: 18C79055CB06beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 46602DE47FBDbeacon id: F1C612AB9195beacon id: 46602DE47FBDbeacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: C3000057B9F3beacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: E017085443A7beacon id: C3000057B9F3beacon id: E01F9A7A47D2beacon id: 0BA3386F193Fbeacon id: 28EE7BA6E367beacon id: 4CD74B223734beacon id: C83F8F17DB35beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 46602DE47FBDbeacon id: 0BA3386F193Fbeacon id: C300003947E2beacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: 28EE7BA6E367beacon id: C83F8F17DB35beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: E01F9A7A47D2beacon id: C3000057A459beacon id: DC1FB511DE9Ebeacon id: F1C612AB9195beacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: C300003947E2beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: E01F9A7A47D2beacon id: 0BA3386F193Fbeacon id: C83F8F17DB35beacon id: DC1FB511DE9Ebeacon id: 46602DE47FBDbeacon id: C300003947C4beacon id: 28EE7BA6E367beacon id: C83F8F17DB35beacon id: C7AE561E38B7beacon id: 18C79055CB06beacon id: D3085FB03A1Fbeacon id: E017085443A7beacon id: 4CD74B223734beacon id: 0BA3386F193Fbeacon id: D3085FB03A1Fbeacon id: 0BA3386F193Fbeacon id: 0BA3386F193Fbeacon id: E017085443A7beacon id: E01F9A7A47D2beacon id: 65D48848F0B7beacon id: 18C79055CB06beacon id: C83F8F17DB35beacon id: C3000057B9EDbeacon id: 4CD74B223734beacon id: 18C79055CB06beacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 46602DE47FBDbeacon id: 46602DE47FBDbeacon id: 0BA3386F193Fbeacon id: 65D48848F0B7beacon id: 28EE7BA6E367beacon id: 18C79055CB06beacon id: 4CD74B223734beacon id: 0BA3386F193Fbeacon id: D3085FB03A1Fbeacon id: 0BA3386F193Fbeacon id: 0BA3386F193Fbeacon id: C83F8F17DB35beacon id: 18C79055CB06beacon id: 18C79055CB06beacon id: C83F8F17DB35beacon id: 0BA3386F193Fbeacon id: 28EE7BA6E367beacon id: C3000057A45Abeacon id: 18C79055CB06beacon id: 28EE7BA6E367beacon id: E017085443A7beacon id: 28EE7BA6E367beacon id: 46602DE47FBDbeacon id: 18C79055CB06beacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 0BA3386F193Fbeacon id: 4CD74B223734beacon id: C300003947E2beacon id: C83F8F17DB35beacon id: 001DA568988Cbeacon id: C300003947E2beacon id: C3000057B9F3beacon id: F045AEE31DB4beacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: 46602DE47FBDbeacon id: 28EE7BA6E367beacon id: C83F8F17DB35beacon id: 001DA568988Cbeacon id: 46602DE47FBDbeacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 001DA568988Cbeacon id: 18C79055CB06beacon id: 001DA568988Cbeacon id: 46602DE47FBDbeacon id: 0BA3386F193Fbeacon id: 0BA3386F193Fbeacon id: 46602DE47FBDbeacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: C83F8F17DB35beacon id: D3085FB03A1Fbeacon id: 28EE7BA6E367beacon id: 4CD74B223734beacon id: C83F8F17DB35beacon id: 18C79055CB06beacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 0BA3386F193Fbeacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 4CD74B223734beacon id: 001DA568988Cbeacon id: C83F8F17DB35beacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: C83F8F17DB35beacon id: 46602DE47FBDbeacon id: 001DA568988Cbeacon id: C83F8F17DB35beacon id: 4CD74B223734beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: C3000057A459beacon id: 001DA568988Cbeacon id: 18C79055CB06beacon id: 18C79055CB06beacon id: 28EE7BA6E367beacon id: 001DA568988Cbeacon id: 001DA568988Cbeacon id: 4CD74B223734beacon id: 18C79055CB06beacon id: C7AE561E38B7beacon id: 18C79055CB06beacon id: C3000057A459beacon id: 28EE7BA6E367beacon id: C83F8F17DB35beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: C300003947C4beacon id: 18C79055CB06beacon id: 28EE7BA6E367beacon id: 0BA3386F193Fbeacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: 17C8E5FAEBB8beacon id: 0BA3386F193Fbeacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 28EE7BA6E367beacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: C3000057A459beacon id: 18C79055CB06beacon id: 28EE7BA6E367beacon id: 46602DE47FBDbeacon id: 28EE7BA6E367beacon id: C3000057A459beacon id: C83F8F17DB35beacon id: E017085443A7beacon id: C3000057A459beacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: C83F8F17DB35beacon id: 18C79055CB06beacon id: 0BA3386F193Fbeacon id: 46602DE47FBDbeacon id: 28EE7BA6E367beacon id: 18C79055CB06beacon id: C7AE561E38B7beacon id: F045AEE31DB4beacon id: 0E8D2974679Abeacon id: 18C79055CB06beacon id: 46602DE47FBDbeacon id: C7AE561E38B7beacon id: 17C8E5FAEBB8beacon id: 17C8E5FAEBB8beacon id: 0BA3386F193Fbeacon id: 28EE7BA6E367beacon id: 28EE7BA6E367beacon id: C3000057A459beacon id: 17C8E5FAEBB8beacon id: 28EE7BA6E367beacon id: DC1FB511DE9Ebeacon id: 17C8E5FAEBB8beacon id: 18C79055CB06beacon id: 4CD74B223734beacon id: F1C612AB9195beacon id: 28EE7BA6E367beacon id: 17C8E5FAEBB8beacon id: 0BA3386F193Fbeacon id: 001DA568988Cbeacon id: 18C79055CB06beacon id: E017085443A7beacon id: C300003946B5beacon id: 28EE7BA6E367error reading message: committing message: context canceled -error reading message: fetching message: context canceled -consumer closed -error reading message: fetching message: context canceled -consumer closed -consumer closed -Kafka readers graceful shutdown complete -shutdown of kafka readers starts -Kafka writers graceful shutdown complete -beacon id: 001DA568988C -beacon id: 4CD74B223734 -beacon id: 28EE7BA6E367 -beacon id: 2647016F8DE4 -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: C3000057A45A -beacon id: C83F8F17DB35 -beacon id: C7AE561E38B7 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C300003947E2 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 001DA568988C -beacon id: 2647016F8DE4 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: E017085443A7 -beacon id: E01F9A7A47D2 -beacon id: C83F8F17DB35 -beacon id: 65D48848F0B7 -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: F1C612AB9195 -beacon id: 001DA568988C -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: C3000057B9ED -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 001DA568988C -beacon id: C3000057A459 -beacon id: 46602DE47FBD -beacon id: E8DDB13B3AF5 -beacon id: 28EE7BA6E367 -beacon id: F045AEE31DB4 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 4CD74B223734 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C3000057A45A -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: C3000057A459 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: C3000057B9F3 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: C83F8F17DB35 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 001DA568988C -beacon id: 2647016F8DE4 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 001DA568988C -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: E8DDB13B3AF5 -beacon id: 18C79055CB06 -beacon id: C300003947C4 -beacon id: 2647016F8DE4 -beacon id: C300003947E2 -beacon id: 46602DE47FBD -beacon id: E01F9A7A47D2 -beacon id: C83F8F17DB35 -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: C300003946B5 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: E017085443A7 -beacon id: C7AE561E38B7 -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 7CC7CDB08849 -beacon id: 18C79055CB06 -beacon id: C3000057A459 -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 2647016F8DE4 -beacon id: C3000057A459 -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: C3000057A45A -beacon id: 6E09D4F8F053 -beacon id: E01F9A7A47D2 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 4CD74B223734 -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C3000057B9F3 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 001DA568988C -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 001DA568988C -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: C3000057B9ED -beacon id: C3000057B9ED -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: E017085443A7 -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 2647016F8DE4 -beacon id: 28EE7BA6E367 -beacon id: C300003947E2 -beacon id: E8DDB13B3AF5 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 001DA568988C -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 001DA568988C -beacon id: C3000057B9F3 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 2647016F8DE4 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: E017085443A7 -beacon id: C300003947E2 -beacon id: DC1FB511DE9E -beacon id: C3000057B9F3 -beacon id: C300003946B5 -beacon id: 4CD74B223734 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C300003947E2 -beacon id: 0BA3386F193F -beacon id: 2647016F8DE4 -beacon id: 0BA3386F193F -beacon id: C3000057A45A -beacon id: C83F8F17DB35 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: C83F8F17DB35 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 4CD74B223734 -beacon id: C3000057B9ED -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: E8DDB13B3AF5 -beacon id: E01F9A7A47D2 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: C3000057A459 -beacon id: D3085FB03A1F -beacon id: 28EE7BA6E367 -beacon id: 001DA568988C -beacon id: 28EE7BA6E367 -beacon id: C3000057A459 -beacon id: 28EE7BA6E367 -beacon id: C3000057A459 -beacon id: 0BA3386F193F -beacon id: C3000057A45A -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: C7AE561E38B7 -beacon id: C3000057A459 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: C83F8F17DB35 -beacon id: E8DDB13B3AF5 -beacon id: C3000057B9ED -beacon id: 0BA3386F193F -beacon id: C300003947E2 -beacon id: 4CD74B223734 -beacon id: 28EE7BA6E367 -beacon id: C7AE561E38B7 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: C300003947E2 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 4CD74B223734 -beacon id: D3085FB03A1F -beacon id: C7AE561E38B7 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: C7AE561E38B7 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: C3000057A459 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: C3000057B9F3 -beacon id: C83F8F17DB35 -beacon id: 4CD74B223734 -beacon id: 001DA568988C -beacon id: C3000057B9F3 -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: C300003947E2 -beacon id: C3000057A45A -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 7CC7CDB08849 -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: C3000057B9ED -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C300003947E2 -beacon id: C3000057A45A -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C3000057B9ED -beacon id: 0BA3386F193F -beacon id: C3000057B9F3 -beacon id: 0BA3386F193F -beacon id: 001DA568988C -beacon id: 46602DE47FBD -beacon id: 2647016F8DE4 -beacon id: 18C79055CB06 -beacon id: C3000057B9F3 -beacon id: 2647016F8DE4 -beacon id: 18C79055CB06 -beacon id: C3000057A459 -beacon id: C83F8F17DB35 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: C300003947E2 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: C300003947C4 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C300003946B1 -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: C300003947C4 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 001DA568988C -beacon id: 18C79055CB06 -beacon id: C83F8F17DB35 -beacon id: 4142909BCF7E -beacon id: 28EE7BA6E367 -beacon id: C3000057B9ED -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: C300003946B5 -beacon id: C3000057B9ED -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: D54E908B7972 -beacon id: F045AEE31DB4 -beacon id: C300003947E2 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: C3000057A459 -beacon id: 46602DE47FBD -beacon id: C83F8F17DB35 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: C3000057A45A -beacon id: 28EE7BA6E367 -beacon id: 001DA568988C -beacon id: E8DDB13B3AF5 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: E8DDB13B3AF5 -beacon id: C3000057A459 -beacon id: 4CD74B223734 -beacon id: 18C79055CB06 -beacon id: F1C612AB9195 -beacon id: C3000057B9F3 -beacon id: DC1FB511DE9E -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: C3000057A459 -beacon id: 0BA3386F193F -beacon id: C3000057B9F3 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: C3000057B9F3 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 4CD74B223734 -beacon id: E017085443A7 -beacon id: 4CD74B223734 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: C300003947E2 -beacon id: E01F9A7A47D2 -beacon id: 0BA3386F193F -beacon id: C300003947C4 -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: 65D48848F0B7 -beacon id: C3000057B9F3 -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: C83F8F17DB35 -beacon id: C3000057B9F3 -beacon id: C3000057B9F3 -beacon id: 0BA3386F193F -beacon id: F045AEE31DB4 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: C83F8F17DB35 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 4142909BCF7E -beacon id: E017085443A7 -beacon id: 28EE7BA6E367 -beacon id: D3085FB03A1F -beacon id: 0BA3386F193F -beacon id: DC1FB511DE9E -beacon id: 0BA3386F193F -beacon id: C3000057B9ED -beacon id: 28EE7BA6E367 -beacon id: C300003947E2 -beacon id: C3000057B9F3 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: E017085443A7 -beacon id: 28EE7BA6E367 -beacon id: DC1FB511DE9E -beacon id: C83F8F17DB35 -beacon id: C3000057B9ED -beacon id: C3000057B9F3 -beacon id: F045AEE31DB4 -beacon id: C7AE561E38B7 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: C7AE561E38B7 -beacon id: 18C79055CB06 -beacon id: 4CD74B223734 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: C3000057A45A -beacon id: C3000057A45A -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: C3000057B9F3 -beacon id: F1C612AB9195 -beacon id: D3085FB03A1F -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: C83F8F17DB35 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: E01F9A7A47D2 -beacon id: C83F8F17DB35 -beacon id: 46602DE47FBD -beacon id: E01F9A7A47D2 -beacon id: 001DA568988C -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: C7AE561E38B7 -beacon id: C3000057B9F3 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 7CC7CDB08849 -beacon id: C83F8F17DB35 -beacon id: C83F8F17DB35 -beacon id: 4CD74B223734 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: E8DDB13B3AF5 -beacon id: 28EE7BA6E367 -beacon id: F045AEE31DB4 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: E8DDB13B3AF5 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: C3000057A45A -beacon id: C300003946AC -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 2647016F8DE4 -beacon id: F1C612AB9195 -beacon id: 2647016F8DE4 -beacon id: 4CD74B223734 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: D3085FB03A1F -beacon id: E8DDB13B3AF5 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: C3000057A45A -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: C3000057B9ED -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: C83F8F17DB35 -beacon id: C300003947E2 -beacon id: 4CD74B223734 -beacon id: C300003947E2 -beacon id: 001DA568988C -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 2647016F8DE4 -beacon id: C3000057A45A -beacon id: C3000057A45A -beacon id: E01F9A7A47D2 -beacon id: C300003947E2 -beacon id: C3000057A45A -beacon id: 28EE7BA6E367 -beacon id: C3000057B9ED -beacon id: 4CD74B223734 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: C300003947C4 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: C300003947E2 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: DC1FB511DE9E -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: C3000057B9F3 -beacon id: E01F9A7A47D2 -beacon id: C3000057B9F3 -beacon id: 46602DE47FBD -beacon id: 001DA568988C -beacon id: DC1FB511DE9E -beacon id: 46602DE47FBD -beacon id: C3000057B9F3 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: F1C612AB9195 -beacon id: F045AEE31DB4 -beacon id: 46602DE47FBD -beacon id: 4CD74B223734 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: C3000057A45A -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: E017085443A7 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C3000057A459 -beacon id: 18C79055CB06 -beacon id: C300003947E2 -beacon id: 4CD74B223734 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: DC1FB511DE9E -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: E01F9A7A47D2 -beacon id: 18C79055CB06 -beacon id: F1C612AB9195 -beacon id: 0BA3386F193F -beacon id: E01F9A7A47D2 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C300003947E2 -beacon id: 001DA568988C -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: D920A4A6D237 -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: 2647016F8DE4 -beacon id: E017085443A7 -beacon id: 28EE7BA6E367 -beacon id: C3000057B9F3 -beacon id: 0BA3386F193F -beacon id: D3085FB03A1F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 7CC7CDB08849 -beacon id: 0BA3386F193F -beacon id: E8DDB13B3AF5 -beacon id: C3000057A45A -beacon id: 0BA3386F193F -beacon id: C3000057A459 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: E017085443A7 -beacon id: F045AEE31DB4 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C3000057B9ED -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: C300003947E2 -beacon id: E017085443A7 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: F1C612AB9195 -beacon id: 0BA3386F193F -beacon id: E01F9A7A47D2 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: C83F8F17DB35 -beacon id: F1C612AB9195 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C3000057A459 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: F1C612AB9195 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: E01F9A7A47D2 -beacon id: 0BA3386F193F -beacon id: C83F8F17DB35 -beacon id: 28EE7BA6E367 -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: C3000057A459 -beacon id: 0BA3386F193F -beacon id: 4CD74B223734 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 4CD74B223734 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: D3085FB03A1F -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: D3085FB03A1F -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 4CD74B223734 -beacon id: 001DA568988C -beacon id: C83F8F17DB35 -beacon id: C3000057B9F3 -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 001DA568988C -beacon id: C3000057B9ED -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: C3000057B9F3 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: E8DDB13B3AF5 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 2647016F8DE4 -beacon id: 46602DE47FBD -beacon id: 001DA568988C -beacon id: 18C79055CB06 -beacon id: E8DDB13B3AF5 -beacon id: 28EE7BA6E367 -beacon id: 001DA568988C -beacon id: 28EE7BA6E367 -beacon id: 2647016F8DE4 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C3000057A45A -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: C3000057A459 -beacon id: E01F9A7A47D2 -beacon id: 0BA3386F193F -beacon id: F045AEE31DB4 -beacon id: 0BA3386F193F -beacon id: E01F9A7A47D2 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 2647016F8DE4 -beacon id: 2647016F8DE4 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: D3085FB03A1F -beacon id: 28EE7BA6E367 -beacon id: C3000057A45A -beacon id: 18C79055CB06 -beacon id: C3000057B9ED -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: C3000057A459 -beacon id: D3085FB03A1F -beacon id: 46602DE47FBD -beacon id: 4CD74B223734 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: C3000057A459 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: C3000057A45A -beacon id: E8DDB13B3AF5 -beacon id: C7AE561E38B7 -beacon id: 18C79055CB06 -beacon id: E01F9A7A47D2 -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: C3000057B9ED -beacon id: 18C79055CB06 -beacon id: C3000057B9ED -beacon id: 28EE7BA6E367 -beacon id: F045AEE31DB4 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: C300003946B5 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 2647016F8DE4 -beacon id: 46602DE47FBD -beacon id: 4CD74B223734 -beacon id: 2647016F8DE4 -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: C3000057A45A -beacon id: C3000057A459 -beacon id: F1C612AB9195 -beacon id: C3000057A459 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: E017085443A7 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: C3000057B9ED -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: C83F8F17DB35 -beacon id: C300003947E2 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C3000057A459 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: C3000057B9F3 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: E017085443A7 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 001DA568988C -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 2647016F8DE4 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: 7CC7CDB08849 -beacon id: 18C79055CB06 -beacon id: 28EE7BA6E367 -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: E8DDB13B3AF5 -beacon id: 18C79055CB06 -beacon id: C3000057A45A -beacon id: 4CD74B223734 -beacon id: F045AEE31DB4 -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: E01F9A7A47D2 -beacon id: E8DDB13B3AF5 -beacon id: E017085443A7 -beacon id: C3000057A45A -beacon id: C3000057B9F3 -beacon id: 46602DE47FBD -beacon id: 001DA568988C -beacon id: 0BA3386F193F -beacon id: D54E908B7972 -beacon id: F1C612AB9195 -beacon id: 18C79055CB06 -beacon id: DC1FB511DE9E -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 001DA568988C -beacon id: C3000057A459 -beacon id: C3000057A45A -beacon id: C3000057A45A -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 46602DE47FBD -beacon id: F1C612AB9195 -beacon id: C83F8F17DB35 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: C300003947E2 -beacon id: 0BA3386F193F -beacon id: 0BA3386F193F -beacon id: C3000057B9ED -beacon id: 46602DE47FBD -beacon id: 46602DE47FBD -beacon id: C83F8F17DB35 -beacon id: 0BA3386F193F -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: 46602DE47FBD -beacon id: C300003947C4 -beacon id: 0BA3386F193F -beacon id: 28EE7BA6E367 -beacon id: 28EE7BA6E367 -beacon id: DC1FB511DE9E -beacon id: 18C79055CB06 -beacon id: 0BA3386F193F -beacon id: E01F9A7A47D2 -beacon id: 28EE7BA6E367 -beacon id: 2647016F8DE4 -beacon id: 4CD74B223734 -beacon id: 4CD74B223734 -beacon id: 18C79055CB06 -beacon id: 18C79055CB06 -beacon id: C300003946B5 -beacon id: C3000057B9F3 -beacon id: 28EE7BA6E367 -error reading message: fetching message: context canceled -consumer closed -error reading message: committing message: context canceled -consumer closed -error reading message: fetching message: context canceled -consumer closed -Kafka readers graceful shutdown complete -shutdown of kafka readers starts -Kafka writers graceful shutdown complete diff --git a/cmd/location/main.go b/cmd/location/main.go index e20748f..106079f 100644 --- a/cmd/location/main.go +++ b/cmd/location/main.go @@ -86,6 +86,7 @@ func getLikelyLocations(appState *appcontext.AppState, writer *kafka.Writer) { settings := appState.GetSettingsValue() for _, beacon := range beacons { + fmt.Println("id: ", beacon.ID) // Shrinking the model because other properties have nothing to do with the location r := model.HTTPLocation{ Method: "Standard", @@ -175,6 +176,8 @@ func getLikelyLocations(appState *appcontext.AppState, writer *kafka.Writer) { Value: js, } + fmt.Println("sending message") + err = writer.WriteMessages(context.Background(), msg) if err != nil { eMsg := fmt.Sprintf("Error in sending Kafka message: %v", err) @@ -184,7 +187,7 @@ func getLikelyLocations(appState *appcontext.AppState, writer *kafka.Writer) { } func assignBeaconToList(adv model.BeaconAdvertisement, appState *appcontext.AppState) { - id := adv.MAC + id := adv.ID now := time.Now().Unix() settings := appState.GetSettingsValue() diff --git a/cmd/server/main.go b/cmd/server/main.go index b7bd72d..92d3e69 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -15,13 +15,13 @@ import ( "syscall" "time" + "github.com/AFASystems/presence/internal/pkg/apiclient" "github.com/AFASystems/presence/internal/pkg/common/appcontext" "github.com/AFASystems/presence/internal/pkg/config" "github.com/AFASystems/presence/internal/pkg/controller" "github.com/AFASystems/presence/internal/pkg/database" "github.com/AFASystems/presence/internal/pkg/kafkaclient" "github.com/AFASystems/presence/internal/pkg/model" - "github.com/AFASystems/presence/internal/pkg/service" "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/gorilla/websocket" @@ -66,6 +66,10 @@ func main() { settingsWriter := appState.AddKafkaWriter(cfg.KafkaURL, "settings") slog.Info("Kafka writers topics: apibeacons, settings initialized") + if err := apiclient.UpdateDB(db, ctx, cfg, writer); err != nil { + fmt.Printf("Error in getting token: %v\n", err) + } + locationReader := appState.AddKafkaReader(cfg.KafkaURL, "locevents", "gid-loc-server") alertsReader := appState.AddKafkaReader(cfg.KafkaURL, "alertbeacons", "gid-alert-serv") slog.Info("Kafka readers topics: locevents, alertbeacons initialized") @@ -92,10 +96,10 @@ func main() { r.HandleFunc("/reslevis/removeZone/{id}", controller.ZoneDeleteController(db)).Methods("DELETE") r.HandleFunc("/reslevis/updateZone", controller.ZoneUpdateController(db)).Methods("PUT") - r.HandleFunc("/reslevis/getTrackerZones", controller.TrackerListController(db)).Methods("GET") - r.HandleFunc("/reslevis/postTrackerZone", controller.TrackerAddController(db)).Methods("POST") - r.HandleFunc("/reslevis/removeTrackerZone/{id}", controller.TrackerDeleteController(db)).Methods("DELETE") - r.HandleFunc("/reslevis/updateTrackerZone", controller.TrackerUpdateController(db)).Methods("PUT") + r.HandleFunc("/reslevis/getTrackerZones", controller.TrackerZoneListController(db)).Methods("GET") + r.HandleFunc("/reslevis/postTrackerZone", controller.TrackerZoneAddController(db)).Methods("POST") + r.HandleFunc("/reslevis/removeTrackerZone/{id}", controller.TrackerZoneDeleteController(db)).Methods("DELETE") + r.HandleFunc("/reslevis/updateTrackerZone", controller.TrackerZoneUpdateController(db)).Methods("PUT") r.HandleFunc("/reslevis/getTrackers", controller.TrackerList(db)).Methods("GET") r.HandleFunc("/reslevis/postTracker", controller.TrackerAdd(db, writer, ctx)).Methods("POST") @@ -126,15 +130,36 @@ eventLoop: case <-ctx.Done(): break eventLoop case msg := <-chLoc: - if err := service.LocationToBeaconService(msg, appState, ctx); err != nil { - eMsg := fmt.Sprintf("Error in writing location change to beacon: %v\n", err) - slog.Error(eMsg) + id := msg.ID + if err := db.First(&model.Tracker{}, "id = ?", id).Error; err != nil { + fmt.Printf("Location event for untracked beacon: %s\n", id) + continue + } + + if err := db.Updates(&model.Tracker{ID: id, Location: msg.Location, Distance: msg.Distance}).Error; err != nil { + fmt.Println("Error in saving distance for beacon: ", err) + continue } + // if err := service.LocationToBeaconService(msg, appState, ctx); err != nil { + // eMsg := fmt.Sprintf("Error in writing location change to beacon: %v\n", err) + // slog.Error(eMsg) + // } case msg := <-chEvents: - if err := service.EventToBeaconService(msg, appState, ctx); err != nil { - eMsg := fmt.Sprintf("Error in writing event change to beacon: %v\n", err) - slog.Error(eMsg) + fmt.Printf("event: %+v\n", msg) + id := msg.ID + if err := db.First(&model.Tracker{}, "id = ?", id).Error; err != nil { + fmt.Printf("Decoder event for untracked beacon: %s\n", id) + continue + } + + if err := db.Updates(&model.Tracker{ID: id, Battery: msg.Battery}).Error; err != nil { + fmt.Printf("Error in saving decoder event for beacon: %s\n", id) + continue } + // if err := service.EventToBeaconService(msg, appState, ctx); err != nil { + // eMsg := fmt.Sprintf("Error in writing event change to beacon: %v\n", err) + // slog.Error(eMsg) + // } } } diff --git a/cmd/token-testbench/main.go b/cmd/token-testbench/main.go new file mode 100644 index 0000000..966610b --- /dev/null +++ b/cmd/token-testbench/main.go @@ -0,0 +1,161 @@ +package main + +import ( + "context" + "crypto/tls" + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/AFASystems/presence/internal/pkg/model" +) + +type response struct { + A string `json:"access_token"` +} + +func main() { + ctx := context.Background() + + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + + formData := url.Values{} + formData.Set("grant_type", "password") + formData.Set("client_id", "Fastapi") + formData.Set("client_secret", "wojuoB7Z5xhlPFrF2lIxJSSdVHCApEgC") + formData.Set("username", "core") + formData.Set("password", "C0r3_us3r_Cr3d3nt14ls") + formData.Set("audience", "Fastapi") + + req, err := http.NewRequest("POST", "https://10.251.0.30:10002/realms/API.Server.local/protocol/openid-connect/token", strings.NewReader(formData.Encode())) + if err != nil { + panic(err) + } + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + req = req.WithContext(ctx) + res, err := client.Do(req) + if err != nil { + panic(err) + } + + var j response + + err = json.NewDecoder(res.Body).Decode(&j) + if err != nil { + panic(err) + } + + token := j.A + + trackers, err := GetTrackers(token, client) + if err != nil { + panic(err) + } + + fmt.Printf("trackers: %+v\n", trackers) + + gateways, err := getGateways(token, client) + if err != nil { + panic(err) + } + + fmt.Printf("gateways: %+v\n", gateways) + + zones, err := GetZones(token, client) + if err != nil { + panic(err) + } + + fmt.Printf("zones: %+v\n", zones) + + trackerZones, err := GetTrackerZones(token, client) + if err != nil { + panic(err) + } + + fmt.Printf("tracker zones: %+v\n", trackerZones) +} + +func GetTrackers(token string, client *http.Client) ([]model.Tracker, error) { + res, err := getRequest(token, "getTrackers", client) + if err != nil { + return nil, err + } + + var i []model.Tracker + err = json.NewDecoder(res.Body).Decode(&i) + if err != nil { + return nil, err + } + + return i, nil +} + +func getGateways(token string, client *http.Client) ([]model.Gateway, error) { + res, err := getRequest(token, "getGateways", client) + if err != nil { + return nil, err + } + + var i []model.Gateway + err = json.NewDecoder(res.Body).Decode(&i) + if err != nil { + return nil, err + } + + return i, nil +} + +func GetTrackerZones(token string, client *http.Client) ([]model.TrackerZones, error) { + res, err := getRequest(token, "getTrackerZones", client) + if err != nil { + return nil, err + } + + var i []model.TrackerZones + err = json.NewDecoder(res.Body).Decode(&i) + if err != nil { + return nil, err + } + + return i, nil +} + +func GetZones(token string, client *http.Client) ([]model.Zone, error) { + res, err := getRequest(token, "getZones", client) + if err != nil { + return nil, err + } + + var i []model.Zone + err = json.NewDecoder(res.Body).Decode(&i) + if err != nil { + return nil, err + } + + return i, nil +} + +func getRequest(token, route string, client *http.Client) (*http.Response, error) { + url := fmt.Sprintf("https://10.251.0.30:5050/reslevis/%s", route) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + + header := fmt.Sprintf("Bearer %s", token) + + req.Header.Add("Authorization", header) + res, err := client.Do(req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/pkg/apiclient/auth.go b/internal/pkg/apiclient/auth.go new file mode 100644 index 0000000..abf78d4 --- /dev/null +++ b/internal/pkg/apiclient/auth.go @@ -0,0 +1,45 @@ +package apiclient + +import ( + "context" + "encoding/json" + "net/http" + "net/url" + "strings" + + "github.com/AFASystems/presence/internal/pkg/config" +) + +type response struct { + Token string `json:"access_token"` +} + +func GetToken(ctx context.Context, cfg *config.Config, client *http.Client) (string, error) { + formData := url.Values{} + formData.Set("grant_type", "password") + formData.Set("client_id", "Fastapi") + formData.Set("client_secret", "wojuoB7Z5xhlPFrF2lIxJSSdVHCApEgC") + formData.Set("username", "core") + formData.Set("password", "C0r3_us3r_Cr3d3nt14ls") + formData.Set("audience", "Fastapi") + + req, err := http.NewRequest("POST", "https://10.251.0.30:10002/realms/API.Server.local/protocol/openid-connect/token", strings.NewReader(formData.Encode())) + if err != nil { + return "", err + } + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + req = req.WithContext(ctx) + res, err := client.Do(req) + if err != nil { + return "", err + } + + var j response + + if err := json.NewDecoder(res.Body).Decode(&j); err != nil { + return "", err + } + + return j.Token, nil +} diff --git a/internal/pkg/apiclient/data.go b/internal/pkg/apiclient/data.go new file mode 100644 index 0000000..b56aab7 --- /dev/null +++ b/internal/pkg/apiclient/data.go @@ -0,0 +1,87 @@ +package apiclient + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/AFASystems/presence/internal/pkg/model" +) + +func GetTrackers(token string, client *http.Client) ([]model.Tracker, error) { + res, err := getRequest(token, "getTrackers", client) + if err != nil { + return []model.Tracker{}, err + } + + var i []model.Tracker + err = json.NewDecoder(res.Body).Decode(&i) + if err != nil { + return []model.Tracker{}, err + } + + return i, nil +} + +func GetGateways(token string, client *http.Client) ([]model.Gateway, error) { + res, err := getRequest(token, "getGateways", client) + if err != nil { + return []model.Gateway{}, err + } + + var i []model.Gateway + err = json.NewDecoder(res.Body).Decode(&i) + if err != nil { + return []model.Gateway{}, err + } + + return i, nil +} + +func GetTrackerZones(token string, client *http.Client) ([]model.TrackerZones, error) { + res, err := getRequest(token, "getTrackerZones", client) + if err != nil { + return []model.TrackerZones{}, err + } + + var i []model.TrackerZones + err = json.NewDecoder(res.Body).Decode(&i) + if err != nil { + return []model.TrackerZones{}, err + } + + return i, nil +} + +func GetZones(token string, client *http.Client) ([]model.Zone, error) { + res, err := getRequest(token, "getZones", client) + if err != nil { + return []model.Zone{}, err + } + + var i []model.Zone + err = json.NewDecoder(res.Body).Decode(&i) + if err != nil { + return []model.Zone{}, err + } + + return i, nil +} + +func getRequest(token, route string, client *http.Client) (*http.Response, error) { + url := fmt.Sprintf("https://10.251.0.30:5050/reslevis/%s", route) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + + header := fmt.Sprintf("Bearer %s", token) + + req.Header.Add("Authorization", header) + res, err := client.Do(req) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/internal/pkg/apiclient/updatedb.go b/internal/pkg/apiclient/updatedb.go new file mode 100644 index 0000000..e54a648 --- /dev/null +++ b/internal/pkg/apiclient/updatedb.go @@ -0,0 +1,79 @@ +package apiclient + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + + "github.com/AFASystems/presence/internal/pkg/config" + "github.com/AFASystems/presence/internal/pkg/controller" + "github.com/AFASystems/presence/internal/pkg/model" + "github.com/segmentio/kafka-go" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +func UpdateDB(db *gorm.DB, ctx context.Context, cfg *config.Config, writer *kafka.Writer) error { + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + + token, err := GetToken(ctx, cfg, client) + if err != nil { + return err + } + trackers, err := GetTrackers(token, client) + if err != nil { + fmt.Printf("Error in getting trackers: %+v\n", err) + } + + if err := controller.SendKafkaMessage(writer, &model.ApiUpdate{Method: "DELETE", MAC: "all"}, ctx); err != nil { + fmt.Printf("Error in sending delete all from lookup message: %v", err) + } + + for _, v := range trackers { + apiUpdate := model.ApiUpdate{ + Method: "POST", + ID: v.ID, + MAC: v.MAC, + } + + if err := controller.SendKafkaMessage(writer, &apiUpdate, ctx); err != nil { + fmt.Printf("Error in sending POST kafka message: %v", err) + } + } + + gateways, err := GetGateways(token, client) + if err != nil { + fmt.Printf("Error in getting gateways: %+v\n", err) + } + zones, err := GetZones(token, client) + if err != nil { + fmt.Printf("Error in getting zones: %+v\n", err) + } + trackerZones, err := GetTrackerZones(token, client) + if err != nil { + fmt.Printf("Error in getting tracker zones: %+v\n", err) + } + + db.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "id"}}, + UpdateAll: true, + }).Create(&trackers) + db.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "id"}}, + UpdateAll: true, + }).Create(&gateways) + db.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "id"}}, + UpdateAll: true, + }).Create(&zones) + db.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "id"}}, + UpdateAll: true, + }).Create(&trackerZones) + + return nil +} diff --git a/internal/pkg/common/appcontext/context.go b/internal/pkg/common/appcontext/context.go index 717d054..55d64ae 100644 --- a/internal/pkg/common/appcontext/context.go +++ b/internal/pkg/common/appcontext/context.go @@ -15,7 +15,7 @@ type AppState struct { httpResults model.HTTPResultList settings model.Settings beaconEvents model.BeaconEventList - beaconsLookup map[string]struct{} + beaconsLookup map[string]string latestList model.LatestBeaconsList kafkaReadersList model.KafkaReadersList kafkaWritersList model.KafkaWritersList @@ -44,7 +44,7 @@ func NewAppState() *AppState { beaconEvents: model.BeaconEventList{ Beacons: make(map[string]model.BeaconEvent), }, - beaconsLookup: make(map[string]struct{}), + beaconsLookup: make(map[string]string), latestList: model.LatestBeaconsList{ LatestList: make(map[string]model.Beacon), }, @@ -129,7 +129,7 @@ func (m *AppState) GetBeaconEvents() *model.BeaconEventList { } // GetBeaconsLookup returns thread-safe access to beacon lookup map -func (m *AppState) GetBeaconsLookup() map[string]struct{} { +func (m *AppState) GetBeaconsLookup() map[string]string { return m.beaconsLookup } @@ -139,8 +139,8 @@ func (m *AppState) GetLatestList() *model.LatestBeaconsList { } // AddBeaconToLookup adds a beacon ID to the lookup map -func (m *AppState) AddBeaconToLookup(id string) { - m.beaconsLookup[id] = struct{}{} +func (m *AppState) AddBeaconToLookup(id, value string) { + m.beaconsLookup[id] = value } // RemoveBeaconFromLookup removes a beacon ID from the lookup map @@ -148,6 +148,10 @@ func (m *AppState) RemoveBeaconFromLookup(id string) { delete(m.beaconsLookup, id) } +func (m *AppState) CleanLookup() { + clear(m.beaconsLookup) +} + func (m *AppState) RemoveBeacon(id string) { m.beacons.Lock.Lock() delete(m.beacons.Beacons, id) @@ -161,9 +165,9 @@ func (m *AppState) RemoveHTTPResult(id string) { } // BeaconExists checks if a beacon exists in the lookup -func (m *AppState) BeaconExists(id string) bool { - _, exists := m.beaconsLookup[id] - return exists +func (m *AppState) BeaconExists(id string) (string, bool) { + val, exists := m.beaconsLookup[id] + return val, exists } // GetBeacon returns a beacon by ID (thread-safe) diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index fdb8714..65403b4 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -14,6 +14,11 @@ type Config struct { DBUser string DBPass string DBName string + HTTPClientID string + ClientSecret string + HTTPUsername string + HTTPPassword string + HTTPAudience string } // getEnv returns env var value or a default if not set. @@ -37,5 +42,10 @@ func Load() *Config { DBUser: getEnv("DBUser", "postgres"), DBPass: getEnv("DBPass", "postgres"), DBName: getEnv("DBName", "go_crud_db"), + HTTPClientID: getEnv("HTTPClientID", "Fastapi"), + ClientSecret: getEnv("ClientSecret", "wojuoB7Z5xhlPFrF2lIxJSSdVHCApEgC"), + HTTPUsername: getEnv("HTTPUsername", "core"), + HTTPPassword: getEnv("HTTPPassword", "C0r3_us3r_Cr3d3nt14ls"), + HTTPAudience: getEnv("HTTPAudience", "Fastapi"), } } diff --git a/internal/pkg/controller/trackers_controller.go b/internal/pkg/controller/trackers_controller.go index 1ac26db..6e39b0a 100644 --- a/internal/pkg/controller/trackers_controller.go +++ b/internal/pkg/controller/trackers_controller.go @@ -12,7 +12,7 @@ import ( "gorm.io/gorm" ) -func sendKafkaMessage(writer *kafka.Writer, value *model.ApiUpdate, ctx context.Context) error { +func SendKafkaMessage(writer *kafka.Writer, value *model.ApiUpdate, ctx context.Context) error { valueStr, err := json.Marshal(&value) if err != nil { fmt.Println("error in encoding: ", err) @@ -42,9 +42,10 @@ func TrackerAdd(db *gorm.DB, writer *kafka.Writer, ctx context.Context) http.Han apiUpdate := model.ApiUpdate{ Method: "POST", ID: tracker.ID, + MAC: tracker.MAC, } - if err := sendKafkaMessage(writer, &apiUpdate, ctx); err != nil { + if err := SendKafkaMessage(writer, &apiUpdate, ctx); err != nil { fmt.Println("error in sending Kafka POST message") http.Error(w, "Error in sending kafka message", 500) return @@ -90,6 +91,9 @@ func TrackerUpdate(db *gorm.DB) http.HandlerFunc { func TrackerDelete(db *gorm.DB, writer *kafka.Writer, ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] + var tracker model.Tracker + db.Find(&tracker, "id = ?", id) + if res := db.Delete(&model.Tracker{}, "id = ?", id); res.RowsAffected == 0 { http.Error(w, "no tracker with such ID found", 400) return @@ -97,12 +101,12 @@ func TrackerDelete(db *gorm.DB, writer *kafka.Writer, ctx context.Context) http. apiUpdate := model.ApiUpdate{ Method: "Delete", - ID: id, + ID: tracker.ID, } fmt.Printf("Sending DELETE tracker id: %s message\n", id) - if err := sendKafkaMessage(writer, &apiUpdate, ctx); err != nil { + if err := SendKafkaMessage(writer, &apiUpdate, ctx); err != nil { fmt.Println("error in sending Kafka DELETE message") http.Error(w, "Error in sending kafka message", 500) return diff --git a/internal/pkg/controller/trackerzones_controller.go b/internal/pkg/controller/trackerzones_controller.go index 1d61616..ece42ad 100644 --- a/internal/pkg/controller/trackerzones_controller.go +++ b/internal/pkg/controller/trackerzones_controller.go @@ -10,7 +10,7 @@ import ( ) // controller/tracker_controller.go -func TrackerAddController(db *gorm.DB) http.HandlerFunc { +func TrackerZoneAddController(db *gorm.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var tz model.TrackerZones if err := json.NewDecoder(r.Body).Decode(&tz); err != nil { @@ -22,7 +22,7 @@ func TrackerAddController(db *gorm.DB) http.HandlerFunc { } } -func TrackerListController(db *gorm.DB) http.HandlerFunc { +func TrackerZoneListController(db *gorm.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var list []model.TrackerZones db.Find(&list) @@ -30,7 +30,7 @@ func TrackerListController(db *gorm.DB) http.HandlerFunc { } } -func TrackerUpdateController(db *gorm.DB) http.HandlerFunc { +func TrackerZoneUpdateController(db *gorm.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var tz model.TrackerZones @@ -55,7 +55,7 @@ func TrackerUpdateController(db *gorm.DB) http.HandlerFunc { } } -func TrackerDeleteController(db *gorm.DB) http.HandlerFunc { +func TrackerZoneDeleteController(db *gorm.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] if res := db.Delete(&model.TrackerZones{}, "id = ?", id); res.RowsAffected == 0 { diff --git a/internal/pkg/model/gateway.go b/internal/pkg/model/gateway.go index 3c6f2f1..609d65b 100644 --- a/internal/pkg/model/gateway.go +++ b/internal/pkg/model/gateway.go @@ -1,16 +1,16 @@ package model type Gateway struct { - ID string `json:"id" gorm:"primaryKey"` - Name string `json:"name"` - MAC string `json:"mac"` - Status string `json:"status"` - Model string `json:"model"` - IP string `json:"ip"` - Position string `json:"position"` - X int `json:"x"` - Y int `json:"y"` - Notes string `json:"notes"` - Floor string `json:"floor"` - Building string `json:"building"` + ID string `json:"id" gorm:"primaryKey"` + Name string `json:"name"` + MAC string `json:"mac"` + Status string `json:"status"` + Model string `json:"model"` + IP string `json:"ip"` + Position string `json:"position"` + X float32 `json:"x"` + Y float32 `json:"y"` + Notes string `json:"notes"` + Floor string `json:"floor"` + Building string `json:"building"` } diff --git a/internal/pkg/model/trackers.go b/internal/pkg/model/trackers.go index 28477de..6ddf694 100644 --- a/internal/pkg/model/trackers.go +++ b/internal/pkg/model/trackers.go @@ -1,15 +1,18 @@ package model type Tracker struct { - ID string `json:"id" gorm:"primaryKey` - Name string `json:"name"` - MAC string `json:"mac"` - Status string `json:"status"` - Model string `json:"model"` - Position string `json:"position"` - Notes string `json:"notes"` - X int `json:"x"` - Y int `json:"y"` - Floor string `json:"floor" gorm:"type:uuid"` - Building string `json:"building" gorm:"type:uuid"` + ID string `json:"id" gorm:"primaryKey"` + Name string `json:"name"` + MAC 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"` + Floor string `json:"floor"` + Building string `json:"building"` + Location string `json:"location"` + Distance float64 `json:"distance"` + Battery uint32 `json:"battery"` } diff --git a/internal/pkg/model/types.go b/internal/pkg/model/types.go index ccafa68..ae0a1c2 100644 --- a/internal/pkg/model/types.go +++ b/internal/pkg/model/types.go @@ -24,6 +24,7 @@ type Settings struct { // BeaconAdvertisement represents the JSON payload received from beacon advertisements. type BeaconAdvertisement struct { + ID string Hostname string `json:"hostname"` MAC string `json:"mac"` RSSI int64 `json:"rssi"` @@ -169,8 +170,8 @@ type LatestBeaconsList struct { type ApiUpdate struct { Method string - Beacon HTTPResult ID string + MAC string } type KafkaReadersList struct {