esp_alox/goTool/main.go

230 lines
5.4 KiB
Go

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.NewCom(bus)
if err != nil {
log.Printf("Could not Create COM %v", err)
}
err = com.Connect(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.NewCom(bus)
ctx, cancle := context.WithCancel(context.Background())
defer cancle()
go com.EventbusHandler(ctx)
if err != nil {
log.Printf("Could not Create Com with Uart Device %v", err)
return
}
err = com.Connect(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)
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
}