Refactored gps. Prepared for adding advanced status checks.
This commit is contained in:
parent
fd9e999b5a
commit
b831d44294
@ -1,4 +1,4 @@
|
|||||||
package modem
|
package gps
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -6,11 +6,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/CGSG-2021-AE4/modem-test/api/modem/at"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type GpsData struct {
|
type Data struct {
|
||||||
Latitude float64 `json:"Latitude"`
|
Latitude float64 `json:"Latitude"`
|
||||||
Longitude float64 `json:"Longitude"`
|
Longitude float64 `json:"Longitude"`
|
||||||
LatitudeIndicator string `json:"Latitude_indicator"` // North/South
|
LatitudeIndicator string `json:"Latitude_indicator"` // North/South
|
||||||
@ -22,13 +20,13 @@ type GpsData struct {
|
|||||||
Time string `json:"-"`
|
Time string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var GpsInfoNil = GpsData{}
|
var GpsInfoNil = Data{}
|
||||||
|
|
||||||
func deg2rad(deg float64) float64 {
|
func deg2rad(deg float64) float64 {
|
||||||
return deg * (math.Pi / 180)
|
return deg * (math.Pi / 180)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gps *GpsData) calculateSpeed(newLatitude, newLongitude float64, lastUpdateTime time.Time) {
|
func (gps *Data) CalculateSpeed(newLatitude, newLongitude float64, lastUpdateTime time.Time) {
|
||||||
earthRad := 6371.0 // TODO ?
|
earthRad := 6371.0 // TODO ?
|
||||||
dLat := deg2rad(math.Abs(newLatitude - gps.Latitude))
|
dLat := deg2rad(math.Abs(newLatitude - gps.Latitude))
|
||||||
dLon := deg2rad(math.Abs(newLongitude - gps.Longitude))
|
dLon := deg2rad(math.Abs(newLongitude - gps.Longitude))
|
||||||
@ -39,10 +37,12 @@ func (gps *GpsData) calculateSpeed(newLatitude, newLongitude float64, lastUpdate
|
|||||||
gps.Speed = earthRad * c / (math.Abs(float64(time.Since(lastUpdateTime))))
|
gps.Speed = earthRad * c / (math.Abs(float64(time.Since(lastUpdateTime))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To remove warning
|
||||||
|
|
||||||
// Parse string from AT command that contains gps data
|
// Parse string from AT command that contains gps data
|
||||||
func (gps *GpsData) decode(str string) error {
|
func (gps *Data) decode(str string) error {
|
||||||
var err error
|
var err error
|
||||||
newGpsInfo := GpsData{}
|
newGpsInfo := Data{}
|
||||||
strs := strings.Split(strings.Split(strings.Replace(str, " ", "", -1), "\n")[0], ",")
|
strs := strings.Split(strings.Split(strings.Replace(str, " ", "", -1), "\n")[0], ",")
|
||||||
|
|
||||||
newGpsInfo.Latitude, err = strconv.ParseFloat(strs[0], 64)
|
newGpsInfo.Latitude, err = strconv.ParseFloat(strs[0], 64)
|
||||||
@ -77,61 +77,3 @@ func (gps *GpsData) decode(str string) error {
|
|||||||
*gps = newGpsInfo
|
*gps = newGpsInfo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gps *GpsData) Update(port at.Port) error {
|
|
||||||
if err := switchGpsMode(port, true); err != nil {
|
|
||||||
return fmt.Errorf("try to GPS mode: %w", err)
|
|
||||||
}
|
|
||||||
defer switchGpsMode(port, false)
|
|
||||||
|
|
||||||
resp, err := port.Send("AT+CGPSINFO")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("receive GPS data: %w", err)
|
|
||||||
}
|
|
||||||
if !resp.Check() {
|
|
||||||
return fmt.Errorf("error response")
|
|
||||||
}
|
|
||||||
if err := gps.decode(strings.Split(strings.Replace(resp.RmFront("+CGPSINFO:").String(), "\r", "", -1), "\n")[0]); err != nil {
|
|
||||||
return fmt.Errorf("decode: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func switchGpsMode(port at.Port, on bool) error {
|
|
||||||
onStr := "0"
|
|
||||||
if on {
|
|
||||||
onStr = "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset input
|
|
||||||
if err := port.GetSerialPort().ResetInputBuffer(); err != nil {
|
|
||||||
return fmt.Errorf("reset input buffer: %w", err)
|
|
||||||
}
|
|
||||||
// Reset output
|
|
||||||
if err := port.GetSerialPort().ResetOutputBuffer(); err != nil {
|
|
||||||
return fmt.Errorf("reset output buffer: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check gps mode status
|
|
||||||
resp, err := port.Send("AT+CGPS?")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("make at ask: %w", err)
|
|
||||||
}
|
|
||||||
if !resp.Check() {
|
|
||||||
return fmt.Errorf("error response")
|
|
||||||
}
|
|
||||||
ans := strings.Replace(strings.Split(strings.Split(resp.RmFront("+CGPS:").String(), "\n")[0], ",")[0], " ", "", -1)
|
|
||||||
if ans == onStr {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modem is not in GPS mode
|
|
||||||
resp, err = port.Send("AT+CGPS=" + onStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("try to switch to gps: %w", err)
|
|
||||||
}
|
|
||||||
if !resp.Check() {
|
|
||||||
return fmt.Errorf("switch tp GPS failed")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
108
api/modem/gps/gps.go
Normal file
108
api/modem/gps/gps.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package gps
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/CGSG-2021-AE4/modem-test/api/modem/at"
|
||||||
|
)
|
||||||
|
|
||||||
|
type gps struct {
|
||||||
|
logger *log.Logger
|
||||||
|
port at.Port
|
||||||
|
data Data
|
||||||
|
}
|
||||||
|
|
||||||
|
type Gps interface {
|
||||||
|
Init() error
|
||||||
|
Update() error
|
||||||
|
GetData() Data
|
||||||
|
CheckStatus() error
|
||||||
|
io.Closer
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(logger *log.Logger, port at.Port) Gps {
|
||||||
|
return &gps{
|
||||||
|
logger: logger,
|
||||||
|
port: port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *gps) Init() error {
|
||||||
|
if g.port.IsConnected() {
|
||||||
|
return fmt.Errorf("at port is not connected")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *gps) Update() error {
|
||||||
|
if err := g.switchGpsMode(true); err != nil {
|
||||||
|
return fmt.Errorf("try to GPS mode: %w", err)
|
||||||
|
}
|
||||||
|
defer g.switchGpsMode(false)
|
||||||
|
|
||||||
|
resp, err := g.port.Send("AT+CGPSINFO")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("receive GPS data: %w", err)
|
||||||
|
}
|
||||||
|
if !resp.Check() {
|
||||||
|
return fmt.Errorf("error response")
|
||||||
|
}
|
||||||
|
if err := g.data.decode(strings.Split(strings.Replace(resp.RmFront("+CGPSINFO:").String(), "\r", "", -1), "\n")[0]); err != nil {
|
||||||
|
return fmt.Errorf("decode: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *gps) switchGpsMode(on bool) error {
|
||||||
|
onStr := "0"
|
||||||
|
if on {
|
||||||
|
onStr = "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset input
|
||||||
|
if err := g.port.GetSerialPort().ResetInputBuffer(); err != nil {
|
||||||
|
return fmt.Errorf("reset input buffer: %w", err)
|
||||||
|
}
|
||||||
|
// Reset output
|
||||||
|
if err := g.port.GetSerialPort().ResetOutputBuffer(); err != nil {
|
||||||
|
return fmt.Errorf("reset output buffer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check gps mode status
|
||||||
|
resp, err := g.port.Send("AT+CGPS?")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("make at ask: %w", err)
|
||||||
|
}
|
||||||
|
if !resp.Check() {
|
||||||
|
return fmt.Errorf("error response")
|
||||||
|
}
|
||||||
|
ans := strings.Replace(strings.Split(strings.Split(resp.RmFront("+CGPS:").String(), "\n")[0], ",")[0], " ", "", -1)
|
||||||
|
if ans == onStr {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modem is not in GPS mode
|
||||||
|
resp, err = g.port.Send("AT+CGPS=" + onStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("try to switch to gps: %w", err)
|
||||||
|
}
|
||||||
|
if !resp.Check() {
|
||||||
|
return fmt.Errorf("switch tp GPS failed")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *gps) GetData() Data {
|
||||||
|
return g.data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *gps) CheckStatus() error {
|
||||||
|
return fmt.Errorf("not impemented yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *gps) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
@ -11,13 +11,14 @@ import (
|
|||||||
|
|
||||||
"github.com/CGSG-2021-AE4/modem-test/api/modem/at"
|
"github.com/CGSG-2021-AE4/modem-test/api/modem/at"
|
||||||
"github.com/CGSG-2021-AE4/modem-test/api/modem/gpio"
|
"github.com/CGSG-2021-AE4/modem-test/api/modem/gpio"
|
||||||
|
"github.com/CGSG-2021-AE4/modem-test/api/modem/gps"
|
||||||
"github.com/CGSG-2021-AE4/modem-test/api/modem/internet"
|
"github.com/CGSG-2021-AE4/modem-test/api/modem/internet"
|
||||||
"github.com/CGSG-2021-AE4/modem-test/api/modem/sms"
|
"github.com/CGSG-2021-AE4/modem-test/api/modem/sms"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ModemData struct {
|
type ModemData struct {
|
||||||
Port string `json:"Port"`
|
Port string `json:"Port"`
|
||||||
GpsData
|
gps.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
type modem struct {
|
type modem struct {
|
||||||
@ -37,7 +38,7 @@ type modem struct {
|
|||||||
lastUpdateTime time.Time
|
lastUpdateTime time.Time
|
||||||
|
|
||||||
// GPS
|
// GPS
|
||||||
gpsInfo GpsData
|
gps gps.Gps
|
||||||
|
|
||||||
// Internet connection
|
// Internet connection
|
||||||
ic internet.Conn
|
ic internet.Conn
|
||||||
@ -50,20 +51,22 @@ type Modem interface {
|
|||||||
Init() error
|
Init() error
|
||||||
Validate() bool
|
Validate() bool
|
||||||
Update() error
|
Update() error
|
||||||
GetInfo() ModemData
|
GetData() ModemData
|
||||||
|
|
||||||
// Temp access to SMS and AT interface
|
// Temp access to SMS, GPS, AT interfaces mostly for debug
|
||||||
Sms() sms.Dialer
|
|
||||||
At() at.Port
|
At() at.Port
|
||||||
|
Gps() gps.Gps
|
||||||
|
Sms() sms.Dialer
|
||||||
|
|
||||||
io.Closer
|
io.Closer
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(logger *log.Logger) Modem {
|
func New(logger *log.Logger) Modem {
|
||||||
return &modem{
|
return &modem{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
baudrate: 115200,
|
baudrate: 115200,
|
||||||
onOffPin: gpio.New(log.New(logger.Writer(), "gpio", log.LstdFlags), 6),
|
onOffPin: gpio.New(log.New(logger.Writer(), "gpio", log.LstdFlags), 6),
|
||||||
|
|
||||||
lastUpdateTime: time.Now(),
|
lastUpdateTime: time.Now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,11 +114,17 @@ func (m *modem) Init() error {
|
|||||||
// return fmt.Errorf("internet connection init: %w", err)
|
// return fmt.Errorf("internet connection init: %w", err)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Init sms dialer
|
// Init submodules
|
||||||
m.sms = sms.New(log.New(m.logger.Writer(), "sms", log.LstdFlags), m.port)
|
m.sms = sms.New(log.New(m.logger.Writer(), "modem-sms", log.LstdFlags), m.port)
|
||||||
if err := m.sms.Init(); err != nil {
|
if err := m.sms.Init(); err != nil {
|
||||||
return fmt.Errorf("sms dialer init %w", err)
|
return fmt.Errorf("sms dialer init %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.gps = gps.New(log.New(m.logger.Writer(), "modem-gps", log.LstdFlags), m.port)
|
||||||
|
if err := m.gps.Init(); err != nil {
|
||||||
|
return fmt.Errorf("gps init %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,44 +138,16 @@ func (m *modem) Update() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
m.logger.Println("Update")
|
m.logger.Println("Update")
|
||||||
// ans, err := m.port.Request(at.CmdQuestion, "CGPSINFO")
|
if err := m.gps.Update(); err != nil {
|
||||||
// if err != nil {
|
return fmt.Errorf("gps update: %w", err)
|
||||||
// return fmt.Errorf("check GPS info mode: %w", err)
|
|
||||||
// }
|
|
||||||
// ok := ans == "1"
|
|
||||||
// if !ok {
|
|
||||||
// _, err := m.port.Request(at.CmdCheck, "CGPSINFO")
|
|
||||||
// if err != nil {
|
|
||||||
// return fmt.Errorf("switch to GPS info mode: %w", err)
|
|
||||||
// }
|
|
||||||
// m.logger.Println("switched to GPS mode")
|
|
||||||
// } else {
|
|
||||||
// m.logger.Println("mode in right GPS mode")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Update
|
|
||||||
m.logger.Println("Receiving GPS data...")
|
|
||||||
resp, err := m.port.Send("AT+CGPSINFO")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("receive GPS data: %w", err)
|
|
||||||
}
|
}
|
||||||
if !resp.Check() {
|
|
||||||
return fmt.Errorf("error response")
|
|
||||||
}
|
|
||||||
m.logger.Println("Decoding data...")
|
|
||||||
|
|
||||||
if err := m.gpsInfo.decode(strings.Split(strings.Replace(resp.RmFront("+CGPSINFO:").String(), "\r", "", -1), "\n")[0]); err != nil {
|
|
||||||
m.logger.Println("Gps info decode error:", err.Error())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
m.logger.Println("Decoded successfully")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *modem) GetInfo() ModemData {
|
func (m *modem) GetData() ModemData {
|
||||||
return ModemData{
|
return ModemData{
|
||||||
Port: m.port.GetName(),
|
Port: m.port.GetName(),
|
||||||
GpsData: m.gpsInfo,
|
Data: m.gps.GetData(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +155,10 @@ func (m *modem) Sms() sms.Dialer {
|
|||||||
return m.sms
|
return m.sms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *modem) Gps() gps.Gps {
|
||||||
|
return m.gps
|
||||||
|
}
|
||||||
|
|
||||||
func (m *modem) At() at.Port {
|
func (m *modem) At() at.Port {
|
||||||
return m.port
|
return m.port
|
||||||
}
|
}
|
||||||
@ -231,7 +216,8 @@ func (m *modem) testGPS() error {
|
|||||||
|
|
||||||
// Difference: I do not set \n at the end of string
|
// Difference: I do not set \n at the end of string
|
||||||
func (m *modem) getShortInfo() string {
|
func (m *modem) getShortInfo() string {
|
||||||
return fmt.Sprintf("%f,%s,%f,%s", m.gpsInfo.Latitude, m.gpsInfo.LatitudeIndicator, m.gpsInfo.Longitude, m.gpsInfo.LongitudeIndicator)
|
d := m.gps.GetData()
|
||||||
|
return fmt.Sprintf("%f,%s,%f,%s", d.Latitude, d.LatitudeIndicator, d.Longitude, d.LongitudeIndicator)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *modem) saveGPS(path string) error {
|
func (m *modem) saveGPS(path string) error {
|
||||||
|
2
main.go
2
main.go
@ -26,7 +26,7 @@ func mainE() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Println("||||||||||||||||| GET INFO |||||||||||||||||")
|
log.Println("||||||||||||||||| GET INFO |||||||||||||||||")
|
||||||
log.Println(m.GetInfo())
|
log.Println(m.GetData())
|
||||||
|
|
||||||
log.Println("||||||||||||||||| SEND SMS |||||||||||||||||")
|
log.Println("||||||||||||||||| SEND SMS |||||||||||||||||")
|
||||||
log.Println(m.At().Send("AT+CNUM"))
|
log.Println(m.At().Send("AT+CNUM"))
|
||||||
|
Loading…
Reference in New Issue
Block a user