package traccar import ( "encoding/json" "io" "net/http" "net/url" "time" "git.fjla.uk/fred.boniface/map-dots/data" "git.fjla.uk/fred.boniface/map-dots/log" "go.uber.org/zap" ) func GetPositions(id string, from, to time.Time) ([]data.LocationData, error) { var params = map[string]string{ "deviceId": id, "from": from.Format("2006-01-02T15:04:05Z"), "to": to.Format("2006-01-02T15:04:05Z"), } req, err := createRequest(params) if err != nil { log.Msg.Error("Error creating request", zap.Error(err)) return nil, err } client := http.Client{} resp, err := client.Do(req) if err != nil { log.Msg.Error("Error carring out request", zap.Error(err)) return nil, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { log.Msg.Error("Error reading response", zap.Error(err)) return nil, err } var positions []Positions err = json.Unmarshal(body, &positions) if err != nil { log.Msg.Error("Error unmarshalling data", zap.Error(err), zap.String("body", string(body))) return nil, err } return MapToPositionData(positions), err } func createRequest(params map[string]string) (*http.Request, error) { cfg, err := loadConfig() if err != nil { log.Msg.Panic("Configuration value missing", zap.Error(err)) } baseURL := cfg.tUrl + "/api/positions" log.Msg.Debug("Attemting fetch", zap.String("url", baseURL)) u, err := url.Parse(baseURL) if err != nil { log.Msg.Error("Error building URL", zap.Error(err)) return nil, err } queryParams := url.Values{} for key, value := range params { queryParams.Add(key, value) } u.RawQuery = queryParams.Encode() req, err := http.NewRequest("GET", u.String(), nil) if err != nil { log.Msg.Error("Error setting up request", zap.Error(err)) return nil, err } req.SetBasicAuth(cfg.user, cfg.pass) return req, nil } type Attributes map[string]interface{} // Generic map to hold attributes type Positions struct { ID int64 `json:"id"` Attributes Attributes `json:"attributes"` DeviceID int64 `json:"deviceId"` Protocol string `json:"protocol"` ServerTime string `json:"serverTime"` DeviceTime string `json:"deviceTime"` FixTime string `json:"fixTime"` Outdated bool `json:"outdated"` Valid bool `json:"valid"` Latitude float64 `json:"latitude"` Longitude float64 `json:"longitude"` Altitude float64 `json:"altitude"` Speed float64 `json:"speed"` Course float64 `json:"course"` Address string `json:"address"` Accuracy float64 `json:"accuracy"` Network interface{} `json:"network"` // Inferred as interface{} since it's not clear GeofenceIDs interface{} `json:"geofenceIds"` // Inferred as interface{} since it's not clear }