mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Razor Chroma Support - Initial version (#1054)
* Razor Chroma Support - Initial version * Address clang and lgtm findings * Razer Fixes * Merge branch 'master' into Razer_Chroma_Support # Conflicts: # assets/webconfig/i18n/en.json # assets/webconfig/js/content_leds.js # libsrc/leddevice/dev_net/ProviderRestApi.cpp # libsrc/leddevice/dev_net/ProviderRestApi.h * Corrections * Set default config for Razer * Simplify * Razer - Support individual LEDs and have default layout per device type * Differentiate between HWLEDCount and LayoutLEDCount * Revert "Differentiate between HWLEDCount and LayoutLEDCount" This reverts commit b147b215a5773a423184618ecb8dc9653d4870cc. * Correct LGTM finding * Disable verbose mode
This commit is contained in:
parent
25d79a9f3f
commit
67280b8566
@ -570,6 +570,7 @@
|
||||
"edt_dev_spec_port_title": "Port",
|
||||
"edt_dev_spec_printTimeStamp_title": "Add timestamp",
|
||||
"edt_dev_spec_pwmChannel_title": "PWM channel",
|
||||
"edt_dev_spec_razer_device_title": "Razer Chroma Device",
|
||||
"edt_dev_spec_restoreOriginalState_title": "Restore lights' state",
|
||||
"edt_dev_spec_restoreOriginalState_title_info": "Restore the device's original state when device is disabled",
|
||||
"edt_dev_spec_serial_title": "Serial number",
|
||||
|
@ -1,4 +1,3 @@
|
||||
var ledsCustomCfgInitialized = false;
|
||||
var onLedLayoutTab = false;
|
||||
var nonBlacklistLedArray = [];
|
||||
var ledBlacklist = [];
|
||||
@ -13,7 +12,7 @@ var canvas_width;
|
||||
var devRPiSPI = ['apa102', 'apa104', 'ws2801', 'lpd6803', 'lpd8806', 'p9813', 'sk6812spi', 'sk6822spi', 'sk9822', 'ws2812spi'];
|
||||
var devRPiPWM = ['ws281x'];
|
||||
var devRPiGPIO = ['piblaster'];
|
||||
var devNET = ['atmoorb', 'cololight', 'fadecandy', 'philipshue', 'nanoleaf', 'tinkerforge', 'tpm2net', 'udpe131', 'udpartnet', 'udph801', 'udpraw', 'wled', 'yeelight'];
|
||||
var devNET = ['atmoorb', 'cololight', 'fadecandy', 'philipshue', 'nanoleaf', 'razer', 'tinkerforge', 'tpm2net', 'udpe131', 'udpartnet', 'udph801', 'udpraw', 'wled', 'yeelight'];
|
||||
var devSerial = ['adalight', 'dmx', 'atmo', 'sedu', 'tpm2', 'karate'];
|
||||
var devHID = ['hyperionusbasp', 'lightpack', 'paintpack', 'rawhid'];
|
||||
|
||||
@ -614,10 +613,7 @@ $(document).ready(function () {
|
||||
var target = $(e.target).attr("href") // activated tab
|
||||
if (target == "#menu_gencfg") {
|
||||
onLedLayoutTab = true;
|
||||
if (!ledsCustomCfgInitialized) {
|
||||
$('#leds_custom_updsim').trigger('click');
|
||||
ledsCustomCfgInitialized = true;
|
||||
}
|
||||
} else {
|
||||
onLedLayoutTab = false;
|
||||
}
|
||||
@ -777,6 +773,16 @@ $(document).ready(function () {
|
||||
colorOrderDefault = "rgb";
|
||||
break;
|
||||
|
||||
case "razer":
|
||||
conf_editor.getEditor("root.generalOptions").disable();
|
||||
hwLedCountDefault = 1;
|
||||
colorOrderDefault = "bgr";
|
||||
|
||||
var subType = conf_editor.getEditor("root.specificOptions.subType").getValue();
|
||||
let params = { subType: subType };
|
||||
getProperties_device(ledType, subType, params);
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
|
||||
@ -1012,6 +1018,19 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
|
||||
conf_editor.watch('root.specificOptions.subType', () => {
|
||||
var subType = conf_editor.getEditor("root.specificOptions.subType").getValue();
|
||||
let params = {};
|
||||
|
||||
switch (ledType) {
|
||||
case "razer":
|
||||
params = { subType: subType };
|
||||
getProperties_device(ledType, subType, params);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
|
||||
conf_editor.watch('root.specificOptions.token', () => {
|
||||
var token = conf_editor.getEditor("root.specificOptions.token").getValue();
|
||||
|
||||
@ -1665,6 +1684,18 @@ function updateElements(ledType, key) {
|
||||
}
|
||||
break;
|
||||
|
||||
case "razer":
|
||||
var ledProperties = devicesProperties[ledType][key];
|
||||
if (ledProperties) {
|
||||
conf_editor.getEditor("root.generalOptions.hardwareLedCount").setValue(ledProperties.maxLedCount);
|
||||
$("#ip_ma_ledshoriz").val(ledProperties.maxColumn);
|
||||
$("#ip_ma_ledsvert").val(ledProperties.maxRow);
|
||||
$("#ip_ma_cabling").val("parallel");
|
||||
$("#ip_ma_start").val("top-left");
|
||||
createMatrixLeds();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ protected slots:
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
int rewriteLEDs();
|
||||
virtual int rewriteLEDs();
|
||||
|
||||
///
|
||||
/// @brief Set device in error state
|
||||
|
@ -35,6 +35,7 @@
|
||||
<file alias="schema-nanoleaf">schemas/schema-nanoleaf.json</file>
|
||||
<file alias="schema-wled">schemas/schema-wled.json</file>
|
||||
<file alias="schema-yeelight">schemas/schema-yeelight.json</file>
|
||||
<file alias="schema-razer">schemas/schema-razer.json</file>
|
||||
<file alias="schema-cololight">schemas/schema-cololight.json</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
399
libsrc/leddevice/dev_net/LedDeviceRazer.cpp
Normal file
399
libsrc/leddevice/dev_net/LedDeviceRazer.cpp
Normal file
@ -0,0 +1,399 @@
|
||||
#include "LedDeviceRazer.h"
|
||||
#include <utils/QStringUtils.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
|
||||
using namespace Chroma;
|
||||
using namespace Chroma::Keyboard;
|
||||
using namespace Chroma::Keypad;
|
||||
using namespace Chroma::Mouse;
|
||||
using namespace Chroma::Mousepad;
|
||||
using namespace Chroma::Headset;
|
||||
using namespace Chroma::Chromalink;
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
bool verbose = false;
|
||||
|
||||
// Configuration settings
|
||||
const char CONFIG_RAZER_DEVICE_TYPE[] = "subType";
|
||||
const char CONFIG_SINGLE_COLOR[] = "singleColor";
|
||||
|
||||
// WLED JSON-API elements
|
||||
const char API_DEFAULT_HOST[] = "localhost";
|
||||
const int API_DEFAULT_PORT = 54235;
|
||||
|
||||
const char API_BASE_PATH[] = "/razer/chromasdk";
|
||||
const char API_RESULT[] = "result";
|
||||
|
||||
constexpr std::chrono::milliseconds HEARTBEAT_INTERVALL{ 1000 };
|
||||
|
||||
} //End of constants
|
||||
|
||||
LedDeviceRazer::LedDeviceRazer(const QJsonObject& deviceConfig)
|
||||
: LedDevice(deviceConfig)
|
||||
, _restApi(nullptr)
|
||||
, _apiPort(API_DEFAULT_PORT)
|
||||
, _maxRow(Chroma::MAX_ROW)
|
||||
, _maxColumn(Chroma::MAX_COLUMN)
|
||||
, _maxLeds(Chroma::MAX_LEDS)
|
||||
{
|
||||
}
|
||||
|
||||
LedDevice* LedDeviceRazer::construct(const QJsonObject& deviceConfig)
|
||||
{
|
||||
return new LedDeviceRazer(deviceConfig);
|
||||
}
|
||||
|
||||
LedDeviceRazer::~LedDeviceRazer()
|
||||
{
|
||||
delete _restApi;
|
||||
_restApi = nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool LedDeviceRazer::init(const QJsonObject& deviceConfig)
|
||||
{
|
||||
bool isInitOK = false;
|
||||
setRewriteTime(HEARTBEAT_INTERVALL.count());
|
||||
connect(_refreshTimer, &QTimer::timeout, this, &LedDeviceRazer::rewriteLEDs);
|
||||
|
||||
// Initialise sub-class
|
||||
if (LedDevice::init(deviceConfig))
|
||||
{
|
||||
// Initialise LedDevice configuration and execution environment
|
||||
uint configuredLedCount = this->getLedCount();
|
||||
Debug(_log, "DeviceType : %s", QSTRING_CSTR(this->getActiveDeviceType()));
|
||||
Debug(_log, "LedCount : %u", configuredLedCount);
|
||||
Debug(_log, "ColorOrder : %s", QSTRING_CSTR(this->getColorOrder()));
|
||||
Debug(_log, "LatchTime : %d", this->getLatchTime());
|
||||
Debug(_log, "RefreshTime : %d", _refreshTimerInterval_ms);
|
||||
|
||||
//Razer Chroma SDK allows localhost connection only
|
||||
_hostname = API_DEFAULT_HOST;
|
||||
_apiPort = API_DEFAULT_PORT;
|
||||
|
||||
Debug(_log, "Hostname : %s", QSTRING_CSTR(_hostname));
|
||||
Debug(_log, "Port : %d", _apiPort);
|
||||
|
||||
_razerDeviceType = deviceConfig[CONFIG_RAZER_DEVICE_TYPE].toString("invalid").toLower();
|
||||
_isSingleColor = deviceConfig[CONFIG_SINGLE_COLOR].toBool();
|
||||
|
||||
Debug(_log, "Razer Device : %s", QSTRING_CSTR(_razerDeviceType));
|
||||
Debug(_log, "Single Color : %d", _isSingleColor);
|
||||
|
||||
if (resolveDeviceProperties(_razerDeviceType))
|
||||
{
|
||||
if (_isSingleColor && configuredLedCount > 1)
|
||||
{
|
||||
Info(_log, "In single color mode only the first LED of the configured [%d] will be used.", configuredLedCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_maxLeds != configuredLedCount)
|
||||
{
|
||||
Warning(_log, "Razer device might not work as expected. The type \"%s\" requires an LED-matrix [%d,%d] configured, i.e. %d LEDs. Currently only %d are defined via the layout.",
|
||||
QSTRING_CSTR(_razerDeviceType),
|
||||
_maxRow, _maxColumn, _maxLeds,
|
||||
configuredLedCount
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (initRestAPI(_hostname, _apiPort))
|
||||
{
|
||||
isInitOK = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Razer devicetype \"%s\" not supported", QSTRING_CSTR(_razerDeviceType));
|
||||
}
|
||||
}
|
||||
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
bool LedDeviceRazer::initRestAPI(const QString& hostname, int port)
|
||||
{
|
||||
bool isInitOK = false;
|
||||
|
||||
if (_restApi == nullptr)
|
||||
{
|
||||
_restApi = new ProviderRestApi(hostname, port);
|
||||
_restApi->setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
isInitOK = true;
|
||||
}
|
||||
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
bool LedDeviceRazer::checkApiError(const httpResponse& response)
|
||||
{
|
||||
bool apiError = false;
|
||||
|
||||
if (response.error())
|
||||
{
|
||||
this->setInError(response.getErrorReason());
|
||||
apiError = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
QString errorReason;
|
||||
|
||||
QString strJson(response.getBody().toJson(QJsonDocument::Compact));
|
||||
//DebugIf(verbose, _log, "Reply: [%s]", strJson.toUtf8().constData());
|
||||
|
||||
QJsonObject jsonObj = response.getBody().object();
|
||||
|
||||
if (!jsonObj[API_RESULT].isNull())
|
||||
{
|
||||
int resultCode = jsonObj[API_RESULT].toInt();
|
||||
|
||||
if (resultCode != 0)
|
||||
{
|
||||
errorReason = QString("Chroma SDK error (%1)").arg(resultCode);
|
||||
this->setInError(errorReason);
|
||||
apiError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return apiError;
|
||||
}
|
||||
|
||||
int LedDeviceRazer::open()
|
||||
{
|
||||
int retval = -1;
|
||||
_isDeviceReady = false;
|
||||
|
||||
// Try to open the LedDevice
|
||||
|
||||
QJsonObject obj;
|
||||
|
||||
obj.insert("title", "Hyperion - Razer Chroma");
|
||||
obj.insert("description", "Hyperion to Razer Chroma interface");
|
||||
|
||||
QJsonObject authorDetails;
|
||||
authorDetails.insert("name", "Hyperion Team");
|
||||
authorDetails.insert("contact", "https://github.com/hyperion-project/hyperion.ng");
|
||||
|
||||
obj.insert("author", authorDetails);
|
||||
obj.insert("device_supported", QJsonArray::fromStringList(Chroma::SupportedDevices));
|
||||
|
||||
obj.insert("category", "application");
|
||||
|
||||
_restApi->setPort(API_DEFAULT_PORT);
|
||||
_restApi->setBasePath(API_BASE_PATH);
|
||||
|
||||
httpResponse response = _restApi->post(obj);
|
||||
if (!checkApiError(response))
|
||||
{
|
||||
QJsonObject jsonObj = response.getBody().object();
|
||||
if (jsonObj["uri"].isNull())
|
||||
{
|
||||
this->setInError("Chroma SDK error. No 'uri' received");
|
||||
}
|
||||
else
|
||||
{
|
||||
_uri = jsonObj.value("uri").toString();
|
||||
_restApi->setUrl(_uri);
|
||||
|
||||
DebugIf(verbose, _log, "Session-ID: %d, uri [%s]", jsonObj.value("sessionid").toInt(), QSTRING_CSTR(_uri.toString()));
|
||||
|
||||
QJsonObject effectObj;
|
||||
effectObj.insert("effect", "CHROMA_STATIC");
|
||||
QJsonObject param;
|
||||
param.insert("color", 255);
|
||||
effectObj.insert("param", param);
|
||||
|
||||
_restApi->setPath(_razerDeviceType);
|
||||
response = _restApi->put(effectObj);
|
||||
|
||||
if (!checkApiError(response))
|
||||
{
|
||||
_restApi->setPath(_razerDeviceType);
|
||||
response = _restApi->put(effectObj);
|
||||
|
||||
if (!checkApiError(response))
|
||||
{
|
||||
// Everything is OK, device is ready
|
||||
_isDeviceReady = true;
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int LedDeviceRazer::close()
|
||||
{
|
||||
int retval = -1;
|
||||
_isDeviceReady = false;
|
||||
|
||||
if (!_uri.isEmpty())
|
||||
{
|
||||
httpResponse response = _restApi->deleteResource(_uri);
|
||||
if (!checkApiError(response))
|
||||
{
|
||||
// Everything is OK -> device is closed
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int LedDeviceRazer::write(const std::vector<ColorRgb>& ledValues)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
QJsonObject effectObj;
|
||||
|
||||
if (_isSingleColor)
|
||||
{
|
||||
//Static effect
|
||||
effectObj.insert("effect", "CHROMA_STATIC");
|
||||
|
||||
ColorRgb color = ledValues[0];
|
||||
int colorParam = (color.red * 65536) + (color.green * 256) + color.blue;
|
||||
|
||||
QJsonObject param;
|
||||
param.insert("color", colorParam);
|
||||
effectObj.insert("param", param);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Custom effect
|
||||
if (_customEffectType == Chroma::CHROMA_CUSTOM2)
|
||||
{
|
||||
effectObj.insert("effect", "CHROMA_CUSTOM2");
|
||||
}
|
||||
else {
|
||||
effectObj.insert("effect", "CHROMA_CUSTOM");
|
||||
}
|
||||
|
||||
QJsonArray rowParams;
|
||||
for (int row = 0; row < _maxRow; row++) {
|
||||
QJsonArray columnParams;
|
||||
for (int col = 0; col < _maxColumn; col++) {
|
||||
int pos = row * _maxColumn + col;
|
||||
int bgrColor;
|
||||
if (pos < ledValues.size())
|
||||
{
|
||||
bgrColor = (ledValues[pos].red * 65536) + (ledValues[pos].green * 256) + ledValues[pos].blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
bgrColor = 0;
|
||||
}
|
||||
columnParams.append(bgrColor);
|
||||
}
|
||||
|
||||
if (_maxRow == 1)
|
||||
{
|
||||
rowParams = columnParams;
|
||||
}
|
||||
else
|
||||
{
|
||||
rowParams.append(columnParams);
|
||||
}
|
||||
}
|
||||
effectObj.insert("param", rowParams);
|
||||
}
|
||||
|
||||
_restApi->setPath(_razerDeviceType);
|
||||
httpResponse response = _restApi->put(effectObj);
|
||||
if (!checkApiError(response))
|
||||
{
|
||||
retval = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int LedDeviceRazer::rewriteLEDs()
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
_restApi->setPath("heartbeat");
|
||||
httpResponse response = _restApi->put();
|
||||
if (!checkApiError(response))
|
||||
{
|
||||
retval = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool LedDeviceRazer::resolveDeviceProperties(const QString& deviceType)
|
||||
{
|
||||
bool rc = true;
|
||||
|
||||
int typeID = Chroma::SupportedDevices.indexOf(deviceType);
|
||||
|
||||
switch (typeID)
|
||||
{
|
||||
case Chroma::DEVICE_KEYBOARD:
|
||||
_maxRow = Chroma::Keyboard::MAX_ROW;
|
||||
_maxColumn = Chroma::Keyboard::MAX_COLUMN;
|
||||
_customEffectType = Chroma::Keyboard::CUSTOM_EFFECT_TYPE;
|
||||
break;
|
||||
case Chroma::DEVICE_MOUSE:
|
||||
_maxRow = Chroma::Mouse::MAX_ROW;
|
||||
_maxColumn = Chroma::Mouse::MAX_COLUMN;
|
||||
_customEffectType = Chroma::Mouse::CUSTOM_EFFECT_TYPE;
|
||||
break;
|
||||
case Chroma::DEVICE_HEADSET:
|
||||
_maxRow = Chroma::Headset::MAX_ROW;
|
||||
_maxColumn = Chroma::Headset::MAX_COLUMN;
|
||||
_customEffectType = Chroma::Headset::CUSTOM_EFFECT_TYPE;
|
||||
break;
|
||||
case Chroma::DEVICE_MOUSEPAD:
|
||||
_maxRow = Chroma::Mousepad::MAX_ROW;
|
||||
_maxColumn = Chroma::Mousepad::MAX_COLUMN;
|
||||
_customEffectType = Chroma::Mousepad::CUSTOM_EFFECT_TYPE;
|
||||
break;
|
||||
case Chroma::DEVICE_KEYPAD:
|
||||
_maxRow = Chroma::Keypad::MAX_ROW;
|
||||
_maxColumn = Chroma::Keypad::MAX_COLUMN;
|
||||
_customEffectType = Chroma::Keypad::CUSTOM_EFFECT_TYPE;
|
||||
break;
|
||||
case Chroma::DEVICE_CHROMALINK:
|
||||
_maxRow = Chroma::Chromalink::MAX_ROW;
|
||||
_maxColumn = Chroma::Chromalink::MAX_COLUMN;
|
||||
_customEffectType = Chroma::Chromalink::CUSTOM_EFFECT_TYPE;
|
||||
break;
|
||||
default:
|
||||
rc = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc)
|
||||
{
|
||||
_maxLeds = _maxRow * _maxColumn;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
QJsonObject LedDeviceRazer::getProperties(const QJsonObject& params)
|
||||
{
|
||||
DebugIf(verbose, _log, "params: [%s]", QString(QJsonDocument(params).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
QJsonObject properties;
|
||||
|
||||
_razerDeviceType = params[CONFIG_RAZER_DEVICE_TYPE].toString("invalid").toLower();
|
||||
if (resolveDeviceProperties(_razerDeviceType))
|
||||
{
|
||||
QJsonObject propertiesDetails;
|
||||
propertiesDetails.insert("maxRow", _maxRow);
|
||||
propertiesDetails.insert("maxColumn", _maxColumn);
|
||||
propertiesDetails.insert("maxLedCount", _maxLeds);
|
||||
|
||||
properties.insert("properties", propertiesDetails);
|
||||
|
||||
DebugIf(verbose, _log, "properties: [%s]", QString(QJsonDocument(properties).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
}
|
||||
return properties;
|
||||
}
|
212
libsrc/leddevice/dev_net/LedDeviceRazer.h
Normal file
212
libsrc/leddevice/dev_net/LedDeviceRazer.h
Normal file
@ -0,0 +1,212 @@
|
||||
#ifndef LEDEVICERAZER_H
|
||||
#define LEDEVICERAZER_H
|
||||
|
||||
// LedDevice includes
|
||||
#include <leddevice/LedDevice.h>
|
||||
#include "ProviderRestApi.h"
|
||||
|
||||
namespace Chroma
|
||||
{
|
||||
typedef enum DeviceType
|
||||
{
|
||||
DEVICE_KEYBOARD = 0,
|
||||
DEVICE_MOUSE = 1,
|
||||
DEVICE_HEADSET = 2,
|
||||
DEVICE_MOUSEPAD = 3,
|
||||
DEVICE_KEYPAD = 4,
|
||||
DEVICE_CHROMALINK = 5,
|
||||
DEVICE_SYSTEM = 6,
|
||||
DEVICE_SPEAKERS = 7,
|
||||
DEVICE_INVALID
|
||||
} DEVICETYPE;
|
||||
|
||||
typedef enum CustomEffectType
|
||||
{
|
||||
CHROMA_CUSTOM = 1,
|
||||
CHROMA_CUSTOM2 = 2,
|
||||
} CUSTOM_EFFECT_TYPE;
|
||||
|
||||
const int MAX_ROW = 30; //!< Maximum rows for custom effects.
|
||||
const int MAX_COLUMN = 30; //!< Maximum columns for custom effects.
|
||||
const int MAX_LEDS = MAX_ROW * MAX_COLUMN;
|
||||
|
||||
namespace Keyboard
|
||||
{
|
||||
const char TYPE_NAME[] = "keyboard";
|
||||
const int MAX_ROW = 6;
|
||||
const int MAX_COLUMN = 22;
|
||||
const CustomEffectType CUSTOM_EFFECT_TYPE = CHROMA_CUSTOM;
|
||||
}
|
||||
namespace Mouse
|
||||
{
|
||||
const char TYPE_NAME[] = "mouse";
|
||||
const int MAX_ROW = 9;
|
||||
const int MAX_COLUMN = 7;
|
||||
const CustomEffectType CUSTOM_EFFECT_TYPE = CHROMA_CUSTOM2;
|
||||
}
|
||||
namespace Headset
|
||||
{
|
||||
const char TYPE_NAME[] = "headset";
|
||||
const int MAX_ROW = 1;
|
||||
const int MAX_COLUMN = 5;
|
||||
const CustomEffectType CUSTOM_EFFECT_TYPE = CHROMA_CUSTOM;
|
||||
}
|
||||
namespace Mousepad
|
||||
{
|
||||
const char TYPE_NAME[] = "mousepad";
|
||||
const int MAX_ROW = 1;
|
||||
const int MAX_COLUMN = 15;
|
||||
const CustomEffectType CUSTOM_EFFECT_TYPE = CHROMA_CUSTOM;
|
||||
}
|
||||
namespace Keypad
|
||||
{
|
||||
const char TYPE_NAME[] = "keypad";
|
||||
const int MAX_ROW = 4;
|
||||
const int MAX_COLUMN = 5;
|
||||
const CustomEffectType CUSTOM_EFFECT_TYPE = CHROMA_CUSTOM;
|
||||
}
|
||||
namespace Chromalink
|
||||
{
|
||||
const char TYPE_NAME[] = "chromalink";
|
||||
const int MAX_ROW = 1;
|
||||
const int MAX_COLUMN = 5;
|
||||
const CustomEffectType CUSTOM_EFFECT_TYPE = CHROMA_CUSTOM;
|
||||
}
|
||||
|
||||
const QStringList SupportedDevices{
|
||||
Keyboard::TYPE_NAME,
|
||||
Mouse::TYPE_NAME,
|
||||
Headset::TYPE_NAME,
|
||||
Mousepad::TYPE_NAME,
|
||||
Keypad::TYPE_NAME,
|
||||
Chromalink::TYPE_NAME
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// Implementation of a Razer Chroma LedDevice
|
||||
/// Supported Razer Chroma device types: Keyboard, Mouse, Headset, Mousepad, Keypad, Chromalink
|
||||
///
|
||||
class LedDeviceRazer : public LedDevice
|
||||
{
|
||||
public:
|
||||
|
||||
///
|
||||
/// @brief Constructs a specific LED-device
|
||||
///
|
||||
/// @param deviceConfig Device's configuration as JSON-Object
|
||||
///
|
||||
explicit LedDeviceRazer(const QJsonObject& deviceConfig);
|
||||
|
||||
///
|
||||
/// @brief Constructs the LED-device
|
||||
///
|
||||
/// @param[in] deviceConfig Device's configuration as JSON-Object
|
||||
/// @return LedDevice constructed
|
||||
///
|
||||
static LedDevice* construct(const QJsonObject& deviceConfig);
|
||||
|
||||
///
|
||||
/// @brief Get a Razer device's resource properties
|
||||
///
|
||||
/// Following parameters are required
|
||||
/// @code
|
||||
/// {
|
||||
/// "subType" : "razer_device_type",
|
||||
/// }
|
||||
/// @endcode
|
||||
/// @param[in] params Parameters to query device
|
||||
/// @return A JSON structure holding the device's properties
|
||||
///
|
||||
QJsonObject getProperties(const QJsonObject& params) override;
|
||||
|
||||
///
|
||||
/// @brief Destructor of the LED-device
|
||||
///
|
||||
~LedDeviceRazer() override;
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
/// @brief Initialise the device's configuration
|
||||
///
|
||||
/// @param[in] deviceConfig the JSON device configuration
|
||||
/// @return True, if success
|
||||
///
|
||||
bool init(const QJsonObject& deviceConfig) override;
|
||||
|
||||
///
|
||||
/// @brief Opens the output device.
|
||||
///
|
||||
/// @return Zero on success (i.e. device is ready), else negative
|
||||
///
|
||||
int open() override;
|
||||
|
||||
///
|
||||
/// @brief Closes the output device.
|
||||
///
|
||||
/// @return Zero on success (i.e. device is closed), else negative
|
||||
///
|
||||
int close() 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;
|
||||
|
||||
protected slots:
|
||||
|
||||
///
|
||||
/// @brief Write the last data to the LEDs again.
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
int rewriteLEDs() override;
|
||||
|
||||
private:
|
||||
|
||||
///
|
||||
/// @brief Initialise the access to the REST-API wrapper
|
||||
///
|
||||
/// @param[in] host
|
||||
/// @param[in] port
|
||||
/// @return True, if success
|
||||
///
|
||||
bool initRestAPI(const QString& hostname, int port);
|
||||
|
||||
///
|
||||
/// @brief Check, if Chroma SDK API response failed
|
||||
///
|
||||
/// @param[in] http response, incl. the response by Chroma SDK in JSON-format
|
||||
/// return True, API call failed
|
||||
///
|
||||
bool checkApiError(const httpResponse& response);
|
||||
|
||||
///
|
||||
/// @brief Update object with properties for a given device
|
||||
///
|
||||
/// @param[in] deviceType
|
||||
/// return True, if success
|
||||
///
|
||||
bool resolveDeviceProperties(const QString& deviceType);
|
||||
|
||||
///REST-API wrapper
|
||||
ProviderRestApi* _restApi;
|
||||
|
||||
QString _hostname;
|
||||
int _apiPort;
|
||||
QUrl _uri;
|
||||
|
||||
QString _razerDeviceType;
|
||||
int _maxRow;
|
||||
int _maxColumn;
|
||||
int _maxLeds;
|
||||
Chroma::CustomEffectType _customEffectType;
|
||||
|
||||
bool _isSingleColor;
|
||||
};
|
||||
|
||||
#endif // LEDEVICERAZER_H
|
@ -14,6 +14,8 @@
|
||||
// Constants
|
||||
namespace {
|
||||
|
||||
bool verbose = false;
|
||||
|
||||
const QChar ONE_SLASH = '/';
|
||||
|
||||
const int HTTP_STATUS_NO_CONTENT = 204;
|
||||
@ -25,22 +27,19 @@ constexpr std::chrono::milliseconds DEFAULT_REST_TIMEOUT{ 400 };
|
||||
|
||||
} //End of constants
|
||||
|
||||
ProviderRestApi::ProviderRestApi(const QString &host, int port, const QString &basePath)
|
||||
ProviderRestApi::ProviderRestApi(const QString& host, int port, const QString& basePath)
|
||||
:_log(Logger::getInstance("LEDDEVICE"))
|
||||
,_networkManager(nullptr)
|
||||
,_scheme("http")
|
||||
,_hostname(host)
|
||||
,_port(port)
|
||||
, _networkManager(nullptr)
|
||||
{
|
||||
_networkManager = new QNetworkAccessManager();
|
||||
|
||||
_apiUrl.setScheme(_scheme);
|
||||
_apiUrl.setScheme("http");
|
||||
_apiUrl.setHost(host);
|
||||
_apiUrl.setPort(port);
|
||||
_basePath = basePath;
|
||||
}
|
||||
|
||||
ProviderRestApi::ProviderRestApi(const QString &host, int port)
|
||||
ProviderRestApi::ProviderRestApi(const QString& host, int port)
|
||||
: ProviderRestApi(host, port, "") {}
|
||||
|
||||
ProviderRestApi::ProviderRestApi()
|
||||
@ -51,40 +50,46 @@ ProviderRestApi::~ProviderRestApi()
|
||||
delete _networkManager;
|
||||
}
|
||||
|
||||
void ProviderRestApi::setBasePath(const QString &basePath)
|
||||
void ProviderRestApi::setUrl(const QUrl& url)
|
||||
{
|
||||
_apiUrl = url;
|
||||
_basePath = url.path();
|
||||
}
|
||||
|
||||
void ProviderRestApi::setBasePath(const QString& basePath)
|
||||
{
|
||||
_basePath.clear();
|
||||
appendPath (_basePath, basePath );
|
||||
appendPath(_basePath, basePath);
|
||||
}
|
||||
|
||||
void ProviderRestApi::setPath ( const QString &path )
|
||||
void ProviderRestApi::setPath(const QString& path)
|
||||
{
|
||||
_path.clear();
|
||||
appendPath (_path, path );
|
||||
appendPath(_path, path);
|
||||
}
|
||||
|
||||
void ProviderRestApi::appendPath ( const QString &path )
|
||||
void ProviderRestApi::appendPath(const QString& path)
|
||||
{
|
||||
appendPath (_path, path );
|
||||
appendPath(_path, path);
|
||||
}
|
||||
|
||||
void ProviderRestApi::appendPath ( QString& path, const QString &appendPath)
|
||||
{
|
||||
if ( !appendPath.isEmpty() && appendPath != ONE_SLASH )
|
||||
if (!appendPath.isEmpty() && appendPath != ONE_SLASH)
|
||||
{
|
||||
if (path.isEmpty() || path == ONE_SLASH )
|
||||
if (path.isEmpty() || path == ONE_SLASH)
|
||||
{
|
||||
path.clear();
|
||||
if (appendPath[0] != ONE_SLASH )
|
||||
if (appendPath[0] != ONE_SLASH)
|
||||
{
|
||||
path.push_back(ONE_SLASH);
|
||||
}
|
||||
}
|
||||
else if (path[path.size()-1] == ONE_SLASH && appendPath[0] == ONE_SLASH)
|
||||
else if (path[path.size() - 1] == ONE_SLASH && appendPath[0] == ONE_SLASH)
|
||||
{
|
||||
path.chop(1);
|
||||
}
|
||||
else if (path[path.size()-1] != ONE_SLASH && appendPath[0] != ONE_SLASH)
|
||||
else if (path[path.size() - 1] != ONE_SLASH && appendPath[0] != ONE_SLASH)
|
||||
{
|
||||
path.push_back(ONE_SLASH);
|
||||
}
|
||||
@ -97,12 +102,12 @@ void ProviderRestApi::appendPath ( QString& path, const QString &appendPath)
|
||||
}
|
||||
}
|
||||
|
||||
void ProviderRestApi::setFragment(const QString &fragment)
|
||||
void ProviderRestApi::setFragment(const QString& fragment)
|
||||
{
|
||||
_fragment = fragment;
|
||||
}
|
||||
|
||||
void ProviderRestApi::setQuery(const QUrlQuery &query)
|
||||
void ProviderRestApi::setQuery(const QUrlQuery& query)
|
||||
{
|
||||
_query = query;
|
||||
}
|
||||
@ -112,23 +117,25 @@ QUrl ProviderRestApi::getUrl() const
|
||||
QUrl url = _apiUrl;
|
||||
|
||||
QString fullPath = _basePath;
|
||||
appendPath (fullPath, _path );
|
||||
appendPath(fullPath, _path);
|
||||
|
||||
url.setPath(fullPath);
|
||||
url.setFragment( _fragment );
|
||||
url.setQuery( _query );
|
||||
url.setFragment(_fragment);
|
||||
url.setQuery(_query);
|
||||
return url;
|
||||
}
|
||||
|
||||
httpResponse ProviderRestApi::get()
|
||||
{
|
||||
return get( getUrl() );
|
||||
return get(getUrl());
|
||||
}
|
||||
|
||||
httpResponse ProviderRestApi::get(const QUrl &url)
|
||||
httpResponse ProviderRestApi::get(const QUrl& url)
|
||||
{
|
||||
// Perform request
|
||||
QNetworkRequest request(url);
|
||||
QNetworkRequest request(_networkRequestHeaders);
|
||||
request.setUrl(url);
|
||||
|
||||
QNetworkReply* reply = _networkManager->get(request);
|
||||
|
||||
// Connect requestFinished signal to quit slot of the loop.
|
||||
@ -141,7 +148,7 @@ httpResponse ProviderRestApi::get(const QUrl &url)
|
||||
loop.exec();
|
||||
|
||||
httpResponse response;
|
||||
if(reply->operation() == QNetworkAccessManager::GetOperation)
|
||||
if (reply->operation() == QNetworkAccessManager::GetOperation)
|
||||
{
|
||||
if(reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
@ -168,7 +175,9 @@ httpResponse ProviderRestApi::put(const QString &body)
|
||||
httpResponse ProviderRestApi::put(const QUrl &url, const QByteArray &body)
|
||||
{
|
||||
// Perform request
|
||||
QNetworkRequest request(url);
|
||||
QNetworkRequest request(_networkRequestHeaders);
|
||||
request.setUrl(url);
|
||||
|
||||
QNetworkReply* reply = _networkManager->put(request, body);
|
||||
// Connect requestFinished signal to quit slot of the loop.
|
||||
QEventLoop loop;
|
||||
@ -180,7 +189,7 @@ httpResponse ProviderRestApi::put(const QUrl &url, const QByteArray &body)
|
||||
loop.exec();
|
||||
|
||||
httpResponse response;
|
||||
if(reply->operation() == QNetworkAccessManager::PutOperation)
|
||||
if (reply->operation() == QNetworkAccessManager::PutOperation)
|
||||
{
|
||||
if(reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
@ -195,20 +204,88 @@ httpResponse ProviderRestApi::put(const QUrl &url, const QByteArray &body)
|
||||
return response;
|
||||
}
|
||||
|
||||
httpResponse ProviderRestApi::getResponse(QNetworkReply* const &reply)
|
||||
httpResponse ProviderRestApi::post(const QJsonObject& body)
|
||||
{
|
||||
return post( getUrl(), QJsonDocument(body).toJson(QJsonDocument::Compact));
|
||||
}
|
||||
|
||||
httpResponse ProviderRestApi::post(const QString& body)
|
||||
{
|
||||
return post( getUrl(), body.toUtf8() );
|
||||
}
|
||||
|
||||
httpResponse ProviderRestApi::post(const QUrl& url, const QByteArray& body)
|
||||
{
|
||||
// Perform request
|
||||
QNetworkRequest request(_networkRequestHeaders);
|
||||
request.setUrl(url);
|
||||
|
||||
QNetworkReply* reply = _networkManager->post(request, body);
|
||||
// Connect requestFinished signal to quit slot of the loop.
|
||||
QEventLoop loop;
|
||||
QEventLoop::connect(reply,&QNetworkReply::finished,&loop,&QEventLoop::quit);
|
||||
// Go into the loop until the request is finished.
|
||||
loop.exec();
|
||||
|
||||
httpResponse response;
|
||||
if (reply->operation() == QNetworkAccessManager::PostOperation)
|
||||
{
|
||||
if(reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
Debug(_log, "POST: [%s] [%s]", QSTRING_CSTR( url.toString() ),body.constData() );
|
||||
}
|
||||
response = getResponse(reply);
|
||||
}
|
||||
// Free space.
|
||||
reply->deleteLater();
|
||||
|
||||
// Return response
|
||||
return response;
|
||||
}
|
||||
|
||||
httpResponse ProviderRestApi::deleteResource(const QUrl& url)
|
||||
{
|
||||
// Perform request
|
||||
QNetworkRequest request(_networkRequestHeaders);
|
||||
request.setUrl(url);
|
||||
|
||||
QNetworkReply* reply = _networkManager->deleteResource(request);
|
||||
// Connect requestFinished signal to quit slot of the loop.
|
||||
QEventLoop loop;
|
||||
QEventLoop::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
// Go into the loop until the request is finished.
|
||||
loop.exec();
|
||||
|
||||
httpResponse response;
|
||||
if (reply->operation() == QNetworkAccessManager::DeleteOperation)
|
||||
{
|
||||
if(reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
Debug(_log, "DELETE: [%s]", QSTRING_CSTR(url.toString()));
|
||||
}
|
||||
response = getResponse(reply);
|
||||
}
|
||||
// Free space.
|
||||
reply->deleteLater();
|
||||
|
||||
// Return response
|
||||
return response;
|
||||
}
|
||||
|
||||
httpResponse ProviderRestApi::getResponse(QNetworkReply* const& reply)
|
||||
{
|
||||
httpResponse response;
|
||||
|
||||
int httpStatusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt();
|
||||
int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
response.setHttpStatusCode(httpStatusCode);
|
||||
response.setNetworkReplyError(reply->error());
|
||||
|
||||
if(reply->error() == QNetworkReply::NoError)
|
||||
if (reply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
if ( httpStatusCode != HTTP_STATUS_NO_CONTENT ){
|
||||
QByteArray replyData = reply->readAll();
|
||||
|
||||
if ( !replyData.isEmpty())
|
||||
if (!replyData.isEmpty())
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(replyData, &error);
|
||||
@ -222,13 +299,13 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const &reply)
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cout << "Response: [" << QString (jsonDoc.toJson(QJsonDocument::Compact)).toStdString() << "]" << std::endl;
|
||||
response.setBody( jsonDoc );
|
||||
//std::cout << "Response: [" << QString(jsonDoc.toJson(QJsonDocument::Compact)).toStdString() << "]" << std::endl;
|
||||
response.setBody(jsonDoc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Create valid body which is empty
|
||||
response.setBody( QJsonDocument() );
|
||||
response.setBody(QJsonDocument());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,8 +313,8 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const &reply)
|
||||
{
|
||||
Debug(_log, "Reply.httpStatusCode [%d]", httpStatusCode );
|
||||
QString errorReason;
|
||||
if ( httpStatusCode > 0 ) {
|
||||
QString httpReason = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString();
|
||||
if (httpStatusCode > 0) {
|
||||
QString httpReason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
|
||||
QString advise;
|
||||
switch ( httpStatusCode ) {
|
||||
case HTTP_STATUS_BAD_REQUEST:
|
||||
@ -271,8 +348,23 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const &reply)
|
||||
}
|
||||
|
||||
// Create valid body which is empty
|
||||
response.setBody( QJsonDocument() );
|
||||
response.setBody(QJsonDocument());
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
void ProviderRestApi::setHeader(QNetworkRequest::KnownHeaders header, const QVariant& value)
|
||||
{
|
||||
QVariant headerValue = _networkRequestHeaders.header(header);
|
||||
if (headerValue.isNull())
|
||||
{
|
||||
_networkRequestHeaders.setHeader(header, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!headerValue.toString().contains(value.toString()))
|
||||
{
|
||||
_networkRequestHeaders.setHeader(header, headerValue.toString() + "," + value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,20 +60,20 @@ class httpResponse
|
||||
public:
|
||||
httpResponse() = default;
|
||||
|
||||
bool error() const { return _hasError;}
|
||||
bool error() const { return _hasError; }
|
||||
void setError(const bool hasError) { _hasError = hasError; }
|
||||
|
||||
QJsonDocument getBody() const { return _responseBody; }
|
||||
void setBody(const QJsonDocument &body) { _responseBody = body; }
|
||||
void setBody(const QJsonDocument& body) { _responseBody = body; }
|
||||
|
||||
QString getErrorReason() const { return _errorReason; }
|
||||
void setErrorReason(const QString &errorReason) { _errorReason = errorReason; }
|
||||
void setErrorReason(const QString& errorReason) { _errorReason = errorReason; }
|
||||
|
||||
int getHttpStatusCode() const { return _httpStatusCode; }
|
||||
void setHttpStatusCode(int httpStatusCode) { _httpStatusCode = httpStatusCode; }
|
||||
|
||||
QNetworkReply::NetworkError getNetworkReplyError() const { return _networkReplyError; }
|
||||
void setNetworkReplyError (const QNetworkReply::NetworkError networkReplyError) { _networkReplyError = networkReplyError; }
|
||||
void setNetworkReplyError(const QNetworkReply::NetworkError networkReplyError) { _networkReplyError = networkReplyError; }
|
||||
|
||||
private:
|
||||
|
||||
@ -119,7 +119,7 @@ public:
|
||||
/// @param[in] host
|
||||
/// @param[in] port
|
||||
///
|
||||
explicit ProviderRestApi(const QString &host, int port);
|
||||
explicit ProviderRestApi(const QString& host, int port);
|
||||
|
||||
///
|
||||
/// @brief Constructor of the REST-API wrapper
|
||||
@ -128,13 +128,34 @@ public:
|
||||
/// @param[in] port
|
||||
/// @param[in] API base-path
|
||||
///
|
||||
explicit ProviderRestApi(const QString &host, int port, const QString &basePath);
|
||||
explicit ProviderRestApi(const QString& host, int port, const QString& basePath);
|
||||
|
||||
///
|
||||
/// @brief Destructor of the REST-API wrapper
|
||||
///
|
||||
virtual ~ProviderRestApi();
|
||||
|
||||
///
|
||||
/// @brief Set an API's host
|
||||
///
|
||||
/// @param[in] host
|
||||
///
|
||||
void setHost(const QString& host) { _apiUrl.setHost(host); }
|
||||
|
||||
///
|
||||
/// @brief Set an API's port
|
||||
///
|
||||
/// @param[in] port
|
||||
///
|
||||
void setPort(const int port) { _apiUrl.setPort(port); }
|
||||
|
||||
///
|
||||
/// @brief Set an API's url
|
||||
///
|
||||
/// @param[in] url, e.g. "http://locahost:60351/chromalink/"
|
||||
///
|
||||
void setUrl(const QUrl& url);
|
||||
|
||||
///
|
||||
/// @brief Get the URL as defined using scheme, host, port, API-basepath, path, query, fragment
|
||||
///
|
||||
@ -147,35 +168,35 @@ public:
|
||||
///
|
||||
/// @param[in] basePath, e.g. "/api/v1/" or "/json"
|
||||
///
|
||||
void setBasePath(const QString &basePath);
|
||||
void setBasePath(const QString& basePath);
|
||||
|
||||
///
|
||||
/// @brief Set an API's path to address resources
|
||||
///
|
||||
/// @param[in] path, e.g. "/lights/1/state/"
|
||||
///
|
||||
void setPath ( const QString &path );
|
||||
void setPath(const QString& path);
|
||||
|
||||
///
|
||||
/// @brief Append an API's path element to path set before
|
||||
///
|
||||
/// @param[in] path
|
||||
///
|
||||
void appendPath (const QString &appendPath);
|
||||
void appendPath(const QString& appendPath);
|
||||
|
||||
///
|
||||
/// @brief Set an API's fragment
|
||||
///
|
||||
/// @param[in] fragment, e.g. "question3"
|
||||
///
|
||||
void setFragment(const QString&fragment);
|
||||
void setFragment(const QString& fragment);
|
||||
|
||||
///
|
||||
/// @brief Set an API's query string
|
||||
///
|
||||
/// @param[in] query, e.g. "&A=128&FX=0"
|
||||
///
|
||||
void setQuery(const QUrlQuery &query);
|
||||
void setQuery(const QUrlQuery& query);
|
||||
|
||||
///
|
||||
/// @brief Execute GET request
|
||||
@ -190,14 +211,14 @@ public:
|
||||
/// @param[in] url GET request for URL
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse get(const QUrl &url);
|
||||
httpResponse get(const QUrl& url);
|
||||
|
||||
/// @brief Execute PUT request
|
||||
///
|
||||
/// @param[in] body The body of the request in JSON
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse put(const QJsonObject &body);
|
||||
httpResponse put(const QJsonObject& body);
|
||||
|
||||
///
|
||||
/// @brief Execute PUT request
|
||||
@ -205,7 +226,7 @@ public:
|
||||
/// @param[in] body The body of the request in JSON
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse put(const QString &body = "");
|
||||
httpResponse put(const QString& body = "");
|
||||
|
||||
///
|
||||
/// @brief Execute PUT request
|
||||
@ -214,7 +235,7 @@ public:
|
||||
/// @param[in] body The body of the request in JSON
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse put(const QUrl &url, const QByteArray &body);
|
||||
httpResponse put(const QUrl &url, const QByteArray& body);
|
||||
|
||||
///
|
||||
/// @brief Execute POST request
|
||||
@ -222,7 +243,31 @@ public:
|
||||
/// @param[in] body The body of the request in JSON
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse post(QString body = "");
|
||||
httpResponse post(const QString& body = "");
|
||||
|
||||
/// @brief Execute POST request
|
||||
///
|
||||
/// @param[in] body The body of the request in JSON
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse post(const QJsonObject& body);
|
||||
|
||||
///
|
||||
/// @brief Execute POST request
|
||||
///
|
||||
/// @param[in] URL for POST request
|
||||
/// @param[in] body The body of the request in JSON
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse post(const QUrl &url, const QByteArray& body);
|
||||
|
||||
///
|
||||
/// @brief Execute DELETE request
|
||||
///
|
||||
/// @param[in] URL (Resource) for DELETE request
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse deleteResource(const QUrl& url);
|
||||
|
||||
///
|
||||
/// @brief Handle responses for REST requests
|
||||
@ -230,7 +275,21 @@ public:
|
||||
/// @param[in] reply Network reply
|
||||
/// @return Response The body of the response in JSON
|
||||
///
|
||||
httpResponse getResponse(QNetworkReply* const &reply);
|
||||
httpResponse getResponse(QNetworkReply* const& reply);
|
||||
|
||||
///
|
||||
/// Adds a header field.
|
||||
///
|
||||
/// @param[in] The type of the header field.
|
||||
/// @param[in] The value of the header field.
|
||||
/// If the header field exists, the value will be combined as comma separated string.
|
||||
|
||||
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant& value);
|
||||
|
||||
///
|
||||
/// Remove all header fields.
|
||||
///
|
||||
void removeAllHeaders() { _networkRequestHeaders = QNetworkRequest(); }
|
||||
|
||||
private:
|
||||
|
||||
@ -249,16 +308,13 @@ private:
|
||||
|
||||
QUrl _apiUrl;
|
||||
|
||||
QString _scheme;
|
||||
QString _hostname;
|
||||
int _port;
|
||||
|
||||
QString _basePath;
|
||||
QString _path;
|
||||
|
||||
QString _fragment;
|
||||
QUrlQuery _query;
|
||||
|
||||
QNetworkRequest _networkRequestHeaders;
|
||||
};
|
||||
|
||||
#endif // PROVIDERRESTKAPI_H
|
||||
|
28
libsrc/leddevice/schemas/schema-razer.json
Normal file
28
libsrc/leddevice/schemas/schema-razer.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": true,
|
||||
"properties": {
|
||||
"subType": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_razer_device_title",
|
||||
"enum": [ "keyboard", "mouse", "headset", "mousepad", "keypad", "chromalink" ],
|
||||
"default": "keyboard",
|
||||
"options": {
|
||||
"enum_titles": [ "Keyboard", "Mouse", "Headset", "Mousepad", "Keypad", "Chromalink" ]
|
||||
},
|
||||
"propertyOrder": 1
|
||||
},
|
||||
"latchTime": {
|
||||
"type": "integer",
|
||||
"title": "edt_dev_spec_latchtime_title",
|
||||
"default": 0,
|
||||
"append": "edt_append_ms",
|
||||
"minimum": 0,
|
||||
"maximum": 1000,
|
||||
"access": "expert",
|
||||
"propertyOrder": 2
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user