resolved: activating/deactivating peripherals

This commit is contained in:
2025-11-01 12:23:22 +01:00
parent cb5c5b688e
commit abcc3e0b5e
17 changed files with 559 additions and 1904 deletions

View File

@@ -3,12 +3,13 @@ package hardware
import (
"context"
_ "embed"
"io"
"sync"
"unsafe"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
/*
@@ -19,14 +20,11 @@ import "C"
// FTDIPeripheral contains the data of an FTDI peripheral
type FTDIPeripheral struct {
info PeripheralInfo // The peripheral basic data
settings map[string]interface{} // The settings of the peripheral
dmxDevice unsafe.Pointer // The command object for piloting the DMX ouptut
stdin io.WriteCloser // For writing in the DMX sender
stdout io.ReadCloser // For reading from the DMX sender
stderr io.ReadCloser // For reading the errors
disconnectChan chan struct{} // Channel to cancel the connection
errorsChan chan error // Channel to get the errors
info PeripheralInfo // The peripheral basic data
settings map[string]interface{} // The settings of the peripheral
dmxSender unsafe.Pointer // The command object for piloting the DMX ouptut
waitGroup sync.WaitGroup // Waitgroup to wait goroutines
isConnected bool // If the FTDI is connected or not
}
// NewFTDIPeripheral creates a new FTDI peripheral
@@ -34,57 +32,83 @@ 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{
info: info,
dmxDevice: C.dmx_create(),
settings: settings,
disconnectChan: make(chan struct{}),
errorsChan: make(chan error, 1),
info: info,
dmxSender: nil,
settings: settings,
isConnected: false,
}, nil
}
// Connect connects the FTDI peripheral
func (p *FTDIPeripheral) Connect(ctx context.Context, location int) error {
func (p *FTDIPeripheral) Connect(ctx context.Context) error {
runtime.EventsEmit(ctx, string(PeripheralStatus), p.info, "connecting")
// Check if the device has already been created
if p.dmxDevice == nil {
return errors.Errorf("the DMX device has not been created!")
if p.dmxSender != nil {
return errors.Errorf("the DMX device has already been created!")
}
// Create the DMX sender
p.dmxSender = C.dmx_create()
// Connect the peripheral
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("connecting FTDI peripheral...")
err := C.dmx_connect(p.dmxDevice)
if err {
log.Error().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("unable to connect the DMX device")
err := C.dmx_connect(p.dmxSender, C.CString(p.info.SerialNumber))
if err != C.DMX_OK {
log.Error().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Any("err", err).Msg("unable to connect the DMX device")
return errors.Errorf("Unable to connect the DMX Device on the specified port")
}
//TODO: Destroy the object when context is done to avoid memory loss
p.waitGroup.Add(1)
go func() {
defer p.waitGroup.Done()
<-ctx.Done()
p.Disconnect(ctx)
}()
p.isConnected = true
runtime.EventsEmit(ctx, string(PeripheralStatus), p.info, "deactivated")
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("DMX device connected successfully")
return nil
}
// Disconnect disconnects the FTDI peripheral
func (p *FTDIPeripheral) Disconnect() error {
func (p *FTDIPeripheral) Disconnect(ctx context.Context) error {
// Check if the device has already been created
if p.dmxDevice == nil {
return errors.Errorf("the DMX device has not been created!")
if p.dmxSender == nil {
return errors.Errorf("the DMX device has not been connected!")
}
//TODO: What actions for disconnecting the DMX device?
// Destroy the dmx sender
C.dmx_destroy(p.dmxSender)
p.isConnected = false
return nil
}
// IsConnected returns if the FTDI is connected or not
func (p *FTDIPeripheral) IsConnected() bool {
return p.isConnected
}
// Activate activates the FTDI peripheral
func (p *FTDIPeripheral) Activate(ctx context.Context) error {
// Check if the device has already been created
if p.dmxDevice == nil {
return errors.Errorf("the DMX device has not been created!")
if p.dmxSender == nil {
return errors.Errorf("the DMX sender has not been created!")
}
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("activating FTDI peripheral...")
C.dmx_activate(p.dmxDevice)
err := C.dmx_activate(p.dmxSender)
if err != C.DMX_OK {
return errors.Errorf("unable to activate the DMX sender!")
}
C.dmx_setValue(p.dmxSender, C.uint16_t(1), C.uint8_t(255))
C.dmx_setValue(p.dmxSender, C.uint16_t(5), C.uint8_t(255))
runtime.EventsEmit(ctx, string(PeripheralStatus), p.info, "activated")
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("DMX device activated successfully")
@@ -94,13 +118,16 @@ func (p *FTDIPeripheral) Activate(ctx context.Context) error {
// Deactivate deactivates the FTDI peripheral
func (p *FTDIPeripheral) Deactivate(ctx context.Context) error {
// Check if the device has already been created
if p.dmxDevice == nil {
if p.dmxSender == nil {
return errors.Errorf("the DMX device has not been created!")
}
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("deactivating FTDI peripheral...")
C.dmx_deactivate(p.dmxDevice)
err := C.dmx_deactivate(p.dmxSender)
if err != C.DMX_OK {
return errors.Errorf("unable to deactivate the DMX sender!")
}
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("DMX device deactivated successfully")
@@ -116,13 +143,16 @@ func (p *FTDIPeripheral) SetSettings(settings map[string]interface{}) error {
// SetDeviceProperty sends a command to the specified device
func (p *FTDIPeripheral) SetDeviceProperty(ctx context.Context, channelNumber uint32, channelValue byte) error {
// Check if the device has already been created
if p.dmxDevice == nil {
if p.dmxSender == nil {
return errors.Errorf("the DMX device has not been created!")
}
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("setting device property on FTDI peripheral...")
C.dmx_setValue(p.dmxDevice, C.int(channelNumber), C.int(channelValue))
err := C.dmx_setValue(p.dmxSender, C.uint16_t(channelNumber), C.uint8_t(channelValue))
if err != C.DMX_OK {
return errors.Errorf("unable to update the channel value!")
}
log.Trace().Str("file", "FTDIPeripheral").Str("s/n", p.info.SerialNumber).Msg("device property set on FTDI peripheral successfully")