mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
LED Device Features, Fixes and Refactoring (Resubmit PR855) (#875)
* Refactor LedDevices - Initial version * Small renamings * Add WLED as own device * Lpd8806 Remove open() method * remove dependency on Qt 5.10 * Lpd8806 Remove open() method * Update WS281x * Update WS2812SPI * Add writeBlack for WLED powerOff * WLED remove extra bracket * Allow different Nanoleaf panel numbering sequence (Feature req.#827) * build(deps): bump websocket-extensions from 0.1.3 to 0.1.4 in /docs (#826) * Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. - [Release notes](https://github.com/faye/websocket-extensions-node/releases) - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4) * Fix typos * Nanoleaf clean-up * Yeelight support, generalize wizard elements * Update Yeelight to handle quota in music mode * Yeelight extend rage for extraTimeDarkness for testing * Clean-up - Add commentary, Remove development debug statements * Fix brightnessSwitchOffOnMinimum typo and default value * Yeelight support restoreOriginalState, additional Fixes * WLED - Remove UDP-Port, as it is not configurable * Fix merging issue * Remove QHostAddress::operator=(const QString&)' is deprecated * Windows compile errors and (Qt 5.15 deprecation) warnings * Fix order includes * LedDeviceFile Support Qt5.7 and greater * Windows compatibility and other Fixes * Fix Qt Version compatability * Rs232 - Resolve portname from unix /dev/ style, fix DMX sub-type support * Disable WLED Wizard Button (until Wizard is available) * Yeelight updates * Add wrong log-type as per #505 * Fixes and Clean-up after clang-tidy report * Fix udpe131 not enabled for generated CID * Change timer into dynamic for Qt Thread-Affinity * Hue clean-up and diyHue workaround * Updates after review feedback by m-seker * Add "chrono" includes
This commit is contained in:
@@ -5,11 +5,12 @@
|
||||
// Local Hyperion includes
|
||||
#include "LedDeviceHyperionUsbasp.h"
|
||||
|
||||
// Static constants which define the Hyperion Usbasp device
|
||||
uint16_t LedDeviceHyperionUsbasp::_usbVendorId = 0x16c0;
|
||||
uint16_t LedDeviceHyperionUsbasp::_usbProductId = 0x05dc;
|
||||
QString LedDeviceHyperionUsbasp::_usbProductDescription = "Hyperion led controller";
|
||||
|
||||
// Constants which define the Hyperion USBasp device
|
||||
namespace {
|
||||
uint16_t _usbVendorId = 0x16c0;
|
||||
uint16_t _usbProductId = 0x05dc;
|
||||
QString _usbProductDescription = "Hyperion led controller";
|
||||
}
|
||||
|
||||
LedDeviceHyperionUsbasp::LedDeviceHyperionUsbasp(const QJsonObject &deviceConfig)
|
||||
: LedDevice()
|
||||
@@ -17,11 +18,17 @@ LedDeviceHyperionUsbasp::LedDeviceHyperionUsbasp(const QJsonObject &deviceConfig
|
||||
, _deviceHandle(nullptr)
|
||||
{
|
||||
_devConfig = deviceConfig;
|
||||
_deviceReady = false;
|
||||
_isDeviceReady = false;
|
||||
|
||||
_activeDeviceType = deviceConfig["type"].toString("UNSPECIFIED").toLower();
|
||||
}
|
||||
|
||||
LedDeviceHyperionUsbasp::~LedDeviceHyperionUsbasp()
|
||||
{
|
||||
if (_libusbContext != nullptr)
|
||||
{
|
||||
libusb_exit(_libusbContext);
|
||||
}
|
||||
}
|
||||
|
||||
LedDevice* LedDeviceHyperionUsbasp::construct(const QJsonObject &deviceConfig)
|
||||
@@ -31,18 +38,68 @@ LedDevice* LedDeviceHyperionUsbasp::construct(const QJsonObject &deviceConfig)
|
||||
|
||||
bool LedDeviceHyperionUsbasp::init(const QJsonObject &deviceConfig)
|
||||
{
|
||||
bool isInitOK = LedDevice::init(deviceConfig);
|
||||
bool isInitOK = false;
|
||||
|
||||
QString ledType = deviceConfig["ledType"].toString("ws2801");
|
||||
if (ledType != "ws2801" && ledType != "ws2812")
|
||||
// Initialise sub-class
|
||||
if ( LedDevice::init(deviceConfig) )
|
||||
{
|
||||
QString errortext = QString ("Invalid ledType; must be 'ws2801' or 'ws2812'.");
|
||||
this->setInError(errortext);
|
||||
isInitOK = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_writeLedsCommand = (ledType == "ws2801") ? CMD_WRITE_WS2801 : CMD_WRITE_WS2812;
|
||||
QString ledType = deviceConfig["ledType"].toString("ws2801");
|
||||
if (ledType != "ws2801" && ledType != "ws2812")
|
||||
{
|
||||
QString errortext = QString ("Invalid ledType; must be 'ws2801' or 'ws2812'.");
|
||||
this->setInError(errortext);
|
||||
isInitOK = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_writeLedsCommand = (ledType == "ws2801") ? CMD_WRITE_WS2801 : CMD_WRITE_WS2812;
|
||||
|
||||
int error;
|
||||
// initialize the USB context
|
||||
if ( (error = libusb_init(&_libusbContext)) != LIBUSB_SUCCESS )
|
||||
{
|
||||
_libusbContext = nullptr;
|
||||
|
||||
QString errortext = QString ("Error while initializing USB context(%1):%2").arg(error).arg(libusb_error_name(error));
|
||||
this->setInError(errortext);
|
||||
isInitOK = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug(_log, "USB context initialized");
|
||||
//libusb_set_debug(_libusbContext, 3);
|
||||
|
||||
// retrieve the list of USB devices
|
||||
libusb_device ** deviceList;
|
||||
ssize_t deviceCount = libusb_get_device_list(_libusbContext, &deviceList);
|
||||
|
||||
// iterate the list of devices
|
||||
for (ssize_t i = 0 ; i < deviceCount; ++i)
|
||||
{
|
||||
// try to open and initialize the device
|
||||
if ( testAndOpen(deviceList[i]) == 0 )
|
||||
{
|
||||
_device = deviceList[i];
|
||||
// a device was successfully opened. break from list
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// free the device list
|
||||
libusb_free_device_list(deviceList, 1);
|
||||
|
||||
if (_deviceHandle == nullptr)
|
||||
{
|
||||
QString errortext;
|
||||
errortext = QString ("No %1 has been found").arg( _usbProductDescription);
|
||||
this->setInError( errortext );
|
||||
}
|
||||
else
|
||||
{
|
||||
isInitOK = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isInitOK;
|
||||
@@ -51,73 +108,29 @@ bool LedDeviceHyperionUsbasp::init(const QJsonObject &deviceConfig)
|
||||
int LedDeviceHyperionUsbasp::open()
|
||||
{
|
||||
int retval = -1;
|
||||
QString errortext;
|
||||
_deviceReady = false;
|
||||
_isDeviceReady = false;
|
||||
|
||||
// General initialisation and configuration of LedDevice
|
||||
if ( init(_devConfig) )
|
||||
if ( libusb_open(_device, &_deviceHandle) != LIBUSB_SUCCESS )
|
||||
{
|
||||
int error;
|
||||
|
||||
// initialize the usb context
|
||||
if ((error = libusb_init(&_libusbContext)) != LIBUSB_SUCCESS)
|
||||
{
|
||||
//Error(_log, "Error while initializing USB context(%d):%s", error, libusb_error_name(error));
|
||||
errortext = QString ("Error while initializing USB context(%1):%2").arg( error).arg(libusb_error_name(error));
|
||||
_libusbContext = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
//libusb_set_debug(_libusbContext, 3);
|
||||
Debug(_log, "USB context initialized");
|
||||
|
||||
// retrieve the list of usb devices
|
||||
libusb_device ** deviceList;
|
||||
ssize_t deviceCount = libusb_get_device_list(_libusbContext, &deviceList);
|
||||
|
||||
// iterate the list of devices
|
||||
for (ssize_t i = 0 ; i < deviceCount; ++i)
|
||||
{
|
||||
// try to open and initialize the device
|
||||
error = testAndOpen(deviceList[i]);
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
// a device was sucessfully opened. break from list
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// free the device list
|
||||
libusb_free_device_list(deviceList, 1);
|
||||
|
||||
if (_deviceHandle == nullptr)
|
||||
{
|
||||
//Error(_log, "No %s has been found", QSTRING_CSTR(_usbProductDescription));
|
||||
errortext = QString ("No %1 has been found").arg( _usbProductDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything is OK -> enable device
|
||||
_deviceReady = true;
|
||||
setEnable(true);
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
// On error/exceptions, set LedDevice in error
|
||||
if ( retval < 0 )
|
||||
{
|
||||
this->setInError( errortext );
|
||||
}
|
||||
QString errortext = QString ("Failed to open [%1]").arg(_usbProductDescription);
|
||||
this->setInError(errortext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything is OK -> enable device
|
||||
_isDeviceReady = true;
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void LedDeviceHyperionUsbasp::close()
|
||||
int LedDeviceHyperionUsbasp::close()
|
||||
{
|
||||
LedDevice::close();
|
||||
int retval = 0;
|
||||
_isDeviceReady = false;
|
||||
|
||||
// LedDevice specific closing activites
|
||||
// LedDevice specific closing activities
|
||||
if (_deviceHandle != nullptr)
|
||||
{
|
||||
libusb_release_interface(_deviceHandle, 0);
|
||||
@@ -126,12 +139,7 @@ void LedDeviceHyperionUsbasp::close()
|
||||
|
||||
_deviceHandle = nullptr;
|
||||
}
|
||||
|
||||
if (_libusbContext != nullptr)
|
||||
{
|
||||
libusb_exit(_libusbContext);
|
||||
_libusbContext = nullptr;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int LedDeviceHyperionUsbasp::testAndOpen(libusb_device * device)
|
||||
@@ -176,7 +184,7 @@ int LedDeviceHyperionUsbasp::write(const std::vector<ColorRgb> &ledValues)
|
||||
{
|
||||
int nbytes = libusb_control_transfer(
|
||||
_deviceHandle, // device handle
|
||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT, // request type
|
||||
static_cast<uint8_t>( LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT ), // request type
|
||||
_writeLedsCommand, // request
|
||||
0, // value
|
||||
0, // index
|
||||
@@ -184,7 +192,7 @@ int LedDeviceHyperionUsbasp::write(const std::vector<ColorRgb> &ledValues)
|
||||
(3*_ledCount) & 0xffff, // length
|
||||
5000); // timeout
|
||||
|
||||
// Disabling interupts for a little while on the device results in a PIPE error. All seems to keep functioning though...
|
||||
// Disabling interrupts for a little while on the device results in a PIPE error. All seems to keep functioning though...
|
||||
if(nbytes < 0 && nbytes != LIBUSB_ERROR_PIPE)
|
||||
{
|
||||
Error(_log, "Error while writing data to %s (%s)", QSTRING_CSTR(_usbProductDescription), libusb_error_name(nbytes));
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef LEDEVICEHYPERIONUSBASP_H
|
||||
#define LEDEVICEHYPERIONUSBASP_H
|
||||
|
||||
// stl includes
|
||||
#include <vector>
|
||||
@@ -32,7 +33,7 @@ public:
|
||||
///
|
||||
/// Sets configuration
|
||||
///
|
||||
/// @param deviceConfig the json device config
|
||||
/// @para#endif // LEDEVICETEMPLATE_Hm deviceConfig the json device config
|
||||
/// @return true if success
|
||||
bool init(const QJsonObject &deviceConfig) override;
|
||||
|
||||
@@ -49,7 +50,7 @@ public slots:
|
||||
/// Closes the output device.
|
||||
/// Includes switching-off the device and stopping refreshes
|
||||
///
|
||||
virtual void close() override;
|
||||
virtual int close() override;
|
||||
|
||||
protected:
|
||||
///
|
||||
@@ -85,11 +86,11 @@ protected:
|
||||
/// libusb context
|
||||
libusb_context * _libusbContext;
|
||||
|
||||
/// libusb device
|
||||
libusb_device * _device;
|
||||
|
||||
/// libusb device handle
|
||||
libusb_device_handle * _deviceHandle;
|
||||
|
||||
/// Usb device identifiers
|
||||
static uint16_t _usbVendorId;
|
||||
static uint16_t _usbProductId;
|
||||
static QString _usbProductDescription;
|
||||
};
|
||||
|
||||
#endif // LEDEVICEHYPERIONUSBASP_H
|
||||
|
@@ -32,20 +32,6 @@ enum DATA_VERSION_INDEXES{
|
||||
INDEX_FW_VER_MINOR
|
||||
};
|
||||
|
||||
LedDeviceLightpack::LedDeviceLightpack(const QString & serialNumber)
|
||||
: LedDevice()
|
||||
, _libusbContext(nullptr)
|
||||
, _deviceHandle(nullptr)
|
||||
, _busNumber(-1)
|
||||
, _addressNumber(-1)
|
||||
, _serialNumber(serialNumber)
|
||||
, _firmwareVersion({-1,-1})
|
||||
, _bitsPerChannel(-1)
|
||||
, _hwLedCount(-1)
|
||||
{
|
||||
_deviceReady = false;
|
||||
}
|
||||
|
||||
LedDeviceLightpack::LedDeviceLightpack(const QJsonObject &deviceConfig)
|
||||
: LedDevice()
|
||||
, _libusbContext(nullptr)
|
||||
@@ -55,13 +41,20 @@ LedDeviceLightpack::LedDeviceLightpack(const QJsonObject &deviceConfig)
|
||||
, _firmwareVersion({-1,-1})
|
||||
, _bitsPerChannel(-1)
|
||||
, _hwLedCount(-1)
|
||||
,_isOpen(false)
|
||||
{
|
||||
_devConfig = deviceConfig;
|
||||
_deviceReady = false;
|
||||
_isDeviceReady = false;
|
||||
|
||||
_activeDeviceType = deviceConfig["type"].toString("UNSPECIFIED").toLower();
|
||||
}
|
||||
|
||||
LedDeviceLightpack::~LedDeviceLightpack()
|
||||
{
|
||||
if (_libusbContext != nullptr)
|
||||
{
|
||||
libusb_exit(_libusbContext);
|
||||
}
|
||||
}
|
||||
|
||||
LedDevice* LedDeviceLightpack::construct(const QJsonObject &deviceConfig)
|
||||
@@ -71,36 +64,29 @@ LedDevice* LedDeviceLightpack::construct(const QJsonObject &deviceConfig)
|
||||
|
||||
bool LedDeviceLightpack::init(const QJsonObject &deviceConfig)
|
||||
{
|
||||
bool isInitOK = LedDevice::init(deviceConfig);
|
||||
_serialNumber = deviceConfig["output"].toString("");
|
||||
bool isInitOK = false;
|
||||
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
int LedDeviceLightpack::open()
|
||||
{
|
||||
int retval = -1;
|
||||
QString errortext;
|
||||
_deviceReady = false;
|
||||
|
||||
// General initialisation and configuration of LedDevice
|
||||
if ( init(_devConfig) )
|
||||
// Initialise sub-class
|
||||
if ( LedDevice::init(deviceConfig) )
|
||||
{
|
||||
int error;
|
||||
_serialNumber = deviceConfig["serial"].toString("");
|
||||
|
||||
// initialize the usb context
|
||||
if ((error = libusb_init(&_libusbContext)) != LIBUSB_SUCCESS)
|
||||
int error;
|
||||
// initialize the USB context
|
||||
if ( (error = libusb_init(&_libusbContext)) != LIBUSB_SUCCESS )
|
||||
{
|
||||
//Error(_log, "Error while initializing USB context(%d): %s", error, libusb_error_name(error));
|
||||
errortext = QString ("Error while initializing USB context(%1):%2").arg( error).arg(libusb_error_name(error));
|
||||
_libusbContext = nullptr;
|
||||
|
||||
QString errortext = QString ("Error while initializing USB context(%1):%2").arg(error).arg(libusb_error_name(error));
|
||||
this->setInError(errortext);
|
||||
isInitOK = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//libusb_set_debug(_libusbContext, 3);
|
||||
Debug(_log, "USB context initialized");
|
||||
//libusb_set_debug(_libusbContext, 3);
|
||||
|
||||
// retrieve the list of usb devices
|
||||
// retrieve the list of USB devices
|
||||
libusb_device ** deviceList;
|
||||
ssize_t deviceCount = libusb_get_device_list(_libusbContext, &deviceList);
|
||||
|
||||
@@ -108,11 +94,10 @@ int LedDeviceLightpack::open()
|
||||
for (ssize_t i = 0 ; i < deviceCount; ++i)
|
||||
{
|
||||
// try to open and initialize the device
|
||||
error = testAndOpen(deviceList[i], _serialNumber);
|
||||
|
||||
if (error == 0)
|
||||
if (testAndOpen(deviceList[i], _serialNumber) == 0)
|
||||
{
|
||||
// a device was sucessfully opened. break from list
|
||||
_device = deviceList[i];
|
||||
// a device was successfully opened. break from list
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -122,53 +107,62 @@ int LedDeviceLightpack::open()
|
||||
|
||||
if (_deviceHandle == nullptr)
|
||||
{
|
||||
QString errortext;
|
||||
if (_serialNumber.isEmpty())
|
||||
{
|
||||
//Warning(_log, "No Lightpack device has been found");
|
||||
errortext = QString ("No Lightpack devices were found");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Error(_log,"No Lightpack device has been found with serial %", QSTRING_CSTR(_serialNumber));
|
||||
errortext = QString ("No Lightpack device has been found with serial %1").arg( _serialNumber);
|
||||
}
|
||||
this->setInError( errortext );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything is OK -> enable device
|
||||
_deviceReady = true;
|
||||
setEnable(true);
|
||||
retval = 0;
|
||||
isInitOK = true;
|
||||
}
|
||||
}
|
||||
// On error/exceptions, set LedDevice in error
|
||||
if ( retval < 0 )
|
||||
{
|
||||
this->setInError( errortext );
|
||||
}
|
||||
}
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
int LedDeviceLightpack::open()
|
||||
{
|
||||
int retval = -1;
|
||||
_isDeviceReady = false;
|
||||
|
||||
if ( libusb_open(_device, &_deviceHandle) != LIBUSB_SUCCESS )
|
||||
{
|
||||
QString errortext = QString ("Failed to open [%1]").arg(_serialNumber);
|
||||
this->setInError(errortext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything is OK -> enable device
|
||||
_isDeviceReady = true;
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void LedDeviceLightpack::close()
|
||||
int LedDeviceLightpack::close()
|
||||
{
|
||||
LedDevice::close();
|
||||
int retval = 0;
|
||||
_isDeviceReady = false;
|
||||
|
||||
// LedDevice specific closing activites
|
||||
// LedDevice specific closing activities
|
||||
if (_deviceHandle != nullptr)
|
||||
{
|
||||
_isOpen = false;
|
||||
libusb_release_interface(_deviceHandle, LIGHTPACK_INTERFACE);
|
||||
libusb_attach_kernel_driver(_deviceHandle, LIGHTPACK_INTERFACE);
|
||||
libusb_close(_deviceHandle);
|
||||
|
||||
_deviceHandle = nullptr;
|
||||
}
|
||||
|
||||
if (_libusbContext != nullptr)
|
||||
{
|
||||
libusb_exit(_libusbContext);
|
||||
_libusbContext = nullptr;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int LedDeviceLightpack::testAndOpen(libusb_device * device, const QString & requestedSerialNumber)
|
||||
@@ -184,7 +178,7 @@ int LedDeviceLightpack::testAndOpen(libusb_device * device, const QString & requ
|
||||
if ((deviceDescriptor.idVendor == USB_VENDOR_ID && deviceDescriptor.idProduct == USB_PRODUCT_ID) ||
|
||||
(deviceDescriptor.idVendor == USB_OLD_VENDOR_ID && deviceDescriptor.idProduct == USB_OLD_PRODUCT_ID))
|
||||
{
|
||||
Info(_log, "Found a lightpack device. Retrieving more information...");
|
||||
Info(_log, "Found a Lightpack device. Retrieving more information...");
|
||||
|
||||
// get the hardware address
|
||||
int busNumber = libusb_get_bus_number(device);
|
||||
@@ -226,7 +220,7 @@ int LedDeviceLightpack::testAndOpen(libusb_device * device, const QString & requ
|
||||
uint8_t buffer[256];
|
||||
error = libusb_control_transfer(
|
||||
_deviceHandle,
|
||||
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
static_cast<uint8_t>( LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE),
|
||||
0x01,
|
||||
0x0100,
|
||||
0,
|
||||
@@ -289,19 +283,19 @@ int LedDeviceLightpack::testAndOpen(libusb_device * device, const QString & requ
|
||||
|
||||
int LedDeviceLightpack::write(const std::vector<ColorRgb> &ledValues)
|
||||
{
|
||||
return write(ledValues.data(), ledValues.size());
|
||||
return write(ledValues.data(), static_cast<int>(ledValues.size()));
|
||||
}
|
||||
|
||||
int LedDeviceLightpack::write(const ColorRgb * ledValues, int size)
|
||||
{
|
||||
int count = qMin(_hwLedCount, static_cast<int>( _ledCount));
|
||||
int count = qMin(_hwLedCount, static_cast<int>( size ));
|
||||
|
||||
for (int i = 0; i < count ; ++i)
|
||||
{
|
||||
const ColorRgb & color = ledValues[i];
|
||||
|
||||
// copy the most significant bits of the rgb values to the first three bytes
|
||||
// offset 1 to accomodate for the command byte
|
||||
// copy the most significant bits of the RGB values to the first three bytes
|
||||
// offset 1 to accommodate for the command byte
|
||||
_ledBuffer[6*i+1] = color.red;
|
||||
_ledBuffer[6*i+2] = color.green;
|
||||
_ledBuffer[6*i+3] = color.blue;
|
||||
@@ -315,14 +309,13 @@ int LedDeviceLightpack::write(const ColorRgb * ledValues, int size)
|
||||
return error >= 0 ? 0 : error;
|
||||
}
|
||||
|
||||
int LedDeviceLightpack::switchOff()
|
||||
bool LedDeviceLightpack::powerOff()
|
||||
{
|
||||
int rc = LedDevice::switchOff();
|
||||
if ( _deviceReady )
|
||||
{
|
||||
unsigned char buf[1] = {CMD_OFF_ALL};
|
||||
rc = writeBytes(buf, sizeof(buf)) == sizeof(buf);
|
||||
}
|
||||
bool rc = false;
|
||||
|
||||
unsigned char buf[1] = {CMD_OFF_ALL};
|
||||
rc = writeBytes(buf, sizeof(buf)) == sizeof(buf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -338,7 +331,7 @@ int LedDeviceLightpack::writeBytes(uint8_t *data, int size)
|
||||
// std::cout << std::endl;
|
||||
|
||||
int error = libusb_control_transfer(_deviceHandle,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
static_cast<uint8_t>( LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE ),
|
||||
0x09,
|
||||
(2 << 8),
|
||||
0x00,
|
||||
@@ -356,7 +349,13 @@ int LedDeviceLightpack::writeBytes(uint8_t *data, int size)
|
||||
int LedDeviceLightpack::disableSmoothing()
|
||||
{
|
||||
unsigned char buf[2] = {CMD_SET_SMOOTH_SLOWDOWN, 0};
|
||||
return writeBytes(buf, sizeof(buf)) == sizeof(buf);
|
||||
|
||||
int rc = 0;
|
||||
if ( writeBytes(buf, sizeof(buf)) == sizeof(buf) )
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
libusb_device_handle * LedDeviceLightpack::openDevice(libusb_device *device)
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef LEDEVICELIGHTPACK_H
|
||||
#define LEDEVICELIGHTPACK_H
|
||||
|
||||
// stl includes
|
||||
#include <cstdint>
|
||||
@@ -15,79 +16,93 @@
|
||||
class LedDeviceLightpack : public LedDevice
|
||||
{
|
||||
public:
|
||||
|
||||
///
|
||||
/// Constructs the LedDeviceLightpack
|
||||
/// @brief Constructs a Lightpack LED-device
|
||||
///
|
||||
/// @param serialNumber serial output device
|
||||
///
|
||||
LedDeviceLightpack(const QString & serialNumber = "");
|
||||
explicit LedDeviceLightpack(const QString & serialNumber = "");
|
||||
|
||||
///
|
||||
/// Constructs specific LedDevice
|
||||
/// @brief Constructs a Lightpack LED-device
|
||||
///
|
||||
/// @param deviceConfig json device config
|
||||
/// @param deviceConfig Device's configuration as JSON-Object
|
||||
///
|
||||
explicit LedDeviceLightpack(const QJsonObject &deviceConfig);
|
||||
|
||||
///
|
||||
/// Sets configuration
|
||||
///
|
||||
/// @param deviceConfig the json device config
|
||||
/// @return true if success
|
||||
bool init(const QJsonObject &deviceConfig) override;
|
||||
|
||||
/// constructs leddevice
|
||||
static LedDevice* construct(const QJsonObject &deviceConfig);
|
||||
|
||||
///
|
||||
/// Destructor of the LedDevice; closes the output device if it is open
|
||||
/// @brief Destructor of the LedDevice
|
||||
///
|
||||
virtual ~LedDeviceLightpack() override;
|
||||
|
||||
///
|
||||
/// Opens and configures the output device
|
||||
/// @brief Constructs the LED-device
|
||||
///
|
||||
/// @return Zero on succes else negative
|
||||
/// @param[in] deviceConfig Device's configuration as JSON-Object
|
||||
/// @return LedDevice constructed
|
||||
///
|
||||
int open() override;
|
||||
static LedDevice* construct(const QJsonObject &deviceConfig);
|
||||
|
||||
///
|
||||
/// Writes the RGB-Color values to the leds.
|
||||
/// @brief Initialise the device's configuration
|
||||
///
|
||||
/// @param[in] deviceConfig the JSON device configuration
|
||||
/// @return True, if success
|
||||
///
|
||||
virtual bool init(const QJsonObject &deviceConfig) override;
|
||||
|
||||
///
|
||||
/// @brief Opens the output device.
|
||||
///
|
||||
/// @return Zero on success (i.e. device is ready), else negative
|
||||
///
|
||||
virtual int open() override;
|
||||
|
||||
///
|
||||
/// @brief Closes the output device.
|
||||
///
|
||||
/// @return Zero on success (i.e. device is closed), else negative
|
||||
///
|
||||
virtual int close() override;
|
||||
|
||||
///
|
||||
/// @brief Power-/turn off the Nanoleaf device.
|
||||
///
|
||||
/// @return True if success
|
||||
///
|
||||
virtual bool powerOff() override;
|
||||
|
||||
///
|
||||
/// @brief Writes the RGB-Color values to the LEDs.
|
||||
///
|
||||
/// @param[in] ledValues Array of RGB values
|
||||
/// @param[in] size The number of RGB values
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
/// @return Zero on success, else negative
|
||||
///
|
||||
int write(const ColorRgb * ledValues, int size);
|
||||
|
||||
///
|
||||
/// Switch the leds off
|
||||
/// @brief Get the serial number of the Lightpack
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
virtual int switchOff() override;
|
||||
|
||||
/// Get the serial of the Lightpack
|
||||
/// @return Serial Number
|
||||
/// ///
|
||||
const QString & getSerialNumber() const;
|
||||
|
||||
public slots:
|
||||
///
|
||||
/// Closes the output device.
|
||||
/// Includes switching-off the device and stopping refreshes
|
||||
///
|
||||
virtual void close() override;
|
||||
bool isOpen(){ return _isOpen; }
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
/// @brief Writes the RGB-Color values to the LEDs.
|
||||
///
|
||||
/// @param[in] ledValues The RGB-color per LED
|
||||
/// @return Zero on success, else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb> & ledValues) override;
|
||||
|
||||
private:
|
||||
///
|
||||
/// Writes the RGB-Color values to the leds.
|
||||
///
|
||||
/// @param[in] ledValues The RGB-color per led
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb>& ledValues) override;
|
||||
|
||||
///
|
||||
/// Test if the device is a (or the) lightpack we are looking for
|
||||
@@ -114,6 +129,9 @@ private:
|
||||
/// libusb context
|
||||
libusb_context * _libusbContext;
|
||||
|
||||
/// libusb device
|
||||
libusb_device * _device;
|
||||
|
||||
/// libusb device handle
|
||||
libusb_device_handle * _deviceHandle;
|
||||
|
||||
@@ -134,4 +152,8 @@ private:
|
||||
|
||||
/// count of real hardware leds
|
||||
int _hwLedCount;
|
||||
|
||||
bool _isOpen;
|
||||
};
|
||||
|
||||
#endif // LEDEVICELIGHTPACK_H
|
||||
|
@@ -22,14 +22,19 @@ LedDeviceMultiLightpack::LedDeviceMultiLightpack(const QJsonObject &deviceConfig
|
||||
, _lightpacks()
|
||||
{
|
||||
_devConfig = deviceConfig;
|
||||
_deviceReady = false;
|
||||
_isDeviceReady = false;
|
||||
|
||||
_activeDeviceType = deviceConfig["type"].toString("UNSPECIFIED").toLower();
|
||||
}
|
||||
|
||||
LedDeviceMultiLightpack::~LedDeviceMultiLightpack()
|
||||
{
|
||||
for (LedDeviceLightpack * device : _lightpacks)
|
||||
{
|
||||
delete device;
|
||||
if ( device != nullptr)
|
||||
{
|
||||
delete device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,14 +43,12 @@ LedDevice* LedDeviceMultiLightpack::construct(const QJsonObject &deviceConfig)
|
||||
return new LedDeviceMultiLightpack(deviceConfig);
|
||||
}
|
||||
|
||||
int LedDeviceMultiLightpack::open()
|
||||
bool LedDeviceMultiLightpack::init(const QJsonObject &deviceConfig)
|
||||
{
|
||||
int retval = -1;
|
||||
QString errortext;
|
||||
_deviceReady = false;
|
||||
bool isInitOK = false;
|
||||
|
||||
// General initialisation and configuration of LedDevice
|
||||
if ( init(_devConfig) )
|
||||
// Initialise sub-class
|
||||
if ( LedDevice::init(deviceConfig) )
|
||||
{
|
||||
// retrieve a list with Lightpack serials
|
||||
QStringList serialList = getLightpackSerials();
|
||||
@@ -53,47 +56,84 @@ int LedDeviceMultiLightpack::open()
|
||||
// sort the list of Lightpacks based on the serial to get a fixed order
|
||||
std::sort(_lightpacks.begin(), _lightpacks.end(), compareLightpacks);
|
||||
|
||||
// open each lightpack device
|
||||
// open each Lightpack device
|
||||
for (auto serial : serialList)
|
||||
{
|
||||
LedDeviceLightpack * device = new LedDeviceLightpack(serial);
|
||||
int error = device->open();
|
||||
QJsonObject devConfig;
|
||||
devConfig["serial"] = serial;
|
||||
devConfig["latchTime"] = deviceConfig["latchTime"];
|
||||
devConfig["rewriteTime"] = deviceConfig["rewriteTime"];
|
||||
|
||||
if (error == 0)
|
||||
LedDeviceLightpack * device = new LedDeviceLightpack(devConfig);
|
||||
|
||||
device->start();
|
||||
if (device->open() == 0)
|
||||
{
|
||||
_lightpacks.push_back(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Error(_log, "Error while creating Lightpack device with serial %s", QSTRING_CSTR(serial));
|
||||
errortext = QString ("Error while creating Lightpack device with serial %1").arg( serial );
|
||||
Error(_log, "Error while creating Lightpack device with serial %s", QSTRING_CSTR(serial));
|
||||
delete device;
|
||||
}
|
||||
}
|
||||
|
||||
if (_lightpacks.size() == 0)
|
||||
if (_lightpacks.empty())
|
||||
{
|
||||
//Warning(_log, "No Lightpack devices were found");
|
||||
errortext = QString ("No Lightpack devices were found");
|
||||
QString errortext = QString ("No Lightpack devices were found");
|
||||
this->setInError(errortext);
|
||||
isInitOK = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info(_log, "%d Lightpack devices were found", _lightpacks.size());
|
||||
|
||||
// Everything is OK -> enable device
|
||||
_deviceReady = true;
|
||||
setEnable(true);
|
||||
retval = 0;
|
||||
}
|
||||
// On error/exceptions, set LedDevice in error
|
||||
if ( retval < 0 )
|
||||
{
|
||||
this->setInError( errortext );
|
||||
isInitOK = true;
|
||||
}
|
||||
}
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
int LedDeviceMultiLightpack::open()
|
||||
{
|
||||
int retval = -1;
|
||||
_isDeviceReady = false;
|
||||
|
||||
int lightsInError = 0;
|
||||
// open each Lightpack device
|
||||
for (LedDeviceLightpack * device : _lightpacks)
|
||||
{
|
||||
if (device->open() < 0)
|
||||
{
|
||||
Error( _log, "Failed to open [%s]", QSTRING_CSTR(device->getSerialNumber()) );
|
||||
++lightsInError;
|
||||
}
|
||||
}
|
||||
|
||||
if ( lightsInError < static_cast<int>(_lightpacks.size()) )
|
||||
{
|
||||
// Everything is OK -> enable device
|
||||
_isDeviceReady = true;
|
||||
retval = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setInError( "All Lightpacks failed to be opened!" );
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int LedDeviceMultiLightpack::close()
|
||||
{
|
||||
_isDeviceReady = false;
|
||||
|
||||
for (LedDeviceLightpack * device : _lightpacks)
|
||||
{
|
||||
device->close();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LedDeviceMultiLightpack::write(const std::vector<ColorRgb> &ledValues)
|
||||
{
|
||||
const ColorRgb * data = ledValues.data();
|
||||
@@ -105,7 +145,10 @@ int LedDeviceMultiLightpack::write(const std::vector<ColorRgb> &ledValues)
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
device->write(data, count);
|
||||
if ( device->isOpen() )
|
||||
{
|
||||
device->write(data, count);
|
||||
}
|
||||
|
||||
data += count;
|
||||
size -= count;
|
||||
@@ -119,14 +162,16 @@ int LedDeviceMultiLightpack::write(const std::vector<ColorRgb> &ledValues)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LedDeviceMultiLightpack::switchOff()
|
||||
bool LedDeviceMultiLightpack::powerOff()
|
||||
{
|
||||
for (LedDeviceLightpack * device : _lightpacks)
|
||||
{
|
||||
device->switchOff();
|
||||
if ( device->isOpen() )
|
||||
{
|
||||
device->powerOff();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList LedDeviceMultiLightpack::getLightpackSerials()
|
||||
@@ -135,7 +180,7 @@ QStringList LedDeviceMultiLightpack::getLightpackSerials()
|
||||
Logger * log = Logger::getInstance("LedDevice");
|
||||
Debug(log, "Getting list of Lightpack serials");
|
||||
|
||||
// initialize the usb context
|
||||
// initialize the USB context
|
||||
libusb_context * libusbContext;
|
||||
int error = libusb_init(&libusbContext);
|
||||
if (error != LIBUSB_SUCCESS)
|
||||
@@ -147,7 +192,7 @@ QStringList LedDeviceMultiLightpack::getLightpackSerials()
|
||||
//libusb_set_debug(_libusbContext, 3);
|
||||
Info(log, "USB context initialized in multi Lightpack device");
|
||||
|
||||
// retrieve the list of usb devices
|
||||
// retrieve the list of USB devices
|
||||
libusb_device ** deviceList;
|
||||
ssize_t deviceCount = libusb_get_device_list(libusbContext, &deviceList);
|
||||
|
||||
@@ -165,7 +210,7 @@ QStringList LedDeviceMultiLightpack::getLightpackSerials()
|
||||
if ((deviceDescriptor.idVendor == USB_VENDOR_ID && deviceDescriptor.idProduct == USB_PRODUCT_ID) ||
|
||||
(deviceDescriptor.idVendor == USB_OLD_VENDOR_ID && deviceDescriptor.idProduct == USB_OLD_PRODUCT_ID))
|
||||
{
|
||||
Info(log, "Found a lightpack device. Retrieving serial...");
|
||||
Info(log, "Found a Lightpack device. Retrieving serial...");
|
||||
|
||||
// get the serial number
|
||||
QString serialNumber;
|
||||
@@ -183,7 +228,7 @@ QStringList LedDeviceMultiLightpack::getLightpackSerials()
|
||||
}
|
||||
}
|
||||
|
||||
Error(log, "Lightpack device found with serial %s", QSTRING_CSTR(serialNumber));;
|
||||
Info(log, "Lightpack device found with serial %s", QSTRING_CSTR(serialNumber));
|
||||
serialList.append(serialNumber);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef LEDEVICEMULTILIGHTPACK_H
|
||||
#define LEDEVICEMULTILIGHTPACK_H
|
||||
|
||||
// stl includes
|
||||
#include <vector>
|
||||
@@ -19,43 +20,67 @@
|
||||
class LedDeviceMultiLightpack : public LedDevice
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs specific LedDevice
|
||||
///
|
||||
explicit LedDeviceMultiLightpack(const QJsonObject &);
|
||||
|
||||
///
|
||||
/// Destructor of the LedDevice; closes the output device if it is open
|
||||
/// @brief Constructs a LedDevice of multiple Lightpack LED-devices
|
||||
///
|
||||
/// @param deviceConfig Device's configuration as JSON-Object
|
||||
///
|
||||
explicit LedDeviceMultiLightpack(const QJsonObject &deviceConfig);
|
||||
|
||||
///
|
||||
/// @brief Destructor of the LedDevice
|
||||
///
|
||||
virtual ~LedDeviceMultiLightpack() override;
|
||||
|
||||
/// constructs leddevice
|
||||
///
|
||||
/// @brief Constructs the LED-device
|
||||
///
|
||||
/// @param[in] deviceConfig Device's configuration as JSON-Object
|
||||
/// @return LedDevice constructed
|
||||
///
|
||||
static LedDevice* construct(const QJsonObject &deviceConfig);
|
||||
|
||||
///
|
||||
virtual int switchOff() override;
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
/// Opens and configures the output device7
|
||||
/// @brief Initialise the device's configuration
|
||||
///
|
||||
/// @return Zero on succes else negative
|
||||
/// @param[in] deviceConfig the JSON device configuration
|
||||
/// @return True, if success
|
||||
///
|
||||
int open() override;
|
||||
virtual bool init(const QJsonObject &deviceConfig) override;
|
||||
|
||||
///
|
||||
/// Switch the leds off
|
||||
/// @brief Opens the output device.
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
/// @return Zero on success (i.e. device is ready), else negative
|
||||
///
|
||||
virtual int open() override;
|
||||
|
||||
///
|
||||
/// @brief Closes the output device.
|
||||
///
|
||||
/// @return Zero on success (i.e. device is closed), else negative
|
||||
///
|
||||
virtual int close() override;
|
||||
|
||||
///
|
||||
/// @brief Power-/turn off the Nanoleaf device.
|
||||
///
|
||||
/// @return True if success
|
||||
///
|
||||
virtual bool powerOff() override;
|
||||
|
||||
///
|
||||
/// @brief Writes the RGB-Color values to the LEDs.
|
||||
///
|
||||
/// @param[in] ledValues The RGB-color per LED
|
||||
/// @return Zero on success, else negative
|
||||
///
|
||||
int write(const std::vector<ColorRgb> & ledValues) override;
|
||||
|
||||
private:
|
||||
///
|
||||
/// Writes the RGB-Color values to the leds.
|
||||
///
|
||||
/// @param[in] ledValues The RGB-color per led
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb>& ledValues) override;
|
||||
|
||||
static QStringList getLightpackSerials();
|
||||
static QString getString(libusb_device * device, int stringDescriptorIndex);
|
||||
@@ -63,3 +88,5 @@ private:
|
||||
/// buffer for led data
|
||||
std::vector<LedDeviceLightpack *> _lightpacks;
|
||||
};
|
||||
|
||||
#endif // LEDEVICEMULTILIGHTPACK_H
|
||||
|
@@ -5,9 +5,11 @@ LedDevicePaintpack::LedDevicePaintpack(const QJsonObject &deviceConfig)
|
||||
: ProviderHID()
|
||||
{
|
||||
_devConfig = deviceConfig;
|
||||
_deviceReady = false;
|
||||
_isDeviceReady = false;
|
||||
|
||||
_useFeature = false;
|
||||
|
||||
_activeDeviceType = deviceConfig["type"].toString("UNSPECIFIED").toLower();
|
||||
}
|
||||
|
||||
LedDevice* LedDevicePaintpack::construct(const QJsonObject &deviceConfig)
|
||||
@@ -17,12 +19,17 @@ LedDevice* LedDevicePaintpack::construct(const QJsonObject &deviceConfig)
|
||||
|
||||
bool LedDevicePaintpack::init(const QJsonObject &deviceConfig)
|
||||
{
|
||||
bool isInitOK = ProviderHID::init(deviceConfig);
|
||||
bool isInitOK = false;
|
||||
|
||||
_ledBuffer.resize(_ledRGBCount + 2, uint8_t(0));
|
||||
_ledBuffer[0] = 3;
|
||||
_ledBuffer[1] = 0;
|
||||
// Initialise sub-class
|
||||
if ( ProviderHID::init(deviceConfig) )
|
||||
{
|
||||
_ledBuffer.resize(_ledRGBCount + 2, uint8_t(0));
|
||||
_ledBuffer[0] = 3;
|
||||
_ledBuffer[1] = 0;
|
||||
|
||||
isInitOK = true;
|
||||
}
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
|
@@ -1,38 +1,48 @@
|
||||
#pragma once
|
||||
#ifndef LEDEVICEPAINTTPACK_H
|
||||
#define LEDEVICEPAINTTPACK_H
|
||||
|
||||
// Hyperion includes
|
||||
#include "ProviderHID.h"
|
||||
|
||||
///
|
||||
/// LedDevice implementation for a paintpack device ()
|
||||
/// LedDevice implementation for a paintpack LED-device
|
||||
///
|
||||
class LedDevicePaintpack : public ProviderHID
|
||||
{
|
||||
public:
|
||||
|
||||
///
|
||||
/// Constructs specific LedDevice
|
||||
/// @brief Constructs a Paintpack LED-device
|
||||
///
|
||||
/// @param deviceConfig json device config
|
||||
/// @param deviceConfig Device's configuration as JSON-Object
|
||||
///
|
||||
explicit LedDevicePaintpack(const QJsonObject &deviceConfig);
|
||||
|
||||
/// constructs leddevice
|
||||
///
|
||||
/// @brief Constructs the LED-device
|
||||
///
|
||||
/// @param[in] deviceConfig Device's configuration as JSON-Object
|
||||
/// @return LedDevice constructed
|
||||
///
|
||||
static LedDevice* construct(const QJsonObject &deviceConfig);
|
||||
|
||||
private:
|
||||
|
||||
///
|
||||
/// Sets configuration
|
||||
/// @brief Initialise the device's configuration
|
||||
///
|
||||
/// @param[in] deviceConfig the JSON device configuration
|
||||
/// @return True, if success
|
||||
///
|
||||
/// @param deviceConfig the json device config
|
||||
/// @return true if success
|
||||
virtual bool init(const QJsonObject &deviceConfig) override;
|
||||
|
||||
private:
|
||||
///
|
||||
/// Writes the RGB-Color values to the leds.
|
||||
/// @brief Writes the RGB-Color values to the LEDs.
|
||||
///
|
||||
/// @param[in] ledValues The RGB-color per led
|
||||
/// @param[in] ledValues The RGB-color per LED
|
||||
/// @return Zero on success, else negative
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb>& ledValues) override;
|
||||
virtual int write(const std::vector<ColorRgb> & ledValues) override;
|
||||
};
|
||||
|
||||
#endif // LEDEVICEPAINTTPACK_H
|
||||
|
@@ -5,7 +5,9 @@ LedDeviceRawHID::LedDeviceRawHID(const QJsonObject &deviceConfig)
|
||||
: ProviderHID()
|
||||
{
|
||||
_devConfig = deviceConfig;
|
||||
_deviceReady = false;
|
||||
_isDeviceReady = false;
|
||||
|
||||
_activeDeviceType = deviceConfig["type"].toString("UNSPECIFIED").toLower();
|
||||
|
||||
_useFeature = true;
|
||||
}
|
||||
@@ -17,10 +19,14 @@ LedDevice* LedDeviceRawHID::construct(const QJsonObject &deviceConfig)
|
||||
|
||||
bool LedDeviceRawHID::init(const QJsonObject &deviceConfig)
|
||||
{
|
||||
bool isInitOK = ProviderHID::init(deviceConfig);
|
||||
|
||||
_ledBuffer.resize(_ledRGBCount);
|
||||
bool isInitOK = false;
|
||||
|
||||
// Initialise sub-class
|
||||
if ( ProviderHID::init(deviceConfig) )
|
||||
{
|
||||
_ledBuffer.resize(_ledRGBCount);
|
||||
isInitOK = true;
|
||||
}
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef LEDEVICERAWHID_H
|
||||
#define LEDEVICERAWHID_H
|
||||
|
||||
// Qt includes
|
||||
#include <QTimer>
|
||||
@@ -11,31 +12,40 @@
|
||||
///
|
||||
class LedDeviceRawHID : public ProviderHID
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
/// Constructs specific LedDevice
|
||||
/// @brief Constructs a Raw-HID LED-device
|
||||
///
|
||||
/// @param deviceConfig json device config
|
||||
/// @param deviceConfig Device's configuration as JSON-Object
|
||||
///
|
||||
explicit LedDeviceRawHID(const QJsonObject &deviceConfig);
|
||||
|
||||
/// constructs leddevice
|
||||
///
|
||||
/// @brief Constructs the LED-device
|
||||
///
|
||||
/// @param[in] deviceConfig Device's configuration as JSON-Object
|
||||
/// @return LedDevice constructed
|
||||
///
|
||||
static LedDevice* construct(const QJsonObject &deviceConfig);
|
||||
|
||||
private:
|
||||
|
||||
///
|
||||
/// Sets configuration
|
||||
/// @brief Initialise the device's configuration
|
||||
///
|
||||
/// @param[in] deviceConfig the JSON device configuration
|
||||
/// @return True, if success
|
||||
///
|
||||
/// @param deviceConfig the json device config
|
||||
/// @return true if success
|
||||
virtual bool init(const QJsonObject &deviceConfig) override;
|
||||
|
||||
private:
|
||||
///
|
||||
/// Writes the led color values to the led-device
|
||||
/// @brief Writes the RGB-Color values to the LEDs.
|
||||
///
|
||||
/// @param ledValues The color-value per led
|
||||
/// @return Zero on succes else negative
|
||||
/// @param[in] ledValues The RGB-color per LED
|
||||
/// @return Zero on success, else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb> & ledValues) override;
|
||||
};
|
||||
|
||||
#endif // LEDEVICERAWHID_H
|
||||
|
@@ -21,54 +21,59 @@ ProviderHID::ProviderHID()
|
||||
|
||||
ProviderHID::~ProviderHID()
|
||||
{
|
||||
if (_deviceHandle != nullptr)
|
||||
{
|
||||
hid_close(_deviceHandle);
|
||||
}
|
||||
hid_exit();
|
||||
}
|
||||
|
||||
bool ProviderHID::init(const QJsonObject &deviceConfig)
|
||||
{
|
||||
bool isInitOK = LedDevice::init(deviceConfig);
|
||||
bool isInitOK = false;
|
||||
|
||||
_delayAfterConnect_ms = deviceConfig["delayAfterConnect"].toInt(0);
|
||||
auto VendorIdString = deviceConfig["VID"].toString("0x2341").toStdString();
|
||||
auto ProductIdString = deviceConfig["PID"].toString("0x8036").toStdString();
|
||||
// Initialise sub-class
|
||||
if ( LedDevice::init(deviceConfig) )
|
||||
{
|
||||
_delayAfterConnect_ms = deviceConfig["delayAfterConnect"].toInt(0);
|
||||
auto VendorIdString = deviceConfig["VID"].toString("0x2341").toStdString();
|
||||
auto ProductIdString = deviceConfig["PID"].toString("0x8036").toStdString();
|
||||
|
||||
// Convert HEX values to integer
|
||||
_VendorId = std::stoul(VendorIdString, nullptr, 16);
|
||||
_ProductId = std::stoul(ProductIdString, nullptr, 16);
|
||||
// Convert HEX values to integer
|
||||
_VendorId = std::stoul(VendorIdString, nullptr, 16);
|
||||
_ProductId = std::stoul(ProductIdString, nullptr, 16);
|
||||
|
||||
// Initialize the USB context
|
||||
if ( hid_init() != 0)
|
||||
{
|
||||
this->setInError("Error initializing the HIDAPI context");
|
||||
isInitOK = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug(_log,"HIDAPI initialized");
|
||||
isInitOK = true;
|
||||
}
|
||||
}
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
int ProviderHID::open()
|
||||
{
|
||||
int retval = -1;
|
||||
QString errortext;
|
||||
_deviceReady = false;
|
||||
_isDeviceReady = false;
|
||||
|
||||
if ( init(_devConfig) )
|
||||
// Open the device
|
||||
Info(_log, "Opening device: VID %04hx PID %04hx\n", _VendorId, _ProductId);
|
||||
_deviceHandle = hid_open(_VendorId, _ProductId, nullptr);
|
||||
|
||||
if (_deviceHandle == nullptr)
|
||||
{
|
||||
// Initialize the usb context
|
||||
int error = hid_init();
|
||||
if (error != 0)
|
||||
{
|
||||
//Error(_log, "Error while initializing the hidapi context");
|
||||
errortext = "Error while initializing the hidapi context";
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug(_log,"Hidapi initialized");
|
||||
// Failed to open the device
|
||||
this->setInError( "Failed to open HID device. Maybe your PID/VID setting is wrong? Make sure to add a udev rule/use sudo." );
|
||||
|
||||
// Open the device
|
||||
Info(_log, "Opening device: VID %04hx PID %04hx\n", _VendorId, _ProductId);
|
||||
_deviceHandle = hid_open(_VendorId, _ProductId, nullptr);
|
||||
|
||||
if (_deviceHandle == nullptr)
|
||||
{
|
||||
// Failed to open the device
|
||||
Error(_log,"Failed to open HID device. Maybe your PID/VID setting is wrong? Make sure to add a udev rule/use sudo.");
|
||||
errortext = "Failed to open HID device";
|
||||
|
||||
// http://www.signal11.us/oss/hidapi/
|
||||
/*
|
||||
// http://www.signal11.us/oss/hidapi/
|
||||
/*
|
||||
std::cout << "Showing a list of all available HID devices:" << std::endl;
|
||||
auto devs = hid_enumerate(0x00, 0x00);
|
||||
auto cur_dev = devs;
|
||||
@@ -83,45 +88,38 @@ int ProviderHID::open()
|
||||
}
|
||||
hid_free_enumeration(devs);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
Info(_log,"Opened HID device successful");
|
||||
// Everything is OK -> enable device
|
||||
_deviceReady = true;
|
||||
setEnable(true);
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
// Wait after device got opened if enabled
|
||||
if (_delayAfterConnect_ms > 0)
|
||||
{
|
||||
_blockedForDelay = true;
|
||||
QTimer::singleShot(_delayAfterConnect_ms, this, SLOT(unblockAfterDelay()));
|
||||
Debug(_log, "Device blocked for %d ms", _delayAfterConnect_ms);
|
||||
}
|
||||
}
|
||||
// On error/exceptions, set LedDevice in error
|
||||
if ( retval < 0 )
|
||||
{
|
||||
this->setInError( errortext );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Info(_log,"Opened HID device successful");
|
||||
// Everything is OK -> enable device
|
||||
_isDeviceReady = true;
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
// Wait after device got opened if enabled
|
||||
if (_delayAfterConnect_ms > 0)
|
||||
{
|
||||
_blockedForDelay = true;
|
||||
QTimer::singleShot(_delayAfterConnect_ms, this, &ProviderHID::unblockAfterDelay );
|
||||
Debug(_log, "Device blocked for %d ms", _delayAfterConnect_ms);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void ProviderHID::close()
|
||||
int ProviderHID::close()
|
||||
{
|
||||
LedDevice::close();
|
||||
int retval = 0;
|
||||
_isDeviceReady = false;
|
||||
|
||||
// LedDevice specific closing activites
|
||||
// LedDevice specific closing activities
|
||||
if (_deviceHandle != nullptr)
|
||||
{
|
||||
hid_close(_deviceHandle);
|
||||
_deviceHandle = nullptr;
|
||||
}
|
||||
|
||||
hid_exit();
|
||||
return retval;
|
||||
}
|
||||
|
||||
int ProviderHID::writeBytes(const unsigned size, const uint8_t * data)
|
||||
@@ -138,7 +136,7 @@ int ProviderHID::writeBytes(const unsigned size, const uint8_t * data)
|
||||
// Try again in 3 seconds
|
||||
int delay_ms = 3000;
|
||||
_blockedForDelay = true;
|
||||
QTimer::singleShot(delay_ms, this, SLOT(unblockAfterDelay()));
|
||||
QTimer::singleShot(delay_ms, this, &ProviderHID::unblockAfterDelay );
|
||||
Debug(_log,"Device blocked for %d ms", delay_ms);
|
||||
}
|
||||
// Return here, to not write led data if the device should be blocked after connect
|
||||
@@ -188,3 +186,38 @@ void ProviderHID::unblockAfterDelay()
|
||||
Debug(_log,"Device unblocked");
|
||||
_blockedForDelay = false;
|
||||
}
|
||||
|
||||
QJsonObject ProviderHID::discover()
|
||||
{
|
||||
QJsonObject devicesDiscovered;
|
||||
devicesDiscovered.insert("ledDeviceType", _activeDeviceType );
|
||||
|
||||
QJsonArray deviceList;
|
||||
|
||||
// Discover HID Devices
|
||||
auto devs = hid_enumerate(0x00, 0x00);
|
||||
|
||||
if ( devs != nullptr )
|
||||
{
|
||||
auto cur_dev = devs;
|
||||
while (cur_dev)
|
||||
{
|
||||
QJsonObject deviceInfo;
|
||||
deviceInfo.insert("manufacturer",QString::fromWCharArray(cur_dev->manufacturer_string));
|
||||
deviceInfo.insert("path",cur_dev->path);
|
||||
deviceInfo.insert("productIdentifier", QString("0x%1").arg(static_cast<ushort>(cur_dev->product_id),0,16));
|
||||
deviceInfo.insert("release_number",QString("0x%1").arg(static_cast<ushort>(cur_dev->release_number),0,16));
|
||||
deviceInfo.insert("serialNumber",QString::fromWCharArray(cur_dev->serial_number));
|
||||
deviceInfo.insert("usage_page", QString("0x%1").arg(static_cast<ushort>(cur_dev->usage_page),0,16));
|
||||
deviceInfo.insert("vendorIdentifier", QString("0x%1").arg(static_cast<ushort>(cur_dev->vendor_id),0,16));
|
||||
deviceInfo.insert("interface_number",cur_dev->interface_number);
|
||||
deviceList.append(deviceInfo);
|
||||
|
||||
cur_dev = cur_dev->next;
|
||||
}
|
||||
hid_free_enumeration(devs);
|
||||
}
|
||||
|
||||
devicesDiscovered.insert("devices", deviceList);
|
||||
return devicesDiscovered;
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#ifndef PROVIDERHID_H
|
||||
#define PROVIDERHID_H
|
||||
|
||||
// libusb include
|
||||
#include <hidapi/hidapi.h>
|
||||
@@ -16,46 +15,57 @@ class ProviderHID : public LedDevice
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
/// Constructs specific LedDevice
|
||||
/// @brief Constructs a HID (USB) LED-device
|
||||
///
|
||||
/// @param deviceConfig Device's configuration as JSON-Object
|
||||
///
|
||||
ProviderHID();
|
||||
|
||||
///
|
||||
/// Destructor of the LedDevice; closes the output device if it is open
|
||||
/// @brief Destructor of the LedDevice
|
||||
///
|
||||
virtual ~ProviderHID() override;
|
||||
|
||||
///
|
||||
/// Sets configuration
|
||||
/// @brief Discover HIB (USB) devices available (for configuration).
|
||||
///
|
||||
/// @param deviceConfig the json device config
|
||||
/// @return true if success
|
||||
virtual bool init(const QJsonObject &deviceConfig) override;
|
||||
|
||||
public slots:
|
||||
/// @return A JSON structure holding a list of devices found
|
||||
///
|
||||
/// Closes the output device.
|
||||
/// Includes switching-off the device and stopping refreshes
|
||||
///
|
||||
virtual void close() override;
|
||||
virtual QJsonObject discover() override;
|
||||
|
||||
protected:
|
||||
///
|
||||
/// Opens and configures the output device
|
||||
///
|
||||
/// @return Zero on succes else negative
|
||||
///
|
||||
int open() override;
|
||||
|
||||
/**
|
||||
* Writes the given bytes to the HID-device and
|
||||
*
|
||||
* @param[in] size The length of the data
|
||||
* @param[in] data The data
|
||||
*
|
||||
* @return Zero on succes else negative
|
||||
*/
|
||||
///
|
||||
/// @brief Initialise the device's configuration
|
||||
///
|
||||
/// @param[in] deviceConfig the JSON device configuration
|
||||
/// @return True, if success
|
||||
///
|
||||
virtual bool init(const QJsonObject &deviceConfig) override;
|
||||
|
||||
///
|
||||
/// @brief Opens the output device.
|
||||
///
|
||||
/// @return Zero on success (i.e. device is ready), else negative
|
||||
///
|
||||
virtual int open() override;
|
||||
|
||||
///
|
||||
/// @brief Closes the output device.
|
||||
///
|
||||
/// @return Zero on success (i.e. device is closed), else negative
|
||||
///
|
||||
virtual int close() override;
|
||||
|
||||
///
|
||||
/// @brief Write the given bytes to the HID-device
|
||||
///
|
||||
/// @param[in[ size The length of the data
|
||||
/// @param[in] data The data
|
||||
/// @return Zero on success, else negative
|
||||
///
|
||||
int writeBytes(const unsigned size, const uint8_t *data);
|
||||
|
||||
// HID VID and PID
|
||||
@@ -74,4 +84,10 @@ protected:
|
||||
private slots:
|
||||
/// Unblock the device after a connection delay
|
||||
void unblockAfterDelay();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif // PROVIDERHID_H
|
||||
|
Reference in New Issue
Block a user