You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 rivejä
3.3 KiB

  1. package mqtt_client
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. "math"
  8. "os/exec"
  9. "strconv"
  10. "github.com/AFASystems/presence/internal/pkg/model"
  11. "github.com/yosssi/gmq/mqtt"
  12. "github.com/yosssi/gmq/mqtt/client"
  13. )
  14. func getBeaconID(incoming model.Incoming_json) string {
  15. unique_id := fmt.Sprintf("%s", incoming.MAC)
  16. return unique_id
  17. }
  18. func updateLatestList(incoming model.Incoming_json, now int64, latestList *model.LatestBeaconsList) {
  19. latestList.LatestListLock.Lock()
  20. defer latestList.LatestListLock.Unlock()
  21. b := model.Beacon{
  22. Beacon_id: getBeaconID(incoming),
  23. Beacon_type: incoming.Beacon_type,
  24. Last_seen: now,
  25. Incoming_JSON: incoming,
  26. Beacon_location: incoming.Hostname,
  27. Distance: getBeaconDistance(incoming),
  28. }
  29. latestList.LatestList[b.Beacon_id] = b
  30. for id, v := range latestList.LatestList {
  31. if now-v.Last_seen > 10 {
  32. delete(latestList.LatestList, id)
  33. }
  34. }
  35. }
  36. func updateBeaconData(beacon *model.Beacon, incoming model.Incoming_json, now int64, cl *client.Client, settings *model.Settings) {
  37. beacon.Incoming_JSON = incoming
  38. beacon.Last_seen = now
  39. beacon.Beacon_type = incoming.Beacon_type
  40. beacon.HB_ButtonCounter = incoming.HB_ButtonCounter
  41. beacon.HB_Battery = incoming.HB_Battery
  42. beacon.HB_RandomNonce = incoming.HB_RandomNonce
  43. beacon.HB_ButtonMode = incoming.HB_ButtonMode
  44. m := model.BeaconMetric{
  45. Distance: getBeaconDistance(incoming),
  46. Timestamp: now,
  47. Rssi: int64(incoming.RSSI),
  48. Location: incoming.Hostname,
  49. }
  50. beacon.Beacon_metrics = append(beacon.Beacon_metrics, m)
  51. if len(beacon.Beacon_metrics) > settings.Beacon_metrics_size {
  52. beacon.Beacon_metrics = beacon.Beacon_metrics[1:]
  53. }
  54. if beacon.HB_ButtonCounter_Prev != beacon.HB_ButtonCounter {
  55. beacon.HB_ButtonCounter_Prev = incoming.HB_ButtonCounter
  56. sendButtonPressed(*beacon, cl)
  57. }
  58. }
  59. func sendButtonPressed(beacon model.Beacon, cl *client.Client) {
  60. btn_msg, err := json.Marshal(beacon)
  61. if err != nil {
  62. panic(err)
  63. }
  64. err = cl.Publish(&client.PublishOptions{
  65. QoS: mqtt.QoS1,
  66. TopicName: []byte("afa-systems/presence/button/" + beacon.Beacon_id),
  67. Message: btn_msg,
  68. })
  69. if err != nil {
  70. panic(err)
  71. }
  72. s := fmt.Sprintf("/usr/bin/php /usr/local/presence/alarm_handler.php --idt=%s --idr=%s --st=%d", beacon.Beacon_id, beacon.Incoming_JSON.Hostname, beacon.HB_ButtonCounter)
  73. err, out, errout := Shellout(s)
  74. if err != nil {
  75. log.Printf("error: %v\n", err)
  76. }
  77. fmt.Println("--- stdout ---")
  78. fmt.Println(out)
  79. fmt.Println("--- stderr ---")
  80. fmt.Println(errout)
  81. }
  82. func getBeaconDistance(incoming model.Incoming_json) float64 {
  83. distance := 1000.0
  84. distance = getiBeaconDistance(incoming.RSSI, incoming.TX_power)
  85. return distance
  86. }
  87. func getiBeaconDistance(rssi int64, power string) float64 {
  88. ratio := float64(rssi) * (1.0 / float64(twos_comp(power)))
  89. distance := 100.0
  90. if ratio < 1.0 {
  91. distance = math.Pow(ratio, 10)
  92. } else {
  93. distance = (0.89976)*math.Pow(ratio, 7.7095) + 0.111
  94. }
  95. return distance
  96. }
  97. func twos_comp(inp string) int64 {
  98. i, _ := strconv.ParseInt("0x"+inp, 0, 64)
  99. return i - 256
  100. }
  101. func Shellout(command string) (error, string, string) {
  102. var stdout bytes.Buffer
  103. var stderr bytes.Buffer
  104. cmd := exec.Command("bash", "-c", command)
  105. cmd.Stdout = &stdout
  106. cmd.Stderr = &stderr
  107. err := cmd.Run()
  108. return err, stdout.String(), stderr.String()
  109. }