mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Merge pull request #829 from Lord-Grey/Update_LedDevices
Update led devices(LPD8806 + Nanoleaf)
This commit is contained in:
commit
5eb45e857f
@ -137,7 +137,7 @@
|
|||||||
"conf_leds_optgroup_RPiPWM": "RPi PWM",
|
"conf_leds_optgroup_RPiPWM": "RPi PWM",
|
||||||
"conf_leds_optgroup_RPiGPIO": "RPi GPIO",
|
"conf_leds_optgroup_RPiGPIO": "RPi GPIO",
|
||||||
"conf_leds_optgroup_network": "Netzwerk",
|
"conf_leds_optgroup_network": "Netzwerk",
|
||||||
"conf_leds_optgroup_usb": "USB",
|
"conf_leds_optgroup_usb": "USB/Seriell",
|
||||||
"conf_leds_optgroup_debug": "Debug",
|
"conf_leds_optgroup_debug": "Debug",
|
||||||
"conf_leds_layout_btn_checklist": "Zeige Checkliste",
|
"conf_leds_layout_btn_checklist": "Zeige Checkliste",
|
||||||
"conf_leds_layout_checkp1": "Die schwarze eingefärbte LED ist die erste LED. Das ist der Punkt, an dem die Daten eingespeist werden.",
|
"conf_leds_layout_checkp1": "Die schwarze eingefärbte LED ist die erste LED. Das ist der Punkt, an dem die Daten eingespeist werden.",
|
||||||
@ -487,6 +487,10 @@
|
|||||||
"edt_dev_spec_clientKey_title": "Clientkey",
|
"edt_dev_spec_clientKey_title": "Clientkey",
|
||||||
"edt_dev_spec_printTimeStamp_title" : "Mit Zeitstempel",
|
"edt_dev_spec_printTimeStamp_title" : "Mit Zeitstempel",
|
||||||
"edt_dev_spec_groupId_title": "Gruppen ID",
|
"edt_dev_spec_groupId_title": "Gruppen ID",
|
||||||
|
"edt_dev_spec_panelorganisation_title" : "Nummerierungsreihenfolge der Panels",
|
||||||
|
"edt_dev_spec_order_top_down_title" : "1.",
|
||||||
|
"edt_dev_spec_order_left_right_title" : "2.",
|
||||||
|
"edt_dev_spec_panel_start_position" : "Startpanel [0-max Panels]",
|
||||||
"edt_conf_general_enable_title": "Aktiviert",
|
"edt_conf_general_enable_title": "Aktiviert",
|
||||||
"edt_conf_general_enable_expl": "Wenn aktiviert, ist die Komponente aktiv.",
|
"edt_conf_general_enable_expl": "Wenn aktiviert, ist die Komponente aktiv.",
|
||||||
"edt_conf_general_priority_title": "Priorität",
|
"edt_conf_general_priority_title": "Priorität",
|
||||||
@ -522,6 +526,10 @@
|
|||||||
"edt_conf_enum_dl_informational": "informativ",
|
"edt_conf_enum_dl_informational": "informativ",
|
||||||
"edt_conf_enum_dl_verbose": "sehr detailiert",
|
"edt_conf_enum_dl_verbose": "sehr detailiert",
|
||||||
"edt_conf_enum_custom": "Benutzerdefiniert",
|
"edt_conf_enum_custom": "Benutzerdefiniert",
|
||||||
|
"edt_conf_enum_bottom_up": "von unten nach oben",
|
||||||
|
"edt_conf_enum_top_down": "von oben nach unten",
|
||||||
|
"edt_conf_enum_right_left": "von rechts and links",
|
||||||
|
"edt_conf_enum_left_right": "von links nach rechts",
|
||||||
"edt_conf_gen_heading_title": "Allgemeine Einstellungen",
|
"edt_conf_gen_heading_title": "Allgemeine Einstellungen",
|
||||||
"edt_conf_gen_name_title": "Name der Konfiguration",
|
"edt_conf_gen_name_title": "Name der Konfiguration",
|
||||||
"edt_conf_gen_name_expl": "Der Name wird verwendet, um Hyperion besser zu identifizieren. (Hilfreich bei mehreren Instanzen)",
|
"edt_conf_gen_name_expl": "Der Name wird verwendet, um Hyperion besser zu identifizieren. (Hilfreich bei mehreren Instanzen)",
|
||||||
|
@ -137,7 +137,7 @@
|
|||||||
"conf_leds_optgroup_RPiPWM" : "RPi PWM",
|
"conf_leds_optgroup_RPiPWM" : "RPi PWM",
|
||||||
"conf_leds_optgroup_RPiGPIO" : "RPi GPIO",
|
"conf_leds_optgroup_RPiGPIO" : "RPi GPIO",
|
||||||
"conf_leds_optgroup_network" : "Network",
|
"conf_leds_optgroup_network" : "Network",
|
||||||
"conf_leds_optgroup_usb" : "USB",
|
"conf_leds_optgroup_usb" : "USB/Serial",
|
||||||
"conf_leds_optgroup_debug" : "Debug",
|
"conf_leds_optgroup_debug" : "Debug",
|
||||||
"conf_leds_layout_btn_checklist" : "Show checklist",
|
"conf_leds_layout_btn_checklist" : "Show checklist",
|
||||||
"conf_leds_layout_checkp1" : "The black led is your first led, the first led is the point where you input your data signal.",
|
"conf_leds_layout_checkp1" : "The black led is your first led, the first led is the point where you input your data signal.",
|
||||||
@ -488,6 +488,10 @@
|
|||||||
"edt_dev_spec_printTimeStamp_title" : "Add timestamp",
|
"edt_dev_spec_printTimeStamp_title" : "Add timestamp",
|
||||||
"edt_dev_spec_clientKey_title" : "Clientkey",
|
"edt_dev_spec_clientKey_title" : "Clientkey",
|
||||||
"edt_dev_spec_groupId_title" : "Group Id",
|
"edt_dev_spec_groupId_title" : "Group Id",
|
||||||
|
"edt_dev_spec_panelorganisation_title" : "Panel numbering sequence",
|
||||||
|
"edt_dev_spec_order_top_down_title" : "1.",
|
||||||
|
"edt_dev_spec_order_left_right_title" : "2.",
|
||||||
|
"edt_dev_spec_panel_start_position" : "Startpanel [0-max panels]",
|
||||||
"edt_conf_general_enable_title" : "Activate",
|
"edt_conf_general_enable_title" : "Activate",
|
||||||
"edt_conf_general_enable_expl" : "If checked, the component is enabled.",
|
"edt_conf_general_enable_expl" : "If checked, the component is enabled.",
|
||||||
"edt_conf_general_priority_title" : "Priority channel",
|
"edt_conf_general_priority_title" : "Priority channel",
|
||||||
@ -523,6 +527,10 @@
|
|||||||
"edt_conf_enum_dl_informational": "Informational",
|
"edt_conf_enum_dl_informational": "Informational",
|
||||||
"edt_conf_enum_dl_verbose": "Verbose",
|
"edt_conf_enum_dl_verbose": "Verbose",
|
||||||
"edt_conf_enum_custom": "Custom",
|
"edt_conf_enum_custom": "Custom",
|
||||||
|
"edt_conf_enum_bottom_up": "Bottom up",
|
||||||
|
"edt_conf_enum_top_down": "Top down",
|
||||||
|
"edt_conf_enum_right_left": "Right to left",
|
||||||
|
"edt_conf_enum_left_right": "Left to right",
|
||||||
"edt_conf_gen_heading_title" : "General Settings",
|
"edt_conf_gen_heading_title" : "General Settings",
|
||||||
"edt_conf_gen_name_title" : "Configuration name",
|
"edt_conf_gen_name_title" : "Configuration name",
|
||||||
"edt_conf_gen_name_expl" : "A user defined name which is used to detect Hyperion. (Helpful with more than one Hyperion instance)",
|
"edt_conf_gen_name_expl" : "A user defined name which is used to detect Hyperion. (Helpful with more than one Hyperion instance)",
|
||||||
|
@ -21,6 +21,10 @@ static const char CONFIG_ADDRESS[] = "host";
|
|||||||
//static const char CONFIG_PORT[] = "port";
|
//static const char CONFIG_PORT[] = "port";
|
||||||
static const char CONFIG_AUTH_TOKEN[] ="token";
|
static const char CONFIG_AUTH_TOKEN[] ="token";
|
||||||
|
|
||||||
|
static const char CONFIG_PANEL_ORDER_TOP_DOWN[] ="panelOrderTopDown";
|
||||||
|
static const char CONFIG_PANEL_ORDER_LEFT_RIGHT[] ="panelOrderLeftRight";
|
||||||
|
static const char CONFIG_PANEL_START_POS[] ="panelStartPos";
|
||||||
|
|
||||||
// Panel configuration settings
|
// Panel configuration settings
|
||||||
static const char PANEL_LAYOUT[] = "layout";
|
static const char PANEL_LAYOUT[] = "layout";
|
||||||
static const char PANEL_NUM[] = "numPanels";
|
static const char PANEL_NUM[] = "numPanels";
|
||||||
@ -123,6 +127,19 @@ bool LedDeviceNanoleaf::init(const QJsonObject &deviceConfig)
|
|||||||
Debug(_log, "RefreshTime : %d", _refresh_timer_interval);
|
Debug(_log, "RefreshTime : %d", _refresh_timer_interval);
|
||||||
Debug(_log, "LatchTime : %d", this->getLatchTime());
|
Debug(_log, "LatchTime : %d", this->getLatchTime());
|
||||||
|
|
||||||
|
// Read panel organisation configuration
|
||||||
|
if ( deviceConfig[ CONFIG_PANEL_ORDER_TOP_DOWN ].isString() )
|
||||||
|
_topDown = deviceConfig[ CONFIG_PANEL_ORDER_TOP_DOWN ].toString().toInt() == 0 ? true : false;
|
||||||
|
else
|
||||||
|
_topDown = deviceConfig[ CONFIG_PANEL_ORDER_TOP_DOWN ].toInt() == 0 ? true : false;
|
||||||
|
|
||||||
|
if ( deviceConfig[ CONFIG_PANEL_ORDER_LEFT_RIGHT ].isString() )
|
||||||
|
_leftRight = deviceConfig[ CONFIG_PANEL_ORDER_LEFT_RIGHT ].toString().toInt() == 0 ? true : false;
|
||||||
|
else
|
||||||
|
_leftRight = deviceConfig[ CONFIG_PANEL_ORDER_LEFT_RIGHT ].toInt() == 0 ? true : false;
|
||||||
|
|
||||||
|
_startPos = deviceConfig[ CONFIG_PANEL_START_POS ].toInt(0);
|
||||||
|
|
||||||
//Set hostname as per configuration and_defaultHost default port
|
//Set hostname as per configuration and_defaultHost default port
|
||||||
_hostname = deviceConfig[ CONFIG_ADDRESS ].toString();
|
_hostname = deviceConfig[ CONFIG_ADDRESS ].toString();
|
||||||
_api_port = API_DEFAULT_PORT;
|
_api_port = API_DEFAULT_PORT;
|
||||||
@ -211,25 +228,52 @@ bool LedDeviceNanoleaf::initLeds()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort panels top down, left right
|
// Travers panels top down
|
||||||
for(auto posY = panelMap.crbegin(); posY != panelMap.crend(); ++posY)
|
for(auto posY = panelMap.crbegin(); posY != panelMap.crend(); ++posY)
|
||||||
{
|
{
|
||||||
// posY.first is the first key
|
// Sort panels left to right
|
||||||
for(auto const &posX : posY->second)
|
if ( _leftRight )
|
||||||
{
|
{
|
||||||
// posX.first is the second key, posX.second is the data
|
for( auto posX = posY->second.cbegin(); posX != posY->second.cend(); ++posX)
|
||||||
DebugIf(verbose3, _log, "panelMap[%u][%u]=%u", posY->first, posX.first, posX.second );
|
{
|
||||||
_panelIds.push_back(posX.second);
|
DebugIf(verbose3, _log, "panelMap[%u][%u]=%u", posY->first, posX->first, posX->second );
|
||||||
|
|
||||||
|
if ( _topDown )
|
||||||
|
_panelIds.push_back(posX->second);
|
||||||
|
else
|
||||||
|
_panelIds.push_front(posX->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Sort panels right to left
|
||||||
|
for( auto posX = posY->second.crbegin(); posX != posY->second.crend(); ++posX)
|
||||||
|
{
|
||||||
|
DebugIf(verbose3, _log, "panelMap[%u][%u]=%u", posY->first, posX->first, posX->second );
|
||||||
|
|
||||||
|
if ( _topDown )
|
||||||
|
_panelIds.push_back(posX->second);
|
||||||
|
else
|
||||||
|
_panelIds.push_front(posX->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this->_panelLedCount = static_cast<uint>(_panelIds.size());
|
this->_panelLedCount = static_cast<uint>(_panelIds.size());
|
||||||
_devConfig["hardwareLedCount"] = static_cast<int>(_panelLedCount);
|
_devConfig["hardwareLedCount"] = static_cast<int>(_panelLedCount);
|
||||||
|
|
||||||
Debug(_log, "PanelsNum : %u", panelNum);
|
Debug(_log, "PanelsNum : %u", panelNum);
|
||||||
Debug(_log, "PanelLedCount : %u", _panelLedCount);
|
Debug(_log, "PanelLedCount : %u", _panelLedCount);
|
||||||
|
|
||||||
// Check. if enough panelds were found.
|
// Check. if enough panels were found.
|
||||||
uint configuredLedCount = this->getLedCount();
|
uint configuredLedCount = this->getLedCount();
|
||||||
|
_endPos = _startPos + configuredLedCount - 1;
|
||||||
|
|
||||||
|
Debug(_log, "Sort Top>Down : %d", _topDown);
|
||||||
|
Debug(_log, "Sort Left>Right: %d", _leftRight);
|
||||||
|
Debug(_log, "Start Panel Pos: %u", _startPos);
|
||||||
|
Debug(_log, "End Panel Pos : %u", _endPos);
|
||||||
|
|
||||||
if (_panelLedCount < configuredLedCount )
|
if (_panelLedCount < configuredLedCount )
|
||||||
{
|
{
|
||||||
QString errorReason = QString("Not enough panels [%1] for configured LEDs [%2] found!")
|
QString errorReason = QString("Not enough panels [%1] for configured LEDs [%2] found!")
|
||||||
@ -242,10 +286,21 @@ bool LedDeviceNanoleaf::initLeds()
|
|||||||
{
|
{
|
||||||
if ( _panelLedCount > this->getLedCount() )
|
if ( _panelLedCount > this->getLedCount() )
|
||||||
{
|
{
|
||||||
Warning(_log, "Nanoleaf: More panels [%u] than configured LEDs [%u].", _panelLedCount, configuredLedCount );
|
Info(_log, "Nanoleaf: More panels [%u] than configured LEDs [%u].", _panelLedCount, configuredLedCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check, if start position + number of configured LEDs is greater than number of panels available
|
||||||
|
if ( _endPos >= _panelLedCount )
|
||||||
|
{
|
||||||
|
QString errorReason = QString("Start panel [%1] out of range. Start panel position can be max [%2] given [%3] panel available!")
|
||||||
|
.arg(_startPos).arg(_panelLedCount-configuredLedCount).arg(_panelLedCount);
|
||||||
|
|
||||||
|
this->setInError(errorReason);
|
||||||
|
isInitOK = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return isInitOK;
|
return isInitOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,6 +515,9 @@ int LedDeviceNanoleaf::write(const std::vector<ColorRgb> & ledValues)
|
|||||||
udpbuffer[i++] = lowByte;
|
udpbuffer[i++] = lowByte;
|
||||||
|
|
||||||
ColorRgb color;
|
ColorRgb color;
|
||||||
|
|
||||||
|
//Maintain LED counter independent from PanelCounter
|
||||||
|
uint ledCounter = 0;
|
||||||
for ( uint panelCounter=0; panelCounter < _panelLedCount; panelCounter++ )
|
for ( uint panelCounter=0; panelCounter < _panelLedCount; panelCounter++ )
|
||||||
{
|
{
|
||||||
uint panelID = _panelIds[panelCounter];
|
uint panelID = _panelIds[panelCounter];
|
||||||
@ -468,12 +526,13 @@ int LedDeviceNanoleaf::write(const std::vector<ColorRgb> & ledValues)
|
|||||||
lowByte = static_cast<uchar>(panelID & 0xFF);
|
lowByte = static_cast<uchar>(panelID & 0xFF);
|
||||||
|
|
||||||
// Set panels configured
|
// Set panels configured
|
||||||
if( panelCounter < this->getLedCount() ) {
|
if( panelCounter >= _startPos && panelCounter <= _endPos ) {
|
||||||
color = static_cast<ColorRgb>(ledValues.at(panelCounter));
|
color = static_cast<ColorRgb>(ledValues.at(ledCounter));
|
||||||
|
++ledCounter;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Set panels not configed to black;
|
// Set panels not configured to black;
|
||||||
color = ColorRgb::BLACK;
|
color = ColorRgb::BLACK;
|
||||||
DebugIf(verbose3, _log, "[%u] >= panelLedCount [%u] => Set to BLACK", panelCounter, _panelLedCount );
|
DebugIf(verbose3, _log, "[%u] >= panelLedCount [%u] => Set to BLACK", panelCounter, _panelLedCount );
|
||||||
}
|
}
|
||||||
|
@ -82,22 +82,6 @@ protected:
|
|||||||
virtual int open() override;
|
virtual int open() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// QNetworkAccessManager object for sending requests.
|
|
||||||
QNetworkAccessManager* _networkmanager;
|
|
||||||
|
|
||||||
QString _hostname;
|
|
||||||
QString _api_port;
|
|
||||||
QString _auth_token;
|
|
||||||
|
|
||||||
//Nanoleaf device details
|
|
||||||
QString _deviceModel;
|
|
||||||
QString _deviceFirmwareVersion;
|
|
||||||
ushort _extControlVersion;
|
|
||||||
/// The number of panels with leds
|
|
||||||
uint _panelLedCount;
|
|
||||||
/// Array of the pannel ids.
|
|
||||||
std::vector<uint> _panelIds;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Discover Nanoleaf device via SSDP identifiers
|
/// Discover Nanoleaf device via SSDP identifiers
|
||||||
///
|
///
|
||||||
@ -162,4 +146,26 @@ private:
|
|||||||
/// @param uint8_t vector
|
/// @param uint8_t vector
|
||||||
/// @return vector as string of hex values
|
/// @return vector as string of hex values
|
||||||
std::string uint8_vector_to_hex_string( const std::vector<uint8_t>& buffer ) const;
|
std::string uint8_vector_to_hex_string( const std::vector<uint8_t>& buffer ) const;
|
||||||
|
|
||||||
|
// QNetworkAccessManager object for sending requests.
|
||||||
|
QNetworkAccessManager* _networkmanager;
|
||||||
|
|
||||||
|
QString _hostname;
|
||||||
|
QString _api_port;
|
||||||
|
QString _auth_token;
|
||||||
|
|
||||||
|
bool _topDown;
|
||||||
|
bool _leftRight;
|
||||||
|
uint _startPos;
|
||||||
|
uint _endPos;
|
||||||
|
|
||||||
|
//Nanoleaf device details
|
||||||
|
QString _deviceModel;
|
||||||
|
QString _deviceFirmwareVersion;
|
||||||
|
ushort _extControlVersion;
|
||||||
|
/// The number of panels with leds
|
||||||
|
uint _panelLedCount;
|
||||||
|
/// Array of the pannel ids.
|
||||||
|
QVector<uint> _panelIds;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -24,38 +24,6 @@ bool LedDeviceLpd8806::init(const QJsonObject &deviceConfig)
|
|||||||
return isInitOK;
|
return isInitOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceLpd8806::open()
|
|
||||||
{
|
|
||||||
int retval = -1;
|
|
||||||
QString errortext;
|
|
||||||
_deviceReady = false;
|
|
||||||
|
|
||||||
// General initialisation and configuration of LedDevice
|
|
||||||
if ( init(_devConfig) )
|
|
||||||
{
|
|
||||||
// Perform an initial reset to start accepting data on the first led
|
|
||||||
|
|
||||||
const unsigned clearSize = _ledCount/32+1;
|
|
||||||
if ( writeBytes(clearSize, _ledBuffer.data()) < 0 )
|
|
||||||
{
|
|
||||||
errortext = QString ("Failed to do initial write");
|
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LedDeviceLpd8806::write(const std::vector<ColorRgb> &ledValues)
|
int LedDeviceLpd8806::write(const std::vector<ColorRgb> &ledValues)
|
||||||
{
|
{
|
||||||
// Copy the colors from the ColorRgb vector to the Ldp8806 data vector
|
// Copy the colors from the ColorRgb vector to the Ldp8806 data vector
|
||||||
|
@ -95,14 +95,6 @@ public:
|
|||||||
/// @return true if success
|
/// @return true if success
|
||||||
virtual bool init(const QJsonObject &deviceConfig) override;
|
virtual bool init(const QJsonObject &deviceConfig) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
///
|
|
||||||
/// Opens and initiatialises the output device
|
|
||||||
///
|
|
||||||
/// @return Zero on succes (i.e. device is ready and enabled) else negative
|
|
||||||
///
|
|
||||||
virtual int open() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///
|
///
|
||||||
/// Writes the led color values to the led-device
|
/// Writes the led color values to the led-device
|
||||||
|
@ -11,6 +11,47 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"title":"edt_dev_auth_key_title",
|
"title":"edt_dev_auth_key_title",
|
||||||
"propertyOrder" : 2
|
"propertyOrder" : 2
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type" : "object",
|
||||||
|
"title":"edt_dev_spec_panelorganisation_title",
|
||||||
|
"access" : "advanced",
|
||||||
|
"propertyOrder" : 3
|
||||||
|
},
|
||||||
|
"panelOrderTopDown": {
|
||||||
|
"type": "integer",
|
||||||
|
"title":"edt_dev_spec_order_top_down_title",
|
||||||
|
"enum" : [0, 1],
|
||||||
|
"default" : 0,
|
||||||
|
"options" : {
|
||||||
|
"enum_titles" : ["edt_conf_enum_top_down", "edt_conf_enum_bottom_up"]
|
||||||
|
},
|
||||||
|
"minimum" : 0,
|
||||||
|
"maximum" : 1,
|
||||||
|
"access" : "advanced",
|
||||||
|
"propertyOrder" : 4
|
||||||
|
},
|
||||||
|
"panelOrderLeftRight": {
|
||||||
|
"type": "integer",
|
||||||
|
"title":"edt_dev_spec_order_left_right_title",
|
||||||
|
"enum" : [0, 1],
|
||||||
|
"default" : 0,
|
||||||
|
"options" : {
|
||||||
|
"enum_titles" : ["edt_conf_enum_left_right", "edt_conf_enum_right_left"]
|
||||||
|
},
|
||||||
|
"minimum" : 0,
|
||||||
|
"maximum" : 1,
|
||||||
|
"access" : "advanced",
|
||||||
|
"propertyOrder" : 5
|
||||||
|
},
|
||||||
|
"panelStartPos": {
|
||||||
|
"type": "integer",
|
||||||
|
"title":"edt_dev_spec_panel_start_position",
|
||||||
|
"step": 1,
|
||||||
|
"minimum" : 0,
|
||||||
|
"default": 0,
|
||||||
|
"access" : "advanced",
|
||||||
|
"propertyOrder" : 6
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": true
|
"additionalProperties": true
|
||||||
|
Loading…
Reference in New Issue
Block a user