Added local compilation. Cleaning.

This commit is contained in:
yotia 2024-08-06 20:37:20 +03:00
parent 026c1aa3bb
commit 6a96656434
10 changed files with 100 additions and 123 deletions

1
.gitignore vendored
View File

@ -1,5 +1,4 @@
out/
Makefile
go.sum
.git/
*.swp

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
export GOOS=linux
export GOARCH=arm
export GOARM=6
export CGO_ENABLED=0
build:
@go build -o out/modem main.go

View File

@ -13,7 +13,7 @@ import (
// Some constants
const (
ReadTimeout = time.Second
InputBufSize = 128
InputBufSize = 2048
)
type atPort struct {

View File

@ -18,8 +18,10 @@ type gps struct {
type Gps interface {
Init() error
Update() error
GetData() Data
CheckStatus() (Status, error)
GetStatus() (Status, error)
io.Closer
}
@ -56,6 +58,14 @@ func (g *gps) Update() error {
return nil
}
func (g *gps) GetData() Data {
return g.data
}
func (g *gps) Close() error {
return nil
}
func (g *gps) switchGpsMode(on bool) error {
onStr := "0"
if on {
@ -94,11 +104,3 @@ func (g *gps) switchGpsMode(on bool) error {
}
return nil
}
func (g *gps) GetData() Data {
return g.data
}
func (g *gps) Close() error {
return nil
}

View File

@ -85,6 +85,9 @@ func (g *gps) rawCollect(flags nmeaFlags) (string, error) {
if _, err := s.Write([]byte("AT+CGPSINFOCFG=0,31\r\n")); err != nil {
return "", fmt.Errorf("serial port write 2: %w", err)
}
if _, err := s.Write([]byte("AT+CGPSFTM=0\r\n")); err != nil { // For sure because sometimes it cannot stop...
return "", fmt.Errorf("serial port write 2: %w", err)
}
time.Sleep(100 * time.Millisecond) // To enshure
@ -115,7 +118,7 @@ func (g *gps) collectNmeaReports(flags nmeaFlags) ([]string, error) {
}
// DEBUG
g.logger.Println("NMEA raw collect:", resp)
// g.logger.Println("NMEA raw collect:", resp)
// Right responce struct:
// \r\n

View File

@ -12,24 +12,13 @@ type Status struct {
ActiveSatelitesCounte int `json:"activeSatelitesCount"`
}
func (st Status) String() string {
got := "false"
if st.GotResponses {
got = "true"
}
return "" +
"GotResponses: " + got + "\n" +
"FoundSatelitesCount: " + string(st.FoundSatelitesCount) + "\n" +
"ActiveSatelitesCounte: " + string(st.ActiveSatelitesCounte) + "\n"
}
var StatusNil = Status{
GotResponses: false,
FoundSatelitesCount: 0,
ActiveSatelitesCounte: 0,
}
func (g *gps) CheckStatus() (Status, error) {
func (g *gps) GetStatus() (Status, error) {
// Provides more information about signal and possible problems using NMEA reports
// Collect reports

View File

@ -26,13 +26,12 @@ type modem struct {
logger *log.Logger
// Serial values
baudrate int
baudrate int
deviceName string
port at.Port
// Gpio values
onOffPin gpio.Pin
onOffPin gpio.Pin // For turning on and off
// Other values
lastUpdateTime time.Time
@ -44,19 +43,19 @@ type modem struct {
ic internet.Conn
// Sms and calls
sms sms.Dialer
sms sms.Sms
}
type Modem interface {
Init() error
Validate() bool
IsConnected() bool
Update() error
GetData() ModemData
// Temp access to SMS, GPS, AT interfaces mostly for debug
At() at.Port
Gps() gps.Gps
Sms() sms.Dialer
// Access to SMS, GPS, AT interfaces mostly for debug
At() at.Port // Send
Gps() gps.Gps // Update, GetData, GetStatus
Sms() sms.Sms // Send, ReadNew
io.Closer
}
@ -77,7 +76,8 @@ func (m *modem) Init() error {
if err := m.onOffPin.Init(); err != nil {
return fmt.Errorf("gpio pin init: %w", err)
}
// m.onOffPin.PowerOn()
m.logger.Println("TURNING ON IS COMMENTED NOW!!!")
// m.onOffPin.PowerOn() // DEBUG do not want to wait 30 seconds
// Search
m.logger.Println("=============================== Search")
@ -101,40 +101,44 @@ func (m *modem) Init() error {
return fmt.Errorf("connect: %w", err)
}
// // Establish internet connection
// m.logger.Println("=============================== Internet")
// m.ic = internet.New(log.New(m.logger.Writer(), "internet", log.LstdFlags), m.port)
// if err := m.ic.Init(); err != nil {
// return fmt.Errorf("internet connection init: %w", err)
// }
// Init submodules
// submodulesLogger := m.logger.Writer() // FOR more logs
submodulesLogger := io.Discard // FOR less logs
m.logger.Println("=============================== Init submodules")
m.sms = sms.New(log.New(m.logger.Writer(), "modem-sms", log.LstdFlags), m.port)
m.ic = internet.New(log.New(submodulesLogger, "modem-internet : ", log.LstdFlags), m.port)
if err := m.ic.Init(); err != nil {
m.logger.Printf("\x1b[38;2;255;0;0mInternet: %s\x1b[38;2;255;255;255m\n", err.Error())
} else {
m.logger.Println("\x1b[38;2;0;255;0mInternet OK\x1b[38;2;255;255;255m")
}
m.sms = sms.New(log.New(submodulesLogger, "modem-sms : ", log.LstdFlags), m.port)
if err := m.sms.Init(); err != nil {
return fmt.Errorf("sms dialer init %w", err)
m.logger.Printf("\x1b[38;2;255;0;0mSMS: %s\x1b[38;2;255;255;255m\n", err.Error())
} else {
m.logger.Println("\x1b[38;2;0;255;0mSMS OK\x1b[38;2;255;255;255m")
}
m.gps = gps.New(log.New(m.logger.Writer(), "modem-gps", log.LstdFlags), m.port)
m.gps = gps.New(log.New(submodulesLogger, "modem-gps : ", log.LstdFlags), m.port)
if err := m.gps.Init(); err != nil {
return fmt.Errorf("gps init %w", err)
m.logger.Printf("\x1b[38;2;255;0;0mgps init %w\x1b[38;2;255;255;255m\n", err)
} else {
m.logger.Println("\x1b[38;2;0;255;0mGPS OK\x1b[38;2;255;255;255m")
}
m.logger.Println(m.gps, m)
// Tests
m.logger.Println("=============================== Test")
if err := m.testGPS(); err != nil {
return fmt.Errorf("testGPS: %w", err)
}
// GPS works fine but almost always there is no signal
// m.logger.Println("=============================== Test")
// if err := m.testGPS(); err != nil {
// return fmt.Errorf("testGPS: %w", err)
// }
return nil
}
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
}
@ -142,6 +146,8 @@ func (m *modem) Update() error {
if err := m.gps.Update(); err != nil {
m.logger.Println("gps update:", err.Error())
}
// Read new messages
return nil
}
@ -152,7 +158,7 @@ func (m *modem) GetData() ModemData {
}
}
func (m *modem) Sms() sms.Dialer {
func (m *modem) Sms() sms.Sms {
return m.sms
}
@ -164,25 +170,26 @@ func (m *modem) At() at.Port {
return m.port
}
func (m *modem) Close() error {
func (m *modem) Close() error { // I can't return error so I log it
if err := m.sms.Close(); err != nil {
return fmt.Errorf("sms: %w", err)
m.logger.Printf("\x1b[38;2;255;0;0mclose sms error: %s\x1b[38;2;255;255;255m\n", err.Error())
}
// Not right way I think
if err := m.port.Close(); err != nil {
return fmt.Errorf("serial port: %w", err)
m.logger.Printf("\x1b[38;2;255;0;0mclose serial port error: %s\x1b[38;2;255;255;255m\n", err.Error())
}
if err := m.onOffPin.Close(); err != nil {
return fmt.Errorf("gpio pin: %w", err)
m.logger.Printf("\x1b[38;2;255;0;0mclose gpio pin error: %s\x1b[38;2;255;255;255m\n", err.Error())
}
if err := m.ic.Close(); err != nil {
return fmt.Errorf("internet connection: %w", err)
m.logger.Printf("\x1b[38;2;255;0;0mclose internet connection error: %s\x1b[38;2;255;255;255m\n", err.Error())
}
return nil
}
///////////// Private functions
func (m *modem) connect() error {
if m.port == nil {
return fmt.Errorf("port is not defined")
@ -197,7 +204,7 @@ func (m *modem) disconnect() error {
return m.port.Disconnect()
}
func (m *modem) isConnected() bool {
func (m *modem) IsConnected() bool {
if m.port != nil {
return m.port.IsConnected()
}
@ -234,22 +241,17 @@ func (m *modem) saveGPS(path string) error {
return nil
}
func (m *modem) testConsole() {
for {
var inStr string
fmt.Scanln(&inStr)
if inStr == "exit" {
return
}
resp, err := m.port.Send(inStr)
if err != nil {
m.logger.Println("ERROR:", err.Error())
}
m.logger.Println(resp)
m.logger.Println("------------------")
// Short way to send command
func (m *modem) printCmd(cmd string) {
if resp, err := m.port.Send(cmd); err != nil {
m.logger.Println("FAILED TO SEND REQ", cmd, ":", err.Error())
} else {
_ = resp
// m.logger.Println("CMD", cmd, ":", resp)
}
}
// Some required commands before checking port
func (m *modem) setupPort() error {
// Reset input
if err := m.port.SerialPort().ResetInputBuffer(); err != nil {
@ -259,37 +261,11 @@ func (m *modem) setupPort() error {
if err := m.port.SerialPort().ResetOutputBuffer(); err != nil {
return fmt.Errorf("reset output buffer: %w", err)
}
m.port.Send("ATE0") // This shit sometimes enables echo mode... why... when... but it can
// Turn on errors' describtion
if resp, err := m.port.Send("AT+CMEE=2"); err != nil || !resp.Check() {
if err != nil {
return fmt.Errorf("AT+CMEE=2 request: %w", err)
}
return fmt.Errorf("turn on errors: error response: %s", resp)
}
// Display other values
m.logger.Println("DEBUG SIM VALUES:")
// ICCID
if resp, err := m.port.Send("AT+CCID"); err != nil || !resp.Check() {
if err != nil {
return fmt.Errorf("AT+CCID request: %w", err)
}
return fmt.Errorf("get ICCID: error response: %s", resp)
} else {
m.logger.Println("ICCID:", strings.Split(resp.String(), "\n")[0])
}
// ICCID
if resp, err := m.port.Send("AT+CNUM"); err != nil || !resp.Check() {
if err != nil {
return fmt.Errorf("AT+CNUM request: %w", err)
}
return fmt.Errorf("get CNUM: error response: %s", resp)
} else {
m.logger.Println("CNUM:", strings.Split(resp.String(), "\n")[0])
}
// These commands ensure that correct modes are set
m.printCmd("ATE0") // Sometimes enables echo mode
m.printCmd("AT+CGPSFTM=0") // Sometimes does not turn off nmea
m.printCmd("AT+CMEE=2") // Turn on errors describtion
return nil
}

View File

@ -14,14 +14,15 @@ type dialer struct {
port at.Port
}
type Dialer interface {
type Sms interface {
Init() error
Send(number, msg string) error
ReadNew() ([]string, error)
Send(number, msg string) error // Send sms
ReadNew() ([]string, error) // Read new smses
io.Closer
}
func New(logger *log.Logger, port at.Port) Dialer {
func New(logger *log.Logger, port at.Port) Sms {
return &dialer{
logger: logger,
port: port,
@ -45,13 +46,15 @@ func (d *dialer) Init() error {
}
func (d *dialer) Send(number, msg string) error {
d.port.Send(fmt.Sprintf("AT+CMGS=\"%s\"", number)) // Because it will throw error
resp, err := d.port.RawSend(fmt.Sprintf("%s\x1A", msg)) // Add additional \r\n because there is not supposed to be
d.port.Send(fmt.Sprintf(`AT+CMGS="%s"`, number)) // Because it will throw error
resp, err := d.port.RawSend(fmt.Sprintf("%s\n\r", msg)) // Add additional \r\n because there is not supposed to be
if err != nil {
return fmt.Errorf("message request: %w", err)
}
if at.Resp(resp).Check() {
return nil
d.logger.Println("SEND RESPONSE:", resp)
resp, err = d.port.RawSend("\x1A")
if err != nil {
return fmt.Errorf("message request: %w", err)
}
d.logger.Println("SEND RESPONSE:", resp)
errCode, err := GetError([]byte(resp))

14
main.go
View File

@ -16,18 +16,18 @@ func main() {
}
func mainE() error {
logger := log.New(os.Stdout, "main:", log.LstdFlags)
m := modem.New(log.New(logger.Writer(), "modem:", log.LstdFlags))
logger := log.New(os.Stdout, "main : ", log.LstdFlags)
m := modem.New(log.New(logger.Writer(), "modem : ", log.LstdFlags))
logger.Println("||||||||||||||||| INIT |||||||||||||||")
if err := m.Init(); err != nil {
return err
}
if !m.Validate() {
logger.Println("AAAAAAAAAAAAAAA Validation failed")
if !m.IsConnected() {
logger.Println("AAAAAAAAAAAAAAA Modem is not connected")
return nil
}
logger.Println("||||||||||||||||| GET INFO |||||||||||||||||")
logger.Println(m.GetData())
logger.Printf("DATA: %+v\n", m.GetData())
// logger.Println("||||||||||||||||| SEND SMS |||||||||||||||||")
// logger.Println(m.At().Send("AT+CNUM"))
@ -40,11 +40,11 @@ func mainE() error {
// logger.Println("NEW:", ms)
// }
logger.Println("||||||||||||||||| Checking gps status |||||||||||||||||")
st, err := m.Gps().CheckStatus()
st, err := m.Gps().GetStatus()
if err != nil {
return err
}
logger.Println("GPS Status:\n", st)
logger.Printf("GPS Status:%+v\n", st)
return nil
}

View File

@ -1,2 +0,0 @@
ISSUES:
- create input buffer every at port creation