package mqttclient import ( "bytes" "encoding/json" "fmt" "log" "math" "os/exec" "strconv" "github.com/AFASystems/presence/internal/pkg/model" "github.com/yosssi/gmq/mqtt" "github.com/yosssi/gmq/mqtt/client" ) func GetBeaconID(incoming model.Incoming_json) string { unique_id := fmt.Sprintf("%s", incoming.MAC) return unique_id } func updateLatestList(incoming model.Incoming_json, now int64, latestList *model.LatestBeaconsList) { latestList.Lock.Lock() defer latestList.Lock.Unlock() b := model.Beacon{ Beacon_id: GetBeaconID(incoming), Beacon_type: incoming.Beacon_type, Last_seen: now, Incoming_JSON: incoming, Beacon_location: incoming.Hostname, Distance: getBeaconDistance(incoming), } latestList.LatestList[b.Beacon_id] = b for id, v := range latestList.LatestList { if now-v.Last_seen > 10 { delete(latestList.LatestList, id) } } } func updateBeaconData(beacon *model.Beacon, incoming model.Incoming_json, now int64, cl *client.Client, settings *model.SettingsVal) { beacon.Incoming_JSON = incoming beacon.Last_seen = now beacon.Beacon_type = incoming.Beacon_type beacon.HB_ButtonCounter = incoming.HB_ButtonCounter beacon.HB_Battery = incoming.HB_Battery beacon.HB_RandomNonce = incoming.HB_RandomNonce beacon.HB_ButtonMode = incoming.HB_ButtonMode m := model.BeaconMetric{ Distance: getBeaconDistance(incoming), Timestamp: now, Rssi: int64(incoming.RSSI), Location: incoming.Hostname, } beacon.Beacon_metrics = append(beacon.Beacon_metrics, m) if len(beacon.Beacon_metrics) > settings.Beacon_metrics_size { beacon.Beacon_metrics = beacon.Beacon_metrics[1:] } if beacon.HB_ButtonCounter_Prev != beacon.HB_ButtonCounter { beacon.HB_ButtonCounter_Prev = incoming.HB_ButtonCounter sendButtonPressed(*beacon, cl) } } func sendButtonPressed(beacon model.Beacon, cl *client.Client) { btn_msg, err := json.Marshal(beacon) if err != nil { panic(err) } err = cl.Publish(&client.PublishOptions{ QoS: mqtt.QoS1, TopicName: []byte("afa-systems/presence/button/" + beacon.Beacon_id), Message: btn_msg, }) if err != nil { panic(err) } 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) err, out, errout := Shellout(s) if err != nil { log.Printf("error: %v\n", err) } fmt.Println("--- stdout ---") fmt.Println(out) fmt.Println("--- stderr ---") fmt.Println(errout) } func getBeaconDistance(incoming model.Incoming_json) float64 { distance := 1000.0 distance = getiBeaconDistance(incoming.RSSI, incoming.TX_power) return distance } func getiBeaconDistance(rssi int64, power string) float64 { ratio := float64(rssi) * (1.0 / float64(twos_comp(power))) distance := 100.0 if ratio < 1.0 { distance = math.Pow(ratio, 10) } else { distance = (0.89976)*math.Pow(ratio, 7.7095) + 0.111 } return distance } func twos_comp(inp string) int64 { i, _ := strconv.ParseInt("0x"+inp, 0, 64) return i - 256 } func Shellout(command string) (error, string, string) { var stdout bytes.Buffer var stderr bytes.Buffer cmd := exec.Command("bash", "-c", command) cmd.Stdout = &stdout cmd.Stderr = &stderr err := cmd.Run() return err, stdout.String(), stderr.String() }