mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Layout corrections and filter for non LED panels
This commit is contained in:
parent
2de4d4ebc1
commit
e954f2a12b
@ -2491,59 +2491,65 @@ function nanoleafGeneratelayout(panelLayout, panelOrderTopDown, panelOrderLeftRi
|
|||||||
|
|
||||||
// Dictionary for Nanoleaf shape types
|
// Dictionary for Nanoleaf shape types
|
||||||
let shapeTypes = {
|
let shapeTypes = {
|
||||||
0: { name: "LightsTriangle", sideLengthX: 150, sideLengthY: 150 },
|
0: { name: "LightsTriangle", led: true, sideLengthX: 150, sideLengthY: 150 },
|
||||||
1: { name: "LightsRythm", sideLengthX: 0, sideLengthY: 0 },
|
1: { name: "LightsRythm", led: false, sideLengthX: 0, sideLengthY: 0 },
|
||||||
2: { name: "Square", sideLengthX: 100, sideLengthY: 100 },
|
2: { name: "Square", led: true, sideLengthX: 100, sideLengthY: 100 },
|
||||||
3: { name: "SquareControllerMaster", sideLengthX: 100, sideLengthY: 100 },
|
3: { name: "SquareControllerMaster", led: true, sideLengthX: 100, sideLengthY: 100 },
|
||||||
4: { name: "SquareControllerPassive", sideLengthX: 100, sideLengthY: 100 },
|
4: { name: "SquareControllerPassive", led: true, sideLengthX: 100, sideLengthY: 100 },
|
||||||
5: { name: "PowerSupply", sideLengthX: 100, sideLengthY: 100 },
|
5: { name: "PowerSupply", led: true, sideLengthX: 100, sideLengthY: 100 },
|
||||||
7: { name: "ShapesHexagon", sideLengthX: 67, sideLengthY: 67 },
|
7: { name: "ShapesHexagon", led: true, sideLengthX: 67, sideLengthY: 67 },
|
||||||
8: { name: "ShapesTriangle", sideLengthX: 134, sideLengthY: 134 },
|
8: { name: "ShapesTriangle", led: true, sideLengthX: 134, sideLengthY: 134 },
|
||||||
9: { name: "ShapesMiniTriangle", sideLengthX: 67, sideLengthY: 67 },
|
9: { name: "ShapesMiniTriangle", led: true, sideLengthX: 67, sideLengthY: 67 },
|
||||||
12: { name: "ShapesController", sideLengthX: 0, sideLengthY: 0 },
|
12: { name: "ShapesController", led: false, sideLengthX: 0, sideLengthY: 0 },
|
||||||
14: { name: "ElementsHexagon", sideLengthX: 134, sideLengthY: 134 },
|
14: { name: "ElementsHexagon", led: true, sideLengthX: 134, sideLengthY: 134 },
|
||||||
15: { name: "ElementsHexagonCorner", sideLengthX: 33.5, sideLengthY: 58 },
|
15: { name: "ElementsHexagonCorner", led: true, sideLengthX: 33.5, sideLengthY: 58 },
|
||||||
16: { name: "LinesConnector", sideLengthX: 11, sideLengthY: 11 },
|
16: { name: "LinesConnector", led: false, sideLengthX: 11, sideLengthY: 11 },
|
||||||
17: { name: "LightLines", sideLengthX: 154, sideLengthY: 154 },
|
17: { name: "LightLines", led: true, sideLengthX: 154, sideLengthY: 154 },
|
||||||
18: { name: "LightLinesSingleZone", sideLengthX: 77, sideLengthY: 77 },
|
18: { name: "LightLinesSingleZone", led: true, sideLengthX: 77, sideLengthY: 77 },
|
||||||
19: { name: "ControllerCap", sideLengthX: 11, sideLengthY: 11 },
|
19: { name: "ControllerCap", led: false, sideLengthX: 11, sideLengthY: 11 },
|
||||||
20: { name: "PowerConnector", sideLengthX: 11, sideLengthY: 11 },
|
20: { name: "PowerConnector", led: false, sideLengthX: 11, sideLengthY: 11 },
|
||||||
999: { name: "Unknown", sideLengthX: 100, sideLengthY: 100 }
|
999: { name: "Unknown", led: true, sideLengthX: 100, sideLengthY: 100 }
|
||||||
};
|
};
|
||||||
|
|
||||||
let { globalOrientation, layout } = panelLayout;
|
let { globalOrientation, layout } = panelLayout;
|
||||||
var positionData = layout.positionData;
|
|
||||||
var degreesToRotate = 0;
|
var degreesToRotate = 0;
|
||||||
if (globalOrientation) {
|
if (globalOrientation) {
|
||||||
degreesToRotate = globalOrientation.value;
|
degreesToRotate = -globalOrientation.value;
|
||||||
}
|
}
|
||||||
// Convert degrees to radians
|
// Convert degrees to radians
|
||||||
var radians = (degreesToRotate * Math.PI) / 180;
|
var radians = (degreesToRotate * Math.PI) / 180;
|
||||||
|
|
||||||
var rotatedCoordinates = rotateCoordinates(positionData[0].x, positionData[0].y, radians);
|
//Reduce the capture area
|
||||||
var minX = rotatedCoordinates.x;
|
const areaSizeFactor = 0.5;
|
||||||
var maxX = rotatedCoordinates.x;
|
|
||||||
var minY = rotatedCoordinates.y;
|
|
||||||
var maxY = rotatedCoordinates.y;
|
|
||||||
|
|
||||||
//Define capture rectangle per panel
|
var panelDataXY = [...layout.positionData];
|
||||||
var factorPartial = 0.25;
|
panelDataXY.forEach(panel => {
|
||||||
|
|
||||||
positionData.forEach(panel => {
|
|
||||||
|
|
||||||
if (shapeTypes[panel.shapeType] == undefined) {
|
if (shapeTypes[panel.shapeType] == undefined) {
|
||||||
panel.shapeType = 999;
|
panel.shapeType = 999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
panel.shapeName = shapeTypes[panel.shapeType].name;
|
||||||
|
panel.led = shapeTypes[panel.shapeType].led;
|
||||||
|
panel.areaWidth = shapeTypes[panel.shapeType].sideLengthX * areaSizeFactor;
|
||||||
|
panel.areaHeight = shapeTypes[panel.shapeType].sideLengthY * areaSizeFactor;
|
||||||
|
|
||||||
if (radians !== 0) {
|
if (radians !== 0) {
|
||||||
rotatedCoordinates = rotateCoordinates(panel.x, panel.y, radians);
|
var rotatedXY = rotateCoordinates(panel.x, panel.y, radians)
|
||||||
panel.x = rotatedCoordinates.x;
|
panel.x = rotatedXY.x;
|
||||||
panel.y = rotatedCoordinates.y;
|
panel.y = rotatedXY.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.maxX = panel.x + shapeTypes[panel.shapeType].sideLengthX * factorPartial;
|
panel.maxX = panel.x + panel.areaWidth;
|
||||||
panel.maxY = panel.y + shapeTypes[panel.shapeType].sideLengthY * factorPartial;
|
panel.maxY = panel.y + panel.areaHeight;
|
||||||
panel.shapeName = shapeTypes[panel.shapeType].name;
|
});
|
||||||
|
|
||||||
|
var minX = panelDataXY[0].x;
|
||||||
|
var maxX = panelDataXY[0].x;
|
||||||
|
var minY = panelDataXY[0].y;
|
||||||
|
var maxY = panelDataXY[0].y;
|
||||||
|
panelDataXY.forEach(panel => {
|
||||||
|
|
||||||
if (panel.maxX > maxX) {
|
if (panel.maxX > maxX) {
|
||||||
maxX = panel.maxX;
|
maxX = panel.maxX;
|
||||||
@ -2559,26 +2565,25 @@ function nanoleafGeneratelayout(panelLayout, panelOrderTopDown, panelOrderLeftRi
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const width = (maxX - minX);
|
const width = Math.abs(maxX - minX);
|
||||||
const height = (maxY - minY);
|
const height = Math.abs(maxY - minY);
|
||||||
const scaleX = 1 / width;
|
const scaleX = 1 / width;
|
||||||
const scaleY = 1 / height;
|
const scaleY = 1 / height;
|
||||||
|
|
||||||
var layoutObjects = [];
|
var layoutObjects = [];
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
||||||
sortByPanelCoordinates(positionData, panelOrderTopDown, panelOrderLeftRight);
|
sortByPanelCoordinates(panelDataXY, panelOrderTopDown, panelOrderLeftRight);
|
||||||
positionData.forEach(panel => {
|
panelDataXY.forEach(panel => {
|
||||||
|
|
||||||
// Skip non-LED elements
|
if (panel.led) {
|
||||||
if (panel.sideLengthX !== 0) {
|
|
||||||
let layoutObject = {
|
let layoutObject = {
|
||||||
name: i + "-" + panel.panelId,
|
name: i + "-" + panel.panelId,
|
||||||
hmin: (panel.x - minX) * scaleX,
|
hmin: Math.min(1, Math.max(0, (panel.x - minX) * scaleX)),
|
||||||
hmax: (panel.maxX - minX) * scaleX,
|
hmax: Math.min(1, Math.max(0, (panel.x - minX + panel.areaWidth) * scaleX)),
|
||||||
//Nanoleaf corodinates start at bottom left, therefore reverse vertical positioning
|
//Nanoleaf corodinates start at bottom left, therefore reverse vertical positioning
|
||||||
vmin: 1 - ((panel.maxY - minY) * scaleY),
|
vmax: (1 - Math.min(1, Math.max(0, (panel.y - minY) * scaleY))),
|
||||||
vmax: 1 - ((panel.y - minY) * scaleY)
|
vmin: (1 - Math.min(1, Math.max(0, (panel.y - minY + panel.areaHeight) * scaleY)))
|
||||||
};
|
};
|
||||||
layoutObjects.push(JSON.parse(JSON.stringify(layoutObject)));
|
layoutObjects.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||||
++i;
|
++i;
|
||||||
|
@ -199,14 +199,19 @@ int LedDeviceNanoleaf::getHwLedCount(const QJsonObject& jsonLayout) const
|
|||||||
|
|
||||||
DebugIf(verbose, _log, "Panel [%d] - Type: [%d]", panelId, panelshapeType);
|
DebugIf(verbose, _log, "Panel [%d] - Type: [%d]", panelId, panelshapeType);
|
||||||
|
|
||||||
// Skip Rhythm and Shapes controller panels
|
// Skip non LED panel types
|
||||||
if (panelshapeType != RHYTM && panelshapeType != SHAPES_CONTROLLER)
|
switch (panelshapeType)
|
||||||
{
|
{
|
||||||
|
case SHAPES_CONTROLLER:
|
||||||
|
case LINES_CONECTOR:
|
||||||
|
case CONTROLLER_CAP:
|
||||||
|
case POWER_CONNECTOR:
|
||||||
|
case RHYTM:
|
||||||
|
DebugIf(verbose, _log, "Rhythm/Shape/lines Controller panel skipped.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
++hwLedCount;
|
++hwLedCount;
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
{ // Reset non support/required features
|
|
||||||
DebugIf(verbose, _log, "Rhythm/Shape Controller panel skipped.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hwLedCount;
|
return hwLedCount;
|
||||||
@ -245,7 +250,7 @@ bool LedDeviceNanoleaf::initLedsConfiguration()
|
|||||||
QJsonObject jsonPanelLayout = jsonAllPanelInfo[API_PANELLAYOUT].toObject();
|
QJsonObject jsonPanelLayout = jsonAllPanelInfo[API_PANELLAYOUT].toObject();
|
||||||
|
|
||||||
const QJsonObject globalOrientation = jsonPanelLayout[PANEL_GLOBALORIENTATION].toObject();
|
const QJsonObject globalOrientation = jsonPanelLayout[PANEL_GLOBALORIENTATION].toObject();
|
||||||
double radians = (globalOrientation[PANEL_GLOBALORIENTATION_VALUE].toInt() * std::acos(-1)) / 180;
|
double radians = (-1 * globalOrientation[PANEL_GLOBALORIENTATION_VALUE].toInt() * std::acos(-1)) / 180;
|
||||||
|
|
||||||
QJsonObject jsonLayout = jsonPanelLayout[PANEL_LAYOUT].toObject();
|
QJsonObject jsonLayout = jsonPanelLayout[PANEL_LAYOUT].toObject();
|
||||||
|
|
||||||
@ -302,7 +307,7 @@ bool LedDeviceNanoleaf::initLedsConfiguration()
|
|||||||
{
|
{
|
||||||
for (auto posX = posY->second.cbegin(); posX != posY->second.cend(); ++posX)
|
for (auto posX = posY->second.cbegin(); posX != posY->second.cend(); ++posX)
|
||||||
{
|
{
|
||||||
DebugIf(verbose3, _log, "panelMap[%d][%d]=%d", posY->first, posX->first, posX->second);
|
DebugIf(verbose, _log, "panelMap[%d][%d]=%d", posY->first, posX->first, posX->second);
|
||||||
|
|
||||||
if (_topDown)
|
if (_topDown)
|
||||||
{
|
{
|
||||||
@ -319,7 +324,7 @@ bool LedDeviceNanoleaf::initLedsConfiguration()
|
|||||||
// Sort panels right to left
|
// Sort panels right to left
|
||||||
for (auto posX = posY->second.crbegin(); posX != posY->second.crend(); ++posX)
|
for (auto posX = posY->second.crbegin(); posX != posY->second.crend(); ++posX)
|
||||||
{
|
{
|
||||||
DebugIf(verbose3, _log, "panelMap[%d][%d]=%d", posY->first, posX->first, posX->second);
|
DebugIf(verbose, _log, "panelMap[%d][%d]=%d", posY->first, posX->first, posX->second);
|
||||||
|
|
||||||
if (_topDown)
|
if (_topDown)
|
||||||
{
|
{
|
||||||
@ -338,6 +343,9 @@ bool LedDeviceNanoleaf::initLedsConfiguration()
|
|||||||
Debug(_log, "Sort Top>Down : %d", _topDown);
|
Debug(_log, "Sort Top>Down : %d", _topDown);
|
||||||
Debug(_log, "Sort Left>Right: %d", _leftRight);
|
Debug(_log, "Sort Left>Right: %d", _leftRight);
|
||||||
|
|
||||||
|
DebugIf(verbose, _log, "PanelMap size : %d", panelMap.size());
|
||||||
|
DebugIf(verbose, _log, "PanelIds count : %d", _panelIds.size());
|
||||||
|
|
||||||
// Check. if enough panels were found.
|
// Check. if enough panels were found.
|
||||||
int configuredLedCount = this->getLedCount();
|
int configuredLedCount = this->getLedCount();
|
||||||
if (_panelLedCount < configuredLedCount)
|
if (_panelLedCount < configuredLedCount)
|
||||||
@ -354,6 +362,17 @@ bool LedDeviceNanoleaf::initLedsConfiguration()
|
|||||||
{
|
{
|
||||||
Info(_log, "%s: More panels [%d] than configured LEDs [%d].", QSTRING_CSTR(this->getActiveDeviceType()), _panelLedCount, configuredLedCount);
|
Info(_log, "%s: More panels [%d] than configured LEDs [%d].", QSTRING_CSTR(this->getActiveDeviceType()), _panelLedCount, configuredLedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Check that panel count matches working list created for processing
|
||||||
|
if (_panelLedCount != _panelIds.size())
|
||||||
|
{
|
||||||
|
QString errorReason = QString("Number of available panels [%1] do not match panel-ID look-up list [%2]!")
|
||||||
|
.arg(_panelLedCount)
|
||||||
|
.arg(_panelIds.size());
|
||||||
|
this->setInError(errorReason, false);
|
||||||
|
isInitOK = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return isInitOK;
|
return isInitOK;
|
||||||
@ -816,9 +835,7 @@ int LedDeviceNanoleaf::write(const std::vector<ColorRgb>& ledValues)
|
|||||||
|
|
||||||
ColorRgb color;
|
ColorRgb color;
|
||||||
|
|
||||||
//Maintain LED counter independent from PanelCounter
|
for (int panelCounter = 0; panelCounter < _panelLedCount; ++panelCounter)
|
||||||
int ledCounter = 0;
|
|
||||||
for (int panelCounter = 0; panelCounter < _panelLedCount; panelCounter++)
|
|
||||||
{
|
{
|
||||||
// Set panelID
|
// Set panelID
|
||||||
int panelID = _panelIds[panelCounter];
|
int panelID = _panelIds[panelCounter];
|
||||||
@ -826,8 +843,16 @@ int LedDeviceNanoleaf::write(const std::vector<ColorRgb>& ledValues)
|
|||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
// Set panel's color LEDs
|
// Set panel's color LEDs
|
||||||
color = static_cast<ColorRgb>(ledValues.at(ledCounter));
|
if (panelCounter < this->getLedCount()) {
|
||||||
++ledCounter;
|
color = static_cast<ColorRgb>(ledValues.at(panelCounter));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set panels not configed to black;
|
||||||
|
color = ColorRgb::BLACK;
|
||||||
|
DebugIf(verbose3, _log, "[%u] >= panelLedCount [%u] => Set to BLACK", panelCounter, _panelLedCount);
|
||||||
|
}
|
||||||
|
|
||||||
udpbuffer[i++] = static_cast<char>(color.red);
|
udpbuffer[i++] = static_cast<char>(color.red);
|
||||||
udpbuffer[i++] = static_cast<char>(color.green);
|
udpbuffer[i++] = static_cast<char>(color.green);
|
||||||
udpbuffer[i++] = static_cast<char>(color.blue);
|
udpbuffer[i++] = static_cast<char>(color.blue);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user