diff --git a/plugins/usbdmx/EuroliteProFactory.cpp b/plugins/usbdmx/EuroliteProFactory.cpp index ce4a0b5e1..f79c81260 100644 --- a/plugins/usbdmx/EuroliteProFactory.cpp +++ b/plugins/usbdmx/EuroliteProFactory.cpp @@ -20,6 +20,8 @@ #include "plugins/usbdmx/EuroliteProFactory.h" +#include + #include "libs/usb/LibUsbAdaptor.h" #include "ola/Logging.h" #include "ola/base/Flags.h" @@ -46,12 +48,34 @@ const uint16_t EuroliteProFactory::VENDOR_ID_MK2 = 0x0403; const char EuroliteProFactory::ENABLE_EUROLITE_MK2_KEY[] = "enable_eurolite_mk2"; +const char EuroliteProFactory::EUROLITE_MK2_SERIAL_KEY[] = + "eurolite_mk2_serial"; EuroliteProFactory::EuroliteProFactory(ola::usb::LibUsbAdaptor *adaptor, Preferences *preferences) : BaseWidgetFactory("EuroliteProFactory"), m_adaptor(adaptor), m_enable_eurolite_mk2(IsEuroliteMk2Enabled(preferences)) { + const std::vector serials = + preferences->GetMultipleValue(EUROLITE_MK2_SERIAL_KEY); + // A single empty string is considered the same as specifying + // no serial numbers. This is useful as a default value. + const bool has_default_value = + serials.size() == 1 && serials[0].empty(); + if (!has_default_value) { + for (std::vector::const_iterator iter = serials.begin(); + iter != serials.end(); ++iter) { + if (iter->empty()) { + OLA_WARN << EUROLITE_MK2_SERIAL_KEY + << " requires a serial number, but it is empty."; + } else if (STLContains(m_expected_eurolite_mk2_serials, *iter)) { + OLA_WARN << EUROLITE_MK2_SERIAL_KEY << " lists serial " + << *iter << " more than once."; + } else { + m_expected_eurolite_mk2_serials.insert(*iter); + } + } + } } bool EuroliteProFactory::IsEuroliteMk2Enabled(Preferences *preferences) { @@ -88,13 +112,22 @@ bool EuroliteProFactory::DeviceAdded( // Eurolite USB-DMX512-PRO MK2? } else if (descriptor.idVendor == VENDOR_ID_MK2 && descriptor.idProduct == PRODUCT_ID_MK2) { - if (m_enable_eurolite_mk2) { - OLA_INFO << "Found a possible new Eurolite USB-DMX512-PRO MK2 device"; - LibUsbAdaptor::DeviceInformation info; - if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) { - return false; - } + LibUsbAdaptor::DeviceInformation info; + if (!m_adaptor->GetDeviceInfo(usb_device, descriptor, &info)) { + return false; + } + + const bool serial_matches = + STLContains(m_expected_eurolite_mk2_serials, info.serial); + if (m_enable_eurolite_mk2 || serial_matches) { + if (serial_matches) { + OLA_INFO << "Found a probable new Eurolite USB-DMX512-PRO MK2 device " + << "with matching serial " << info.serial; + } else { + OLA_INFO << "Found a probable new Eurolite USB-DMX512-PRO MK2 device " + << "with serial " << info.serial; + } if (!m_adaptor->CheckManufacturer(EXPECTED_MANUFACTURER_MK2, info)) { return false; } @@ -104,9 +137,12 @@ bool EuroliteProFactory::DeviceAdded( } is_mk2 = true; } else { - OLA_INFO << "Connected FTDI device could be a Eurolite " - << "USB-DMX512-PRO MK2 but was ignored, because " - << ENABLE_EUROLITE_MK2_KEY << " was false."; + OLA_INFO << "Connected FTDI device with serial " << info.serial + << " could be a Eurolite USB-DMX512-PRO MK2 but was " + << "ignored, because " + << ENABLE_EUROLITE_MK2_KEY << " was false and " + << "its serial number was not listed specifically in " + << EUROLITE_MK2_SERIAL_KEY; return false; } } else { diff --git a/plugins/usbdmx/EuroliteProFactory.h b/plugins/usbdmx/EuroliteProFactory.h index 23ebdc3f8..249735dd7 100644 --- a/plugins/usbdmx/EuroliteProFactory.h +++ b/plugins/usbdmx/EuroliteProFactory.h @@ -21,6 +21,9 @@ #ifndef PLUGINS_USBDMX_EUROLITEPROFACTORY_H_ #define PLUGINS_USBDMX_EUROLITEPROFACTORY_H_ +#include +#include + #include "libs/usb/LibUsbAdaptor.h" #include "ola/base/Macro.h" #include "olad/Preferences.h" @@ -46,10 +49,12 @@ class EuroliteProFactory : public BaseWidgetFactory { static bool IsEuroliteMk2Enabled(Preferences *preferences); static const char ENABLE_EUROLITE_MK2_KEY[]; + static const char EUROLITE_MK2_SERIAL_KEY[]; private: ola::usb::LibUsbAdaptor *m_adaptor; bool m_enable_eurolite_mk2; + std::set m_expected_eurolite_mk2_serials; static const uint16_t PRODUCT_ID; static const uint16_t VENDOR_ID; diff --git a/plugins/usbdmx/README.md b/plugins/usbdmx/README.md index 79d0eb8b8..04696f1c3 100644 --- a/plugins/usbdmx/README.md +++ b/plugins/usbdmx/README.md @@ -9,7 +9,7 @@ This plugin supports various USB DMX devices including: * DMXControl Projects e.V. Nodle U1 * DMXCreator 512 Basic * Eurolite USB-DMX512 PRO -* Eurolite USB-DMX512 PRO MK2 (when `enable_eurolite_mk2 = true`) +* Eurolite USB-DMX512 PRO MK2 (see notes below) * Eurolite freeDMX Wi-Fi * Fadecandy * FX5 DMX @@ -20,25 +20,36 @@ This plugin supports various USB DMX devices including: ## Config file : `ola-usbdmx.conf` -`libusb_debug_level = {0,1,2,3,4}` -The debug level for libusb, see http://libusb.sourceforge.net/api-1.0/ +`libusb_debug_level = {0,1,2,3,4}` +The debug level for libusb, see http://libusb.sourceforge.net/api-1.0/ 0 = No logging, 4 = Verbose debug. `enable_eurolite_mk2 = {false,true}` Whether to enable detection of the Eurolite USB-DMX512 PRO MK2. -Default = false. This device is indistinguishable from other devices +Default = `false`. This device is indistinguishable from other devices with an FTDI chip, and is therefore disabled by default. When enabled, this plugin will conflict with the usbserial, StageProfi and FTDI USB DMX -plugins. +plugins. If this is undesirable, the `eurolite_mk2_serial` setting can be +used instead, which manually marks a specific USB device as a Eurolite +USB-DMX512 PRO MK2. -`nodle--mode = {0,1,2,3,4,5,6,7}` +`eurolite_mk2_serial = ` +Claim the USB device with the given serial number as a Eurolite USB-DMX512 +PRO MK2 even when `enable_eurolite_mk2 = false`. This makes it possible +to use the Eurolite USB-DMX512 PRO MK2 together with other devices that +can not be distinguished otherwise. This setting has no effect when +`enable_eurolite_mk2 = true` or if no device is connected with the given +serial. The setting may be specified multiple times to use multiple Eurolite +USB-DMX512 PRO MK2 devices. + +`nodle--mode = {0,1,2,3,4,5,6,7}` The mode for the Nodle U1 interface with serial number `` to operate -in. Default = 6 -0 - Standby -1 - DMX In -> DMX Out -2 - PC Out -> DMX Out -3 - DMX In + PC Out -> DMX Out -4 - DMX In -> PC In -5 - DMX In -> DMX Out & DMX In -> PC In -6 - PC Out -> DMX Out & DMX In -> PC In +in. Default = 6 +0 - Standby +1 - DMX In -> DMX Out +2 - PC Out -> DMX Out +3 - DMX In + PC Out -> DMX Out +4 - DMX In -> PC In +5 - DMX In -> DMX Out & DMX In -> PC In +6 - PC Out -> DMX Out & DMX In -> PC In 7 - DMX In + PC Out -> DMX Out & DMX In -> PC In diff --git a/plugins/usbdmx/UsbDmxPlugin.cpp b/plugins/usbdmx/UsbDmxPlugin.cpp index d1760aea9..4aa3f7f88 100644 --- a/plugins/usbdmx/UsbDmxPlugin.cpp +++ b/plugins/usbdmx/UsbDmxPlugin.cpp @@ -107,6 +107,11 @@ bool UsbDmxPlugin::SetDefaultPreferences() { BoolValidator(), false); + save |= m_preferences->SetDefaultValue( + EuroliteProFactory::EUROLITE_MK2_SERIAL_KEY, + StringValidator(), + ""); + if (save) { m_preferences->Save(); }