|
- package main
-
- import (
- "encoding/json"
- "fmt"
- "log"
- "os"
- "os/signal"
- "strconv"
- "strings"
- "time"
-
- "github.com/AFASystems/presence/internal/pkg/config"
- "github.com/AFASystems/presence/internal/pkg/httpserver"
- "github.com/AFASystems/presence/internal/pkg/model"
- "github.com/AFASystems/presence/internal/pkg/mqtt_client"
- "github.com/AFASystems/presence/internal/pkg/persistence"
- "github.com/boltdb/bolt"
- "github.com/gorilla/websocket"
- "github.com/yosssi/gmq/mqtt"
- "github.com/yosssi/gmq/mqtt/client"
- )
-
- func main() {
- sigc := make(chan os.Signal, 1)
- signal.Notify(sigc, os.Interrupt)
- cfg := config.Load()
-
- db, err := bolt.Open("presence.db", 0644, nil)
- if err != nil {
- log.Fatal(err)
- }
- defer db.Close()
-
- model.Db = db
-
- cli := client.New(&client.Options{
- ErrorHandler: func(err error) {
- fmt.Println(err)
- },
- })
-
- defer cli.Terminate()
-
- fmt.Println("host: ", cfg.MQTTHost, " Client ID: ", cfg.MQTTClientID, "user: ", cfg.MQTTUser)
-
- err = cli.Connect(&client.ConnectOptions{
- Network: "tcp",
- Address: cfg.MQTTHost,
- ClientID: []byte(cfg.MQTTClientID),
- UserName: nil,
- Password: nil,
- // UserName: []byte(cfg.MQTTUser),
- // Password: []byte(cfg.MQTTPass),
- })
-
- if err != nil {
- fmt.Println("Error comes from here")
- panic(err)
- }
-
- ctx := &model.AppContext{
- HTTPResults: model.HTTPResultsList{
- HTTPResults: model.HTTPLocationsList{Beacons: []model.HTTPLocation{}},
- },
- Beacons: model.BeaconsList{
- Beacons: make(map[string]model.Beacon),
- },
- ButtonsList: make(map[string]model.Button),
- Settings: model.Settings{
- Location_confidence: 4,
- Last_seen_threshold: 15,
- Beacon_metrics_size: 30,
- HA_send_interval: 5,
- HA_send_changes_only: false,
- },
- Clients: make(map[*websocket.Conn]bool),
- Broadcast: make(chan model.Message, 100),
- Locations: model.LocationsList{Locations: make(map[string]model.Location)},
- LatestList: model.LatestBeaconsList{LatestList: make(map[string]model.Beacon)},
- }
-
- persistence.LoadState(model.Db, ctx)
- incomingChan := mqtt_client.IncomingMQTTProcessor(1*time.Second, cli, model.Db, ctx)
-
- err = cli.Subscribe(&client.SubscribeOptions{
- SubReqs: []*client.SubReq{
- &client.SubReq{
- TopicFilter: []byte("publish_out/#"),
- QoS: mqtt.QoS0,
- Handler: func(topicName, message []byte) {
- msgStr := string(message)
- t := strings.Split(string(topicName), "/")
- hostname := t[1]
-
- if strings.HasPrefix(msgStr, "[") {
- var readings []model.RawReading
- err := json.Unmarshal(message, &readings)
- if err != nil {
- log.Printf("Errore parsing JSON: %v", err)
- return
- }
-
- for _, reading := range readings {
- if reading.Type == "Gateway" {
- continue
- }
- incoming := model.Incoming_json{
- Hostname: hostname,
- MAC: reading.MAC,
- RSSI: int64(reading.RSSI),
- Data: reading.RawData,
- HB_ButtonCounter: parseButtonState(reading.RawData),
- }
- incomingChan <- incoming
- }
- } else {
- s := strings.Split(string(message), ",")
- if len(s) < 6 {
- log.Printf("Messaggio CSV non valido: %s", msgStr)
- return
- }
-
- rawdata := s[4]
- buttonCounter := parseButtonState(rawdata)
- if buttonCounter > 0 {
- incoming := model.Incoming_json{}
- i, _ := strconv.ParseInt(s[3], 10, 64)
- incoming.Hostname = hostname
- incoming.Beacon_type = "hb_button"
- incoming.MAC = s[1]
- incoming.RSSI = i
- incoming.Data = rawdata
- incoming.HB_ButtonCounter = buttonCounter
-
- read_line := strings.TrimRight(string(s[5]), "\r\n")
- it, err33 := strconv.Atoi(read_line)
- if err33 != nil {
- fmt.Println(it)
- fmt.Println(err33)
- os.Exit(2)
- }
- incomingChan <- incoming
- }
- }
- },
- },
- },
- })
- if err != nil {
- panic(err)
- }
-
- fmt.Println("CONNECTED TO MQTT")
- fmt.Println("\n ")
- fmt.Println("Visit http://" + cfg.HTTPAddr + " on your browser to see the web interface")
- fmt.Println("\n ")
-
- go httpserver.StartHTTPServer(cfg.HTTPAddr, ctx)
-
- <-sigc
-
- if err := cli.Disconnect(); err != nil {
- panic(err)
- }
- }
-
- func parseButtonState(raw string) int64 {
- raw = strings.ToUpper(raw)
-
- if strings.HasPrefix(raw, "0201060303E1FF12") && len(raw) >= 38 {
- buttonField := raw[34:38]
- if buttonValue, err := strconv.ParseInt(buttonField, 16, 64); err == nil {
- return buttonValue
- }
- }
-
- if strings.HasPrefix(raw, "02010612FF590") && len(raw) >= 24 {
- counterField := raw[22:24]
- buttonState, err := strconv.ParseInt(counterField, 16, 64)
- if err == nil {
- return buttonState
- }
- }
-
- return 0
- }
|