mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Merge remote-tracking branch 'hyperion-project/master' into h801
This commit is contained in:
@@ -24,3 +24,8 @@ std::wstring Option::getStdWString(Parser &parser)
|
||||
return value(parser).toStdWString();
|
||||
}
|
||||
|
||||
const char* Option::getCString(Parser &parser)
|
||||
{
|
||||
return value(parser).toLocal8Bit().constData();
|
||||
}
|
||||
|
||||
|
@@ -48,6 +48,8 @@ add_library(effectengine
|
||||
${EffectEngineSOURCES}
|
||||
)
|
||||
|
||||
qt5_use_modules(effectengine Core Gui)
|
||||
|
||||
target_link_libraries(effectengine
|
||||
hyperion
|
||||
jsoncpp
|
||||
|
@@ -8,16 +8,27 @@
|
||||
// Qt includes
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <Qt>
|
||||
#include <QLinearGradient>
|
||||
#include <QConicalGradient>
|
||||
#include <QRadialGradient>
|
||||
#include <QRect>
|
||||
|
||||
// effect engin eincludes
|
||||
#include "Effect.h"
|
||||
#include <utils/Logger.h>
|
||||
#include <hyperion/Hyperion.h>
|
||||
|
||||
// Python method table
|
||||
PyMethodDef Effect::effectMethods[] = {
|
||||
{"setColor", Effect::wrapSetColor, METH_VARARGS, "Set a new color for the leds."},
|
||||
{"setImage", Effect::wrapSetImage, METH_VARARGS, "Set a new image to process and determine new led colors."},
|
||||
{"abort", Effect::wrapAbort, METH_NOARGS, "Check if the effect should abort execution."},
|
||||
{"setColor", Effect::wrapSetColor, METH_VARARGS, "Set a new color for the leds."},
|
||||
{"setImage", Effect::wrapSetImage, METH_VARARGS, "Set a new image to process and determine new led colors."},
|
||||
{"abort", Effect::wrapAbort, METH_NOARGS, "Check if the effect should abort execution."},
|
||||
{"imageShow", Effect::wrapImageShow, METH_NOARGS, "set current effect image to hyperion core."},
|
||||
{"imageCanonicalGradient", Effect::wrapImageCanonicalGradient, METH_VARARGS, ""},
|
||||
{"imageRadialGradient" , Effect::wrapImageRadialGradient, METH_VARARGS, ""},
|
||||
// {"imageSetPixel",Effect::wrapImageShow, METH_VARARGS, "set pixel color of image"},
|
||||
// {"imageGetPixel",Effect::wrapImageShow, METH_VARARGS, "get pixel color of image"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -69,6 +80,12 @@ Effect::Effect(PyThreadState * mainThreadState, int priority, int timeout, const
|
||||
|
||||
// disable the black border detector for effects
|
||||
_imageProcessor->enableBlackBorderDetector(false);
|
||||
|
||||
// init effect image for image based effects, size is based on led layout
|
||||
_imageSize = Hyperion::getInstance()->getLedGridSize();
|
||||
_image = new QImage(_imageSize, QImage::Format_ARGB32_Premultiplied);
|
||||
_image->fill(Qt::black);
|
||||
_painter = new QPainter(_image);
|
||||
|
||||
// connect the finished signal
|
||||
connect(this, SIGNAL(finished()), this, SLOT(effectFinished()));
|
||||
@@ -77,6 +94,8 @@ Effect::Effect(PyThreadState * mainThreadState, int priority, int timeout, const
|
||||
|
||||
Effect::~Effect()
|
||||
{
|
||||
delete _painter;
|
||||
delete _image;
|
||||
}
|
||||
|
||||
void Effect::run()
|
||||
@@ -96,6 +115,12 @@ void Effect::run()
|
||||
// add ledCount variable to the interpreter
|
||||
PyObject_SetAttrString(module, "ledCount", Py_BuildValue("i", _imageProcessor->getLedCount()));
|
||||
|
||||
// add imageWidth variable to the interpreter
|
||||
PyObject_SetAttrString(module, "imageWidth", Py_BuildValue("i", _imageSize.width()));
|
||||
|
||||
// add imageHeight variable to the interpreter
|
||||
PyObject_SetAttrString(module, "imageHeight", Py_BuildValue("i", _imageSize.height()));
|
||||
|
||||
// add a args variable to the interpreter
|
||||
PyObject_SetAttrString(module, "args", json2python(_args));
|
||||
|
||||
@@ -357,6 +382,207 @@ PyObject* Effect::wrapAbort(PyObject *self, PyObject *)
|
||||
return Py_BuildValue("i", effect->_abortRequested ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
PyObject* Effect::wrapImageShow(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
// determine the timeout
|
||||
int timeout = effect->_timeout;
|
||||
if (timeout > 0)
|
||||
{
|
||||
timeout = effect->_endTime - QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
// we are done if the time has passed
|
||||
if (timeout <= 0)
|
||||
{
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
}
|
||||
|
||||
int width = effect->_imageSize.width();
|
||||
int height = effect->_imageSize.height();
|
||||
QImage * qimage = effect->_image;
|
||||
|
||||
Image<ColorRgb> image(width, height);
|
||||
QByteArray binaryImage;
|
||||
|
||||
for (int i = 0; i <qimage->height(); ++i)
|
||||
{
|
||||
const QRgb * scanline = reinterpret_cast<const QRgb *>(qimage->scanLine(i));
|
||||
for (int j = 0; j < qimage->width(); ++j)
|
||||
{
|
||||
binaryImage.append((char) qRed(scanline[j]));
|
||||
binaryImage.append((char) qGreen(scanline[j]));
|
||||
binaryImage.append((char) qBlue(scanline[j]));
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(image.memptr(), binaryImage.data(), binaryImage.size());
|
||||
effect->_imageProcessor->process(image, effect->_colors);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false);
|
||||
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
|
||||
|
||||
PyObject* Effect::wrapImageCanonicalGradient(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
int argCount = PyTuple_Size(args);
|
||||
PyObject * bytearray = nullptr;
|
||||
int centerX, centerY, angle;
|
||||
int startX = 0;
|
||||
int startY = 0;
|
||||
int width = effect->_imageSize.width();
|
||||
int height = effect->_imageSize.height();
|
||||
|
||||
bool argsOK = false;
|
||||
|
||||
if ( argCount == 8 && PyArg_ParseTuple(args, "iiiiiiiO", &startX, &startY, &width, &height, ¢erX, ¢erY, &angle, &bytearray) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 4 && PyArg_ParseTuple(args, "iiiO", ¢erX, ¢erY, &angle, &bytearray) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
angle = std::max(std::min(angle,360),0);
|
||||
|
||||
if (argsOK)
|
||||
{
|
||||
if (PyByteArray_Check(bytearray))
|
||||
{
|
||||
int length = PyByteArray_Size(bytearray);
|
||||
if (length % 4 == 0)
|
||||
{
|
||||
|
||||
QPainter * painter = effect->_painter;
|
||||
QRect myQRect(startX,startY,width,height);
|
||||
QConicalGradient gradient(QPoint(centerX,centerY), angle );
|
||||
char * data = PyByteArray_AS_STRING(bytearray);
|
||||
|
||||
for (int idx=0; idx<length; idx+=4)
|
||||
{
|
||||
gradient.setColorAt(
|
||||
((uint8_t)data[idx])/255.0,
|
||||
QColor(
|
||||
(uint8_t)(data[idx+1]),
|
||||
(uint8_t)(data[idx+2]),
|
||||
(uint8_t)(data[idx+3])
|
||||
));
|
||||
}
|
||||
|
||||
gradient.setSpread(QGradient::RepeatSpread);
|
||||
painter->fillRect(myQRect, gradient);
|
||||
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Length of bytearray argument should multiple of 4");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Argument 8 is not a bytearray");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyObject* Effect::wrapImageRadialGradient(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
int argCount = PyTuple_Size(args);
|
||||
PyObject * bytearray = nullptr;
|
||||
int centerX, centerY, radius, focalX, focalY, focalRadius;
|
||||
int startX = 0;
|
||||
int startY = 0;
|
||||
int width = effect->_imageSize.width();
|
||||
int height = effect->_imageSize.height();
|
||||
|
||||
bool argsOK = false;
|
||||
|
||||
if ( argCount == 11 && PyArg_ParseTuple(args, "iiiiiiiiiiO", &startX, &startY, &width, &height, ¢erX, ¢erY, &radius, &focalX, &focalY, &focalRadius, &bytearray) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 8 && PyArg_ParseTuple(args, "iiiiiiiO", &startX, &startY, &width, &height, ¢erX, ¢erY, &radius, &bytearray) )
|
||||
{
|
||||
argsOK = true;
|
||||
focalX = centerX;
|
||||
focalY = centerY;
|
||||
focalRadius = radius;
|
||||
}
|
||||
if ( argCount == 7 && PyArg_ParseTuple(args, "iiiiiiO", ¢erX, ¢erY, &radius, &focalX, &focalY, &focalRadius, &bytearray) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 4 && PyArg_ParseTuple(args, "iiiO", ¢erX, ¢erY, &radius, &bytearray) )
|
||||
{
|
||||
argsOK = true;
|
||||
focalX = centerX;
|
||||
focalY = centerY;
|
||||
focalRadius = radius;
|
||||
}
|
||||
|
||||
if (argsOK)
|
||||
{
|
||||
if (PyByteArray_Check(bytearray))
|
||||
{
|
||||
int length = PyByteArray_Size(bytearray);
|
||||
if (length % 4 == 0)
|
||||
{
|
||||
|
||||
QPainter * painter = effect->_painter;
|
||||
QRect myQRect(startX,startY,width,height);
|
||||
QRadialGradient gradient(QPoint(centerX,centerY), std::max(radius,0) );
|
||||
char * data = PyByteArray_AS_STRING(bytearray);
|
||||
|
||||
for (int idx=0; idx<length; idx+=4)
|
||||
{
|
||||
gradient.setColorAt(
|
||||
((uint8_t)data[idx])/255.0,
|
||||
QColor(
|
||||
(uint8_t)(data[idx+1]),
|
||||
(uint8_t)(data[idx+2]),
|
||||
(uint8_t)(data[idx+3])
|
||||
));
|
||||
}
|
||||
|
||||
//gradient.setSpread(QGradient::ReflectSpread);
|
||||
painter->fillRect(myQRect, gradient);
|
||||
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Length of bytearray argument should multiple of 4");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Last argument is not a bytearray");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Effect * Effect::getEffect()
|
||||
{
|
||||
// extract the module from the runtime
|
||||
|
@@ -5,6 +5,9 @@
|
||||
|
||||
// Qt includes
|
||||
#include <QThread>
|
||||
#include <QSize>
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
@@ -48,21 +51,25 @@ private:
|
||||
PyObject * json2python(const Json::Value & json) const;
|
||||
|
||||
// Wrapper methods for Python interpreter extra buildin methods
|
||||
static PyMethodDef effectMethods[];
|
||||
static PyObject* wrapSetColor(PyObject *self, PyObject *args);
|
||||
static PyMethodDef effectMethods[];
|
||||
static PyObject* wrapSetColor(PyObject *self, PyObject *args);
|
||||
static PyObject* wrapSetImage(PyObject *self, PyObject *args);
|
||||
static PyObject* wrapAbort(PyObject *self, PyObject *args);
|
||||
static Effect * getEffect();
|
||||
static PyObject* wrapImageShow(PyObject *self, PyObject *args);
|
||||
static PyObject* wrapImageCanonicalGradient(PyObject *self, PyObject *args);
|
||||
static PyObject* wrapImageRadialGradient(PyObject *self, PyObject *args);
|
||||
|
||||
static Effect * getEffect();
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
static struct PyModuleDef moduleDef;
|
||||
static PyObject* PyInit_hyperion();
|
||||
static struct PyModuleDef moduleDef;
|
||||
static PyObject* PyInit_hyperion();
|
||||
#else
|
||||
static void PyInit_hyperion();
|
||||
static void PyInit_hyperion();
|
||||
#endif
|
||||
|
||||
private:
|
||||
PyThreadState * _mainThreadState;
|
||||
PyThreadState * _mainThreadState;
|
||||
|
||||
const int _priority;
|
||||
|
||||
@@ -84,5 +91,10 @@ private:
|
||||
|
||||
/// Buffer for colorData
|
||||
std::vector<ColorRgb> _colors;
|
||||
|
||||
QSize _imageSize;
|
||||
|
||||
QImage * _image;
|
||||
QPainter * _painter;
|
||||
};
|
||||
|
||||
|
@@ -423,6 +423,7 @@ LedString Hyperion::createLedString(const Json::Value& ledsConfig, const ColorOr
|
||||
LedString ledString;
|
||||
const std::string deviceOrderStr = colorOrderToString(deviceOrder);
|
||||
int maxLedId = ledsConfig.size();
|
||||
|
||||
for (const Json::Value& ledConfig : ledsConfig)
|
||||
{
|
||||
Led led;
|
||||
@@ -499,6 +500,51 @@ LedString Hyperion::createLedStringClone(const Json::Value& ledsConfig, const Co
|
||||
return ledString;
|
||||
}
|
||||
|
||||
QSize Hyperion::getLedLayoutGridSize(const Json::Value& ledsConfig)
|
||||
{
|
||||
std::vector<int> midPointsX;
|
||||
std::vector<int> midPointsY;
|
||||
|
||||
for (const Json::Value& ledConfig : ledsConfig)
|
||||
{
|
||||
if ( ledConfig.get("clone",-1).asInt() < 0 )
|
||||
{
|
||||
const Json::Value& hscanConfig = ledConfig["hscan"];
|
||||
const Json::Value& vscanConfig = ledConfig["vscan"];
|
||||
double minX_frac = std::max(0.0, std::min(1.0, hscanConfig["minimum"].asDouble()));
|
||||
double maxX_frac = std::max(0.0, std::min(1.0, hscanConfig["maximum"].asDouble()));
|
||||
double minY_frac = std::max(0.0, std::min(1.0, vscanConfig["minimum"].asDouble()));
|
||||
double maxY_frac = std::max(0.0, std::min(1.0, vscanConfig["maximum"].asDouble()));
|
||||
// Fix if the user swapped min and max
|
||||
if (minX_frac > maxX_frac)
|
||||
{
|
||||
std::swap(minX_frac, maxX_frac);
|
||||
}
|
||||
if (minY_frac > maxY_frac)
|
||||
{
|
||||
std::swap(minY_frac, maxY_frac);
|
||||
}
|
||||
|
||||
// calculate mid point and make grid calculation
|
||||
midPointsX.push_back( int(1000.0*(minX_frac + maxX_frac) / 2.0) );
|
||||
midPointsY.push_back( int(1000.0*(minY_frac + maxY_frac) / 2.0) );
|
||||
}
|
||||
}
|
||||
|
||||
// remove duplicates
|
||||
std::sort(midPointsX.begin(), midPointsX.end());
|
||||
midPointsX.erase(std::unique(midPointsX.begin(), midPointsX.end()), midPointsX.end());
|
||||
std::sort(midPointsY.begin(), midPointsY.end());
|
||||
midPointsY.erase(std::unique(midPointsY.begin(), midPointsY.end()), midPointsY.end());
|
||||
|
||||
QSize gridSize( midPointsX.size(), midPointsY.size() );
|
||||
Debug(Logger::getInstance("Core"), "led layout grid: %dx%d", gridSize.width(), gridSize.height());
|
||||
|
||||
return gridSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LinearColorSmoothing * Hyperion::createColorSmoothing(const Json::Value & smoothingConfig, LedDevice* leddevice)
|
||||
{
|
||||
Logger * log = Logger::getInstance("Core");
|
||||
@@ -578,6 +624,7 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
|
||||
, _hwLedCount(_ledString.leds().size())
|
||||
, _sourceAutoSelectEnabled(true)
|
||||
, _configHash()
|
||||
, _ledGridSize(getLedLayoutGridSize(jsonConfig["leds"]))
|
||||
{
|
||||
registerPriority("Off", PriorityMuxer::LOWEST_PRIORITY);
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
"name" :
|
||||
{
|
||||
"type" : "string",
|
||||
"title" : "Configuration name",
|
||||
"required" : true,
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
@@ -48,6 +49,7 @@
|
||||
"colorOrder" :
|
||||
{
|
||||
"type" : "string",
|
||||
"title" : "RGB byte order",
|
||||
"enum" : ["rgb", "bgr", "rbg", "brg", "gbr", "grb"],
|
||||
"propertyOrder" : 3
|
||||
}
|
||||
@@ -397,6 +399,7 @@
|
||||
"minimum" : 25,
|
||||
"maximum": 600,
|
||||
"default" : 200,
|
||||
"append" : "ms",
|
||||
"propertyOrder" : 3
|
||||
},
|
||||
"updateFrequency" :
|
||||
@@ -406,6 +409,7 @@
|
||||
"minimum" : 1.000,
|
||||
"maximum" : 100.000,
|
||||
"default" : 25.000,
|
||||
"append" : "Hz",
|
||||
"propertyOrder" : 4
|
||||
},
|
||||
"updateDelay" :
|
||||
@@ -415,6 +419,7 @@
|
||||
"minimum" : 0,
|
||||
"maximum": 2048,
|
||||
"default" : 0,
|
||||
"append" : "ms",
|
||||
"propertyOrder" : 5
|
||||
},
|
||||
"continuousOutput" :
|
||||
@@ -427,12 +432,14 @@
|
||||
},
|
||||
"additionalProperties" : false
|
||||
},
|
||||
"grabber-v4l2" :
|
||||
"grabberV4L2" :
|
||||
{
|
||||
"type":"array",
|
||||
"title" : "USB Grabber",
|
||||
"items":
|
||||
{
|
||||
"type" : "object",
|
||||
"title" : "USB Grabber",
|
||||
"properties" :
|
||||
{
|
||||
"enable" :
|
||||
@@ -469,6 +476,7 @@
|
||||
"type" : "integer",
|
||||
"title" : "Width",
|
||||
"default" : -1,
|
||||
"append" : "Pixel",
|
||||
"propertyOrder" : 5
|
||||
},
|
||||
"height" :
|
||||
@@ -476,6 +484,7 @@
|
||||
"type" : "integer",
|
||||
"title" : "Height",
|
||||
"default" : -1,
|
||||
"append" : "Pixel",
|
||||
"propertyOrder" : 6
|
||||
},
|
||||
"frameDecimation" :
|
||||
@@ -520,6 +529,7 @@
|
||||
"title" : "Crop left",
|
||||
"minimum" : 0,
|
||||
"default" : 0,
|
||||
"append" : "Pixel",
|
||||
"propertyOrder" : 12
|
||||
},
|
||||
"cropRight" :
|
||||
@@ -528,6 +538,7 @@
|
||||
"title" : "Crop right",
|
||||
"minimum" : 0,
|
||||
"default" : 0,
|
||||
"append" : "Pixel",
|
||||
"propertyOrder" : 13
|
||||
},
|
||||
"cropTop" :
|
||||
@@ -536,6 +547,7 @@
|
||||
"title" : "Crop top",
|
||||
"minimum" : 0,
|
||||
"default" : 0,
|
||||
"append" : "Pixel",
|
||||
"propertyOrder" : 14
|
||||
},
|
||||
"cropBottom" :
|
||||
@@ -544,6 +556,7 @@
|
||||
"title" : "Crop bottom",
|
||||
"minimum" : 0,
|
||||
"default" : 0,
|
||||
"append" : "Pixel",
|
||||
"propertyOrder" : 15
|
||||
},
|
||||
"redSignalThreshold" :
|
||||
@@ -553,6 +566,7 @@
|
||||
"minimum" : 0.0,
|
||||
"maximum" : 1.0,
|
||||
"default" : 0.1,
|
||||
"append" : "%",
|
||||
"propertyOrder" : 16
|
||||
},
|
||||
"greenSignalThreshold" :
|
||||
@@ -562,6 +576,7 @@
|
||||
"minimum" : 0.0,
|
||||
"maximum" : 1.0,
|
||||
"default" : 0.1,
|
||||
"append" : "%",
|
||||
"propertyOrder" : 17
|
||||
},
|
||||
"blueSignalThreshold" :
|
||||
@@ -571,6 +586,7 @@
|
||||
"minimum" : 0.0,
|
||||
"maximum" : 1.0,
|
||||
"default" : 0.1,
|
||||
"append" : "%",
|
||||
"propertyOrder" : 18
|
||||
}
|
||||
},
|
||||
@@ -601,20 +617,23 @@
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "Width",
|
||||
"default" : 96
|
||||
"default" : 96,
|
||||
"append" : "Pixel"
|
||||
},
|
||||
"height" :
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "Height",
|
||||
"default" : 96
|
||||
"default" : 96,
|
||||
"append" : "Pixel"
|
||||
},
|
||||
"frequency_Hz" :
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "Frequency",
|
||||
"minimum" : 0,
|
||||
"default" : 10
|
||||
"default" : 10,
|
||||
"append" : "Hz"
|
||||
},
|
||||
"priority" :
|
||||
{
|
||||
@@ -628,28 +647,32 @@
|
||||
"type" : "integer",
|
||||
"title" : "Crop left",
|
||||
"minimum" : 0,
|
||||
"default" : 0
|
||||
"default" : 0,
|
||||
"append" : "Pixel"
|
||||
},
|
||||
"cropRight" :
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "Crop right",
|
||||
"minimum" : 0,
|
||||
"default" : 0
|
||||
"default" : 0,
|
||||
"append" : "Pixel"
|
||||
},
|
||||
"cropTop" :
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "Crop top",
|
||||
"minimum" : 0,
|
||||
"default" : 0
|
||||
"default" : 0,
|
||||
"append" : "Pixel"
|
||||
},
|
||||
"cropBottom" :
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "Crop bottom",
|
||||
"minimum" : 0,
|
||||
"default" : 0
|
||||
"default" : 0,
|
||||
"append" : "Pixel"
|
||||
},
|
||||
"useXGetImage" :
|
||||
{
|
||||
@@ -707,6 +730,7 @@
|
||||
"minimum" : 0.0,
|
||||
"maximum" : 1.0,
|
||||
"default" : 0.05,
|
||||
"append" : "%",
|
||||
"propertyOrder" : 2
|
||||
},
|
||||
"unknownFrameCnt" :
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file alias="hyperion-schema">hyperion.schema.json</file>
|
||||
<file alias="hyperion_default.config">../../config/hyperion.config.json.default</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -17,6 +17,7 @@
|
||||
"type": "integer",
|
||||
"title":"Delay after connect",
|
||||
"default": 250,
|
||||
"append" : "ms",
|
||||
"propertyOrder" : 3
|
||||
}
|
||||
},
|
||||
|
@@ -17,6 +17,7 @@
|
||||
"type": "integer",
|
||||
"title":"Delay after connect",
|
||||
"default": 250,
|
||||
"append" : "ms",
|
||||
"propertyOrder" : 3
|
||||
}
|
||||
},
|
||||
|
@@ -17,6 +17,7 @@
|
||||
"type": "integer",
|
||||
"title":"Delay after connect",
|
||||
"default": 250,
|
||||
"append" : "ms",
|
||||
"propertyOrder" : 3
|
||||
}
|
||||
},
|
||||
|
@@ -23,8 +23,9 @@
|
||||
},
|
||||
"transitiontime": {
|
||||
"type": "integer",
|
||||
"title":"Transistion time (x100ms)",
|
||||
"title":"Transistion time",
|
||||
"default" : 1,
|
||||
"append" : "x100ms",
|
||||
"propertyOrder" : 4
|
||||
},
|
||||
"switchOffOnBlack": {
|
||||
|
@@ -109,7 +109,7 @@ void QJsonSchemaChecker::validate(const QJsonValue & value, const QJsonObject &s
|
||||
else if (attribute == "id")
|
||||
; // references have already been collected
|
||||
else if (attribute == "title" || attribute == "description" || attribute == "default" || attribute == "format"
|
||||
|| attribute == "defaultProperties" || attribute == "propertyOrder")
|
||||
|| attribute == "defaultProperties" || attribute == "propertyOrder" || attribute == "append")
|
||||
; // nothing to do.
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user