display-test/main.go
2024-08-29 22:03:56 +03:00

180 lines
3.8 KiB
Go

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
}