Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

198 wiersze
4.8 KiB

  1. package main
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "math"
  6. "strconv"
  7. "time"
  8. "github.com/AFASystems/presence/internal/pkg/config"
  9. "github.com/AFASystems/presence/internal/pkg/kafkaclient"
  10. "github.com/AFASystems/presence/internal/pkg/model"
  11. "github.com/AFASystems/presence/internal/pkg/mqttclient"
  12. )
  13. func main() {
  14. // Load global context to init beacons and latest list
  15. appCtx := model.AppContext{
  16. Beacons: model.BeaconsList{
  17. Beacons: make(map[string]model.Beacon),
  18. },
  19. LatestList: model.LatestBeaconsList{
  20. LatestList: make(map[string]model.Beacon),
  21. },
  22. Settings: model.Settings{
  23. Settings: model.SettingsVal{
  24. Location_confidence: 4,
  25. Last_seen_threshold: 15,
  26. Beacon_metrics_size: 30,
  27. HA_send_interval: 5,
  28. HA_send_changes_only: false,
  29. },
  30. },
  31. }
  32. fmt.Println("init")
  33. cfg := config.Load()
  34. // Kafka reader for Raw MQTT beacons
  35. rawReader := kafkaclient.KafkaReader(cfg.KafkaURL, "rawbeacons", "gid-raw")
  36. defer rawReader.Close()
  37. // Kafka reader for API server updates
  38. // apiReader := kafkaclient.KafkaReader(cfg.KafkaURL, "apibeacons", "gid-api")
  39. // defer apiReader.Close()
  40. // // Kafka reader for latest list updates
  41. // latestReader := kafkaclient.KafkaReader(cfg.KafkaURL, "latestbeacons", "gid-latest")
  42. // defer latestReader.Close()
  43. // // Kafka reader for settings updates
  44. // settingsReader := kafkaclient.KafkaReader(cfg.KafkaURL, "settings", "gid-settings")
  45. // defer settingsReader.Close()
  46. // declare channel for collecting Kafka messages
  47. chRaw := make(chan model.Incoming_json, 2000)
  48. // chApi := make(chan model.ApiUpdate, 2000)
  49. // chLatest := make(chan model.Incoming_json, 2000)
  50. // chSettings := make(chan model.SettingsVal, 10)
  51. go kafkaclient.Consume(rawReader, chRaw)
  52. // go kafkaclient.Consume(apiReader, chApi)
  53. // go kafkaclient.Consume(latestReader, chLatest)
  54. // go kafkaclient.Consume(settingsReader, chSettings)
  55. for {
  56. select {
  57. case msg := <-chRaw:
  58. processIncoming(msg, &appCtx)
  59. // case msg := <-chApi:
  60. // switch msg.Method {
  61. // case "POST":
  62. // fmt.Println("Incoming POST")
  63. // appCtx.Beacons.Lock.Lock()
  64. // appCtx.Beacons.Beacons[msg.Beacon.Beacon_id] = msg.Beacon
  65. // case "DELETE":
  66. // fmt.Println("Incoming delete")
  67. // _, exists := appCtx.Beacons.Beacons[msg.ID]
  68. // if exists {
  69. // appCtx.Beacons.Lock.Lock()
  70. // delete(appCtx.Beacons.Beacons, msg.ID)
  71. // }
  72. // default:
  73. // fmt.Println("unknown method: ", msg.Method)
  74. // }
  75. // appCtx.Beacons.Lock.Unlock()
  76. // case msg := <-chLatest:
  77. // fmt.Println("latest msg: ", msg)
  78. // case msg := <-chSettings:
  79. // appCtx.Settings.Lock.Lock()
  80. // appCtx.Settings.Settings = msg
  81. // fmt.Println("settings channel: ", msg)
  82. // appCtx.Settings.Lock.Unlock()
  83. }
  84. }
  85. }
  86. func processIncoming(incoming model.Incoming_json, ctx *model.AppContext) {
  87. defer func() {
  88. if err := recover(); err != nil {
  89. fmt.Println("work failed:", err)
  90. }
  91. }()
  92. // Get ID
  93. id := mqttclient.GetBeaconID(incoming)
  94. fmt.Println(incoming.Data)
  95. beacons := &ctx.Beacons
  96. beacons.Lock.Lock()
  97. defer beacons.Lock.Unlock()
  98. incoming = mqttclient.IncomingBeaconFilter(incoming)
  99. beacon, exists := beacons.Beacons[id]
  100. if !exists {
  101. return
  102. }
  103. fmt.Printf("%+v\n", beacon)
  104. updateBeacon(&beacon, incoming)
  105. beacons.Beacons[id] = beacon
  106. }
  107. func processBeacon(hexStr string) {
  108. b, _ := hex.DecodeString(hexStr)
  109. if len(b) > 2 && b[0] == 0x02 && b[1] == 0x01 {
  110. b = b[2+int(b[0]):]
  111. }
  112. ads := ParseADFast(b)
  113. _ = ads
  114. }
  115. func ParseADFast(b []byte) [][2]int {
  116. var res [][2]int
  117. i := 0
  118. for i < len(b) {
  119. l := int(b[i])
  120. if l == 0 || i+1+l > len(b) {
  121. break
  122. }
  123. res = append(res, [2]int{i, i + 1 + l})
  124. i += 1 + l
  125. }
  126. return res
  127. }
  128. func getBeaconDistance(incoming model.Incoming_json) float64 {
  129. rssi := incoming.RSSI
  130. power := incoming.TX_power
  131. distance := 100.0
  132. ratio := float64(rssi) * (1.0 / float64(twos_comp(power)))
  133. if ratio < 1.0 {
  134. distance = math.Pow(ratio, 10)
  135. } else {
  136. distance = (0.89976)*math.Pow(ratio, 7.7095) + 0.111
  137. }
  138. return distance
  139. }
  140. func updateBeacon(beacon *model.Beacon, incoming model.Incoming_json) {
  141. now := time.Now().Unix()
  142. beacon.Incoming_JSON = incoming
  143. beacon.Last_seen = now
  144. beacon.Beacon_type = incoming.Beacon_type
  145. beacon.HB_ButtonCounter = incoming.HB_ButtonCounter
  146. beacon.HB_Battery = incoming.HB_Battery
  147. beacon.HB_RandomNonce = incoming.HB_RandomNonce
  148. beacon.HB_ButtonMode = incoming.HB_ButtonMode
  149. if beacon.Beacon_metrics == nil {
  150. beacon.Beacon_metrics = make([]model.BeaconMetric, 10)
  151. }
  152. metric := model.BeaconMetric{}
  153. metric.Distance = getBeaconDistance(incoming)
  154. metric.Timestamp = now
  155. metric.Rssi = int64(incoming.RSSI)
  156. metric.Location = incoming.Hostname
  157. beacon.Beacon_metrics = append(beacon.Beacon_metrics, metric)
  158. }
  159. func twos_comp(inp string) int64 {
  160. i, _ := strconv.ParseInt("0x"+inp, 0, 64)
  161. return i - 256
  162. }