Merge pull request #829 from Lord-Grey/Update_LedDevices

Update led devices(LPD8806 + Nanoleaf)
This commit is contained in:
Serhan
2020-06-17 21:38:24 +02:00
committed by GitHub
7 changed files with 153 additions and 71 deletions

View File

@@ -21,6 +21,10 @@ static const char CONFIG_ADDRESS[] = "host";
//static const char CONFIG_PORT[] = "port";
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
static const char PANEL_LAYOUT[] = "layout";
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, "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
_hostname = deviceConfig[ CONFIG_ADDRESS ].toString();
_api_port = API_DEFAULT_PORT;
@@ -211,30 +228,57 @@ bool LedDeviceNanoleaf::initLeds()
}
}
// Sort panels top down, left right
// Travers panels top down
for(auto posY = panelMap.crbegin(); posY != panelMap.crend(); ++posY)
{
// posY.first is the first key
for(auto const &posX : posY->second)
// Sort panels left to right
if ( _leftRight )
{
// posX.first is the second key, posX.second is the data
DebugIf(verbose3, _log, "panelMap[%u][%u]=%u", posY->first, posX.first, posX.second );
_panelIds.push_back(posX.second);
for( auto posX = posY->second.cbegin(); posX != posY->second.cend(); ++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);
}
}
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());
_devConfig["hardwareLedCount"] = static_cast<int>(_panelLedCount);
Debug(_log, "PanelsNum : %u", panelNum);
Debug(_log, "PanelLedCount : %u", _panelLedCount);
// Check. if enough panelds were found.
// Check. if enough panels were found.
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 )
{
QString errorReason = QString("Not enough panels [%1] for configured LEDs [%2] found!")
.arg(_panelLedCount)
.arg(configuredLedCount);
.arg(_panelLedCount)
.arg(configuredLedCount);
this->setInError(errorReason);
isInitOK = false;
}
@@ -242,10 +286,21 @@ bool LedDeviceNanoleaf::initLeds()
{
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;
}
@@ -460,6 +515,9 @@ int LedDeviceNanoleaf::write(const std::vector<ColorRgb> & ledValues)
udpbuffer[i++] = lowByte;
ColorRgb color;
//Maintain LED counter independent from PanelCounter
uint ledCounter = 0;
for ( uint panelCounter=0; panelCounter < _panelLedCount; panelCounter++ )
{
uint panelID = _panelIds[panelCounter];
@@ -468,12 +526,13 @@ int LedDeviceNanoleaf::write(const std::vector<ColorRgb> & ledValues)
lowByte = static_cast<uchar>(panelID & 0xFF);
// Set panels configured
if( panelCounter < this->getLedCount() ) {
color = static_cast<ColorRgb>(ledValues.at(panelCounter));
if( panelCounter >= _startPos && panelCounter <= _endPos ) {
color = static_cast<ColorRgb>(ledValues.at(ledCounter));
++ledCounter;
}
else
{
// Set panels not configed to black;
// Set panels not configured to black;
color = ColorRgb::BLACK;
DebugIf(verbose3, _log, "[%u] >= panelLedCount [%u] => Set to BLACK", panelCounter, _panelLedCount );
}

View File

@@ -82,22 +82,6 @@ protected:
virtual int open() override;
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
///
@@ -162,4 +146,26 @@ private:
/// @param uint8_t vector
/// @return vector as string of hex values
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;
};

View File

@@ -24,38 +24,6 @@ bool LedDeviceLpd8806::init(const QJsonObject &deviceConfig)
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)
{
// Copy the colors from the ColorRgb vector to the Ldp8806 data vector

View File

@@ -95,14 +95,6 @@ public:
/// @return true if success
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:
///
/// Writes the led color values to the led-device

View File

@@ -11,6 +11,47 @@
"type": "string",
"title":"edt_dev_auth_key_title",
"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