diff --git a/api/modem/at/at.go b/api/modem/at/at.go index 6a2f98d..1a34b85 100644 --- a/api/modem/at/at.go +++ b/api/modem/at/at.go @@ -2,6 +2,7 @@ package at import ( "fmt" + "io" "log" "time" @@ -32,6 +33,8 @@ type Port interface { IsConnected() bool Send(cmd string) (Resp, error) + + io.Closer } func New(logger *log.Logger, portName string, baudrate int) Port { @@ -110,3 +113,7 @@ func (p *atPort) Send(cmd string) (Resp, error) { return Resp(resp), nil } + +func (p *atPort) Close() error { + return p.port.Close() +} diff --git a/api/modem/gpio.go b/api/modem/gpio.go index c08da44..9344de1 100644 --- a/api/modem/gpio.go +++ b/api/modem/gpio.go @@ -43,3 +43,7 @@ func (p gpioPin) PowerOn() { func (p *gpioPin) PowerOff() { p.sendOnOffSignal() } + +func (p *gpioPin) Close() error { + return gpio.Close() +} diff --git a/api/modem/gps.go b/api/modem/gps.go index 78cdf78..f8bee09 100644 --- a/api/modem/gps.go +++ b/api/modem/gps.go @@ -8,7 +8,7 @@ import ( "time" ) -type GpsInfo struct { +type GpsData struct { Latitude float64 `json:"Latitude"` Longitude float64 `json:"Longitude"` LatitudeIndicator string `json:"Latitude_indicator"` // North/South @@ -20,13 +20,13 @@ type GpsInfo struct { Time string `json:"-"` } -var GpsInfoNil = GpsInfo{} +var GpsInfoNil = GpsData{} func deg2rad(deg float64) float64 { return deg * (math.Pi / 180) } -func (gps *GpsInfo) calculateSpeed(newLatitude, newLongitude float64, lastUpdateTime time.Time) { +func (gps *GpsData) calculateSpeed(newLatitude, newLongitude float64, lastUpdateTime time.Time) { earthRad := 6371.0 // TODO ? dLat := deg2rad(math.Abs(newLatitude - gps.Latitude)) dLon := deg2rad(math.Abs(newLongitude - gps.Longitude)) @@ -37,9 +37,9 @@ func (gps *GpsInfo) calculateSpeed(newLatitude, newLongitude float64, lastUpdate gps.Speed = earthRad * c / (math.Abs(float64(time.Since(lastUpdateTime)))) } -func (gps *GpsInfo) decode(str string) error { +func (gps *GpsData) decode(str string) error { var err error - newGpsInfo := GpsInfo{} + newGpsInfo := GpsData{} strs := strings.Split(strings.Split(strings.Replace(str, " ", "", -1), "\n")[0], ",") newGpsInfo.Latitude, err = strconv.ParseFloat(strs[0], 64) diff --git a/api/modem/modem.go b/api/modem/modem.go index d38dd81..3047d92 100644 --- a/api/modem/modem.go +++ b/api/modem/modem.go @@ -1,18 +1,22 @@ package modem import ( - "encoding/json" "fmt" + "io" "log" "os" "os/exec" - "slices" "strings" "time" "github.com/CGSG-2021-AE4/modem-test/api/modem/at" ) +type ModemData struct { + Port string `json:"Port"` + GpsData +} + type modem struct { // Internal values logger *log.Logger @@ -27,23 +31,16 @@ type modem struct { onOffPin gpioPin // Other values - gpsInfo GpsInfo + gpsInfo GpsData lastUpdateTime time.Time } type Modem interface { Init() error - // SearchPort(isSoft bool) error - Connect() error - Disconnect() error - IsAvailable() bool - IsConnected() bool - // Ping() error - // SwitchToGpsMode() error - // CalculateSpeed(newLatitude, newlongitude float64) + Validate() bool Update() error - GetInfo() (string, error) - TestGPS() error + GetInfo() ModemData + io.Closer } func New(logger *log.Logger) Modem { @@ -81,45 +78,24 @@ func (m *modem) Init() error { // Connect m.logger.Println("=============================== Connect") - if err := m.Connect(); err != nil { + if err := m.connect(); err != nil { return fmt.Errorf("connect: %w", err) } // Tests m.logger.Println("=============================== Test") - if err := m.TestGPS(); err != nil { + if err := m.testGPS(); err != nil { return fmt.Errorf("testGPS: %w", err) } return nil } -func (m *modem) Connect() error { - if !m.IsAvailable() { - return fmt.Errorf("port is not defined") - } - return m.port.Connect() -} - -func (m *modem) Disconnect() error { - if !m.IsAvailable() { - return fmt.Errorf("port is not defined") - } - return m.port.Disconnect() -} - -func (m *modem) IsAvailable() bool { - return m.port != nil -} - -func (m *modem) IsConnected() bool { - if m.IsAvailable() { - return m.port.IsConnected() - } - return false +func (m *modem) Validate() bool { + return m.isConnected() } func (m *modem) Update() error { - if !m.IsConnected() { + if !m.isConnected() { m.logger.Println("No connection to module") return nil } @@ -158,7 +134,46 @@ func (m *modem) Update() error { return nil } -func (m *modem) TestGPS() error { +func (m *modem) GetInfo() ModemData { + return ModemData{ + Port: m.port.GetName(), + GpsData: m.gpsInfo, + } +} + +func (m *modem) Close() error { + // Not right way I think + if err := m.port.Close(); err != nil { + return err + } + if err := m.onOffPin.Close(); err != nil { + return err + } + return nil +} + +func (m *modem) connect() error { + if !m.Validate() { + return fmt.Errorf("port is not defined") + } + return m.port.Connect() +} + +func (m *modem) disconnect() error { + if !m.Validate() { + return fmt.Errorf("port is not defined") + } + return m.port.Disconnect() +} + +func (m *modem) isConnected() bool { + if m.port != nil { + return m.port.IsConnected() + } + return false +} + +func (m *modem) testGPS() error { m.logger.Println("Testing GPS") if err := m.switchToGpsMode(); err != nil { @@ -169,39 +184,16 @@ func (m *modem) TestGPS() error { return fmt.Errorf("update: %w", err) } - m.logger.Println("Current coords:", m.GetShortInfo()) + m.logger.Println("Current coords:", m.getShortInfo()) return nil } -type ModemInfo struct { - Port string `json:"Port"` - GpsInfo -} - -type Info struct { - Modem ModemInfo `json:"Modem"` -} - -func (m *modem) GetInfo() (string, error) { - info := Info{ - Modem: ModemInfo{ - Port: m.port.GetName(), - GpsInfo: m.gpsInfo, - }, - } - buf, err := json.Marshal(info) - if err != nil { - fmt.Errorf("marshal info: %w", err) - } - return string(buf), nil // why you clamp -} - // 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) } -func (m *modem) SaveGPS(path string) error { +func (m *modem) saveGPS(path string) error { f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) if err != nil { return fmt.Errorf("open file: %w", err) @@ -209,7 +201,7 @@ func (m *modem) SaveGPS(path string) error { defer f.Close() - if _, err = f.WriteString(m.GetShortInfo()); err != nil { + if _, err = f.WriteString(m.getShortInfo()); err != nil { return fmt.Errorf("write file: %W", err) } return nil @@ -269,7 +261,7 @@ func (m *modem) searchPort(isSoft bool) error { // Get ports ports := []string{"ttyUSB1", "ttyUSB2", "ttyUSB3"} if !isSoft { - ps, err := GetTtyDevices() + ps, err := getTtyDevices() if err != nil { fmt.Errorf("get serial devices: %w", err) } @@ -338,24 +330,15 @@ func (m *modem) switchToGpsMode() error { return nil } -func GetTtyDevices() ([]string, error) { - devices := []string{} - +func getTtyDevices() ([]string, error) { // Get ports /**/ - out, err := exec.Command("/bin/ls", "/dev").Output() + out, err := exec.Command("ls", "--", "/dev/tty[!0-9]*").Output() if err != nil { return nil, fmt.Errorf("execute ls command: %w", err) } - allPorts := strings.Split(string(out), "\n") - for _, p := range allPorts { - if len(p) > 3 && p[:3] == "tty" { - devices = append(devices, p) - } - } - slices.Reverse(devices) // ASK why - - return devices, nil + ports := strings.Split(string(out), "\n") + return ports, nil } /*