187 lines
4.0 KiB
Go
187 lines
4.0 KiB
Go
package state
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"sync"
|
|
|
|
"alox.tool/api"
|
|
"alox.tool/eventbus"
|
|
"alox.tool/uart"
|
|
)
|
|
|
|
type ESPStateHandler struct {
|
|
RWMutex sync.RWMutex
|
|
Master MasterESP
|
|
}
|
|
|
|
type ESPVersion struct {
|
|
Version uint16
|
|
Buildhash [7]byte
|
|
}
|
|
|
|
type BaseESP struct {
|
|
ClientId byte
|
|
IsUpdating bool
|
|
UpdateProgress float32
|
|
Version ESPVersion
|
|
RunningPartition int
|
|
MAC [6]byte
|
|
}
|
|
|
|
type MasterESP struct {
|
|
BaseESP
|
|
Slaves map[byte]*SlaveESP
|
|
}
|
|
|
|
type SlaveESP struct {
|
|
BaseESP
|
|
SlotAvailable bool
|
|
SlotUsed bool
|
|
Bitmask uint32
|
|
LageX float32
|
|
LageY float32
|
|
LastPing uint32
|
|
LastSuccessfullPing uint32
|
|
}
|
|
|
|
func New() *ESPStateHandler {
|
|
return &ESPStateHandler{
|
|
RWMutex: sync.RWMutex{},
|
|
Master: NewMasterESP(),
|
|
}
|
|
}
|
|
|
|
func NewMasterESP() MasterESP {
|
|
return MasterESP{
|
|
BaseESP: BaseESP{
|
|
ClientId: 0,
|
|
IsUpdating: false,
|
|
UpdateProgress: 0,
|
|
Version: ESPVersion{
|
|
Version: 0,
|
|
Buildhash: [7]byte{},
|
|
},
|
|
RunningPartition: 0,
|
|
MAC: [6]byte{},
|
|
},
|
|
Slaves: map[byte]*SlaveESP{},
|
|
}
|
|
}
|
|
|
|
func NewSlaveESP() *SlaveESP {
|
|
return &SlaveESP{
|
|
BaseESP: BaseESP{
|
|
ClientId: 0,
|
|
IsUpdating: false,
|
|
UpdateProgress: 0,
|
|
Version: ESPVersion{
|
|
Version: 0,
|
|
Buildhash: [7]byte{},
|
|
},
|
|
RunningPartition: 0,
|
|
MAC: [6]byte{},
|
|
},
|
|
SlotAvailable: false,
|
|
SlotUsed: false,
|
|
Bitmask: 0,
|
|
LageX: 0,
|
|
LageY: 0,
|
|
LastPing: 0,
|
|
LastSuccessfullPing: 0,
|
|
}
|
|
}
|
|
|
|
func (s *ESPStateHandler) Start(ctx context.Context, bus eventbus.EventBus) {
|
|
go func() {
|
|
RXC := bus.Subscribe(api.TopicUARTRx)
|
|
defer bus.Unsubscribe(api.TopicUARTRx, RXC)
|
|
|
|
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)
|
|
s.processFrame(val)
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (s *ESPStateHandler) processFrame(val api.Frame) {
|
|
s.RWMutex.Lock()
|
|
defer s.RWMutex.Unlock()
|
|
|
|
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)
|
|
return
|
|
}
|
|
log.Printf("Version Info %d %s", v.Version, v.Buildhash)
|
|
|
|
// Update State
|
|
s.Master.Version.Version = v.Version
|
|
s.Master.Version.Buildhash = v.Buildhash
|
|
|
|
case api.CmdClientInfo:
|
|
v, err := uart.ParseFrameClientInfo(val)
|
|
if err != nil {
|
|
log.Printf("Could not Parse Client Info %v", err)
|
|
return
|
|
}
|
|
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)
|
|
|
|
_, ok := s.Master.Slaves[c.ClientID]
|
|
if !ok {
|
|
s.Master.Slaves[c.ClientID] = NewSlaveESP()
|
|
}
|
|
|
|
s.Master.Slaves[c.ClientID].SlotAvailable = c.IsAvailable != 0
|
|
s.Master.Slaves[c.ClientID].SlotUsed = c.SlotIsUsed != 0
|
|
s.Master.Slaves[c.ClientID].LastPing = c.LastPing
|
|
s.Master.Slaves[c.ClientID].LastSuccessfullPing = c.LastSuccessfulPing
|
|
s.Master.Slaves[c.ClientID].Version.Version = c.Version
|
|
s.Master.Slaves[c.ClientID].MAC = c.MACAddr
|
|
}
|
|
|
|
case api.CmdClientInput:
|
|
v, err := uart.ParseFrameClientInput(val)
|
|
if err != nil {
|
|
log.Printf("Could not Parse Client Input %v", err)
|
|
return
|
|
}
|
|
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)
|
|
|
|
_, ok := s.Master.Slaves[c.ClientID]
|
|
if !ok {
|
|
s.Master.Slaves[c.ClientID] = NewSlaveESP()
|
|
}
|
|
|
|
s.Master.Slaves[c.ClientID].LageX = c.X
|
|
s.Master.Slaves[c.ClientID].LageY = c.Y
|
|
s.Master.Slaves[c.ClientID].Bitmask = c.InputMask
|
|
}
|
|
}
|
|
}
|