package main import ( "context" "fmt" "log" "os" "os/signal" "syscall" "time" "gitea.unprism.ru/yotia/display-test/display" "gitea.unprism.ru/yotia/display-test/drawer" "gitea.unprism.ru/KRBL/sim-modem/api/modem" ) const ( displayUpdateTimeout = 10 * time.Millisecond ) func main() { log.Println("CGSG forever!!!") ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer cancel() // Just for logs go func(ctx context.Context) { <-ctx.Done() log.Println("GOT INTERUPT SIGNAL") }(ctx) if err := mainE(ctx); err != nil { log.Println("MAIN finished with error:", err.Error()) } log.Println("END") } var logger *log.Logger var dev display.Display var d drawer.Drawer var m modem.Modem func DrawProgress(ctx context.Context, timeout time.Duration) error { deadline := time.Now().Add(timeout) // Draw outline x := 0 y := d.GetFont().Metrics().Height.Ceil() + 4 w := d.GetImg().Rect.Dx() h := d.GetFont().Metrics().Height.Ceil() - 4 d.PutBar(x, y, x+w, y+h, 255) gap := 3 // Draw body x += gap y += gap w -= 2 * gap h -= 2 * gap lastX := x for { select { case <-ctx.Done(): return nil case <-time.After(displayUpdateTimeout): value := 1 - float64(time.Until(deadline).Milliseconds())/float64(timeout.Milliseconds()) newX := x + int(value*float64(w)) // Draw d.FillBar(lastX, y, newX, y+h, 255) lastX = newX if value >= 1 { return nil } if err := d.Flush(); err != nil { return fmt.Errorf("display flush: %w", err) } } } } func Init(ctx context.Context) error { // Display init var err error dev, err = display.New(log.New(log.Writer(), "display", log.LstdFlags), display.SSD1306) if err != nil { return fmt.Errorf("new display: %w", err) } logger.Println("Display inited") d := drawer.New(dev) d.Clear() d.PutText(0, d.GetFont().Metrics().Height.Ceil(), "Initing modem...") d.Flush() // Modem init mInitCtx, mInitCtxCancel := context.WithCancel(ctx) go DrawProgress(mInitCtx, 13*time.Second) defer mInitCtxCancel() m = modem.New(log.New(logger.Writer(), "modem : ", log.LstdFlags)) if err := m.Init(); err != nil { return fmt.Errorf("modem init: %w", err) } logger.Println("Display inited") mInitCtxCancel() d.Clear() d.PutText(0, d.GetFont().Metrics().Height.Ceil(), "Modem inited.") d.PutText(0, d.GetFont().Metrics().Height.Ceil()*2, "Starting test...") d.Flush() return nil } func Close() { m.Close() if d != nil { d.Clear() d.Flush() } dev.Close() } func MainLoop(ctx context.Context) error { mainLoopTimeout := time.Second frameCounter := 0 deadline := time.Now().Add(100 * time.Millisecond) for { select { case <-ctx.Done(): return nil case <-time.After(time.Until(deadline)): deadline = time.Now().Add(mainLoopTimeout) st, _ := m.Gps().GetStatus() data := m.GetData() coordsStr := fmt.Sprintf("%03d°%02.0f'%s %03d°%02.0f'%s", int(data.Latitude), (data.Latitude-float64(int(data.Latitude)))*100, data.LatitudeIndicator, int(data.Longitude), (data.Longitude-float64(int(data.Longitude)))*100, data.LongitudeIndicator) var str1 string var str2 string if frameCounter%4 < 2 { str2 = fmt.Sprintf("Sat. count: %d", st.FoundSatelitesCount) } else { str2 = coordsStr } str1 = fmt.Sprintf("%s", time.Now().Format("15:04:05")) d.Clear() d.PutText(0, d.GetFont().Metrics().Height.Ceil(), str1) d.PutText(0, d.GetFont().Metrics().Height.Ceil()*2, str2) d.Flush() frameCounter++ } } } func mainE(ctx context.Context) error { logger = log.New(os.Stdout, "main : ", log.LstdFlags) // disp, err := display.New(logger, display.MT12864A) if err != nil { return err } time.Sleep(2 * time.Second) defer disp.Close() // if err := Init(ctx); err != nil { // return err // } // defer Close() // if err := MainLoop(ctx); err != nil { // return err // } return nil }