|
|
|
@@ -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 { |
|
|
|
|