package main import ( "context" "flag" "fmt" "log" "os" "time" "alox.tool/api" "alox.tool/eventbus" "alox.tool/frontend" "alox.tool/testrunner" "alox.tool/uart" ) var ( Tests bool ) func main() { flag.BoolVar(&Tests, "t", false, "Tests") flag.Parse() config := Config{ Port: 8000, Host: "0.0.0.0", UartPort: "/dev/ttyUSB0", //Baudrate: 115200, Baudrate: 921600, } if Tests { StartTests(config) return } StartApp(config) } func StartTests(config Config) { bus := eventbus.New() com, err := uart.Connect(bus, config.UartPort, config.Baudrate) if err != nil { log.Printf("Could not Connect with Uart Device %v", err) } defer com.Close() tr := testrunner.New(bus, com) testTest1 := make(map[string]func() error) testTest1["Echo Test"] = tr.RunEchoTest testTest1["Version Test"] = tr.RunVersionTest testTest1["Info Test"] = tr.RunClientInfoTest testTest1["Input Test"] = tr.RunClientInputTest tr.RunTestSet(testTest1) } func StartApp(config Config) { bus := eventbus.New() com, err := uart.Connect(bus, config.UartPort, config.Baudrate) if err != nil { log.Printf("Could not Connect with Uart Device %v", err) } defer com.Close() update, err := os.ReadFile("../espAlox.bin") if err != nil { log.Printf("Could not read Update file %v", err) return } updateSlices := SliceUpdate(update, 200) oManager := NewOTAManager(bus, com, updateSlices) ctx, cancle := context.WithCancel(context.Background()) defer cancle() StartMessageHandling(ctx, bus) oManager.StartUpdateHandler(ctx) time.Sleep(time.Millisecond * 5) //tr := testrunner.New(bus, com) //tr.RunVersionTest() time.Sleep(time.Millisecond * 5) com.Send(api.CmdEcho, make([]byte, 0)) com.Send(api.CmdVersion, make([]byte, 0)) com.Send(api.CmdClientInfo, make([]byte, 0)) com.Send(api.CmdClientInput, make([]byte, 0)) //com.Send(api.CmdOtaStart, make([]byte, 0)) com.Send(api.CmdOtaStartEspNow, make([]byte, 0)) url := fmt.Sprintf("%s:%d", config.Host, config.Port) fserver := frontend.New(bus) fserver.Start(url) } func StartMessageHandling(ctx context.Context, bus eventbus.EventBus) { RXC := bus.Subscribe(api.TopicUARTRx) defer bus.Unsubscribe(api.TopicUARTRx, RXC) TXC := bus.Subscribe(api.TopicUARTTx) defer bus.Unsubscribe(api.TopicUARTTx, TXC) go func() { for { select { case <-ctx.Done(): return case _ = <-TXC: //log.Printf("MSG[TX]: % X", msg) case msg := <-RXC: //log.Printf("MSG[RX]: % X", msg) val, ok := msg.(api.Frame) if !ok { log.Printf("val is not type api.Frame its %T", val) continue } log.Printf("[%d] Frame: %X, % X", val.Time, val.ID, val.Data) switch val.ID { case api.CmdEcho: log.Printf("Echo %v", val) case api.CmdVersion: v, err := uart.ParseFrameVersion(val) if err != nil { log.Printf("Could not Parse Version %v", err) continue } log.Printf("Version Info %d %s", v.Version, v.Buildhash) case api.CmdClientInfo: v, err := uart.ParseFrameClientInfo(val) if err != nil { log.Printf("Could not Parse Client Info %v", err) continue } for _, c := range v { log.Printf("Client ID %d", c.ClientID) log.Printf("\tIsAvailable %d", c.IsAvailable) log.Printf("\tLastPing %d", c.LastPing) log.Printf("\tLastSuccessfulPing %d", c.LastSuccessfulPing) log.Printf("\tSlotIsUsed %d", c.SlotIsUsed) log.Printf("\tVersion %d", c.Version) log.Printf("\tMACAddr % X", c.MACAddr) } case api.CmdClientInput: v, err := uart.ParseFrameClientInput(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) continue } for _, c := range v { log.Printf("Client ID %d", c.ClientID) log.Printf("\tX %f", c.X) log.Printf("\tY %f", c.Y) log.Printf("\tBitmask %08b", c.InputMask) } case api.CmdOtaPayload: v, err := uart.ParseFrameOtaPayload(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) continue } bus.Publish(api.TopicOTA, v) log.Printf("%v", v) case api.CmdOtaStatus: v, err := uart.ParseFrameOtaStatus(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) continue } bus.Publish(api.TopicOTA, v) log.Printf("%v", v) // Update State Machine case api.CmdOtaStart: v, err := uart.ParseFrameOtaStart(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) continue } bus.Publish(api.TopicOTA, v) log.Printf("%v", v) case api.CmdOtaEnd: v, err := uart.ParseFrameOtaEnd(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) continue } bus.Publish(api.TopicOTA, v) log.Printf("%v", v) case api.CmdOtaStartEspNow: v, err := uart.ParseFrameOtaStartEspNow(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) continue } bus.Publish(api.TopicOTA, v) log.Printf("%v", v) } } } }() } func SliceUpdate(update []byte, maxlen int) [][]byte { updateSlices := [][]byte{} for i := 0; i < len(update); i += 200 { end := min(i+200, len(update)) updateSlices = append(updateSlices, update[i:end]) } return updateSlices }