diff --git a/cmd/decoder/main.go b/cmd/decoder/main.go index 97f01d2..acfecf7 100644 --- a/cmd/decoder/main.go +++ b/cmd/decoder/main.go @@ -9,6 +9,7 @@ import ( "fmt" "strings" + "github.com/AFASystems/presence/internal/pkg/common/appcontext" "github.com/AFASystems/presence/internal/pkg/config" "github.com/AFASystems/presence/internal/pkg/kafkaclient" "github.com/AFASystems/presence/internal/pkg/model" @@ -17,25 +18,7 @@ import ( func main() { // Load global context to init beacons and latest list - appCtx := model.AppContext{ - Beacons: model.BeaconsList{ - Beacons: make(map[string]model.Beacon), - }, - Settings: model.Settings{ - Settings: model.SettingsVal{ - LocationConfidence: 4, - LastSeenThreshold: 15, - BeaconMetricSize: 30, - HASendInterval: 5, - HASendChangesOnly: false, - }, - }, - BeaconEvents: model.BeaconEventList{ - Beacons: make(map[string]model.BeaconEvent), - }, - BeaconsLookup: make(map[string]struct{}), - } - + appState := appcontext.NewAppState() cfg := config.Load() // Kafka reader for Raw MQTT beacons @@ -59,12 +42,12 @@ func main() { for { select { case msg := <-chRaw: - processIncoming(msg, &appCtx, alertWriter) + processIncoming(msg, appState, alertWriter) case msg := <-chApi: switch msg.Method { case "POST": id := msg.Beacon.ID - appCtx.BeaconsLookup[id] = struct{}{} + appState.AddBeaconToLookup(id) case "DELETE": fmt.Println("Incoming delete message") } @@ -72,21 +55,21 @@ func main() { } } -func processIncoming(adv model.BeaconAdvertisement, ctx *model.AppContext, writer *kafka.Writer) { +func processIncoming(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer) { id := adv.MAC - _, ok := ctx.BeaconsLookup[id] + ok := appState.BeaconExists(id) if !ok { return } - err := decodeBeacon(adv, ctx, writer) + err := decodeBeacon(adv, appState, writer) if err != nil { fmt.Println("error in decoding") return } } -func decodeBeacon(adv model.BeaconAdvertisement, ctx *model.AppContext, writer *kafka.Writer) error { +func decodeBeacon(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer) error { beacon := strings.TrimSpace(adv.Data) id := adv.MAC if beacon == "" { @@ -127,8 +110,8 @@ func decodeBeacon(adv model.BeaconAdvertisement, ctx *model.AppContext, writer * } if event.ID != "" { - prevEvent, ok := ctx.BeaconEvents.Beacons[id] - ctx.BeaconEvents.Beacons[id] = event + prevEvent, ok := appState.GetBeaconEvent(id) + appState.UpdateBeaconEvent(id, event) if ok && bytes.Equal(prevEvent.Hash(), event.Hash()) { return nil } diff --git a/cmd/location/main.go b/cmd/location/main.go index 489c02a..13a9e68 100644 --- a/cmd/location/main.go +++ b/cmd/location/main.go @@ -8,6 +8,7 @@ import ( "strconv" "time" + "github.com/AFASystems/presence/internal/pkg/common/appcontext" "github.com/AFASystems/presence/internal/pkg/config" "github.com/AFASystems/presence/internal/pkg/kafkaclient" "github.com/AFASystems/presence/internal/pkg/model" @@ -16,27 +17,7 @@ import ( func main() { // Load global context to init beacons and latest list - appCtx := model.AppContext{ - Settings: model.Settings{ - Settings: model.SettingsVal{ - LocationConfidence: 4, - LastSeenThreshold: 15, - BeaconMetricSize: 30, - HASendInterval: 5, - HASendChangesOnly: false, - RSSIEnforceThreshold: false, - RSSIMinThreshold: 100, - }, - }, - BeaconsLookup: make(map[string]struct{}), - LatestList: model.LatestBeaconsList{ - LatestList: make(map[string]model.Beacon), - }, - Beacons: model.BeaconsList{ - Beacons: make(map[string]model.Beacon), - }, - } - + appState := appcontext.NewAppState() cfg := config.Load() // Kafka reader for Raw MQTT beacons @@ -64,14 +45,14 @@ func main() { for { select { case <-locTicker.C: - getLikelyLocations(&appCtx, writer) + getLikelyLocations(appState, writer) case msg := <-chRaw: - assignBeaconToList(msg, &appCtx) + assignBeaconToList(msg, appState) case msg := <-chApi: switch msg.Method { case "POST": id := msg.Beacon.ID - appCtx.BeaconsLookup[id] = struct{}{} + appState.AddBeaconToLookup(id) case "DELETE": fmt.Println("Incoming delete message") } @@ -79,11 +60,10 @@ func main() { } } -func getLikelyLocations(ctx *model.AppContext, writer *kafka.Writer) { +func getLikelyLocations(appState *appcontext.AppState, writer *kafka.Writer) { fmt.Println("get likely locations called") - ctx.Beacons.Lock.Lock() - beacons := ctx.Beacons.Beacons - ctx.Beacons.Lock.Unlock() + beacons := appState.GetAllBeacons() + settings := appState.GetSettingsValue() for _, beacon := range beacons { // Shrinking the model because other properties have nothing to do with the location @@ -97,7 +77,7 @@ func getLikelyLocations(ctx *model.AppContext, writer *kafka.Writer) { mSize := len(beacon.BeaconMetrics) - if (int64(time.Now().Unix()) - (beacon.BeaconMetrics[mSize-1].Timestamp)) > ctx.Settings.Settings.LastSeenThreshold { + if (int64(time.Now().Unix()) - (beacon.BeaconMetrics[mSize-1].Timestamp)) > settings.LastSeenThreshold { continue } @@ -128,7 +108,7 @@ func getLikelyLocations(ctx *model.AppContext, writer *kafka.Writer) { r.Location = bestLocName r.LastSeen = beacon.BeaconMetrics[mSize-1].Timestamp - if beacon.LocationConfidence == ctx.Settings.Settings.LocationConfidence && beacon.PreviousConfidentLocation != bestLocName { + if beacon.LocationConfidence == settings.LocationConfidence && beacon.PreviousConfidentLocation != bestLocName { beacon.LocationConfidence = 0 // Who do I need this if I am sending entire structure anyways? who knows @@ -144,9 +124,7 @@ func getLikelyLocations(ctx *model.AppContext, writer *kafka.Writer) { if err != nil { beacon.PreviousConfidentLocation = bestLocName beacon.PreviousLocation = bestLocName - ctx.Beacons.Lock.Lock() - ctx.Beacons.Beacons[beacon.ID] = beacon - ctx.Beacons.Lock.Unlock() + appState.UpdateBeacon(beacon.ID, beacon) continue } @@ -161,9 +139,7 @@ func getLikelyLocations(ctx *model.AppContext, writer *kafka.Writer) { } beacon.PreviousLocation = bestLocName - ctx.Beacons.Lock.Lock() - ctx.Beacons.Beacons[beacon.ID] = beacon - ctx.Beacons.Lock.Unlock() + appState.UpdateBeacon(beacon.ID, beacon) js, err := json.Marshal(r) if err != nil { @@ -181,38 +157,35 @@ func getLikelyLocations(ctx *model.AppContext, writer *kafka.Writer) { } } -func assignBeaconToList(adv model.BeaconAdvertisement, ctx *model.AppContext) { +func assignBeaconToList(adv model.BeaconAdvertisement, appState *appcontext.AppState) { id := adv.MAC - _, ok := ctx.BeaconsLookup[id] - + ok := appState.BeaconExists(id) now := time.Now().Unix() if !ok { - ctx.LatestList.Lock.Lock() - ctx.LatestList.LatestList[id] = model.Beacon{ID: id, BeaconType: adv.BeaconType, LastSeen: now, IncomingJSON: adv, BeaconLocation: adv.Hostname, Distance: getBeaconDistance(adv)} - ctx.LatestList.Lock.Unlock() + appState.UpdateLatestBeacon(id, model.Beacon{ID: id, BeaconType: adv.BeaconType, LastSeen: now, IncomingJSON: adv, BeaconLocation: adv.Hostname, Distance: getBeaconDistance(adv)}) return } + settings := appState.GetSettingsValue() + fmt.Println("RSSI: ", adv.RSSI) - if ctx.Settings.Settings.RSSIEnforceThreshold && (int64(adv.RSSI) < ctx.Settings.Settings.RSSIMinThreshold) { + if settings.RSSIEnforceThreshold && (int64(adv.RSSI) < settings.RSSIMinThreshold) { return } - ctx.Beacons.Lock.Lock() - beacon, ok := ctx.Beacons.Beacons[id] + beacon, ok := appState.GetBeacon(id) if !ok { beacon = model.Beacon{ ID: id, } } - ctx.Beacons.Lock.Unlock() beacon.IncomingJSON = adv beacon.LastSeen = now if beacon.BeaconMetrics == nil { - beacon.BeaconMetrics = make([]model.BeaconMetric, 0, ctx.Settings.Settings.BeaconMetricSize) + beacon.BeaconMetrics = make([]model.BeaconMetric, 0, settings.BeaconMetricSize) } metric := model.BeaconMetric{ @@ -222,16 +195,14 @@ func assignBeaconToList(adv model.BeaconAdvertisement, ctx *model.AppContext) { Location: adv.Hostname, } - if len(beacon.BeaconMetrics) >= ctx.Settings.Settings.BeaconMetricSize { + if len(beacon.BeaconMetrics) >= settings.BeaconMetricSize { copy(beacon.BeaconMetrics, beacon.BeaconMetrics[1:]) - beacon.BeaconMetrics[ctx.Settings.Settings.BeaconMetricSize-1] = metric + beacon.BeaconMetrics[settings.BeaconMetricSize-1] = metric } else { beacon.BeaconMetrics = append(beacon.BeaconMetrics, metric) } - ctx.Beacons.Lock.Lock() - ctx.Beacons.Beacons[id] = beacon - ctx.Beacons.Lock.Unlock() + appState.UpdateBeacon(id, beacon) } func getBeaconDistance(adv model.BeaconAdvertisement) float64 {