resolved disconnected hardware when it is detected

This commit is contained in:
2025-08-31 11:15:38 +02:00
parent 0db468bfef
commit bc15407cad
14 changed files with 96 additions and 80 deletions

View File

@@ -15,6 +15,7 @@ import (
"time"
"github.com/rs/zerolog/log"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
const (
@@ -54,10 +55,10 @@ func (f *FTDIFinder) RegisterPeripheral(ctx context.Context, peripheralData Peri
}
// UnregisterPeripheral unregisters an existing peripheral
func (f *FTDIFinder) UnregisterPeripheral(ctx context.Context, peripheralID string) error {
func (f *FTDIFinder) UnregisterPeripheral(peripheralID string) error {
peripheral, registered := f.registeredPeripherals[peripheralID]
if registered {
err := peripheral.Disconnect(ctx)
err := peripheral.Disconnect()
if err != nil {
return err
}
@@ -248,13 +249,22 @@ func (f *FTDIFinder) scanPeripherals(ctx context.Context) error {
ProtocolName: "FTDI",
}
// If this peripheral is already registered, connect it
// If this peripheral is already registered, connect it and activate it
peripheral, registered := f.registeredPeripherals[peripheralInfo[1]]
if registered {
runtime.EventsEmit(ctx, string(PeripheralStatus), peripheral.info, "connecting")
time.Sleep(2 * time.Second)
err := peripheral.Connect(ctx, location)
if err != nil {
log.Err(err).Str("file", "FTDIFinder").Str("peripheralSN", peripheralInfo[1]).Msg("unable to connect the peripheral")
}
runtime.EventsEmit(ctx, string(PeripheralStatus), peripheral.info, "deactivated")
time.Sleep(2 * time.Second)
err = peripheral.Activate(ctx)
if err != nil {
log.Err(err).Str("file", "FTDIFinder").Str("peripheralSN", peripheralInfo[1]).Msg("unable to activate the peripheral")
}
runtime.EventsEmit(ctx, string(PeripheralStatus), peripheral.info, "activated")
}
log.Trace().Any("periph", temporaryPeripherals).Str("file", "FTDIFinder").Str("peripheralName", peripheralInfo[2]).Msg("successfully added the FTDI peripheral to the finder")

View File

@@ -6,6 +6,7 @@ import (
_ "embed"
"fmt"
"io"
"path/filepath"
"github.com/rs/zerolog/log"
@@ -37,6 +38,7 @@ func NewFTDIPeripheral(info PeripheralInfo) (*FTDIPeripheral, error) {
log.Info().Str("file", "FTDIPeripheral").Str("name", info.Name).Str("s/n", info.SerialNumber).Msg("FTDI peripheral created")
settings := make(map[string]interface{})
return &FTDIPeripheral{
programName: filepath.Join(os.TempDir(), ftdiSenderExecutableName),
info: info,
dmxSender: nil,
settings: settings,
@@ -94,6 +96,10 @@ func (p *FTDIPeripheral) Connect(ctx context.Context, location int) error {
select {
case <-ctx.Done():
// If the context is canceled, handle it gracefully
err = p.Disconnect()
if err != nil {
log.Err(err).Str("file", "FTDIPeripheral").Msg("unable to disconnect the peripheral")
}
log.Warn().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("dmxSender was canceled by context")
return
default:
@@ -114,7 +120,7 @@ func (p *FTDIPeripheral) Connect(ctx context.Context, location int) error {
}
// Disconnect disconnects the FTDI peripheral
func (p *FTDIPeripheral) Disconnect(ctx context.Context) error {
func (p *FTDIPeripheral) Disconnect() error {
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("disconnecting FTDI peripheral...")
if p.dmxSender != nil {
log.Debug().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("dmxsender is defined for this FTDI")
@@ -174,10 +180,10 @@ func (p *FTDIPeripheral) SetSettings(settings map[string]interface{}) error {
}
// SetDeviceProperty sends a command to the specified device
func (p *FTDIPeripheral) SetDeviceProperty(ctx context.Context, uint32, channelNumber uint32, channelValue byte) error {
func (p *FTDIPeripheral) SetDeviceProperty(ctx context.Context, channelNumber uint32, channelValue byte) error {
if p.dmxSender != nil {
log.Debug().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("dmxsender is defined for this FTDI")
commandString := []byte{0x03, 0x01, 0x00, 0xff, 0x03, 0x02, 0x00, channelValue}
commandString := []byte{0x03, byte(channelNumber & 0xFF), byte((channelNumber >> 8) & 0xFF), channelValue}
_, err := io.WriteString(p.stdin, string(commandString))
if err != nil {
log.Err(err).Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("unable to write command to sender")

View File

@@ -48,10 +48,10 @@ func (f *MIDIFinder) RegisterPeripheral(ctx context.Context, peripheralData Peri
}
// UnregisterPeripheral unregisters an existing peripheral
func (f *MIDIFinder) UnregisterPeripheral(ctx context.Context, peripheralID string) error {
func (f *MIDIFinder) UnregisterPeripheral(peripheralID string) error {
peripheral, registered := f.registeredPeripherals[peripheralID]
if registered {
err := peripheral.Disconnect(ctx)
err := peripheral.Disconnect()
if err != nil {
return err
}

View File

@@ -28,7 +28,7 @@ func (p *MIDIPeripheral) Connect(ctx context.Context) error {
}
// Disconnect disconnects the MIDI peripheral
func (p *MIDIPeripheral) Disconnect(ctx context.Context) error {
func (p *MIDIPeripheral) Disconnect() error {
return nil
}

View File

@@ -38,26 +38,27 @@ func (f *OS2LFinder) RegisterPeripheral(ctx context.Context, peripheralData Peri
if err != nil {
return "", fmt.Errorf("unable to create the OS2L peripheral: %v", err)
}
// Connect this peripheral
err = os2lPeripheral.Connect(ctx)
if err != nil {
return "", err
}
f.registeredPeripherals[peripheralData.SerialNumber] = *os2lPeripheral
log.Trace().Any("periph", &os2lPeripheral).Str("file", "OS2LFinder").Str("peripheralName", peripheralData.Name).Msg("OS2L peripheral has been created")
// Send the change to the front
// runtime.EventsEmit(ctx, string(PeripheralArrival), peripheralData)
return peripheralData.SerialNumber, nil
}
// UnregisterPeripheral unregisters an existing peripheral
func (f *OS2LFinder) UnregisterPeripheral(ctx context.Context, peripheralID string) error {
func (f *OS2LFinder) UnregisterPeripheral(peripheralID string) error {
peripheral, registered := f.registeredPeripherals[peripheralID]
if registered {
err := peripheral.Disconnect(ctx)
err := peripheral.Disconnect()
if err != nil {
return err
}
}
delete(f.registeredPeripherals, peripheralID)
// Send the change to the front
// runtime.EventsEmit(ctx, string(PeripheralRemoval), peripheral.GetInfo())
return nil
}
@@ -71,10 +72,10 @@ func (f *OS2LFinder) GetPeripheralSettings(peripheralID string) (map[string]inte
// Return the specified peripheral
peripheral, found := f.registeredPeripherals[peripheralID]
if !found {
log.Error().Str("file", "OS2LFinder").Str("peripheralID", peripheralID).Msg("unable to get this peripheral from the FTDI finder")
log.Error().Str("file", "OS2LFinder").Str("peripheralID", peripheralID).Msg("unable to get this peripheral from the OS2L finder")
return nil, fmt.Errorf("unable to found the peripheral")
}
log.Debug().Str("file", "OS2LFinder").Str("peripheralID", peripheralID).Msg("peripheral found by the FTDI finder")
log.Debug().Str("file", "OS2LFinder").Str("peripheralID", peripheralID).Msg("peripheral found by the OS2L finder")
return peripheral.GetSettings(), nil
}

View File

@@ -3,8 +3,10 @@ package hardware
import (
"context"
"fmt"
"time"
"github.com/rs/zerolog/log"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
// OS2LPeripheral contains the data of an OS2L peripheral
@@ -27,11 +29,16 @@ func NewOS2LPeripheral(peripheralData PeripheralInfo) (*OS2LPeripheral, error) {
// Connect connects the MIDI peripheral
func (p *OS2LPeripheral) Connect(ctx context.Context) error {
log.Info().Str("file", "OS2LPeripheral").Msg("OS2L peripheral connected")
go func() {
runtime.EventsEmit(ctx, string(PeripheralStatus), p.info, "connecting")
time.Sleep(5 * time.Second)
runtime.EventsEmit(ctx, string(PeripheralStatus), p.info, "disconnected")
}()
return nil
}
// Disconnect disconnects the MIDI peripheral
func (p *OS2LPeripheral) Disconnect(ctx context.Context) error {
func (p *OS2LPeripheral) Disconnect() error {
log.Info().Str("file", "OS2LPeripheral").Msg("OS2L peripheral disconnected")
return nil
}

View File

@@ -19,6 +19,8 @@ const (
PeripheralArrival PeripheralEvent = "PERIPHERAL_ARRIVAL"
// PeripheralRemoval is triggered when a peripheral has been disconnected from the system
PeripheralRemoval PeripheralEvent = "PERIPHERAL_REMOVAL"
// PeripheralStatus is triggered when a peripheral status has been updated (disconnected - connecting - connected)
PeripheralStatus PeripheralEvent = "PERIPHERAL_STATUS"
// debounceDuration = 500 * time.Millisecond
)

View File

@@ -4,12 +4,12 @@ import "context"
// Peripheral represents the methods used to manage a peripheral (input or output hardware)
type Peripheral interface {
Connect(context.Context) error // Connect the peripheral
Disconnect(context.Context) error // Disconnect the peripheral
Activate(context.Context) error // Activate the peripheral
Deactivate(context.Context) error // Deactivate the peripheral
SetSettings(map[string]interface{}) error // Set a peripheral setting
SetDeviceProperty(context.Context, uint32, uint32, byte) error // Update a device property
Connect(context.Context) error // Connect the peripheral
Disconnect() error // Disconnect the peripheral
Activate(context.Context) error // Activate the peripheral
Deactivate(context.Context) error // Deactivate the peripheral
SetSettings(map[string]interface{}) error // Set a peripheral setting
SetDeviceProperty(context.Context, uint32, byte) error // Update a device property
GetInfo() PeripheralInfo // Get the peripheral information
GetSettings() map[string]interface{} // Get the peripheral settings
@@ -30,7 +30,7 @@ type PeripheralFinder interface {
Stop() error // Stop the detection
ForceScan() // Explicitly scans for peripherals
RegisterPeripheral(context.Context, PeripheralInfo) (string, error) // Registers a new peripheral data
UnregisterPeripheral(context.Context, string) error // Unregisters an existing peripheral
UnregisterPeripheral(string) error // Unregisters an existing peripheral
GetPeripheralSettings(string) (map[string]interface{}, error) // Gets the peripheral settings
SetPeripheralSettings(string, map[string]interface{}) error // Sets the peripheral settings
GetName() string // Get the name of the finder