generated from thinkode/modelRepository
11-hardware-definition #17
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,4 +8,5 @@ frontend/wailsjs
|
||||
*/package.json.md5
|
||||
*.exe
|
||||
*.o
|
||||
*.rc
|
||||
*.rc
|
||||
frontend/public
|
||||
130
app.go
130
app.go
@@ -10,6 +10,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
|
||||
@@ -27,6 +28,8 @@ type App struct {
|
||||
ctx context.Context
|
||||
hardwareManager *hardware.HardwareManager // For managing all the hardware
|
||||
wmiMutex sync.Mutex // Avoid some WMI operations at the same time
|
||||
projectInfo ProjectInfo // The project information structure
|
||||
projectSave string // The file name of the project
|
||||
// FOR TESTING PURPOSE ONLY
|
||||
ftdi *hardware.FTDIPeripheral
|
||||
}
|
||||
@@ -39,6 +42,7 @@ func NewApp() *App {
|
||||
hardwareManager.RegisterFinder(hardware.NewFTDIFinder())
|
||||
return &App{
|
||||
hardwareManager: hardwareManager,
|
||||
projectSave: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,14 +57,27 @@ func (a *App) startup(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// CreateProject creates a new blank project
|
||||
func (a *App) CreateProject() ShowInfo {
|
||||
date := time.Now()
|
||||
a.projectSave = ""
|
||||
a.projectInfo.ShowInfo = ShowInfo{
|
||||
Name: "My new show",
|
||||
Date: fmt.Sprintf("%04d-%02d-%02dT%02d:%02d", date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute()),
|
||||
Avatar: "appicon.png",
|
||||
Comments: "Write your comments here",
|
||||
}
|
||||
return a.projectInfo.ShowInfo
|
||||
}
|
||||
|
||||
// GetPeripherals gets all the peripherals connected
|
||||
func (a *App) GetPeripherals() {
|
||||
a.hardwareManager.Scan(a.ctx)
|
||||
func (a *App) GetPeripherals() error {
|
||||
return a.hardwareManager.Scan(a.ctx)
|
||||
}
|
||||
|
||||
// GetProjects gets all the projects in the projects directory
|
||||
func (a *App) GetProjects() ([]ProjectInfo, error) {
|
||||
projects := []ProjectInfo{}
|
||||
func (a *App) GetProjects() ([]ProjectMetaData, error) {
|
||||
projects := []ProjectMetaData{}
|
||||
|
||||
f, err := os.Open(projectsDirectory)
|
||||
if err != nil {
|
||||
@@ -82,8 +99,10 @@ func (a *App) GetProjects() ([]ProjectInfo, error) {
|
||||
err = yaml.Unmarshal(fileData, &projectObject)
|
||||
if err == nil {
|
||||
// Add the SaveFile property
|
||||
projectObject.ShowInfo.SaveFile = fileInfo.Name()
|
||||
projects = append(projects, projectObject)
|
||||
projects = append(projects, ProjectMetaData{
|
||||
Name: projectObject.ShowInfo.Name,
|
||||
Save: fileInfo.Name(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,23 +110,23 @@ func (a *App) GetProjects() ([]ProjectInfo, error) {
|
||||
}
|
||||
|
||||
// GetProjectInfo returns the information of the saved project
|
||||
func (a *App) GetProjectInfo(projectFile string) (ShowInfo, error) {
|
||||
func (a *App) GetProjectInfo(projectFile string) (ProjectInfo, error) {
|
||||
// Open the project file
|
||||
projectPath := filepath.Join(projectsDirectory, projectFile)
|
||||
content, err := os.ReadFile(projectPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to read the project file: %v", err)
|
||||
return ShowInfo{}, err
|
||||
return ProjectInfo{}, err
|
||||
}
|
||||
|
||||
projectInfo := ProjectInfo{}
|
||||
|
||||
err = yaml.Unmarshal(content, &projectInfo)
|
||||
err = yaml.Unmarshal(content, &a.projectInfo)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to get the project information: %v", err)
|
||||
return ShowInfo{}, err
|
||||
return ProjectInfo{}, err
|
||||
}
|
||||
projectInfo.ShowInfo.SaveFile = projectFile
|
||||
return projectInfo.ShowInfo, nil
|
||||
// Load it into the app
|
||||
a.projectSave = projectFile
|
||||
// Return the show information
|
||||
return a.projectInfo, nil
|
||||
}
|
||||
|
||||
// ChooseAvatarPath opens a filedialog to choose the show avatar
|
||||
@@ -134,40 +153,85 @@ func (a *App) ChooseAvatarPath() (string, error) {
|
||||
return filepath.Base(filePath), nil
|
||||
}
|
||||
|
||||
// UpdateShowInfo updates the show information
|
||||
func (a *App) UpdateShowInfo(showInfo ShowInfo) {
|
||||
fmt.Printf("%s\n", showInfo)
|
||||
a.projectInfo.ShowInfo = showInfo
|
||||
}
|
||||
|
||||
// AddPeripheral adds a peripheral to the project
|
||||
func (a *App) AddPeripheral(protocolName string, peripheralID string) error {
|
||||
// Get the device from its finder
|
||||
p, found := a.hardwareManager.GetPeripheral(protocolName, peripheralID)
|
||||
if !found {
|
||||
return fmt.Errorf("Unable to localize the peripheral %s", peripheralID)
|
||||
}
|
||||
// Add the peripheral ID to the project
|
||||
a.projectInfo.PeripheralsInfo = append(a.projectInfo.PeripheralsInfo, p.GetInfo())
|
||||
// TODO: Connect the peripheral
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemovePeripheral adds a peripheral to the project
|
||||
func (a *App) RemovePeripheral(protocolName string, peripheralID string) error {
|
||||
// TODO: Disconnect the peripheral
|
||||
// Remove the peripheral ID from the project
|
||||
a.projectInfo.PeripheralsInfo = removePeripheralFromList(a.projectInfo.PeripheralsInfo, peripheralID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveProject saves the project
|
||||
func (a *App) SaveProject(showInfo ShowInfo) (string, error) {
|
||||
log.Printf("Saving the project %s to %s", showInfo.Name, showInfo.SaveFile)
|
||||
func (a *App) SaveProject() (string, error) {
|
||||
log.Printf("Saving the project %s to %s", a.projectInfo.ShowInfo.Name, a.projectSave)
|
||||
// If there is no save file, create a new one with the show name
|
||||
if showInfo.SaveFile == "" {
|
||||
showInfo.SaveFile = fmt.Sprintf("%s%s", formatString(showInfo.Name), projectExtension)
|
||||
if a.projectSave == "" {
|
||||
date := time.Now()
|
||||
a.projectSave = fmt.Sprintf("%04d%02d%02d%02d%02d%02d%s", date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), projectExtension)
|
||||
}
|
||||
project := ProjectInfo{}
|
||||
log.Printf("The number of universes: %d", showInfo.UniversesNumber)
|
||||
project.ShowInfo = showInfo
|
||||
data, err := yaml.Marshal(project)
|
||||
data, err := yaml.Marshal(a.projectInfo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = os.WriteFile(filepath.Join(projectsDirectory, showInfo.SaveFile), data, os.ModePerm)
|
||||
// Create the project directory if not exists
|
||||
err = os.MkdirAll(projectsDirectory, os.ModePerm)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return showInfo.SaveFile, nil
|
||||
err = os.WriteFile(filepath.Join(projectsDirectory, a.projectSave), data, os.ModePerm)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return a.projectSave, nil
|
||||
}
|
||||
|
||||
// ShowInfo defines the information of the show
|
||||
type ShowInfo struct {
|
||||
Name string `yaml:"name"`
|
||||
Date string `yaml:"date"`
|
||||
UniversesNumber int `yaml:"universesNumber"`
|
||||
Avatar string `yaml:"avatar"`
|
||||
Comments string `yaml:"comments"`
|
||||
SaveFile string `yaml:"-"`
|
||||
Name string `yaml:"name"`
|
||||
Date string `yaml:"date"`
|
||||
Avatar string `yaml:"avatar"`
|
||||
Comments string `yaml:"comments"`
|
||||
}
|
||||
|
||||
// ProjectMetaData defines all the minimum information for a lighting project
|
||||
type ProjectMetaData struct {
|
||||
Name string // Show name
|
||||
Save string // The save file of the project
|
||||
}
|
||||
|
||||
// ProjectInfo defines all the information for a lighting project
|
||||
type ProjectInfo struct {
|
||||
ShowInfo ShowInfo `yaml:"show"` // Show information
|
||||
ShowInfo ShowInfo `yaml:"show"` // Show information
|
||||
PeripheralsInfo []hardware.PeripheralInfo `yaml:"peripherals"` // Peripherals information
|
||||
}
|
||||
|
||||
func removePeripheralFromList(slice []hardware.PeripheralInfo, idToRemove string) []hardware.PeripheralInfo {
|
||||
result := []hardware.PeripheralInfo{}
|
||||
for _, peripheral := range slice {
|
||||
if peripheral.SerialNumber != idToRemove {
|
||||
result = append(result, peripheral)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func formatString(input string) string {
|
||||
@@ -208,7 +272,7 @@ func copy(src, dst string) (int64, error) {
|
||||
func (a *App) ConnectFTDI() error {
|
||||
// Create a new FTDI object
|
||||
var err error
|
||||
a.ftdi, err = hardware.NewFTDIPeripheral("FTDI TEST INTERFACE", "A50825I", 0)
|
||||
a.ftdi, err = hardware.NewFTDIPeripheral("FTDI TEST INTERFACE", "A50825I", 0, "Virtual FTDI finder")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -9,29 +9,30 @@
|
||||
import Show from './components/Show/Show.svelte';
|
||||
import GeneralConsole from './components/Console/GeneralConsole.svelte';
|
||||
import RoundIconButton from './components/General/RoundIconButton.svelte';
|
||||
import { currentProject, needProjectSave, peripherals } from './stores';
|
||||
import { showInformation, needProjectSave, availablePeripherals, savedPeripherals } from './stores';
|
||||
import { SaveProject } from '../wailsjs/go/main/App.js';
|
||||
import { construct_svelte_component } from 'svelte/internal';
|
||||
import { EventsOn } from '../wailsjs/runtime'
|
||||
import { GetPeripherals } from "../wailsjs/go/main/App";
|
||||
import { CreateProject, GetPeripherals } from "../wailsjs/go/main/App";
|
||||
import { WindowSetTitle } from "../wailsjs/runtime/runtime"
|
||||
|
||||
// When the list of hardware changed, update the store
|
||||
// Handle the event when a new peripheral is detected
|
||||
EventsOn('PERIPHERAL_ARRIVAL', function(peripheralInfo){
|
||||
console.log("Hardware has been added to the system");
|
||||
console.log(peripheralInfo)
|
||||
$peripherals = [...$peripherals, peripheralInfo];
|
||||
$availablePeripherals = [...$availablePeripherals, peripheralInfo];
|
||||
})
|
||||
|
||||
// Handle the event when a peripheral is removed from the system
|
||||
EventsOn('PERIPHERAL_REMOVAL', function(peripheralInfo){
|
||||
console.log("Hardware has been removed from the system");
|
||||
console.log(peripheralInfo)
|
||||
$peripherals = $peripherals.filter(item => JSON.stringify(item) !== JSON.stringify(peripheralInfo))
|
||||
console.log($peripherals)
|
||||
|
||||
// $peripherals = devicesList
|
||||
// console.log(devicesList)
|
||||
$availablePeripherals = $availablePeripherals.filter(item => JSON.stringify(item) !== JSON.stringify(peripheralInfo))
|
||||
})
|
||||
|
||||
// Set the window title
|
||||
$: {
|
||||
WindowSetTitle("DMXConnect - " + $showInformation.Name + ($needProjectSave ? " (unsaved)" : ""))
|
||||
}
|
||||
|
||||
let selectedMenu = "settings"
|
||||
// When the navigation menu changed, update the selected menu
|
||||
function onNavigationChanged(event){
|
||||
@@ -40,44 +41,41 @@
|
||||
|
||||
// Save the project
|
||||
function saveProject(){
|
||||
SaveProject($currentProject).then((saveFile) => {
|
||||
console.log($currentProject)
|
||||
$currentProject.SaveFile = saveFile
|
||||
SaveProject().then((filePath) => {
|
||||
needProjectSave.set(false)
|
||||
console.log("Project has been saved")
|
||||
console.log("Project has been saved to " + filePath)
|
||||
}).catch((error) => {
|
||||
console.error(`Unable to save the project: ${error}`)
|
||||
})
|
||||
}
|
||||
|
||||
function formatDate(date) {
|
||||
const pad = (number) => number.toString().padStart(2, '0');
|
||||
const year = date.getFullYear();
|
||||
const month = pad(date.getMonth() + 1); // Les mois commencent à 0
|
||||
const day = pad(date.getDate());
|
||||
const hours = pad(date.getHours());
|
||||
const minutes = pad(date.getMinutes());
|
||||
return `${year}-${month}-${day}T${hours}:${minutes}`;
|
||||
}
|
||||
|
||||
currentProject.set({
|
||||
Name: "My new show",
|
||||
Date: formatDate(new Date()),
|
||||
Avatar: "appicon.png",
|
||||
UniversesNumber: 1,
|
||||
Comments: "Write your comments here",
|
||||
SaveFile: "",
|
||||
});
|
||||
// Instanciate a new project
|
||||
CreateProject().then((showInfo) => {
|
||||
showInformation.set(showInfo)
|
||||
$needProjectSave = true
|
||||
})
|
||||
|
||||
// Request the list of peripherals
|
||||
// TODO: Handle the error here
|
||||
GetPeripherals()
|
||||
|
||||
// Handle window shortcuts
|
||||
document.addEventListener('keydown', function(event) {
|
||||
// Check the CTRL+S keys
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 's') {
|
||||
// Avoid the natural behaviour
|
||||
event.preventDefault();
|
||||
// Save the current project
|
||||
saveProject()
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<header>
|
||||
<NavigationBar on:navigationChanged="{onNavigationChanged}"/>
|
||||
{#if $needProjectSave}
|
||||
<RoundIconButton on:click={saveProject} icon="bx-save" width="2.5em" tooltip={$_("saveButtonTooltip")}></RoundIconButton>
|
||||
<RoundIconButton on:mouseup={saveProject} icon="bx-save" width="2.5em" tooltip={$_("saveButtonTooltip")}></RoundIconButton>
|
||||
{/if}
|
||||
<Clock/>
|
||||
</header>
|
||||
|
||||
@@ -15,21 +15,27 @@
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function handleInput(event){
|
||||
value = event.target.value
|
||||
dispatch('input', value)
|
||||
function handleInput(){
|
||||
dispatch('input')
|
||||
}
|
||||
|
||||
function handleBlur(event){
|
||||
dispatch('blur', event)
|
||||
}
|
||||
|
||||
function handleDblClick(){
|
||||
dispatch('dblclick')
|
||||
}
|
||||
</script>
|
||||
|
||||
<div style="width: {width}; height: {height};">
|
||||
<p style="color: {$colors.white};">{label}</p>
|
||||
<!-- Handle the textarea input -->
|
||||
{#if type === 'large'}
|
||||
<textarea style="background-color: {$colors.second}; color: {$colors.white};" placeholder={placeholder} value={value} on:input={handleInput}/>
|
||||
<textarea style="background-color: {$colors.second}; color: {$colors.white};" placeholder={placeholder} value={value} on:dblclick={handleDblClick} on:input={handleInput} on:blur={handleBlur}/>
|
||||
<!-- Handle the simple inputs -->
|
||||
{:else}
|
||||
<input style="background-color: {$colors.second}; color: {$colors.white};" type={type} min={min} max={max} src={src} alt={alt} value={value} placeholder={placeholder} on:input={handleInput}/>
|
||||
<input style="background-color: {$colors.second}; color: {$colors.white};" type={type} min={min} max={max} src={src} alt={alt} value={value} placeholder={placeholder} on:dblclick={handleDblClick} on:input={handleInput} on:blur={handleBlur}/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -48,14 +54,14 @@
|
||||
}
|
||||
|
||||
input::selection {
|
||||
background: #0F4C75; /* Couleur de fond de la sélection */
|
||||
color: #FFFFFF; /* Couleur du texte de la sélection */
|
||||
background: var(--first-color); /* Couleur de fond de la sélection */
|
||||
color: var(--white-color); /* Couleur du texte de la sélection */
|
||||
}
|
||||
|
||||
/* Pour Firefox */
|
||||
input::-moz-selection {
|
||||
background: #0F4C75; /* Couleur de fond de la sélection */
|
||||
color: #FFFFFF; /* Couleur du texte de la sélection */
|
||||
background: var(--first-color); /* Couleur de fond de la sélection */
|
||||
color: var(--white-color); /* Couleur du texte de la sélection */
|
||||
}
|
||||
input:focus {
|
||||
outline: 1px solid #BBE1FA;
|
||||
@@ -69,14 +75,14 @@
|
||||
}
|
||||
|
||||
textarea::selection {
|
||||
background: #0F4C75; /* Couleur de fond de la sélection */
|
||||
color: #FFFFFF; /* Couleur du texte de la sélection */
|
||||
background: var(--first-color); /* Couleur de fond de la sélection */
|
||||
color: var(--white-color); /* Couleur du texte de la sélection */
|
||||
}
|
||||
|
||||
/* Pour Firefox */
|
||||
textarea::-moz-selection {
|
||||
background: #0F4C75; /* Couleur de fond de la sélection */
|
||||
color: #FFFFFF; /* Couleur du texte de la sélection */
|
||||
background: var(--first-color); /* Couleur de fond de la sélection */
|
||||
color: var(--white-color); /* Couleur du texte de la sélection */
|
||||
}
|
||||
textarea:focus {
|
||||
outline: 1px solid #BBE1FA;
|
||||
|
||||
@@ -48,8 +48,11 @@
|
||||
|
||||
// Emit a click event when the button is clicked
|
||||
const dispatch = createEventDispatcher();
|
||||
function emitClick() {
|
||||
dispatch('click');
|
||||
function emitMouseDown() {
|
||||
dispatch('mousedown');
|
||||
}
|
||||
function emitMouseUp() {
|
||||
dispatch('mouseup');
|
||||
}
|
||||
|
||||
let tooltipPosition = {top: 0, left: 0}
|
||||
@@ -71,7 +74,8 @@
|
||||
<div class="container">
|
||||
<button bind:this={buttonRef}
|
||||
style="width:{width}; height:{width}; border-radius:{width}; background-color:{background}; color:{foreground};"
|
||||
on:mousedown={emitClick}
|
||||
on:mousedown={emitMouseDown}
|
||||
on:mouseup={emitMouseUp}
|
||||
on:mouseenter={() => { toggleTooltip(true) }}
|
||||
on:mouseleave={() => { toggleTooltip(false) }}>
|
||||
<i class='bx {icon}' style="font-size:100%;"></i>
|
||||
|
||||
@@ -29,10 +29,15 @@
|
||||
dispatch('click');
|
||||
}
|
||||
|
||||
function handleBlur(){
|
||||
dispatch('blur')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<button bind:this={buttonRef}
|
||||
on:blur={handleBlur}
|
||||
on:mousedown={emitClick}
|
||||
on:mouseenter={() => { toggleTooltip(true) }}
|
||||
on:mouseleave={() => { toggleTooltip(false) }}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
<style>
|
||||
.headerContainer{
|
||||
cursor: pointer;
|
||||
margin:0;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
@@ -25,16 +25,17 @@
|
||||
dispatch('add')
|
||||
}
|
||||
|
||||
let showOptions = false
|
||||
|
||||
function click(){
|
||||
showOptions = !showOptions
|
||||
dispatch('click')
|
||||
}
|
||||
|
||||
function dblclick(){
|
||||
dispatch('dblclick')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="card">
|
||||
<div class="card" on:dblclick={dblclick}>
|
||||
<div class="profile" on:mousedown={click} style="color: {disconnected ? $colors.first : $colors.white};">
|
||||
<div>
|
||||
<p>{#if disconnected}<i class='bx bx-no-signal' style="font-size:100%; color: var(--nok-color);"></i> {/if}{title}</p>
|
||||
@@ -53,9 +54,6 @@
|
||||
<InfoButton style="margin: 0.2em;" background={ signalized ? $colors.orange : $colors.first } icon='bx-pulse' hide={!signalizable}/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="options" style="display: {showOptions ? "block" : "none"};">
|
||||
<Input label={$_("projectCommentsLabel")} type='large' width='100%'/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -83,17 +81,6 @@
|
||||
.actions {
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
.options {
|
||||
color: var(--first-color);
|
||||
padding: 0.2em;
|
||||
margin-top: 0.2em;
|
||||
position: absolute;
|
||||
display:block;
|
||||
border-radius: 0.5em;
|
||||
max-width: 50;
|
||||
background-color: var(--fourth-color);
|
||||
text-align: left;
|
||||
}
|
||||
p{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import DeviceCard from "./DeviceCard.svelte";
|
||||
import Tab from "../General/Tab.svelte";
|
||||
import { _ } from 'svelte-i18n'
|
||||
import { peripherals } from "../../stores";
|
||||
import { ConnectFTDI, ActivateFTDI, DeactivateFTDI, DisconnectFTDI, SetDeviceFTDI } from "../../../wailsjs/go/main/App";
|
||||
import { availablePeripherals, needProjectSave, savedPeripherals } from "../../stores";
|
||||
import { RemovePeripheral, ConnectFTDI, ActivateFTDI, DeactivateFTDI, DisconnectFTDI, SetDeviceFTDI, AddPeripheral } from "../../../wailsjs/go/main/App";
|
||||
|
||||
function ftdiConnect(){
|
||||
ConnectFTDI().then(() =>
|
||||
@@ -47,45 +47,60 @@
|
||||
})
|
||||
}
|
||||
|
||||
// Add the peripheral to the project
|
||||
function addPeripheral(peripheral){
|
||||
// Add the peripheral to the project (backend)
|
||||
AddPeripheral(peripheral.ProtocolName, peripheral.SerialNumber).then(() => {
|
||||
$needProjectSave = true
|
||||
$savedPeripherals = [...$savedPeripherals, peripheral];
|
||||
}).catch((error) => {
|
||||
console.log("Unable to add the peripheral to the project: " + error)
|
||||
})
|
||||
}
|
||||
|
||||
// Remove the peripheral from the project
|
||||
function removePeripheral(peripheral) {
|
||||
// Delete the peripheral from the project (backend)
|
||||
RemovePeripheral(peripheral.ProtocolName, peripheral.SerialNumber).then(() => {
|
||||
$needProjectSave = true
|
||||
$savedPeripherals = $savedPeripherals.filter(item => JSON.stringify(item) !== JSON.stringify(peripheral))
|
||||
}).catch((error) => {
|
||||
console.log("Unable to remove the peripheral from the project: " + error)
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="hardware">
|
||||
<div style="padding: 0.5em;">
|
||||
<p style="margin-bottom: 1em;">Available devices</p>
|
||||
<p style="margin-bottom: 1em;">Available peripherals</p>
|
||||
<div class="availableHardware">
|
||||
<p style="color: var(--first-color);"><i class='bx bxs-plug'></i> Detected</p>
|
||||
{#each $peripherals as peripheral}
|
||||
<DeviceCard title={peripheral.Name == "" ? "Please wait..." : peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={peripheral.SerialNumber ? "S/N: " + peripheral.SerialNumber : ""} addable/>
|
||||
{/each}
|
||||
{#each $availablePeripherals as peripheral}
|
||||
<DeviceCard on:add={() => addPeripheral(peripheral)} on:dblclick={() => addPeripheral(peripheral)}
|
||||
title={peripheral.Name == "" ? "Please wait..." : peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={peripheral.SerialNumber ? "S/N: " + peripheral.SerialNumber : ""} addable={!peripheral.isAdded}/>
|
||||
{/each}
|
||||
<p style="color: var(--first-color);"><i class='bx bxs-network-chart' ></i> Others</p>
|
||||
<DeviceCard on:click={() => console.log("Edit the OS2L hardware")} title="OS2L device" type="OS2L" line1="Add to configure" addable on:delete={() => console.log("Delete the OS2L device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the OSC hardware")} title="OSC device" type="OSC" line1="Add to configure" addable on:delete={() => console.log("Delete the OSC device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
<DeviceCard on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:delete={() => console.log("Delete the ArtNet device")}/>
|
||||
|
||||
<DeviceCard disconnected on:click={() => console.log("Edit the OS2L hardware")} title="OS2L device" type="OS2L" line1="Add to configure" addable on:add={() => console.log("Add an OS2L device")}/>
|
||||
<DeviceCard disconnected on:click={() => console.log("Edit the OSC hardware")} title="OSC device" type="OSC" line1="Add to configure" addable on:add={() => console.log("Add an OSC device")}/>
|
||||
<DeviceCard disconnected on:click={() => console.log("Edit the ArtNet hardware")} title="ArtNet device" type="ArtNet" line1="Add to configure" addable on:add={() => console.log("Add an ArtNet device")}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 0.5em; flex:2; width:100%;">
|
||||
<p style="margin-bottom: 1em;">Project devices</p>
|
||||
<p style="margin-bottom: 1em;">Project peripherals</p>
|
||||
<div class="configuredHardware">
|
||||
<DeviceCard disconnected on:click={() => console.log("Edit the VDJ hardware")} title="Virtual DJ" type="OS2L" location="192.168.1.53" line1="Please update your OS2L client" removable signalizable on:delete={() => console.log("Delete the Virtual DJ device")}/>
|
||||
<DeviceCard disconnected title="Pioneer DDJ-FLX4" type="MIDI" location="COM14" line1="Version: 0-alpha-13.15" removable signalizable/>
|
||||
<DeviceCard title="Platformia LM730" type="OSC" location="192.168.1.418" line1="Please update your OSC client" removable signalizable/>
|
||||
{#if $savedPeripherals.length == 0}
|
||||
<i>Add peripherals from the left panel</i>
|
||||
{/if}
|
||||
{#each $savedPeripherals as peripheral}
|
||||
<DeviceCard on:delete={() => removePeripheral(peripheral)} on:dblclick={() => removePeripheral(peripheral)}
|
||||
title={peripheral.Name == "" ? "Please wait..." : peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={peripheral.SerialNumber ? "S/N: " + peripheral.SerialNumber : ""} removable signalizable/>
|
||||
{/each}
|
||||
</div>
|
||||
<p style="margin-bottom: 1em;">Device settings</p>
|
||||
<p style="margin-bottom: 1em;">Peripheral settings</p>
|
||||
<div>
|
||||
<p><i>Select a device to edit its settings</i></p>
|
||||
<p><i>Select a peripheral to edit its settings</i></p>
|
||||
<button on:click={ftdiConnect}>Connect FTDI 0</button>
|
||||
<button on:click={ftdiActivate}>Activate FTDI 0</button>
|
||||
<div class="slidecontainer">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang=ts>
|
||||
import { ChooseAvatarPath } from '../../../wailsjs/go/main/App.js';
|
||||
import { currentProject } from '../../stores.js';
|
||||
import { set_data_contenteditable } from 'svelte/internal';
|
||||
import { ChooseAvatarPath, UpdateShowInfo } from '../../../wailsjs/go/main/App.js';
|
||||
import { showInformation, needProjectSave } from '../../stores.js';
|
||||
import Input from "../General/Input.svelte";
|
||||
import RoundedButton from '../General/RoundedButton.svelte';
|
||||
import { _ } from 'svelte-i18n'
|
||||
@@ -8,41 +9,42 @@
|
||||
// Choose the avatar path
|
||||
function chooseAvatar(){
|
||||
ChooseAvatarPath().then((avatarPath) => {
|
||||
console.log(`Avatar path is ${avatarPath}`)
|
||||
$currentProject.Avatar = avatarPath
|
||||
$showInformation["Avatar"] = avatarPath
|
||||
UpdateShowInfo($showInformation).then(()=> {
|
||||
$needProjectSave = true
|
||||
})
|
||||
}).catch((error) => {
|
||||
console.error(`An error occured: ${error}`)
|
||||
})
|
||||
}
|
||||
|
||||
function updateUniverses(event) {
|
||||
currentProject.update(obj => {
|
||||
return {
|
||||
...obj,
|
||||
UniversesNumber: parseInt(event.detail, 10) // Conversion en entier
|
||||
};
|
||||
});
|
||||
function validate(field, value){
|
||||
$showInformation[field] = value
|
||||
console.log($showInformation)
|
||||
UpdateShowInfo($showInformation).then(()=> {
|
||||
$needProjectSave = true
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class='flexSettings'>
|
||||
<div>
|
||||
<Input bind:value={$currentProject.Name} label={$_("projectShowNameLabel")} type='text'/>
|
||||
<Input bind:value={$currentProject.Date} label={$_("projectShowDateLabel")} type='datetime-local'/>
|
||||
<Input bind:value={$currentProject.UniversesNumber} on:input={updateUniverses} label={$_("projectUniversesLabel")} type='number' min=1 max=10/>
|
||||
<Input on:blur={(event) => validate("Name", event.detail.target.value)} label={$_("projectShowNameLabel")} type='text' value={$showInformation.Name}/>
|
||||
<Input on:blur={(event) => validate("Date", event.detail.target.value)} label={$_("projectShowDateLabel")} type='datetime-local' value={$showInformation.Date}/>
|
||||
</div>
|
||||
<div>
|
||||
<Input bind:src={$currentProject.Avatar} label={$_("projectAvatarLabel")} type='image' alt={$_("projectAvatarLabel")} width='11em'/>
|
||||
<RoundedButton on:click={chooseAvatar} style='display:block;' tooltip={$_("projectAvatarTooltip")} text={$_("projectLoadAvatarButton")} icon='bxs-image' active/>
|
||||
</div>
|
||||
<div>
|
||||
<Input bind:value={$currentProject.Comments} label={$_("projectCommentsLabel")} type='large' width='100%'/>
|
||||
<Input on:dblclick={chooseAvatar} label={$_("projectAvatarLabel")} type='image' alt={$_("projectAvatarLabel")} width='11em' src={$showInformation.Avatar}/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Input on:blur={(event) => validate("Comments", event.detail.target.value)} label={$_("projectCommentsLabel")} type='large' width='100%' value={$showInformation.Comments}/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.flexSettings{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,11 @@
|
||||
<script lang=ts>
|
||||
import { projectsList, currentProject, needProjectSave } from '../../stores.js';
|
||||
import { projectsList, showInformation, needProjectSave, savedPeripherals } from '../../stores.js';
|
||||
import RoundedButton from "../General/RoundedButton.svelte";
|
||||
import ProjectPropertiesContent from "./ProjectPropertiesContent.svelte";
|
||||
import DropdownList from "../General/DropdownList.svelte";
|
||||
import InputsOutputsContent from "./InputsOutputsContent.svelte";
|
||||
import Tab from "../General/Tab.svelte";
|
||||
import { GetProjects, GetProjectInfo } from "../../../wailsjs/go/main/App";
|
||||
import { CreateProject, GetProjects, GetProjectInfo } from "../../../wailsjs/go/main/App";
|
||||
import { _ } from 'svelte-i18n'
|
||||
import {colors} from '../../stores.js';
|
||||
|
||||
@@ -14,14 +14,12 @@
|
||||
{ title: $_("projectInputOutputTab"), icon: 'bxs-plug', tooltip: $_("projectInputOutputTooltip"), component: InputsOutputsContent },
|
||||
];
|
||||
|
||||
|
||||
// Refresh the projects list
|
||||
let choices = new Map()
|
||||
function loadProjectsList(){
|
||||
GetProjects().then((projects) => {
|
||||
choices = new Map(projects.map(item => [item.ShowInfo.SaveFile, item.ShowInfo.Name]));
|
||||
$projectsList = projects
|
||||
console.log(projectsList)
|
||||
choices = new Map(projects.map(item => [item.Save, item.Name]));
|
||||
$projectsList = projects
|
||||
}).catch((error) => {
|
||||
console.error(`Unable to get the projects list: ${error}`)
|
||||
})
|
||||
@@ -31,8 +29,10 @@
|
||||
let selectedOption = event.detail.key
|
||||
// Open the selected project
|
||||
GetProjectInfo(selectedOption).then((projectInfo) => {
|
||||
console.log(projectInfo)
|
||||
console.log("Project opened")
|
||||
$currentProject = projectInfo
|
||||
$showInformation = projectInfo.ShowInfo
|
||||
$savedPeripherals = projectInfo.PeripheralsInfo
|
||||
needProjectSave.set(false)
|
||||
}).catch((error) => {
|
||||
console.error(`Unable to open the project: ${error}`)
|
||||
@@ -40,24 +40,12 @@
|
||||
}
|
||||
|
||||
function initializeNewProject(){
|
||||
currentProject.set({
|
||||
Name: "My new show",
|
||||
Date: formatDate(new Date()),
|
||||
Avatar: "appicon.png",
|
||||
UniversesNumber: 1,
|
||||
Comments: "Write your comments here",
|
||||
SaveFile: "",
|
||||
});
|
||||
}
|
||||
|
||||
function formatDate(date) {
|
||||
const pad = (number) => number.toString().padStart(2, '0');
|
||||
const year = date.getFullYear();
|
||||
const month = pad(date.getMonth() + 1); // Les mois commencent à 0
|
||||
const day = pad(date.getDate());
|
||||
const hours = pad(date.getHours());
|
||||
const minutes = pad(date.getMinutes());
|
||||
return `${year}-${month}-${day}T${hours}:${minutes}`;
|
||||
// Instanciate a new project
|
||||
CreateProject().then((showInfo) => {
|
||||
$showInformation = showInfo
|
||||
$savedPeripherals = []
|
||||
$needProjectSave = true
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import App from './App.svelte';
|
||||
|
||||
import { WindowSetTitle } from "../wailsjs/runtime/runtime"
|
||||
|
||||
import {currentProject, needProjectSave} from './stores.js';
|
||||
import {showInformation, needProjectSave} from './stores.js';
|
||||
|
||||
// Load dictionaries
|
||||
import { addMessages, init } from 'svelte-i18n';
|
||||
@@ -24,28 +24,4 @@ const app = new App({
|
||||
target: document.body,
|
||||
});
|
||||
|
||||
// Set the initial title
|
||||
WindowSetTitle("DMXConnect")
|
||||
|
||||
// When the current project data is modified, pass it to unsaved and change the title
|
||||
let title;
|
||||
currentProject.subscribe(value => {
|
||||
needProjectSave.set(true)
|
||||
title = value.Name
|
||||
});
|
||||
|
||||
// If the project need to be saved, show the information in the title
|
||||
needProjectSave.subscribe(value => {
|
||||
if (value) {
|
||||
console.log(`<!> The current project need to be save`);
|
||||
WindowSetTitle("DMXConnect - " + title + " (unsaved)")
|
||||
} else {
|
||||
WindowSetTitle("DMXConnect - " + title)
|
||||
}
|
||||
})
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
|
||||
});
|
||||
|
||||
export default app;
|
||||
@@ -2,10 +2,10 @@ import { writable } from 'svelte/store';
|
||||
|
||||
// Projects management
|
||||
export let projectsList = writable([])
|
||||
export let needProjectSave = writable(true)
|
||||
|
||||
// Show settings
|
||||
export let currentProject = writable({})
|
||||
export let needProjectSave = writable(false)
|
||||
export let showInformation = writable({})
|
||||
|
||||
// Application colors
|
||||
export const colors = writable({
|
||||
@@ -25,4 +25,5 @@ export const secondSize = writable("14px")
|
||||
export const thirdSize = writable("20px")
|
||||
|
||||
// List of current hardware
|
||||
export let peripherals = writable([])
|
||||
export let availablePeripherals = writable([])
|
||||
export let savedPeripherals = writable([])
|
||||
@@ -40,7 +40,20 @@ func (f *FTDIFinder) Initialize() error {
|
||||
|
||||
// GetName returns the name of the finder
|
||||
func (f *FTDIFinder) GetName() string {
|
||||
return "FTDI Finder"
|
||||
return "FTDI"
|
||||
}
|
||||
|
||||
// GetPeripheral gets the peripheral that correspond to the specified ID
|
||||
func (f *FTDIFinder) GetPeripheral(peripheralID string) (Peripheral, bool) {
|
||||
// Return the specified peripheral
|
||||
peripheral := f.peripherals[peripheralID]
|
||||
if peripheral == nil {
|
||||
fmt.Println("Unable to get the peripheral in the finder")
|
||||
return nil, false
|
||||
}
|
||||
fmt.Println("Peripheral found in the finder")
|
||||
|
||||
return peripheral, true
|
||||
}
|
||||
|
||||
//go:embed third-party/ftdi/detectFTDI.exe
|
||||
@@ -100,7 +113,7 @@ func (f *FTDIFinder) Scan(ctx context.Context) error {
|
||||
location = -1
|
||||
}
|
||||
// Add the peripheral to the temporary list
|
||||
peripheral, err := NewFTDIPeripheral(deviceInfo[2], deviceInfo[1], location)
|
||||
peripheral, err := NewFTDIPeripheral(deviceInfo[2], deviceInfo[1], location, f.GetName())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to create the FTDI peripheral: %v", err)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ type FTDIPeripheral struct {
|
||||
serialNumber string // The S/N of the FTDI peripheral
|
||||
location int // The location of the peripheral
|
||||
universesNumber int // The number of DMX universes handled by this peripheral
|
||||
finderName string // The name of the parent finder
|
||||
programName string // The temp file name of the executable
|
||||
dmxSender *exec.Cmd // The command to pilot the DMX sender program
|
||||
stdin io.WriteCloser // For writing in the DMX sender
|
||||
@@ -37,7 +38,7 @@ type FTDIPeripheral struct {
|
||||
}
|
||||
|
||||
// NewFTDIPeripheral creates a new FTDI peripheral
|
||||
func NewFTDIPeripheral(name string, serialNumber string, location int) (*FTDIPeripheral, error) {
|
||||
func NewFTDIPeripheral(name string, serialNumber string, location int, finderName string) (*FTDIPeripheral, error) {
|
||||
// Create a temporary file
|
||||
tempFile, err := os.CreateTemp("", "dmxSender*.exe")
|
||||
if err != nil {
|
||||
@@ -56,6 +57,7 @@ func NewFTDIPeripheral(name string, serialNumber string, location int) (*FTDIPer
|
||||
programName: tempFile.Name(),
|
||||
serialNumber: serialNumber,
|
||||
location: location,
|
||||
finderName: finderName,
|
||||
universesNumber: 1,
|
||||
disconnectChan: make(chan struct{}),
|
||||
errorsChan: make(chan error, 1),
|
||||
@@ -194,9 +196,8 @@ func (p *FTDIPeripheral) SetDeviceProperty(uint32, channelNumber uint32, channel
|
||||
// GetInfo gets all the peripheral information
|
||||
func (p *FTDIPeripheral) GetInfo() PeripheralInfo {
|
||||
return PeripheralInfo{
|
||||
Name: p.name,
|
||||
SerialNumber: p.serialNumber,
|
||||
ProtocolName: "FTDI",
|
||||
UniversesNumber: p.universesNumber,
|
||||
Name: p.name,
|
||||
SerialNumber: p.serialNumber,
|
||||
ProtocolName: "FTDI",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,16 @@ func (f *MIDIFinder) GetName() string {
|
||||
return "MIDI"
|
||||
}
|
||||
|
||||
// GetPeripheral gets the peripheral that correspond to the specified ID
|
||||
func (f *MIDIFinder) GetPeripheral(peripheralID string) (Peripheral, bool) {
|
||||
// Return the specified peripheral
|
||||
peripheral := f.peripherals[peripheralID]
|
||||
if peripheral == nil {
|
||||
return nil, false
|
||||
}
|
||||
return peripheral, true
|
||||
}
|
||||
|
||||
func splitStringAndNumber(input string) (string, int, error) {
|
||||
// Regular expression to match the text part and the number at the end
|
||||
re := regexp.MustCompile(`^(.*?)(\d+)$`)
|
||||
@@ -99,7 +109,7 @@ func (f *MIDIFinder) Scan(ctx context.Context) error {
|
||||
}
|
||||
fmt.Printf("New MIDI device found: %s on %i\n", name, location)
|
||||
// Add the peripheral to the temporary list
|
||||
midiPeripherals[portName] = NewMIDIPeripheral(name, location)
|
||||
midiPeripherals[portName] = NewMIDIPeripheral(name, location, f.GetName())
|
||||
}
|
||||
// Compare with the current peripherals to detect arrivals/removals
|
||||
removedList, addedList := comparePeripherals(f.peripherals, midiPeripherals)
|
||||
|
||||
@@ -2,15 +2,17 @@ package hardware
|
||||
|
||||
// MIDIPeripheral contains the data of a MIDI peripheral
|
||||
type MIDIPeripheral struct {
|
||||
name string // The name of the peripheral
|
||||
location int // The location of the peripheral
|
||||
name string // The name of the peripheral
|
||||
location int // The location of the peripheral
|
||||
finderName string // The name of the parent finder
|
||||
}
|
||||
|
||||
// NewMIDIPeripheral creates a new MIDI peripheral
|
||||
func NewMIDIPeripheral(name string, location int) *MIDIPeripheral {
|
||||
func NewMIDIPeripheral(name string, location int, finderName string) *MIDIPeripheral {
|
||||
return &MIDIPeripheral{
|
||||
name: name,
|
||||
location: location,
|
||||
name: name,
|
||||
location: location,
|
||||
finderName: finderName,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,16 +29,16 @@ var (
|
||||
|
||||
// HardwareManager is the class who manages the hardware
|
||||
type HardwareManager struct {
|
||||
finders []PeripheralFinder // The list of peripherals finders
|
||||
peripherals []Peripheral // The current list of peripherals
|
||||
deviceChangedEvent chan struct{} // The event when the devices list changed
|
||||
finders map[string]PeripheralFinder // The map of peripherals finders
|
||||
peripherals []Peripheral // The current list of peripherals
|
||||
deviceChangedEvent chan struct{} // The event when the devices list changed
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// NewHardwareManager creates a new HardwareManager
|
||||
func NewHardwareManager() *HardwareManager {
|
||||
return &HardwareManager{
|
||||
finders: make([]PeripheralFinder, 0),
|
||||
finders: make(map[string]PeripheralFinder),
|
||||
peripherals: make([]Peripheral, 0),
|
||||
deviceChangedEvent: make(chan struct{}),
|
||||
}
|
||||
@@ -120,10 +120,25 @@ func (h *HardwareManager) Start(ctx context.Context) error {
|
||||
|
||||
// RegisterFinder registers a new peripherals finder
|
||||
func (h *HardwareManager) RegisterFinder(finder PeripheralFinder) {
|
||||
h.finders = append(h.finders, finder)
|
||||
h.finders[finder.GetName()] = finder
|
||||
fmt.Printf("Success registered the %s finder\n", finder.GetName())
|
||||
}
|
||||
|
||||
// GetPeripheral gets the peripheral object from the parent finder
|
||||
func (h *HardwareManager) GetPeripheral(finderName string, peripheralID string) (Peripheral, bool) {
|
||||
// Get the parent finder
|
||||
parentFinder := h.finders[finderName]
|
||||
// If no finder found, return false
|
||||
if parentFinder == nil {
|
||||
fmt.Println("Unable to get the finder")
|
||||
return nil, false
|
||||
}
|
||||
fmt.Println("Finder ok, returning the peripheral")
|
||||
|
||||
// Contact the finder to get the device
|
||||
return parentFinder.GetPeripheral(peripheralID)
|
||||
}
|
||||
|
||||
// Scan scans all the peripherals for the registered finders
|
||||
func (h *HardwareManager) Scan(ctx context.Context) error {
|
||||
if len(h.finders) == 0 {
|
||||
|
||||
@@ -15,15 +15,16 @@ type Peripheral interface {
|
||||
|
||||
// PeripheralInfo represents a peripheral information
|
||||
type PeripheralInfo struct {
|
||||
Name string // Name of the peripheral
|
||||
SerialNumber string // S/N of the peripheral
|
||||
ProtocolName string // Protocol name of the peripheral
|
||||
UniversesNumber int // Number of DMX universes handled by the peripheral
|
||||
Name string `yaml:"name"` // Name of the peripheral
|
||||
SerialNumber string `yaml:"sn"` // S/N of the peripheral
|
||||
ProtocolName string `yaml:"protocol"` // Protocol name of the peripheral
|
||||
Settings []interface{} `yaml:"settings"` // Number of DMX universes handled by the peripheral
|
||||
}
|
||||
|
||||
// PeripheralFinder represents how compatible peripheral finders are implemented
|
||||
type PeripheralFinder interface {
|
||||
Initialize() error // Initializes the protocol
|
||||
GetName() string // Get the name of the finder
|
||||
Scan(context.Context) error // Scan for peripherals
|
||||
Initialize() error // Initializes the protocol
|
||||
GetName() string // Get the name of the finder
|
||||
GetPeripheral(string) (Peripheral, bool) // Get the peripheral
|
||||
Scan(context.Context) error // Scan for peripherals
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user