diff --git a/.gitignore b/.gitignore index b41ca378ac..b6eb68d426 100644 --- a/.gitignore +++ b/.gitignore @@ -246,3 +246,5 @@ javascript/new-src/node_modules .cproject .settings .vscode/ +etc +.pydevproject diff --git a/plugins/uartdmx/UartDmxDevice.cpp b/plugins/uartdmx/UartDmxDevice.cpp index 83a15348b2..827f2a2c72 100644 --- a/plugins/uartdmx/UartDmxDevice.cpp +++ b/plugins/uartdmx/UartDmxDevice.cpp @@ -34,8 +34,10 @@ using std::string; const char UartDmxDevice::K_MALF[] = "-malf"; const char UartDmxDevice::K_BREAK[] = "-break"; +const char UartDmxDevice::K_PADDING[] = "-padding"; const unsigned int UartDmxDevice::DEFAULT_BREAK = 100; const unsigned int UartDmxDevice::DEFAULT_MALF = 100; +const unsigned int UartDmxDevice::DEFAULT_PADDING = 24; UartDmxDevice::UartDmxDevice(AbstractPlugin *owner, @@ -57,7 +59,11 @@ UartDmxDevice::UartDmxDevice(AbstractPlugin *owner, if (!StringToInt(m_preferences->GetValue(DeviceMalfKey()), &m_malft)) { m_malft = DEFAULT_MALF; } - m_widget.reset(new UartWidget(path)); + // Minimum amount of DMX channels to transmit + if (!StringToInt(m_preferences->GetValue(DevicePaddingKey()), &m_padding)) { + m_padding = DEFAULT_PADDING; + } + m_widget.reset(new UartWidget(path, m_padding)); } UartDmxDevice::~UartDmxDevice() { @@ -77,6 +83,9 @@ string UartDmxDevice::DeviceMalfKey() const { string UartDmxDevice::DeviceBreakKey() const { return m_path + K_BREAK; } +string UartDmxDevice::DevicePaddingKey() const { + return m_path + K_PADDING; +} /** * Set the default preferences for this one Device @@ -94,6 +103,9 @@ void UartDmxDevice::SetDefaults() { save |= m_preferences->SetDefaultValue(DeviceMalfKey(), UIntValidator(8, 1000000), DEFAULT_MALF); + save |= m_preferences->SetDefaultValue(DevicePaddingKey(), + UIntValidator(24, 512), + DEFAULT_PADDING); if (save) { m_preferences->Save(); } diff --git a/plugins/uartdmx/UartDmxDevice.h b/plugins/uartdmx/UartDmxDevice.h index b4efbb388e..09dcbb08d8 100644 --- a/plugins/uartdmx/UartDmxDevice.h +++ b/plugins/uartdmx/UartDmxDevice.h @@ -52,6 +52,7 @@ class UartDmxDevice : public Device { // Per device options std::string DeviceBreakKey() const; std::string DeviceMalfKey() const; + std::string DevicePaddingKey() const; void SetDefaults(); std::auto_ptr m_widget; @@ -60,11 +61,14 @@ class UartDmxDevice : public Device { const std::string m_path; unsigned int m_breakt; unsigned int m_malft; + unsigned int m_padding; static const unsigned int DEFAULT_MALF; static const char K_MALF[]; static const unsigned int DEFAULT_BREAK; static const char K_BREAK[]; + static const unsigned int DEFAULT_PADDING; + static const char K_PADDING[]; DISALLOW_COPY_AND_ASSIGN(UartDmxDevice); }; diff --git a/plugins/uartdmx/UartWidget.cpp b/plugins/uartdmx/UartWidget.cpp index d0fc3a709c..ec6d5c0873 100644 --- a/plugins/uartdmx/UartWidget.cpp +++ b/plugins/uartdmx/UartWidget.cpp @@ -46,6 +46,7 @@ #include "ola/io/IOUtils.h" #include "ola/Logging.h" #include "plugins/uartdmx/UartWidget.h" +#include "plugins/uartdmx/UartDmxDevice.h" namespace ola { namespace plugin { @@ -54,8 +55,9 @@ namespace uartdmx { using std::string; using std::vector; -UartWidget::UartWidget(const string& path) +UartWidget::UartWidget(const std::string &path, unsigned int padding) : m_path(path), + m_padding (padding), m_fd(NOT_OPEN) { } @@ -122,6 +124,10 @@ bool UartWidget::Write(const ola::DmxBuffer& data) { buffer[0] = DMX512_START_CODE; data.Get(buffer + 1, &length); + if (length < m_padding) { + memset ((buffer + 1 + length), 0x00, (m_padding - length) ); + length = m_padding; + } if (write(m_fd, buffer, length + 1) <= 0) { // TODO(richardash1981): handle errors better as per the test code, diff --git a/plugins/uartdmx/UartWidget.h b/plugins/uartdmx/UartWidget.h index 81faf15fe7..b697588b32 100644 --- a/plugins/uartdmx/UartWidget.h +++ b/plugins/uartdmx/UartWidget.h @@ -48,8 +48,9 @@ class UartWidget { /** * Construct a new UartWidget instance for one widget. * @param path The device file path of the serial port + * @param padding Minimal DMX frame size, padded with zeros */ - explicit UartWidget(const std::string &path); + explicit UartWidget(const std::string &path, unsigned int padding); /** Destructor */ virtual ~UartWidget(); @@ -80,7 +81,8 @@ class UartWidget { bool SetupOutput(); private: - const std::string m_path; + const std::string m_path; + unsigned int m_padding; /** * variable to hold the Unix file descriptor used to open and manipulate diff --git a/plugins/usbpro/Makefile.mk b/plugins/usbpro/Makefile.mk index 95a9444815..c1f9c36935 100644 --- a/plugins/usbpro/Makefile.mk +++ b/plugins/usbpro/Makefile.mk @@ -32,7 +32,9 @@ plugins_usbpro_libolausbprowidget_la_SOURCES = \ plugins/usbpro/UsbProWidgetDetector.h \ plugins/usbpro/WidgetDetectorInterface.h \ plugins/usbpro/WidgetDetectorThread.cpp \ - plugins/usbpro/WidgetDetectorThread.h + plugins/usbpro/WidgetDetectorThread.h \ + plugins/usbpro/UsbProExtWidget.cpp \ + plugins/usbpro/UsbProExtWidget.h plugins_usbpro_libolausbprowidget_la_LIBADD = common/libolacommon.la if USE_USBPRO @@ -57,6 +59,8 @@ plugins_usbpro_libolausbpro_la_SOURCES = \ plugins/usbpro/RobeDevice.h \ plugins/usbpro/UltraDMXProDevice.cpp \ plugins/usbpro/UltraDMXProDevice.h \ + plugins/usbpro/UsbProExtDevice.cpp \ + plugins/usbpro/UsbProExtDevice.h \ plugins/usbpro/UsbProDevice.cpp \ plugins/usbpro/UsbProDevice.h \ plugins/usbpro/UsbSerialDevice.h \ diff --git a/plugins/usbpro/UsbProExtDevice.cpp b/plugins/usbpro/UsbProExtDevice.cpp new file mode 100644 index 0000000000..4c2cd91a87 --- /dev/null +++ b/plugins/usbpro/UsbProExtDevice.cpp @@ -0,0 +1,263 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * UsbProExtDevice.cpp + * A DMX King Ultra DMX Pro Device + * Copyright (C) 2011 Simon Newton + * + * This device creates 3 ports, 1 input and 2 output. + */ + +#include +#include +#include + +#include "common/rpc/RpcController.h" +#include "ola/Callback.h" +#include "ola/Constants.h" +#include "ola/Logging.h" +#include "plugins/usbpro/UsbProExtDevice.h" +#include "plugins/usbpro/UsbProWidgetDetector.h" + +namespace ola { +namespace plugin { +namespace usbpro { + +using ola::plugin::usbpro::Request; +using ola::plugin::usbpro::Reply; +using ola::rpc::RpcController; +using std::string; + +/* + * Create a new device + * @param owner the plugin that owns this device + * @param name the device name + * @param dev_path path to the pro widget + */ + +UsbProExtDevice::UsbProExtDevice(ola::PluginAdaptor *plugin_adaptor, + ola::AbstractPlugin *owner, + const string &name, + UsbProExtWidget *widget, + OLA_UNUSED uint16_t esta_id, + uint16_t device_id, + uint32_t serial, + uint16_t firmware_version, + unsigned int fps_limit): + UsbSerialDevice(owner, name, widget), + m_widget(widget), + m_serial(), + m_got_parameters(false), + m_break_time(0), + m_mab_time(0), + m_rate(0) { + std::ostringstream str; + str << std::setfill('0'); + uint8_t *ptr = reinterpret_cast(&serial); + for (int i = UsbProWidgetInformation::SERIAL_LENGTH - 1; i >= 0; i--) { + int digit = (10 * (ptr[i] & 0xf0) >> 4) + (ptr[i] & 0x0f); + str << std::setw(2) << digit; + } + m_serial = str.str(); + str.str(""); + str << "Serial #: " << m_serial << ", firmware " + << (firmware_version >> 8) << "." << (firmware_version & 0xff); + + + m_widget->GetParameters(NewSingleCallback( + this, + &UsbProExtDevice::UpdateParams)); + + // device_id determines i/o count, max 16 + +// uint8_t input_port_count = (uint8_t) ((device_id >> 8) & 0x000F); + uint8_t output_port_count = (uint8_t) (device_id & 0x000F); + + UsbProExtInputPort *input_port = new UsbProExtInputPort( + this, + m_widget, + 0, + plugin_adaptor, + str.str()); + + m_widget->SetDMXCallback( + NewCallback( + static_cast(input_port), + &InputPort::DmxChanged)); + AddPort(input_port); + + for (unsigned int id=0; id <= output_port_count; id++) { + OutputPort *output_port = new UsbProExtOutputPort( + this, + m_widget, + id, + str.str(), + plugin_adaptor->WakeUpTime(), + 5, // allow up to 5 burst frames + fps_limit); + AddPort(output_port); + } +} + + +/* + * Stop this device + */ +void UsbProExtDevice::PrePortStop() { + m_widget->Stop(); +} + + +/* + * Handle device config messages + * @param controller An RpcController + * @param request the request data + * @param response the response to return + * @param done the closure to call once the request is complete + */ +void UsbProExtDevice::Configure(RpcController *controller, + const string &request, + string *response, + ConfigureCallback *done) { + Request request_pb; + if (!request_pb.ParseFromString(request)) { + controller->SetFailed("Invalid Request"); + done->Run(); + return; + } + + switch (request_pb.type()) { + case ola::plugin::usbpro::Request::USBPRO_PARAMETER_REQUEST: + HandleParametersRequest(controller, &request_pb, response, done); + break; + case ola::plugin::usbpro::Request::USBPRO_SERIAL_REQUEST: + HandleSerialRequest(controller, &request_pb, response, done); + break; + default: + controller->SetFailed("Invalid Request"); + done->Run(); + } +} + + +/** + * Update the cached param values + */ +void UsbProExtDevice::UpdateParams(bool status, + const usb_pro_parameters ¶ms) { + if (status) { + m_got_parameters = true; + m_break_time = params.break_time; + m_mab_time = params.mab_time; + m_rate = params.rate; + } +} + + +/* + * Handle a parameter request. This may set some parameters in the widget. + * If no parameters are set we simply fetch the parameters and return them to + * the client. If we are setting parameters, we send a SetParam() request and + * then another GetParam() request in order to return the latest values to the + * client. + */ +void UsbProExtDevice::HandleParametersRequest(RpcController *controller, + const Request *request, + string *response, + ConfigureCallback *done) { + if (request->has_parameters() && + (request->parameters().has_break_time() || + request->parameters().has_mab_time() || + request->parameters().has_rate())) { + if (!m_got_parameters) { + controller->SetFailed("SetParameters failed, startup not complete"); + done->Run(); + return; + } + + bool ret = m_widget->SetParameters( + request->parameters().has_break_time() ? + request->parameters().break_time() : m_break_time, + request->parameters().has_mab_time() ? + request->parameters().mab_time() : m_mab_time, + request->parameters().has_rate() ? + request->parameters().rate() : m_rate); + + if (!ret) { + controller->SetFailed("SetParameters failed"); + done->Run(); + return; + } + } + + m_widget->GetParameters(NewSingleCallback( + this, + &UsbProExtDevice::HandleParametersResponse, + controller, + response, + done)); +} + + +/** + * Handle the GetParameters response + */ +void UsbProExtDevice::HandleParametersResponse( + RpcController *controller, + string *response, + ConfigureCallback *done, + bool status, + const usb_pro_parameters ¶ms) { + if (!status) { + controller->SetFailed("GetParameters failed"); + } else { + UpdateParams(true, params); + Reply reply; + reply.set_type(ola::plugin::usbpro::Reply::USBPRO_PARAMETER_REPLY); + ola::plugin::usbpro::ParameterReply *parameters_reply = + reply.mutable_parameters(); + + parameters_reply->set_firmware_high(params.firmware_high); + parameters_reply->set_firmware(params.firmware); + parameters_reply->set_break_time(params.break_time); + parameters_reply->set_mab_time(params.mab_time); + parameters_reply->set_rate(params.rate); + reply.SerializeToString(response); + } + done->Run(); +} + + +/* + * Handle a Serial number Configure RPC. We can just return the cached number. + */ +void UsbProExtDevice::HandleSerialRequest( + RpcController *controller, + const Request *request, + string *response, + ConfigureCallback *done) { + Reply reply; + reply.set_type(ola::plugin::usbpro::Reply::USBPRO_SERIAL_REPLY); + ola::plugin::usbpro::SerialNumberReply *serial_reply = + reply.mutable_serial_number(); + serial_reply->set_serial(m_serial); + reply.SerializeToString(response); + done->Run(); + (void) controller; + (void) request; +} +} // namespace usbpro +} // namespace plugin +} // namespace ola diff --git a/plugins/usbpro/UsbProExtDevice.h b/plugins/usbpro/UsbProExtDevice.h new file mode 100644 index 0000000000..2f2f421b87 --- /dev/null +++ b/plugins/usbpro/UsbProExtDevice.h @@ -0,0 +1,163 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * UsbProExtDevice.h + * Extended USBPro emulation device support + * Copyright (C) 2011 Simon Newton + */ + +#ifndef PLUGINS_USBPRO_USBPROEXTDEVICE_H_ +#define PLUGINS_USBPRO_USBPROEXTDEVICE_H_ + +#include +#include +#include "ola/DmxBuffer.h" +#include "olad/TokenBucket.h" +#include "olad/PluginAdaptor.h" +#include "olad/Port.h" + +#include "plugins/usbpro/UsbProExtWidget.h" +#include "plugins/usbpro/UsbSerialDevice.h" +#include "plugins/usbpro/messages/UsbProConfigMessages.pb.h" + +namespace ola { +namespace plugin { +namespace usbpro { + +/* + * Extended USBPro device + */ +class UsbProExtDevice: public UsbSerialDevice { + public: + UsbProExtDevice(ola::PluginAdaptor *plugin_adaptor, + ola::AbstractPlugin *owner, + const std::string &name, + UsbProExtWidget *widget, + uint16_t esta_id, + uint16_t device_id, + uint32_t serial, + uint16_t firmware_version, + unsigned int fps_limit); + + std::string DeviceId() const { return m_serial; } + // both output ports can be bound to the same universe + bool AllowMultiPortPatching() const { return true; } + + void Configure(ola::rpc::RpcController *controller, + const std::string &request, + std::string *response, + ConfigureCallback *done); + + protected: + void PrePortStop(); + + private: + void UpdateParams(bool status, const usb_pro_parameters ¶ms); + + void HandleParametersRequest(ola::rpc::RpcController *controller, + const ola::plugin::usbpro::Request *request, + std::string *response, + ConfigureCallback *done); + + void HandleParametersResponse(ola::rpc::RpcController *controller, + std::string *response, + ConfigureCallback *done, + bool status, + const usb_pro_parameters ¶ms); + + void HandleSerialRequest(ola::rpc::RpcController *controller, + const ola::plugin::usbpro::Request *request, + std::string *response, + ConfigureCallback *done); + + UsbProExtWidget *m_widget; + std::string m_serial; + + bool m_got_parameters; + uint8_t m_break_time; + uint8_t m_mab_time; + uint8_t m_rate; +}; + + +/* + * The Input port + */ +class UsbProExtInputPort: public BasicInputPort { + public: + UsbProExtInputPort(UsbProExtDevice *parent, + UsbProExtWidget *widget, + unsigned int id, + ola::PluginAdaptor *plugin_adaptor, + const std::string &description) + : BasicInputPort(parent, id, plugin_adaptor), + m_description(description), + m_widget(widget) {} + + const DmxBuffer &ReadDMX() const { + return m_widget->FetchDMX(); + } + + std::string Description() const { return m_description; } + + private: + const std::string m_description; + UsbProExtWidget *m_widget; +}; + + +/* + * The output port + */ +class UsbProExtOutputPort: public BasicOutputPort { + public: + UsbProExtOutputPort(UsbProExtDevice *parent, + UsbProExtWidget *widget, + unsigned int id, + const std::string &description, + const TimeStamp *wake_time, + unsigned int max_burst, + unsigned int rate) + : BasicOutputPort(parent, id), + m_port_id_ext(id), + m_description(description), + m_widget(widget), + m_bucket(max_burst, rate, max_burst, *wake_time), + m_wake_time(wake_time) {} + + bool WriteDMX(const DmxBuffer &buffer, OLA_UNUSED uint8_t priority) { + if (m_bucket.GetToken(*m_wake_time)) { + return m_widget->SendDMX(m_port_id_ext, buffer); + } else { + OLA_INFO << "Port rated limited, dropping frame"; + } + return true; + } + + std::string Description() const { return m_description; } + + protected: + const unsigned int m_port_id_ext; + private: + const std::string m_description; + UsbProExtWidget *m_widget; + TokenBucket m_bucket; + const TimeStamp *m_wake_time; +// bool m_primary; +}; +} // namespace usbpro +} // namespace plugin +} // namespace ola +#endif // PLUGINS_USBPRO_USBPROEXTDEVICE_H_ diff --git a/plugins/usbpro/UsbProExtWidget.cpp b/plugins/usbpro/UsbProExtWidget.cpp new file mode 100644 index 0000000000..ddd2dd9fe7 --- /dev/null +++ b/plugins/usbpro/UsbProExtWidget.cpp @@ -0,0 +1,51 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * UsbProExtWidget.cpp + * The DMXKing Ultra DMX Pro Widget. + * Copyright (C) 2011 Simon Newton + */ + +#include "ola/Constants.h" +#include "plugins/usbpro/UsbProExtWidget.h" + +namespace ola { +namespace plugin { +namespace usbpro { + +uint8_t UsbProExtWidget::PortLabel (uint8_t port_id) { + return ((DMX_PORT_LABEL_BASE + port_id) > 0xFF ) ? + 0xFF : + (DMX_PORT_LABEL_BASE + port_id); +} + + +bool UsbProExtWidget::SendDMX(uint8_t port_id, + const DmxBuffer &data) { + struct { + uint8_t start_code; + uint8_t dmx[DMX_UNIVERSE_SIZE]; + } widget_dmx; + + widget_dmx.start_code = DMX512_START_CODE; + unsigned int length = DMX_UNIVERSE_SIZE; + data.Get(widget_dmx.dmx, &length); + return SendMessage(PortLabel(port_id), + reinterpret_cast(&widget_dmx), + length + 1); +} +} // namespace usbpro +} // namespace plugin +} // namespace ola diff --git a/plugins/usbpro/UsbProExtWidget.h b/plugins/usbpro/UsbProExtWidget.h new file mode 100644 index 0000000000..2ab3ac71ac --- /dev/null +++ b/plugins/usbpro/UsbProExtWidget.h @@ -0,0 +1,57 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * UsbProExtWidget.h + * The DMXKing Ultra DMX Pro Widget. + * This is similar to the Enttec Usb Pro, but it has two output ports. + * Copyright (C) 2011 Simon Newton + */ + +#ifndef PLUGINS_USBPRO_USBPROEXTWIDGET_H_ +#define PLUGINS_USBPRO_USBPROEXTWIDGET_H_ + +#include +#include +#include "ola/Callback.h" +#include "ola/DmxBuffer.h" +#include "plugins/usbpro/GenericUsbProWidget.h" + +namespace ola { +namespace plugin { +namespace usbpro { + +/* + * An Ultra DMX Pro Widget + */ +class UsbProExtWidget: public GenericUsbProWidget { + public: + + explicit UsbProExtWidget( + ola::io::ConnectedDescriptor *descriptor) + : GenericUsbProWidget(descriptor) {}; + + ~UsbProExtWidget() {} + void Stop() { GenericStop(); } + + bool SendDMX(uint8_t label, const DmxBuffer &data); + + protected: + static uint8_t PortLabel (uint8_t port_id); + static const uint8_t DMX_PORT_LABEL_BASE = 100; +}; +} // namespace usbpro +} // namespace plugin +} // namespace ola +#endif // PLUGINS_USBPRO_USBPROEXTWIDGET_H_ diff --git a/plugins/usbpro/UsbSerialPlugin.cpp b/plugins/usbpro/UsbSerialPlugin.cpp index 1ba6ee49a4..c6db22965a 100644 --- a/plugins/usbpro/UsbSerialPlugin.cpp +++ b/plugins/usbpro/UsbSerialPlugin.cpp @@ -41,6 +41,8 @@ #include "plugins/usbpro/UsbProDevice.h" #include "plugins/usbpro/UsbSerialPlugin.h" #include "plugins/usbpro/UsbSerialPluginDescription.h" +#include "plugins/usbpro/UsbProExtDevice.h" +#include "plugins/usbpro/UsbProExtWidget.h" namespace ola { @@ -201,6 +203,22 @@ void UsbSerialPlugin::NewWidget(UltraDMXProWidget *widget, GetUltraDMXProFrameLimit())); } +/** + * New UsbPro Extended Widget + */ +void UsbSerialPlugin::NewWidget(UsbProExtWidget *widget, + const UsbProWidgetInformation &information) { + AddDevice(new UsbProExtDevice( + m_plugin_adaptor, + this, + GetDeviceName(information), + widget, + information.esta_id, + information.device_id, + information.serial, + information.firmware_version, + GetUltraDMXProFrameLimit())); +} /* * Add a new device to the list diff --git a/plugins/usbpro/UsbSerialPlugin.h b/plugins/usbpro/UsbSerialPlugin.h index 5df6993eff..3eb1569bf9 100644 --- a/plugins/usbpro/UsbSerialPlugin.h +++ b/plugins/usbpro/UsbSerialPlugin.h @@ -55,6 +55,8 @@ class UsbSerialPlugin: public ola::Plugin, public NewWidgetHandler { const RobeWidgetInformation &information); void NewWidget(UltraDMXProWidget *widget, const UsbProWidgetInformation &information); + void NewWidget(UsbProExtWidget *widget, + const UsbProWidgetInformation &information); private: void AddDevice(UsbSerialDevice *device); diff --git a/plugins/usbpro/WidgetDetectorThread.cpp b/plugins/usbpro/WidgetDetectorThread.cpp index 124f416cc5..0a7386f66a 100644 --- a/plugins/usbpro/WidgetDetectorThread.cpp +++ b/plugins/usbpro/WidgetDetectorThread.cpp @@ -42,6 +42,7 @@ #include "plugins/usbpro/UltraDMXProWidget.h" #include "plugins/usbpro/UsbProWidgetDetector.h" #include "plugins/usbpro/WidgetDetectorThread.h" +#include "plugins/usbpro/UsbProExtWidget.h" namespace ola { namespace plugin { @@ -310,6 +311,12 @@ void WidgetDetectorThread::UsbProWidgetReady( return; } break; + case ESTA_ID_EXPERIMENTAL: + DispatchWidget( + new UsbProExtWidget(descriptor), + information); + return; + break; } OLA_WARN << "Defaulting to a Usb Pro device"; if (information->dual_port) { diff --git a/plugins/usbpro/WidgetDetectorThread.h b/plugins/usbpro/WidgetDetectorThread.h index d88909b439..775f1ba616 100644 --- a/plugins/usbpro/WidgetDetectorThread.h +++ b/plugins/usbpro/WidgetDetectorThread.h @@ -37,6 +37,7 @@ #include "plugins/usbpro/UsbProWidgetDetector.h" #include "plugins/usbpro/SerialWidgetInterface.h" #include "plugins/usbpro/WidgetDetectorInterface.h" +#include "plugins/usbpro/UsbProExtWidget.h" namespace ola { namespace plugin { @@ -65,6 +66,8 @@ class NewWidgetHandler { const RobeWidgetInformation &information) = 0; virtual void NewWidget(class UltraDMXProWidget *widget, const UsbProWidgetInformation &information) = 0; + virtual void NewWidget(class UsbProExtWidget *widget, + const UsbProWidgetInformation &information) = 0; }; @@ -183,6 +186,7 @@ class WidgetDetectorThread: public ola::thread::Thread { static const uint16_t DMX_KING_ESTA_ID = 0x6a6b; static const uint16_t GODDARD_ESTA_ID = 0x4744; static const uint16_t JESE_ESTA_ID = 0x6864; + static const uint16_t ESTA_ID_EXPERIMENTAL = 0x7FF7; }; } // namespace usbpro } // namespace plugin diff --git a/python/ola/ClientWrapper.py b/python/ola/ClientWrapper.py index 630c32f615..c168aab3f4 100644 --- a/python/ola/ClientWrapper.py +++ b/python/ola/ClientWrapper.py @@ -47,6 +47,12 @@ def __init__(self, time_ms, callback): def __cmp__(self, other): return cmp(self._run_at, other._run_at) + def __lt__(self, other): + return (self._run_at < other._run_at) + + def __gt__(self, other): + return (self._run_at > other._run_at) + def TimeLeft(self, now): """Get the time remaining before this event triggers.