您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

151 行
4.3 KiB

  1. package main
  2. import (
  3. "context"
  4. "time"
  5. "github.com/AFASystems/presence/internal/pkg/model"
  6. presenseredis "github.com/AFASystems/presence/internal/pkg/redis"
  7. "github.com/redis/go-redis/v9"
  8. )
  9. func main() {
  10. ctx := context.Background()
  11. client := redis.NewClient(&redis.Options{
  12. Addr: "127.0.0.1:6379",
  13. Password: "",
  14. })
  15. getLikelyLocations(client, ctx)
  16. }
  17. func getLikelyLocations(client *redis.Client, ctx context.Context) {
  18. httpRes := model.HTTPResultsList{
  19. HTTPResults: model.HTTPLocationsList{
  20. Beacons: make([]model.HTTPLocation, 0),
  21. },
  22. }
  23. shouldPersist := false
  24. beaconsList := presenseredis.LoadBeaconsList(client, ctx)
  25. settings := presenseredis.LoadSettings(client, ctx)
  26. for _, beacon := range beaconsList {
  27. length := len(beacon.Beacon_metrics)
  28. if length == 0 {
  29. continue
  30. }
  31. if (int64(time.Now().Unix()) - (beacon.Beacon_metrics[length-1].Timestamp)) > settings.Last_seen_threshold {
  32. if beacon.Expired_location == "expired" {
  33. continue
  34. }
  35. beacon.Expired_location = "expired" // define type expired
  36. } else {
  37. beacon.Expired_location = ""
  38. }
  39. locList := make(map[string]float64)
  40. seenWeight := 1.5
  41. rssiWeight := 0.75
  42. for _, metric := range beacon.Beacon_metrics {
  43. weightCalc := seenWeight + (rssiWeight * (1.0 - (float64(metric.Rssi) / -100.0)))
  44. loc, ok := locList[metric.Location]
  45. if !ok {
  46. loc = weightCalc
  47. } else {
  48. loc = loc + weightCalc
  49. }
  50. }
  51. bestName := ""
  52. ts := 0.0
  53. for name, timesSeen := range locList {
  54. if timesSeen > ts {
  55. bestName = name
  56. ts = timesSeen
  57. }
  58. }
  59. bestLocation := model.BestLocation{Name: bestName, Distance: beacon.Beacon_metrics[length-1].Distance, Last_seen: beacon.Beacon_metrics[length-1].Timestamp}
  60. beacon.Location_history = append(beacon.Location_history, bestName)
  61. if len(beacon.Location_history) > 10 {
  62. beacon.Location_history = beacon.Location_history[1:]
  63. }
  64. locationCounts := make(map[string]int)
  65. for _, loc := range beacon.Location_history {
  66. locationCounts[loc]++
  67. }
  68. maxCount := 0
  69. mostCommonLocation := ""
  70. for loc, count := range locationCounts {
  71. if count > maxCount {
  72. maxCount = count
  73. mostCommonLocation = loc
  74. }
  75. }
  76. if maxCount >= 7 {
  77. beacon.Previous_location = mostCommonLocation
  78. if mostCommonLocation == beacon.Previous_confident_location {
  79. beacon.Location_confidence++
  80. } else {
  81. beacon.Location_confidence = 1
  82. beacon.Previous_confident_location = mostCommonLocation
  83. }
  84. }
  85. r := model.HTTPLocation{
  86. Distance: bestLocation.Distance,
  87. Name: beacon.Name,
  88. Beacon_name: beacon.Name,
  89. Beacon_id: beacon.Beacon_id,
  90. Beacon_type: beacon.Beacon_type,
  91. HB_Battery: beacon.HB_Battery,
  92. HB_ButtonMode: beacon.HB_ButtonMode,
  93. HB_ButtonCounter: beacon.HB_ButtonCounter,
  94. Location: bestName,
  95. Last_seen: bestLocation.Last_seen,
  96. }
  97. if (beacon.Location_confidence == settings.Location_confidence && beacon.Previous_confident_location != bestLocation.Name) || (beacon.Expired_location == "expired") {
  98. shouldPersist = true
  99. beacon.Location_confidence = 0
  100. location := ""
  101. if beacon.Expired_location == "expired" {
  102. location = "expired"
  103. } else {
  104. location = bestName
  105. }
  106. }
  107. }
  108. }
  109. // get likely locations:
  110. /*
  111. 1. Locks the http_results list
  112. 2. inits list to empty struct type -> TODO: what is this list used for
  113. 3. loops through beacons list -> should be locked?
  114. 4. check for beacon metrics -> how do you get beacon metrics, I guess it has an array of timestamps
  115. 5. check for threshold value in the settings
  116. 5.1. check for property expired location
  117. 5.2. if location is not expired -> mark it as expired, generate message and send to all clients,
  118. if clients do not respond close the connection
  119. 6. Init best location with type Best_location{} -> what is this type
  120. 7. make locations list -> key: string, val: float64
  121. 7.1 set weight for seen and rssi
  122. 7.2 loop over metrics of the beacon -> some alogirthm based on location value
  123. I think the algorithm is recording names of different gateways and their rssi's and then from
  124. that it checks gateway name and makes decisions based on calculated values
  125. 7.3 writes result in best location and updates list location history with this name if the list
  126. is longer than 10 elements it removes the first element
  127. */