sim-modem/api/modem/gps/data.go

84 lines
2.4 KiB
Go
Raw Normal View History

package gps
2024-07-23 16:02:28 +00:00
import (
"fmt"
2024-08-08 12:52:52 +00:00
"io"
"log"
2024-07-23 16:02:28 +00:00
"math"
"strconv"
"strings"
"time"
)
type Data struct {
2024-09-30 17:43:37 +00:00
Latitude float64 `json:"Latitude"` // ddmm.mmmmmm
Longitude float64 `json:"Longitude"` // dddmm.mmmmmm
LatitudeIndicator string `json:"Latitude_indicator"` // N/S - North/South
LongitudeIndicator string `json:"Longitude_indicator"` // W/E - West/East
2024-07-23 16:02:28 +00:00
Speed float64 `json:"Speed"`
Course float64 `json:"-"`
Altitude float64 `json:"-"`
Date string `json:"-"`
Time string `json:"-"`
}
var GpsInfoNil = Data{}
2024-07-23 16:02:28 +00:00
func deg2rad(deg float64) float64 {
return deg * (math.Pi / 180)
}
func (gps *Data) CalculateSpeed(newLatitude, newLongitude float64, lastUpdateTime time.Time) {
2024-07-23 16:02:28 +00:00
earthRad := 6371.0 // TODO ?
dLat := deg2rad(math.Abs(newLatitude - gps.Latitude))
dLon := deg2rad(math.Abs(newLongitude - gps.Longitude))
a := math.Sin(dLat/2)*math.Sin(dLat/2) +
math.Cos(deg2rad(newLatitude))*math.Cos(deg2rad(gps.Latitude))*math.Sin(dLon/2)*math.Sin(dLon/2)
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
gps.Speed = earthRad * c / (math.Abs(float64(time.Since(lastUpdateTime))))
}
// To remove warning
2024-07-28 18:01:18 +00:00
// Parse string from AT command that contains gps data
func (gps *Data) decode(str string) error {
2024-07-23 16:02:28 +00:00
var err error
newGpsInfo := Data{}
2024-07-23 16:02:28 +00:00
strs := strings.Split(strings.Split(strings.Replace(str, " ", "", -1), "\n")[0], ",")
2024-08-08 12:52:52 +00:00
logger := log.New(io.Discard, "modem-gps", log.LstdFlags)
2024-07-23 16:02:28 +00:00
2024-08-08 12:52:52 +00:00
if len(strs) < 7 {
return fmt.Errorf("ERROR: too small msg: %s", strs)
}
2024-07-23 16:02:28 +00:00
newGpsInfo.Latitude, err = strconv.ParseFloat(strs[0], 64)
if err != nil {
2024-08-08 12:52:52 +00:00
logger.Println("ERROR parse latitude:", err.Error())
2024-07-23 16:02:28 +00:00
}
newGpsInfo.Longitude, err = strconv.ParseFloat(strs[2], 64)
if err != nil {
2024-08-08 12:52:52 +00:00
logger.Println("ERROR parse longitude:", err.Error())
2024-07-23 16:02:28 +00:00
}
newGpsInfo.LatitudeIndicator = strs[1]
2024-07-23 19:04:15 +00:00
newGpsInfo.LongitudeIndicator = strs[3]
2024-07-23 16:02:28 +00:00
newGpsInfo.Date = strs[4]
newGpsInfo.Time = strs[5]
newGpsInfo.Altitude, err = strconv.ParseFloat(strs[6], 64)
if err != nil {
2024-08-08 12:52:52 +00:00
logger.Println("ERROR parse altitude:", err.Error())
2024-07-23 16:02:28 +00:00
}
newGpsInfo.Speed, err = strconv.ParseFloat(strs[7], 64)
if err != nil {
2024-08-08 12:52:52 +00:00
logger.Println("ERROR parse speed:", err.Error())
2024-07-23 16:02:28 +00:00
}
// Course sometimes may be null
if len(strs[8]) > 0 {
newGpsInfo.Course, err = strconv.ParseFloat(strs[8], 64)
if err != nil {
2024-08-08 12:52:52 +00:00
logger.Println("ERROR parse course:", err.Error())
2024-07-23 16:02:28 +00:00
}
}
*gps = newGpsInfo
return nil
}