diff --git a/frontend/src/components/Settings/DeviceCard.svelte b/frontend/src/components/Settings/DeviceCard.svelte index 8c72cb1..a9620ee 100644 --- a/frontend/src/components/Settings/DeviceCard.svelte +++ b/frontend/src/components/Settings/DeviceCard.svelte @@ -53,7 +53,7 @@
- +
diff --git a/frontend/src/components/Settings/InputsOutputsContent.svelte b/frontend/src/components/Settings/InputsOutputsContent.svelte index 403ac56..2da0fe1 100644 --- a/frontend/src/components/Settings/InputsOutputsContent.svelte +++ b/frontend/src/components/Settings/InputsOutputsContent.svelte @@ -104,7 +104,7 @@ {#each Object.entries($peripherals) as [serialNumber, peripheral]} {#if peripheral.isSaved} removePeripheral(peripheral)} on:dblclick={() => removePeripheral(peripheral)} on:click={() => selectPeripheral(peripheral)} - title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={peripheral.SerialNumber ? "S/N: " + peripheral.SerialNumber : ""} selected={serialNumber == selectedPeripheralSN} removable signalizable/> + title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={peripheral.SerialNumber ? "S/N: " + peripheral.SerialNumber : ""} selected={serialNumber == selectedPeripheralSN} removable signalizable signalized={peripheral.eventEmitted}/> {/if} {/each} {:else} diff --git a/frontend/src/runtime-events.js b/frontend/src/runtime-events.js index 59a290b..d509a83 100644 --- a/frontend/src/runtime-events.js +++ b/frontend/src/runtime-events.js @@ -120,6 +120,32 @@ function unloadPeripheral (peripheralInfo) { needProjectSave.set(true) } +// A peripheral event has been emitted +function onPeripheralEvent(sn, event) { + // If not exists, add it to the map + // eventEmitted key to true for 0.2 sec + + peripherals.update((storedPeripherals) => { + return { + ...storedPeripherals, + [sn]: { + ...storedPeripherals[sn], + eventEmitted: true + }, + }}) + + setTimeout(() => { + peripherals.update((storedPeripherals) => { + return { + ...storedPeripherals, + [sn]: { + ...storedPeripherals[sn], + eventEmitted: false + }, + }}) + }, 200); +} + let initialized = false export function initRuntimeEvents(){ @@ -143,6 +169,9 @@ export function initRuntimeEvents(){ // Handle a peripheral unloaded from the project EventsOn('UNLOAD_PERIPHERAL', unloadPeripheral) + + // Handle a peripheral event + EventsOn('PERIPHERAL_EVENT_EMITTED', onPeripheralEvent) } export function destroyRuntimeEvents(){ @@ -166,4 +195,7 @@ export function destroyRuntimeEvents(){ // Handle a peripheral unloaded from the project EventsOff('UNLOAD_PERIPHERAL') + + // Handle a peripheral event + EventsOff('PERIPHERAL_EVENT_EMITTED') } \ No newline at end of file diff --git a/frontend/src/stores.js b/frontend/src/stores.js index 02aeb53..984a346 100644 --- a/frontend/src/stores.js +++ b/frontend/src/stores.js @@ -45,4 +45,5 @@ export let peripherals = writable({}) // isSaved // if the peripheral is saved in the project // isDetected // if the peripheral is detected by the system -// status // the status of connection \ No newline at end of file +// status // the status of connection +// eventEmitted // if an event has been emitted for this peripheral (disappear after a delay) \ No newline at end of file diff --git a/hardware/OS2LFinder.go b/hardware/OS2LFinder.go index 8974ac3..16b65c5 100644 --- a/hardware/OS2LFinder.go +++ b/hardware/OS2LFinder.go @@ -57,10 +57,16 @@ func (f *OS2LFinder) RegisterPeripheral(ctx context.Context, peripheralData Peri peripheralData.SerialNumber = strings.ToUpper(fmt.Sprintf("%08x", rand.Intn(1<<32))) } + // Create a new OS2L peripheral peripheral, err := NewOS2LPeripheral(peripheralData) if err != nil { return "", fmt.Errorf("unable to create the OS2L peripheral: %v", err) } + // Set the event callback + peripheral.SetEventCallback(func(event any) { + runtime.EventsEmit(ctx, string(PeripheralEventEmitted), peripheralData.SerialNumber, event) + }) + f.saved[peripheralData.SerialNumber] = peripheral log.Trace().Str("file", "OS2LFinder").Str("serialNumber", peripheralData.SerialNumber).Msg("OS2L peripheral created") diff --git a/hardware/OS2LPeripheral.go b/hardware/OS2LPeripheral.go index 2ab48cb..c67f971 100644 --- a/hardware/OS2LPeripheral.go +++ b/hardware/OS2LPeripheral.go @@ -24,25 +24,32 @@ type OS2LMessage struct { type OS2LPeripheral struct { wg sync.WaitGroup - info PeripheralInfo // The basic info for this peripheral - serverIP string // OS2L server IP - serverPort int // OS2L server port - + info PeripheralInfo // The basic info for this peripheral + serverIP string // OS2L server IP + serverPort int // OS2L server port listener net.Listener // Net listener (TCP) listenerCancel context.CancelFunc // Call this function to cancel the peripheral activation + + eventCallback func(any) // This callback is called for returning events } // NewOS2LPeripheral creates a new OS2L peripheral func NewOS2LPeripheral(peripheralData PeripheralInfo) (*OS2LPeripheral, error) { log.Trace().Str("file", "OS2LPeripheral").Str("name", peripheralData.Name).Str("s/n", peripheralData.SerialNumber).Msg("OS2L peripheral created") return &OS2LPeripheral{ - info: peripheralData, - serverIP: "127.0.0.1", - serverPort: 9995, - listener: nil, + info: peripheralData, + serverIP: "127.0.0.1", + serverPort: 9995, + listener: nil, + eventCallback: nil, }, nil } +// SetEventCallback sets the callback for returning events +func (p *OS2LPeripheral) SetEventCallback(eventCallback func(any)) { + p.eventCallback = eventCallback +} + // Connect connects the MIDI peripheral func (p *OS2LPeripheral) Connect(ctx context.Context) error { var err error @@ -56,14 +63,18 @@ func (p *OS2LPeripheral) Connect(ctx context.Context) error { return nil } -func handleMessage(raw []byte) error { +// handleMessage handles an OS2L message +func (p *OS2LPeripheral) handleMessage(raw []byte) error { message := OS2LMessage{} err := json.Unmarshal(raw, &message) if err != nil { return fmt.Errorf("Unable to parse the OS2L message: %w", err) } - // Display the message - fmt.Printf("Event: %s, Name: %s, State: %s, ID: %d, Param: %f\n", message.Event, message.Name, message.State, message.ID, message.Param) + log.Debug().Str("event", message.Event).Str("name", message.Name).Str("state", message.State).Int("ID", int(message.ID)).Float64("param", message.Param).Msg("OS2L event received") + // Return the event to the finder + if p.eventCallback != nil { + go p.eventCallback(message) + } return nil } @@ -135,7 +146,7 @@ func (p *OS2LPeripheral) Activate(ctx context.Context) error { return // autre erreur ou EOF } - handleMessage(buffer[:n]) + p.handleMessage(buffer[:n]) } } }(conn) diff --git a/hardware/hardware.go b/hardware/hardware.go index 466f4b4..81ba457 100644 --- a/hardware/hardware.go +++ b/hardware/hardware.go @@ -21,8 +21,10 @@ const ( PeripheralArrival PeripheralEvent = "PERIPHERAL_ARRIVAL" // PeripheralRemoval is triggered when a peripheral has been disconnected from the system PeripheralRemoval PeripheralEvent = "PERIPHERAL_REMOVAL" - // PeripheralStatusUpdated is triggered when a peripheral status has been updated (disconnected - connecting - connected) + // PeripheralStatusUpdated is triggered when a peripheral status has been updated (disconnected - connecting - deactivated - activated) PeripheralStatusUpdated PeripheralEvent = "PERIPHERAL_STATUS" + // PeripheralEventEmitted is triggered when a peripheral event is emitted + PeripheralEventEmitted PeripheralEvent = "PERIPHERAL_EVENT_EMITTED" // PeripheralStatusDisconnected : peripheral is now disconnected PeripheralStatusDisconnected PeripheralStatus = "PERIPHERAL_DISCONNECTED" // PeripheralStatusConnecting : peripheral is now connecting diff --git a/hardware/interfaces.go b/hardware/interfaces.go index e27d216..0b31397 100644 --- a/hardware/interfaces.go +++ b/hardware/interfaces.go @@ -5,6 +5,7 @@ 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 + SetEventCallback(func(any)) // Callback is called when an event is emitted from the peripheral Disconnect() error // Disconnect the peripheral Activate(context.Context) error // Activate the peripheral Deactivate(context.Context) error // Deactivate the peripheral