package main import ( "context" "log" "time" "alox.tool/api" "alox.tool/eventbus" "alox.tool/uart" ) type OTAManager struct { Bus eventbus.EventBus Com *uart.Com Update [][]byte CurrentSlice uint16 Partition byte StartTime time.Time EndTime time.Time } func NewOTAManager(bus eventbus.EventBus, com *uart.Com, update [][]byte) OTAManager { return OTAManager{ Bus: bus, Com: com, Update: update, CurrentSlice: 0, } } func (om *OTAManager) StartUpdateHandler(ctx context.Context) { RXC := om.Bus.Subscribe(api.TopicUARTRx) defer om.Bus.Unsubscribe(api.TopicUARTRx, RXC) go func() { for { select { case <-ctx.Done(): return case msg := <-RXC: 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) om.processFrame(val) } } }() } func (om *OTAManager) processFrame(val api.Frame) { switch val.ID { case api.CmdOtaStart: msgT, err := uart.ParseFrameOtaStart(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) return } // Send First Payload om.StartTime = time.Now() om.Partition = msgT.Parition err = om.Com.Send(api.CmdOtaPayload, om.Update[om.CurrentSlice]) if err != nil { log.Printf("Error Sending Update Step!: %v", err) return } om.CurrentSlice = om.CurrentSlice + 1 log.Printf("First Update Step %d", om.CurrentSlice) log.Printf("%v", msgT) case api.CmdOtaPayload: msgT, err := uart.ParseFrameOtaPayload(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) return } // Send Next Payload until there is no more then send end package log.Printf("msgT %v", msgT) if msgT.Error != 0x00 { log.Printf("Error in Sending Update! Check ESP Log") return } log.Printf("NEXT PAYLOAD") if om.CurrentSlice == uint16(len(om.Update)) { log.Printf("LAST PAYLOAD SEND ENDING") om.Com.Send(api.CmdOtaEnd, make([]byte, 1)) return } err = om.Com.Send(api.CmdOtaPayload, om.Update[om.CurrentSlice]) if err != nil { log.Printf("Error Sending Update Step!: %v", err) return } om.CurrentSlice = om.CurrentSlice + 1 log.Printf("UPDATE CURRENT SLICE %d/%d", om.CurrentSlice, len(om.Update)) log.Printf("UPDATE Part/WriteIndex %d/%d", msgT.SequenzCounter, msgT.WriteIndex) log.Printf("Progress: %05.2f%%", (float32(om.CurrentSlice)/float32(len(om.Update)))*100) case api.CmdOtaStatus: v, err := uart.ParseFrameOtaStatus(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) return } log.Printf("%v", v) // Update State Machine case api.CmdOtaEnd: msgT, err := uart.ParseFrameOtaEnd(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) return } // End bestätigung om.EndTime = time.Now() duration := om.EndTime.Sub(om.StartTime) log.Printf("Partition %d Update done in %f.2s!", om.Partition, duration.Seconds()) log.Printf("%v", msgT) case api.CmdOtaStartEspNow: v, err := uart.ParseFrameOtaStartEspNow(val) if err != nil { log.Printf("Could not Parse Client Input %v", err) return } //bus.Publish(api.TopicOTA, v) log.Printf("%v", v) } }