diff --git a/devices/cdashdisplay/display.go b/devices/cdashdisplay/display.go index dcb6489..7175bc2 100644 --- a/devices/cdashdisplay/display.go +++ b/devices/cdashdisplay/display.go @@ -12,6 +12,7 @@ import ( "time" helper "esdi/helpers" + "esdi/peripheral" "esdi/peripheral/communication" "esdi/peripheral/communication/packets" "esdi/peripheral/types" @@ -107,10 +108,12 @@ func NewCDashState() *CDashState { } type CDashDisplay struct { - WT *communication.WalkieTalkie - State *CDashState - fieldToWindows map[telemetry.FieldID][]int16 - bufPool sync.Pool + WT *communication.WalkieTalkie + State *CDashState + fieldToWindows map[telemetry.FieldID][]int16 + bufPool sync.Pool + failedSends int + FailedSendsConsecutiveLimit int } // Connect will try to find and connect to the CDashDisplay @@ -118,7 +121,7 @@ func NewCDashDisplay() (*CDashDisplay, error) { // Look for the port p, err := findDisplayPort() if err != nil { - slog.Info("failed to find cdashdisplay port: %s", err.Error()) + slog.Info("failed to find cdashdisplay port", "reason", err.Error()) return nil, err } @@ -132,6 +135,8 @@ func NewCDashDisplay() (*CDashDisplay, error) { return &b }, }, + failedSends: 0, + FailedSendsConsecutiveLimit: 5, }, nil } @@ -393,12 +398,12 @@ func (d *CDashDisplay) UnloadLayout() error { return nil } -func (d *CDashDisplay) SendData(data *telemetry.TelemetryData) { +func (d *CDashDisplay) SendData(data *telemetry.TelemetryData) error { packet := d.encodePacket(data) bytes, err := helper.StructToBytes(packet) if err != nil { - return + return peripheral.ErrFailureToPackData } curStr := "" @@ -408,7 +413,6 @@ func (d *CDashDisplay) SendData(data *telemetry.TelemetryData) { curStr += fmt.Sprintf("%02x ", byte) if byteCount == 8 { - // slog.Debug(curStr) curStr = "" byteCount = 0 } @@ -417,6 +421,11 @@ func (d *CDashDisplay) SendData(data *telemetry.TelemetryData) { // var ack packets.AckPacket err = d.WT.SendCommand(sendDataCMDID, bytes, nil) if err != nil && err != io.EOF { - return + if d.failedSends == d.FailedSendsConsecutiveLimit { + return peripheral.ErrDeviceTimedOut + } + d.failedSends++ } + + return nil } diff --git a/devices/uidevice/device.go b/devices/uidevice/device.go index c08fd85..4f0ac2e 100644 --- a/devices/uidevice/device.go +++ b/devices/uidevice/device.go @@ -17,9 +17,9 @@ func NewUIDevice() (peripheral.Peripheral, error) { }, nil } -func (uid *UIDevice) SendData(data *telemetry.TelemetryData) { +func (uid *UIDevice) SendData(data *telemetry.TelemetryData) error { if data == nil { - return + return peripheral.ErrInvalidData } select { @@ -27,6 +27,8 @@ func (uid *UIDevice) SendData(data *telemetry.TelemetryData) { default: // Drop frame if buffer is full } + + return nil } func (uid *UIDevice) Name() string { diff --git a/peripheral/errors.go b/peripheral/errors.go new file mode 100644 index 0000000..c2674ba --- /dev/null +++ b/peripheral/errors.go @@ -0,0 +1,9 @@ +package peripheral + +import "errors" + +var ( + ErrInvalidData = errors.New("invalid data") + ErrDeviceTimedOut = errors.New("device timed out") + ErrFailureToPackData = errors.New("failed to pack received data") +) diff --git a/peripheral/peripheral.go b/peripheral/peripheral.go index f7b31e5..21379af 100644 --- a/peripheral/peripheral.go +++ b/peripheral/peripheral.go @@ -17,7 +17,7 @@ const ( type Peripheral interface { Name() string - SendData(*telemetry.TelemetryData) + SendData(*telemetry.TelemetryData) error RequiredFields() []telemetry.FieldID } diff --git a/services/devices.go b/services/devices.go index 714025d..8ea1a3c 100644 --- a/services/devices.go +++ b/services/devices.go @@ -159,7 +159,11 @@ func (ds *DeviceService) transmit(ctx context.Context) { // the data locked ds.mu.RLock() for _, dev := range ds.Devices { - dev.SendData(&data) + err := dev.SendData(&data) + if err == peripheral.ErrDeviceTimedOut { + // What do we do here? + // TODO: somehow we need to handle reconnection + } } ds.mu.RUnlock()