mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Clone single led color from other led (#157)
* start ledclone * led cloning: clone scan areas from original led main: show exceptions, better exit * tune json schema for new option. somwe cleanup * fix warnings and bug for framebuffer selection. thx to clang brought by new osx buikld on travis * make ledclone feature work flawlessly for effects too. Effect sees the ledstring without cloned leds. cloned leds will be inserted just before sending to leddevice additional: remove warnings and fix code style * fix warning
This commit is contained in:
		@@ -268,6 +268,7 @@ public:
 | 
			
		||||
	 * @return The constructed ledstring
 | 
			
		||||
	 */
 | 
			
		||||
	static LedString createLedString(const Json::Value & ledsConfig, const ColorOrder deviceOrder);
 | 
			
		||||
	static LedString createLedStringClone(const Json::Value & ledsConfig, const ColorOrder deviceOrder);
 | 
			
		||||
 | 
			
		||||
	static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig);
 | 
			
		||||
	static MultiColorCorrection * createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorTemperatureConfig);
 | 
			
		||||
@@ -312,6 +313,10 @@ private:
 | 
			
		||||
	/// The specifiation of the led frame construction and picture integration
 | 
			
		||||
	LedString _ledString;
 | 
			
		||||
 | 
			
		||||
	/// specifiation of cloned leds
 | 
			
		||||
	LedString _ledStringClone;
 | 
			
		||||
 | 
			
		||||
	std::vector<ColorOrder> _ledStringColorOrder;
 | 
			
		||||
	/// The priority muxer
 | 
			
		||||
	PriorityMuxer _muxer;
 | 
			
		||||
 | 
			
		||||
@@ -368,4 +373,5 @@ private:
 | 
			
		||||
	
 | 
			
		||||
	/// holds the current priority channel that is manualy selected
 | 
			
		||||
	int _currentSourcePriority;
 | 
			
		||||
	
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,8 @@ struct Led
 | 
			
		||||
	double minY_frac;
 | 
			
		||||
	///  The maximum horizontal scan line included for this leds color
 | 
			
		||||
	double maxY_frac;
 | 
			
		||||
	/// id to clone
 | 
			
		||||
	int clone;
 | 
			
		||||
	/// the color order
 | 
			
		||||
	ColorOrder colorOrder;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -50,18 +50,18 @@ void Effect::registerHyperionExtensionModule()
 | 
			
		||||
	PyImport_AppendInittab("hyperion", &PyInit_hyperion);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Effect::Effect(PyThreadState * mainThreadState, int priority, int timeout, const std::string & script, const Json::Value & args) :
 | 
			
		||||
	QThread(),
 | 
			
		||||
	_mainThreadState(mainThreadState),
 | 
			
		||||
	_priority(priority),
 | 
			
		||||
	_timeout(timeout),
 | 
			
		||||
	_script(script),
 | 
			
		||||
	_args(args),
 | 
			
		||||
	_endTime(-1),
 | 
			
		||||
	_interpreterThreadState(nullptr),
 | 
			
		||||
	_abortRequested(false),
 | 
			
		||||
	_imageProcessor(ImageProcessorFactory::getInstance().newImageProcessor()),
 | 
			
		||||
	_colors()
 | 
			
		||||
Effect::Effect(PyThreadState * mainThreadState, int priority, int timeout, const std::string & script, const Json::Value & args)
 | 
			
		||||
	: QThread()
 | 
			
		||||
	, _mainThreadState(mainThreadState)
 | 
			
		||||
	, _priority(priority)
 | 
			
		||||
	, _timeout(timeout)
 | 
			
		||||
	, _script(script)
 | 
			
		||||
	, _args(args)
 | 
			
		||||
	, _endTime(-1)
 | 
			
		||||
	, _interpreterThreadState(nullptr)
 | 
			
		||||
	, _abortRequested(false)
 | 
			
		||||
	, _imageProcessor(ImageProcessorFactory::getInstance().newImageProcessor())
 | 
			
		||||
	, _colors()
 | 
			
		||||
{
 | 
			
		||||
	_colors.resize(_imageProcessor->getLedCount(), ColorRgb::BLACK);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,12 +18,12 @@
 | 
			
		||||
#include "Effect.h"
 | 
			
		||||
#include "HyperionConfig.h"
 | 
			
		||||
 | 
			
		||||
EffectEngine::EffectEngine(Hyperion * hyperion, const Json::Value & jsonEffectConfig) :
 | 
			
		||||
	_hyperion(hyperion),
 | 
			
		||||
	_availableEffects(),
 | 
			
		||||
	_activeEffects(),
 | 
			
		||||
	_mainThreadState(nullptr),
 | 
			
		||||
	_log(Logger::getInstance("EFFECTENGINE"))
 | 
			
		||||
EffectEngine::EffectEngine(Hyperion * hyperion, const Json::Value & jsonEffectConfig)
 | 
			
		||||
	: _hyperion(hyperion)
 | 
			
		||||
	, _availableEffects()
 | 
			
		||||
	, _activeEffects()
 | 
			
		||||
	, _mainThreadState(nullptr)
 | 
			
		||||
	, _log(Logger::getInstance("EFFECTENGINE"))
 | 
			
		||||
{
 | 
			
		||||
	qRegisterMetaType<std::vector<ColorRgb>>("std::vector<ColorRgb>");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -54,31 +54,7 @@ Hyperion* Hyperion::getInstance()
 | 
			
		||||
 | 
			
		||||
ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig)
 | 
			
		||||
{
 | 
			
		||||
	std::string order = deviceConfig.get("colorOrder", "rgb").asString();
 | 
			
		||||
	if (order == "bgr")
 | 
			
		||||
	{
 | 
			
		||||
		return ORDER_BGR;
 | 
			
		||||
	}
 | 
			
		||||
	if (order == "rbg")
 | 
			
		||||
	{
 | 
			
		||||
		return ORDER_RBG;
 | 
			
		||||
	}
 | 
			
		||||
	if (order == "brg")
 | 
			
		||||
	{
 | 
			
		||||
		return ORDER_BRG;
 | 
			
		||||
	}
 | 
			
		||||
	if (order == "gbr")
 | 
			
		||||
	{
 | 
			
		||||
		return ORDER_GBR;
 | 
			
		||||
	}
 | 
			
		||||
	if (order == "grb")
 | 
			
		||||
	{
 | 
			
		||||
		return ORDER_GRB;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WarningIf( order != "rgb", Logger::getInstance("Core"), "Unknown color order defined (%s). Using RGB.", order.c_str());
 | 
			
		||||
 | 
			
		||||
	return ORDER_RGB;
 | 
			
		||||
	return stringToColorOrder( deviceConfig.get("colorOrder", "rgb").asString() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ColorTransform * Hyperion::createColorTransform(const Json::Value & transformConfig)
 | 
			
		||||
@@ -443,40 +419,81 @@ RgbChannelAdjustment* Hyperion::createRgbChannelAdjustment(const Json::Value& co
 | 
			
		||||
LedString Hyperion::createLedString(const Json::Value& ledsConfig, const ColorOrder deviceOrder)
 | 
			
		||||
{
 | 
			
		||||
	LedString ledString;
 | 
			
		||||
 | 
			
		||||
	const std::string deviceOrderStr = colorOrderToString(deviceOrder);
 | 
			
		||||
	int maxLedId = ledsConfig.size();
 | 
			
		||||
	for (const Json::Value& ledConfig : ledsConfig)
 | 
			
		||||
	{
 | 
			
		||||
		Led led;
 | 
			
		||||
		led.index = ledConfig["index"].asInt();
 | 
			
		||||
 | 
			
		||||
		const Json::Value& hscanConfig = ledConfig["hscan"];
 | 
			
		||||
		const Json::Value& vscanConfig = ledConfig["vscan"];
 | 
			
		||||
		led.minX_frac = std::max(0.0, std::min(1.0, hscanConfig["minimum"].asDouble()));
 | 
			
		||||
		led.maxX_frac = std::max(0.0, std::min(1.0, hscanConfig["maximum"].asDouble()));
 | 
			
		||||
		led.minY_frac = std::max(0.0, std::min(1.0, vscanConfig["minimum"].asDouble()));
 | 
			
		||||
		led.maxY_frac = std::max(0.0, std::min(1.0, vscanConfig["maximum"].asDouble()));
 | 
			
		||||
 | 
			
		||||
		// Fix if the user swapped min and max
 | 
			
		||||
		if (led.minX_frac > led.maxX_frac)
 | 
			
		||||
		led.clone = ledConfig.get("clone",-1).asInt();
 | 
			
		||||
		if ( led.clone < -1 || led.clone >= maxLedId )
 | 
			
		||||
		{
 | 
			
		||||
			std::swap(led.minX_frac, led.maxX_frac);
 | 
			
		||||
		}
 | 
			
		||||
		if (led.minY_frac > led.maxY_frac)
 | 
			
		||||
		{
 | 
			
		||||
			std::swap(led.minY_frac, led.maxY_frac);
 | 
			
		||||
			Warning(Logger::getInstance("Core"), "LED %d: clone index of %d is out of range, clone ignored", led.index, led.clone);
 | 
			
		||||
			led.clone = -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Get the order of the rgb channels for this led (default is device order)
 | 
			
		||||
		const std::string ledOrderStr = ledConfig.get("colorOrder", deviceOrderStr).asString();
 | 
			
		||||
		led.colorOrder = stringToColorOrder(ledOrderStr);
 | 
			
		||||
		if ( led.clone < 0 )
 | 
			
		||||
		{
 | 
			
		||||
			const Json::Value& hscanConfig = ledConfig["hscan"];
 | 
			
		||||
			const Json::Value& vscanConfig = ledConfig["vscan"];
 | 
			
		||||
			led.minX_frac = std::max(0.0, std::min(1.0, hscanConfig["minimum"].asDouble()));
 | 
			
		||||
			led.maxX_frac = std::max(0.0, std::min(1.0, hscanConfig["maximum"].asDouble()));
 | 
			
		||||
			led.minY_frac = std::max(0.0, std::min(1.0, vscanConfig["minimum"].asDouble()));
 | 
			
		||||
			led.maxY_frac = std::max(0.0, std::min(1.0, vscanConfig["maximum"].asDouble()));
 | 
			
		||||
			// Fix if the user swapped min and max
 | 
			
		||||
			if (led.minX_frac > led.maxX_frac)
 | 
			
		||||
			{
 | 
			
		||||
				std::swap(led.minX_frac, led.maxX_frac);
 | 
			
		||||
			}
 | 
			
		||||
			if (led.minY_frac > led.maxY_frac)
 | 
			
		||||
			{
 | 
			
		||||
				std::swap(led.minY_frac, led.maxY_frac);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		ledString.leds().push_back(led);
 | 
			
		||||
			// Get the order of the rgb channels for this led (default is device order)
 | 
			
		||||
			led.colorOrder = stringToColorOrder(ledConfig.get("colorOrder", deviceOrderStr).asString());
 | 
			
		||||
			ledString.leds().push_back(led);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Make sure the leds are sorted (on their indices)
 | 
			
		||||
	std::sort(ledString.leds().begin(), ledString.leds().end(), [](const Led& lhs, const Led& rhs){ return lhs.index < rhs.index; });
 | 
			
		||||
	return ledString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LedString Hyperion::createLedStringClone(const Json::Value& ledsConfig, const ColorOrder deviceOrder)
 | 
			
		||||
{
 | 
			
		||||
	LedString ledString;
 | 
			
		||||
	const std::string deviceOrderStr = colorOrderToString(deviceOrder);
 | 
			
		||||
	int maxLedId = ledsConfig.size();
 | 
			
		||||
	for (const Json::Value& ledConfig : ledsConfig)
 | 
			
		||||
	{
 | 
			
		||||
		Led led;
 | 
			
		||||
		led.index = ledConfig["index"].asInt();
 | 
			
		||||
		led.clone = ledConfig.get("clone",-1).asInt();
 | 
			
		||||
		if ( led.clone < -1 || led.clone >= maxLedId )
 | 
			
		||||
		{
 | 
			
		||||
			Warning(Logger::getInstance("Core"), "LED %d: clone index of %d is out of range, clone ignored", led.index, led.clone);
 | 
			
		||||
			led.clone = -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( led.clone >= 0 )
 | 
			
		||||
		{
 | 
			
		||||
			Debug(Logger::getInstance("Core"), "LED %d: clone from led %d", led.index, led.clone);
 | 
			
		||||
			led.minX_frac = 0;
 | 
			
		||||
			led.maxX_frac = 0;
 | 
			
		||||
			led.minY_frac = 0;
 | 
			
		||||
			led.maxY_frac = 0;
 | 
			
		||||
			// Get the order of the rgb channels for this led (default is device order)
 | 
			
		||||
			led.colorOrder = stringToColorOrder(ledConfig.get("colorOrder", deviceOrderStr).asString());
 | 
			
		||||
 | 
			
		||||
			ledString.leds().push_back(led);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Make sure the leds are sorted (on their indices)
 | 
			
		||||
	std::sort(ledString.leds().begin(), ledString.leds().end(), [](const Led& lhs, const Led& rhs){ return lhs.index < rhs.index; });
 | 
			
		||||
	return ledString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -543,6 +560,7 @@ MessageForwarder * Hyperion::getForwarder()
 | 
			
		||||
 | 
			
		||||
Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
 | 
			
		||||
	: _ledString(createLedString(jsonConfig["leds"], createColorOrder(jsonConfig["device"])))
 | 
			
		||||
	, _ledStringClone(createLedStringClone(jsonConfig["leds"], createColorOrder(jsonConfig["device"])))
 | 
			
		||||
	, _muxer(_ledString.leds().size())
 | 
			
		||||
	, _raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"]))
 | 
			
		||||
	, _raw2ledTemperature(createLedColorsTemperature(_ledString.leds().size(), jsonConfig["color"]))
 | 
			
		||||
@@ -595,7 +613,7 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
 | 
			
		||||
	QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
 | 
			
		||||
 | 
			
		||||
	// create the effect engine
 | 
			
		||||
	_effectEngine = new EffectEngine(this, jsonConfig["effects"]);
 | 
			
		||||
	_effectEngine = new EffectEngine(this,jsonConfig["effects"]);
 | 
			
		||||
	
 | 
			
		||||
	unsigned int hwLedCount = jsonConfig["device"].get("ledCount",getLedCount()).asUInt();
 | 
			
		||||
	_hwLedCount = std::max(hwLedCount, getLedCount());
 | 
			
		||||
@@ -867,14 +885,32 @@ void Hyperion::update()
 | 
			
		||||
	if (_adjustmentEnabled)  _raw2ledAdjustment->applyAdjustment(_ledBuffer);
 | 
			
		||||
	if (_temperatureEnabled) _raw2ledTemperature->applyCorrection(_ledBuffer);
 | 
			
		||||
 | 
			
		||||
	const std::vector<Led>& leds = _ledString.leds();
 | 
			
		||||
 | 
			
		||||
	// init colororder vector, if nempty
 | 
			
		||||
	if (_ledStringColorOrder.empty())
 | 
			
		||||
	{
 | 
			
		||||
		for (Led& led : _ledString.leds())
 | 
			
		||||
		{
 | 
			
		||||
			_ledStringColorOrder.push_back(led.colorOrder);
 | 
			
		||||
		}
 | 
			
		||||
		for (Led& led : _ledStringClone.leds())
 | 
			
		||||
		{
 | 
			
		||||
			_ledStringColorOrder.insert(_ledStringColorOrder.begin() + led.index, led.colorOrder);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// insert cloned leds into buffer
 | 
			
		||||
	for (Led& led : _ledStringClone.leds())
 | 
			
		||||
	{
 | 
			
		||||
		_ledBuffer.insert(_ledBuffer.begin() + led.index, _ledBuffer.at(led.clone));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	for (ColorRgb& color : _ledBuffer)
 | 
			
		||||
	{
 | 
			
		||||
		const ColorOrder ledColorOrder = leds.at(i).colorOrder;
 | 
			
		||||
		//const ColorOrder ledColorOrder = leds.at(i).colorOrder;
 | 
			
		||||
 | 
			
		||||
		// correct the color byte order
 | 
			
		||||
		switch (ledColorOrder)
 | 
			
		||||
		switch (_ledStringColorOrder.at(i))
 | 
			
		||||
		{
 | 
			
		||||
		case ORDER_RGB:
 | 
			
		||||
			// leave as it is
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
			"properties" :
 | 
			
		||||
			{
 | 
			
		||||
				"level" :
 | 
			
		||||
				{
 | 
			
		||||
				{ 
 | 
			
		||||
					"enum" : ["silent", "warn", "verbose", "debug"]
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
@@ -33,19 +33,19 @@
 | 
			
		||||
				},
 | 
			
		||||
				"output" :
 | 
			
		||||
				{
 | 
			
		||||
					"type" : "string",
 | 
			
		||||
					"required" : true
 | 
			
		||||
					"type" : "string"
 | 
			
		||||
				},
 | 
			
		||||
				"rate" :
 | 
			
		||||
				{
 | 
			
		||||
					"type" : "integer",
 | 
			
		||||
					"required" : false,
 | 
			
		||||
					"minimum" : 0
 | 
			
		||||
				},
 | 
			
		||||
				"colorOrder" :
 | 
			
		||||
				{
 | 
			
		||||
					"type" : "string",
 | 
			
		||||
					"required" : false
 | 
			
		||||
					"type":
 | 
			
		||||
					{
 | 
			
		||||
						"enum" : ["bgr", "rbg", "brg", "gbr", "grb"]
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			"additionalProperties" : true
 | 
			
		||||
@@ -852,20 +852,27 @@
 | 
			
		||||
						"type":"integer",
 | 
			
		||||
						"required":true
 | 
			
		||||
					},
 | 
			
		||||
					"clone":
 | 
			
		||||
					{
 | 
			
		||||
						"type":"integer"
 | 
			
		||||
					},
 | 
			
		||||
					"hscan":
 | 
			
		||||
					{
 | 
			
		||||
						"type":"object",
 | 
			
		||||
						"required":true,
 | 
			
		||||
						"properties":
 | 
			
		||||
						{
 | 
			
		||||
							"minimum":
 | 
			
		||||
							{
 | 
			
		||||
								"type":"number",
 | 
			
		||||
								"minimum" : 0,
 | 
			
		||||
								"maximum" : 1,
 | 
			
		||||
								"required":true
 | 
			
		||||
							},
 | 
			
		||||
							"maximum":
 | 
			
		||||
							{
 | 
			
		||||
								"type":"number",
 | 
			
		||||
								"minimum" : 0,
 | 
			
		||||
								"maximum" : 1,
 | 
			
		||||
								"required":true
 | 
			
		||||
							}
 | 
			
		||||
						},
 | 
			
		||||
@@ -874,17 +881,20 @@
 | 
			
		||||
					"vscan":
 | 
			
		||||
					{
 | 
			
		||||
						"type":"object",
 | 
			
		||||
						"required":true,
 | 
			
		||||
						"properties":
 | 
			
		||||
						{
 | 
			
		||||
							"minimum":
 | 
			
		||||
							{
 | 
			
		||||
								"type":"number",
 | 
			
		||||
								"minimum" : 0,
 | 
			
		||||
								"maximum" : 1,
 | 
			
		||||
								"required":true
 | 
			
		||||
							},
 | 
			
		||||
							"maximum":
 | 
			
		||||
							{
 | 
			
		||||
								"type":"number",
 | 
			
		||||
								"minimum" : 0,
 | 
			
		||||
								"maximum" : 1,
 | 
			
		||||
								"required":true
 | 
			
		||||
							}
 | 
			
		||||
						},
 | 
			
		||||
@@ -892,8 +902,10 @@
 | 
			
		||||
					},
 | 
			
		||||
					"colorOrder":
 | 
			
		||||
					{
 | 
			
		||||
						"type":"string",
 | 
			
		||||
						"required":false
 | 
			
		||||
						"type":
 | 
			
		||||
						{
 | 
			
		||||
							"enum" : ["bgr", "rbg", "brg", "gbr", "grb"]
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
				"additionalProperties" : false
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <exception>
 | 
			
		||||
 | 
			
		||||
// Build configuration
 | 
			
		||||
#include <HyperionConfig.h>
 | 
			
		||||
@@ -62,260 +63,265 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
 | 
			
		||||
	std::transform(type.begin(), type.end(), type.begin(), ::tolower);
 | 
			
		||||
 | 
			
		||||
	LedDevice* device = nullptr;
 | 
			
		||||
	if (false) {}
 | 
			
		||||
	else if (type == "adalight")
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceAdalight(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt(),
 | 
			
		||||
			deviceConfig.get("delayAfterConnect",500).asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "adalightapa102")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceAdalightApa102(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt(),
 | 
			
		||||
			deviceConfig.get("delayAfterConnect",500).asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
#ifdef ENABLE_SPIDEV
 | 
			
		||||
	else if (type == "lpd6803" || type == "ldp6803")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceLpd6803(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "lpd8806" || type == "ldp8806")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceLpd8806(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "p9813")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceP9813(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "apa102")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceAPA102(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "ws2801" || type == "lightberry")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceWs2801(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt(),
 | 
			
		||||
			deviceConfig.get("latchtime",500000).asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "ws2812spi")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceWs2812SPI(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig.get("rate",2857143).asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "sk6812rgbw-spi")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceSk6812SPI(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig.get("rate",2857143).asInt(),
 | 
			
		||||
			deviceConfig.get("white_algorithm","").asString()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ENABLE_TINKERFORGE
 | 
			
		||||
	else if (type=="tinkerforge")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceTinkerforge(
 | 
			
		||||
			deviceConfig.get("output", "127.0.0.1").asString(),
 | 
			
		||||
			deviceConfig.get("port", 4223).asInt(),
 | 
			
		||||
			deviceConfig["uid"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt()
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	else if (type == "rawhid")
 | 
			
		||||
	{
 | 
			
		||||
		const int delay_ms        = deviceConfig["delayAfterConnect"].asInt();
 | 
			
		||||
		auto VendorIdString       = deviceConfig.get("VID", "0x2341").asString();
 | 
			
		||||
		auto ProductIdString      = deviceConfig.get("PID", "0x8036").asString();
 | 
			
		||||
 | 
			
		||||
		// Convert HEX values to integer
 | 
			
		||||
		auto VendorId = std::stoul(VendorIdString, nullptr, 16);
 | 
			
		||||
		auto ProductId = std::stoul(ProductIdString, nullptr, 16);
 | 
			
		||||
 | 
			
		||||
		device = new LedDeviceRawHID(VendorId, ProductId, delay_ms);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "lightpack")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceLightpack(
 | 
			
		||||
			deviceConfig.get("output", "").asString()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "multi-lightpack")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceMultiLightpack();
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "paintpack")
 | 
			
		||||
	{
 | 
			
		||||
		const int delay_ms        = deviceConfig["delayAfterConnect"].asInt();
 | 
			
		||||
		auto VendorIdString       = deviceConfig.get("VID", "0x0EBF").asString();
 | 
			
		||||
		auto ProductIdString      = deviceConfig.get("PID", "0x0025").asString();
 | 
			
		||||
 | 
			
		||||
		// Convert HEX values to integer
 | 
			
		||||
		auto VendorId = std::stoul(VendorIdString, nullptr, 16);
 | 
			
		||||
		auto ProductId = std::stoul(ProductIdString, nullptr, 16);
 | 
			
		||||
 | 
			
		||||
		device = new LedDevicePaintpack(VendorId, ProductId, delay_ms);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "piblaster")
 | 
			
		||||
	{
 | 
			
		||||
		const std::string output     = deviceConfig.get("output",     "").asString();
 | 
			
		||||
		const std::string assignment = deviceConfig.get("assignment", "").asString();
 | 
			
		||||
		const Json::Value gpioMapping = deviceConfig.get("gpiomap", Json::nullValue);
 | 
			
		||||
 | 
			
		||||
		if (! assignment.empty())
 | 
			
		||||
		if (false) {}
 | 
			
		||||
		else if (type == "adalight")
 | 
			
		||||
		{
 | 
			
		||||
			throw std::runtime_error("Piblaster: The piblaster configuration syntax has changed in this version.");
 | 
			
		||||
			device = new LedDeviceAdalight(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt(),
 | 
			
		||||
				deviceConfig.get("delayAfterConnect",500).asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		if (gpioMapping.isNull())
 | 
			
		||||
		else if (type == "adalightapa102")
 | 
			
		||||
		{
 | 
			
		||||
			throw std::runtime_error("Piblaster: no gpiomap defined.");
 | 
			
		||||
			device = new LedDeviceAdalightApa102(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt(),
 | 
			
		||||
				deviceConfig.get("delayAfterConnect",500).asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		device = new LedDevicePiBlaster(output, gpioMapping);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "sedu")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceSedu(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "hyperion-usbasp-ws2801")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceHyperionUsbasp(LedDeviceHyperionUsbasp::CMD_WRITE_WS2801);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "hyperion-usbasp-ws2812")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceHyperionUsbasp(LedDeviceHyperionUsbasp::CMD_WRITE_WS2812);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "philipshue")
 | 
			
		||||
	{
 | 
			
		||||
		const std::string output = deviceConfig["output"].asString();
 | 
			
		||||
		const std::string username = deviceConfig.get("username", "newdeveloper").asString();
 | 
			
		||||
		const bool switchOffOnBlack = deviceConfig.get("switchOffOnBlack", true).asBool();
 | 
			
		||||
		const int transitiontime = deviceConfig.get("transitiontime", 1).asInt();
 | 
			
		||||
		std::vector<unsigned int> lightIds;
 | 
			
		||||
		for (Json::Value::ArrayIndex i = 0; i < deviceConfig["lightIds"].size(); i++) {
 | 
			
		||||
			lightIds.push_back(deviceConfig["lightIds"][i].asInt());
 | 
			
		||||
	#ifdef ENABLE_SPIDEV
 | 
			
		||||
		else if (type == "lpd6803" || type == "ldp6803")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceLpd6803(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		device = new LedDevicePhilipsHue(output, username, switchOffOnBlack, transitiontime, lightIds);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "atmoorb")
 | 
			
		||||
	{
 | 
			
		||||
		const std::string output = deviceConfig["output"].asString();
 | 
			
		||||
		const bool useOrbSmoothing = deviceConfig.get("useOrbSmoothing", false).asBool();
 | 
			
		||||
		const int transitiontime = deviceConfig.get("transitiontime", 1).asInt();
 | 
			
		||||
		const int skipSmoothingDiff = deviceConfig.get("skipSmoothingDiff", 0).asInt();
 | 
			
		||||
		const int port = deviceConfig.get("port", 1).asInt();
 | 
			
		||||
		const int numLeds = deviceConfig.get("numLeds", 1).asInt();
 | 
			
		||||
		const std::string orbId = deviceConfig["orbIds"].asString();
 | 
			
		||||
		std::vector<unsigned int> orbIds;
 | 
			
		||||
		else if (type == "lpd8806" || type == "ldp8806")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceLpd8806(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "p9813")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceP9813(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "apa102")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceAPA102(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "ws2801" || type == "lightberry")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceWs2801(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt(),
 | 
			
		||||
				deviceConfig.get("latchtime",500000).asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "ws2812spi")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceWs2812SPI(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig.get("rate",2857143).asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "sk6812rgbw-spi")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceSk6812SPI(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig.get("rate",2857143).asInt(),
 | 
			
		||||
				deviceConfig.get("white_algorithm","").asString()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
	#endif
 | 
			
		||||
	#ifdef ENABLE_TINKERFORGE
 | 
			
		||||
		else if (type=="tinkerforge")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceTinkerforge(
 | 
			
		||||
				deviceConfig.get("output", "127.0.0.1").asString(),
 | 
			
		||||
				deviceConfig.get("port", 4223).asInt(),
 | 
			
		||||
				deviceConfig["uid"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt()
 | 
			
		||||
			);
 | 
			
		||||
 | 
			
		||||
		// If we find multiple Orb ids separate them and add to list
 | 
			
		||||
		const std::string separator (",");
 | 
			
		||||
		if (orbId.find(separator) != std::string::npos) {
 | 
			
		||||
		  std::stringstream ss(orbId);
 | 
			
		||||
		  std::vector<int> output;
 | 
			
		||||
		  unsigned int i;
 | 
			
		||||
		  while (ss >> i) {
 | 
			
		||||
			  orbIds.push_back(i);
 | 
			
		||||
			  if (ss.peek() == ',' || ss.peek() == ' ')
 | 
			
		||||
				  ss.ignore();
 | 
			
		||||
		  }
 | 
			
		||||
		}
 | 
			
		||||
	#endif
 | 
			
		||||
		else if (type == "rawhid")
 | 
			
		||||
		{
 | 
			
		||||
			const int delay_ms        = deviceConfig["delayAfterConnect"].asInt();
 | 
			
		||||
			auto VendorIdString       = deviceConfig.get("VID", "0x2341").asString();
 | 
			
		||||
			auto ProductIdString      = deviceConfig.get("PID", "0x8036").asString();
 | 
			
		||||
 | 
			
		||||
			// Convert HEX values to integer
 | 
			
		||||
			auto VendorId = std::stoul(VendorIdString, nullptr, 16);
 | 
			
		||||
			auto ProductId = std::stoul(ProductIdString, nullptr, 16);
 | 
			
		||||
 | 
			
		||||
			device = new LedDeviceRawHID(VendorId, ProductId, delay_ms);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "lightpack")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceLightpack(
 | 
			
		||||
				deviceConfig.get("output", "").asString()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "multi-lightpack")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceMultiLightpack();
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "paintpack")
 | 
			
		||||
		{
 | 
			
		||||
			const int delay_ms        = deviceConfig["delayAfterConnect"].asInt();
 | 
			
		||||
			auto VendorIdString       = deviceConfig.get("VID", "0x0EBF").asString();
 | 
			
		||||
			auto ProductIdString      = deviceConfig.get("PID", "0x0025").asString();
 | 
			
		||||
 | 
			
		||||
			// Convert HEX values to integer
 | 
			
		||||
			auto VendorId = std::stoul(VendorIdString, nullptr, 16);
 | 
			
		||||
			auto ProductId = std::stoul(ProductIdString, nullptr, 16);
 | 
			
		||||
 | 
			
		||||
			device = new LedDevicePaintpack(VendorId, ProductId, delay_ms);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "piblaster")
 | 
			
		||||
		{
 | 
			
		||||
			const std::string output     = deviceConfig.get("output",     "").asString();
 | 
			
		||||
			const std::string assignment = deviceConfig.get("assignment", "").asString();
 | 
			
		||||
			const Json::Value gpioMapping = deviceConfig.get("gpiomap", Json::nullValue);
 | 
			
		||||
 | 
			
		||||
			if (! assignment.empty())
 | 
			
		||||
			{
 | 
			
		||||
				throw std::runtime_error("Piblaster: The piblaster configuration syntax has changed in this version.");
 | 
			
		||||
			}
 | 
			
		||||
			if (gpioMapping.isNull())
 | 
			
		||||
			{
 | 
			
		||||
				throw std::runtime_error("Piblaster: no gpiomap defined.");
 | 
			
		||||
			}
 | 
			
		||||
			device = new LedDevicePiBlaster(output, gpioMapping);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "sedu")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceSedu(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "hyperion-usbasp-ws2801")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceHyperionUsbasp(LedDeviceHyperionUsbasp::CMD_WRITE_WS2801);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "hyperion-usbasp-ws2812")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceHyperionUsbasp(LedDeviceHyperionUsbasp::CMD_WRITE_WS2812);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "philipshue")
 | 
			
		||||
		{
 | 
			
		||||
			const std::string output = deviceConfig["output"].asString();
 | 
			
		||||
			const std::string username = deviceConfig.get("username", "newdeveloper").asString();
 | 
			
		||||
			const bool switchOffOnBlack = deviceConfig.get("switchOffOnBlack", true).asBool();
 | 
			
		||||
			const int transitiontime = deviceConfig.get("transitiontime", 1).asInt();
 | 
			
		||||
			std::vector<unsigned int> lightIds;
 | 
			
		||||
			for (Json::Value::ArrayIndex i = 0; i < deviceConfig["lightIds"].size(); i++) {
 | 
			
		||||
				lightIds.push_back(deviceConfig["lightIds"][i].asInt());
 | 
			
		||||
			}
 | 
			
		||||
			device = new LedDevicePhilipsHue(output, username, switchOffOnBlack, transitiontime, lightIds);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "atmoorb")
 | 
			
		||||
		{
 | 
			
		||||
			const std::string output = deviceConfig["output"].asString();
 | 
			
		||||
			const bool useOrbSmoothing = deviceConfig.get("useOrbSmoothing", false).asBool();
 | 
			
		||||
			const int transitiontime = deviceConfig.get("transitiontime", 1).asInt();
 | 
			
		||||
			const int skipSmoothingDiff = deviceConfig.get("skipSmoothingDiff", 0).asInt();
 | 
			
		||||
			const int port = deviceConfig.get("port", 1).asInt();
 | 
			
		||||
			const int numLeds = deviceConfig.get("numLeds", 1).asInt();
 | 
			
		||||
			const std::string orbId = deviceConfig["orbIds"].asString();
 | 
			
		||||
			std::vector<unsigned int> orbIds;
 | 
			
		||||
 | 
			
		||||
			// If we find multiple Orb ids separate them and add to list
 | 
			
		||||
			const std::string separator (",");
 | 
			
		||||
			if (orbId.find(separator) != std::string::npos) {
 | 
			
		||||
			std::stringstream ss(orbId);
 | 
			
		||||
			std::vector<int> output;
 | 
			
		||||
			unsigned int i;
 | 
			
		||||
			while (ss >> i) {
 | 
			
		||||
				orbIds.push_back(i);
 | 
			
		||||
				if (ss.peek() == ',' || ss.peek() == ' ')
 | 
			
		||||
					ss.ignore();
 | 
			
		||||
			}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
			orbIds.push_back(atoi(orbId.c_str()));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			device = new LedDeviceAtmoOrb(output, useOrbSmoothing, transitiontime, skipSmoothingDiff, port, numLeds, orbIds);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "fadecandy")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceFadeCandy(deviceConfig);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "udp")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceUdp(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["protocol"].asInt(),
 | 
			
		||||
				deviceConfig["maxpacket"].asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "udpraw")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceUdpRaw(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig.get("latchtime",500000).asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "tpm2")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceTpm2(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				deviceConfig["rate"].asInt()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == "atmo")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceAtmo(
 | 
			
		||||
				deviceConfig["output"].asString(),
 | 
			
		||||
				38400
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
	#ifdef ENABLE_WS2812BPWM
 | 
			
		||||
		else if (type == "ws2812b")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceWS2812b();
 | 
			
		||||
		}
 | 
			
		||||
	#endif
 | 
			
		||||
	#ifdef ENABLE_WS281XPWM
 | 
			
		||||
		else if (type == "ws281x")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceWS281x(
 | 
			
		||||
				deviceConfig.get("gpio", 18).asInt(),
 | 
			
		||||
				deviceConfig.get("leds", 256).asInt(),
 | 
			
		||||
				deviceConfig.get("freq", (Json::UInt)800000ul).asInt(),
 | 
			
		||||
				deviceConfig.get("dmanum", 5).asInt(),
 | 
			
		||||
				deviceConfig.get("pwmchannel", 0).asInt(),
 | 
			
		||||
				deviceConfig.get("invert", 0).asInt(),
 | 
			
		||||
				deviceConfig.get("rgbw", 0).asInt(),
 | 
			
		||||
				deviceConfig.get("white_algorithm","").asString()
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
	#endif
 | 
			
		||||
		else if (type == "file")
 | 
			
		||||
		{
 | 
			
		||||
			device = new LedDeviceFile( deviceConfig.get("output", "/dev/null").asString() );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
		  orbIds.push_back(atoi(orbId.c_str()));
 | 
			
		||||
			throw std::runtime_error("unknown device");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		device = new LedDeviceAtmoOrb(output, useOrbSmoothing, transitiontime, skipSmoothingDiff, port, numLeds, orbIds);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "fadecandy")
 | 
			
		||||
	catch(std::exception e)
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceFadeCandy(deviceConfig);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "udp")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceUdp(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt(),
 | 
			
		||||
			deviceConfig["protocol"].asInt(),
 | 
			
		||||
			deviceConfig["maxpacket"].asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "udpraw")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceUdpRaw(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt(),
 | 
			
		||||
			deviceConfig.get("latchtime",500000).asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "tpm2")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceTpm2(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			deviceConfig["rate"].asInt()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == "atmo")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceAtmo(
 | 
			
		||||
			deviceConfig["output"].asString(),
 | 
			
		||||
			38400
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
#ifdef ENABLE_WS2812BPWM
 | 
			
		||||
	else if (type == "ws2812b")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceWS2812b();
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ENABLE_WS281XPWM
 | 
			
		||||
	else if (type == "ws281x")
 | 
			
		||||
	{
 | 
			
		||||
		device = new LedDeviceWS281x(
 | 
			
		||||
			deviceConfig.get("gpio", 18).asInt(),
 | 
			
		||||
			deviceConfig.get("leds", 256).asInt(),
 | 
			
		||||
			deviceConfig.get("freq", (Json::UInt)800000ul).asInt(),
 | 
			
		||||
			deviceConfig.get("dmanum", 5).asInt(),
 | 
			
		||||
			deviceConfig.get("pwmchannel", 0).asInt(),
 | 
			
		||||
			deviceConfig.get("invert", 0).asInt(),
 | 
			
		||||
			deviceConfig.get("rgbw", 0).asInt(),
 | 
			
		||||
			deviceConfig.get("white_algorithm","").asString()
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (type != "file")
 | 
			
		||||
		{
 | 
			
		||||
			Error(log, "Dummy device used, because unknown device %s set.", type.c_str());
 | 
			
		||||
		}
 | 
			
		||||
		device = new LedDeviceFile(
 | 
			
		||||
			deviceConfig.get("output", "/dev/null").asString()
 | 
			
		||||
		);
 | 
			
		||||
		
 | 
			
		||||
		Error(log, "Dummy device used, because configured device '%s' throws error '%s'", type.c_str(), e.what());
 | 
			
		||||
		device = new LedDeviceFile( "/dev/null" );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	device->open();
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,9 @@
 | 
			
		||||
// Local LedDevice includes
 | 
			
		||||
#include "LedDevicePiBlaster.h"
 | 
			
		||||
 | 
			
		||||
LedDevicePiBlaster::LedDevicePiBlaster(const std::string & deviceName, const Json::Value & gpioMapping) :
 | 
			
		||||
	_deviceName(deviceName),
 | 
			
		||||
	_fid(nullptr)
 | 
			
		||||
LedDevicePiBlaster::LedDevicePiBlaster(const std::string & deviceName, const Json::Value & gpioMapping)
 | 
			
		||||
	: _deviceName(deviceName)
 | 
			
		||||
	, _fid(nullptr)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	signal(SIGPIPE,  SIG_IGN);
 | 
			
		||||
@@ -59,34 +59,25 @@ LedDevicePiBlaster::~LedDevicePiBlaster()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int LedDevicePiBlaster::open(bool report)
 | 
			
		||||
int LedDevicePiBlaster::open()
 | 
			
		||||
{
 | 
			
		||||
	if (_fid != nullptr)
 | 
			
		||||
	{
 | 
			
		||||
		// The file pointer is already open
 | 
			
		||||
		if (report)
 | 
			
		||||
		{
 | 
			
		||||
			Error( _log, "Device (%s) is already open.", _deviceName.c_str() );
 | 
			
		||||
		}
 | 
			
		||||
		Error( _log, "Device (%s) is already open.", _deviceName.c_str() );
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!QFile::exists(_deviceName.c_str()))
 | 
			
		||||
	{
 | 
			
		||||
		if (report)
 | 
			
		||||
		{
 | 
			
		||||
			Error( _log, "The device (%s) does not yet exist.", _deviceName.c_str() );
 | 
			
		||||
		}
 | 
			
		||||
		Error( _log, "The device (%s) does not yet exist.", _deviceName.c_str() );
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_fid = fopen(_deviceName.c_str(), "w");
 | 
			
		||||
	if (_fid == nullptr)
 | 
			
		||||
	{
 | 
			
		||||
		if (report)
 | 
			
		||||
		{
 | 
			
		||||
			Error( _log, "Failed to open device (%s). Error message: %s", _deviceName.c_str(),  strerror(errno) );
 | 
			
		||||
		}
 | 
			
		||||
		Error( _log, "Failed to open device (%s). Error message: %s", _deviceName.c_str(),  strerror(errno) );
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -98,7 +89,7 @@ int LedDevicePiBlaster::open(bool report)
 | 
			
		||||
int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
 | 
			
		||||
{
 | 
			
		||||
	// Attempt to open if not yet opened
 | 
			
		||||
	if (_fid == nullptr && open(false) < 0)
 | 
			
		||||
	if (_fid == nullptr && open() < 0)
 | 
			
		||||
	{
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
@@ -151,7 +142,7 @@ int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
 | 
			
		||||
int LedDevicePiBlaster::switchOff()
 | 
			
		||||
{
 | 
			
		||||
	// Attempt to open if not yet opened
 | 
			
		||||
	if (_fid == nullptr && open(false) < 0)
 | 
			
		||||
	if (_fid == nullptr && open() < 0)
 | 
			
		||||
	{
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,10 +27,9 @@ public:
 | 
			
		||||
	/// Attempts to open the piblaster-device. This will only succeed if the device is not yet open
 | 
			
		||||
	/// and the device is available.
 | 
			
		||||
	///
 | 
			
		||||
	/// @param report If true errors are writen to the standard error else silent
 | 
			
		||||
	/// @return Zero on succes else negative
 | 
			
		||||
	///
 | 
			
		||||
	int open(bool report = true);
 | 
			
		||||
	int open();
 | 
			
		||||
 | 
			
		||||
	///
 | 
			
		||||
	/// Writes the colors to the PiBlaster device
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ unsigned leds_per_pkt;
 | 
			
		||||
int update_number;
 | 
			
		||||
int fragment_number;
 | 
			
		||||
 | 
			
		||||
LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, const unsigned protocol, const unsigned maxPacket) 
 | 
			
		||||
LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned protocol, const unsigned maxPacket) 
 | 
			
		||||
{
 | 
			
		||||
	std::string hostname;
 | 
			
		||||
	std::string port;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,8 @@
 | 
			
		||||
#include <leddevice/LedDevice.h>
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Implementation of the LedDevice that write the led-colors to an
 | 
			
		||||
/// ASCII-textfile('/home/pi/LedDevice.out')
 | 
			
		||||
/// Implementation of the LedDevice that write the led-colors via udp
 | 
			
		||||
/// 
 | 
			
		||||
///
 | 
			
		||||
class LedDeviceUdp : public LedDevice
 | 
			
		||||
{
 | 
			
		||||
@@ -16,7 +16,7 @@ public:
 | 
			
		||||
	///
 | 
			
		||||
	/// Constructs the test-device, which opens an output stream to the file
 | 
			
		||||
	///
 | 
			
		||||
	LedDeviceUdp(const std::string& output,  const unsigned baudrate, const unsigned protocol, const unsigned maxPacket);
 | 
			
		||||
	LedDeviceUdp(const std::string& output,  const unsigned protocol, const unsigned maxPacket);
 | 
			
		||||
 | 
			
		||||
	///
 | 
			
		||||
	/// Destructor of this test-device
 | 
			
		||||
@@ -36,9 +36,6 @@ public:
 | 
			
		||||
	virtual int switchOff();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	/// The outputstream
 | 
			
		||||
//	std::ofstream _ofs;
 | 
			
		||||
 | 
			
		||||
        /// the number of leds (needed when switching off)
 | 
			
		||||
        size_t mLedCount;
 | 
			
		||||
	/// the number of leds (needed when switching off)
 | 
			
		||||
	size_t mLedCount;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,8 @@
 | 
			
		||||
// hyperion local includes
 | 
			
		||||
#include "LedDeviceUdpRaw.h"
 | 
			
		||||
 | 
			
		||||
LedDeviceUdpRaw::LedDeviceUdpRaw(const std::string& outputDevice, const unsigned baudrate, const unsigned latchTime) :
 | 
			
		||||
	LedUdpDevice(outputDevice, baudrate, latchTime),
 | 
			
		||||
LedDeviceUdpRaw::LedDeviceUdpRaw(const std::string& outputDevice, const unsigned latchTime) :
 | 
			
		||||
	LedUdpDevice(outputDevice, latchTime),
 | 
			
		||||
	mLedCount(0)
 | 
			
		||||
{
 | 
			
		||||
	// empty
 | 
			
		||||
 
 | 
			
		||||
@@ -7,21 +7,19 @@
 | 
			
		||||
#include "LedUdpDevice.h"
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Implementation of the LedDevice interface for writing to Ws2801 led device.
 | 
			
		||||
/// Implementation of the LedDevice interface for sending led colors via udp.
 | 
			
		||||
///
 | 
			
		||||
class LedDeviceUdpRaw : public LedUdpDevice
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	///
 | 
			
		||||
	/// Constructs the LedDevice for a string containing leds of the type Ws2801
 | 
			
		||||
	/// Constructs the LedDevice for sending led colors via udp
 | 
			
		||||
	///
 | 
			
		||||
	/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
 | 
			
		||||
	/// @param baudrate The used baudrate for writing to the output device
 | 
			
		||||
	/// @param outputDevice hostname:port
 | 
			
		||||
	/// @param latchTime 
 | 
			
		||||
	///
 | 
			
		||||
 | 
			
		||||
	LedDeviceUdpRaw(const std::string& outputDevice,
 | 
			
		||||
					const unsigned baudrate,
 | 
			
		||||
					const unsigned latchTime);
 | 
			
		||||
	LedDeviceUdpRaw(const std::string& outputDevice, const unsigned latchTime);
 | 
			
		||||
 | 
			
		||||
	///
 | 
			
		||||
	/// Writes the led color values to the led-device
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ public:
 | 
			
		||||
	///
 | 
			
		||||
	/// Constructs the LedDevice attached to a SPI-device
 | 
			
		||||
	///
 | 
			
		||||
	/// @param[in] outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
 | 
			
		||||
	/// @param[in] outputDevice The name of the output device (eg '/dev/spidev.0.0')
 | 
			
		||||
	/// @param[in] baudrate The used baudrate for writing to the output device
 | 
			
		||||
	/// @param[in] latchTime_ns The latch-time to latch in the values across the SPI-device (negative
 | 
			
		||||
	/// means no latch required) [ns]
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <exception>
 | 
			
		||||
// Linux includes
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
@@ -15,17 +15,15 @@
 | 
			
		||||
// Local Hyperion includes
 | 
			
		||||
#include "LedUdpDevice.h"
 | 
			
		||||
 | 
			
		||||
LedUdpDevice::LedUdpDevice(const std::string& output, const unsigned baudrate, const int latchTime_ns) :
 | 
			
		||||
LedUdpDevice::LedUdpDevice(const std::string& output, const int latchTime_ns) :
 | 
			
		||||
	_target(output),
 | 
			
		||||
	_BaudRate_Hz(baudrate),
 | 
			
		||||
	_LatchTime_ns(latchTime_ns)
 | 
			
		||||
{
 | 
			
		||||
	udpSocket = new QUdpSocket();
 | 
			
		||||
	QString str = QString::fromStdString(_target);
 | 
			
		||||
	QStringList _list = str.split(":");
 | 
			
		||||
	if (_list.size() != 2)  {
 | 
			
		||||
		Error( _log, "Error parsing hostname:port");
 | 
			
		||||
		exit (-1);
 | 
			
		||||
		throw("Error parsing hostname:port");
 | 
			
		||||
	}
 | 
			
		||||
	QHostInfo info = QHostInfo::fromName(_list.at(0));
 | 
			
		||||
	if (!info.addresses().isEmpty()) {
 | 
			
		||||
@@ -45,8 +43,7 @@ int LedUdpDevice::open()
 | 
			
		||||
	QHostAddress _localAddress = QHostAddress::Any;
 | 
			
		||||
	quint16 _localPort = 0;
 | 
			
		||||
 | 
			
		||||
	WarningIf( !udpSocket->bind(_localAddress, _localPort), 
 | 
			
		||||
		_log, "Couldnt bind local address: %s", strerror(errno));
 | 
			
		||||
	WarningIf( !udpSocket->bind(_localAddress, _localPort), _log, "Couldnt bind local address: %s", strerror(errno));
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,14 +13,13 @@ class LedUdpDevice : public LedDevice
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	///
 | 
			
		||||
	/// Constructs the LedDevice attached to a SPI-device
 | 
			
		||||
	/// Constructs the LedDevice sendig data via udp
 | 
			
		||||
	///
 | 
			
		||||
	/// @param[in] outputDevice The name of the output device (eg '/etc/UdpDev.0.0')
 | 
			
		||||
	/// @param[in] baudrate The used baudrate for writing to the output device
 | 
			
		||||
	/// @param[in] outputDevice string hostname:port
 | 
			
		||||
	/// @param[in] latchTime_ns The latch-time to latch in the values across the SPI-device (negative
 | 
			
		||||
	/// means no latch required) [ns]
 | 
			
		||||
	///
 | 
			
		||||
	LedUdpDevice(const std::string& outputDevice, const unsigned baudrate, const int latchTime_ns = -1);
 | 
			
		||||
	LedUdpDevice(const std::string& outputDevice, const int latchTime_ns = -1);
 | 
			
		||||
 | 
			
		||||
	///
 | 
			
		||||
	/// Destructor of the LedDevice; closes the output device if it is open
 | 
			
		||||
@@ -49,8 +48,6 @@ protected:
 | 
			
		||||
private:
 | 
			
		||||
	/// The UDP destination as "host:port"
 | 
			
		||||
	const std::string _target;
 | 
			
		||||
	/// The used baudrate of the output device for rate limiting
 | 
			
		||||
	const int _BaudRate_Hz;
 | 
			
		||||
	/// The time which the device should be untouched after a write
 | 
			
		||||
	const int _LatchTime_ns;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,9 @@
 | 
			
		||||
 | 
			
		||||
WebConfig::WebConfig(QObject * parent)
 | 
			
		||||
	:  QObject(parent)
 | 
			
		||||
	, _port(WEBCONFIG_DEFAULT_PORT)
 | 
			
		||||
	, _server(nullptr)
 | 
			
		||||
{
 | 
			
		||||
	_port = WEBCONFIG_DEFAULT_PORT;
 | 
			
		||||
	_hyperion = Hyperion::getInstance();
 | 
			
		||||
	const Json::Value &config = _hyperion->getJsonConfig();
 | 
			
		||||
	_baseUrl = QString::fromStdString(WEBCONFIG_DEFAULT_PATH);
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,10 @@ find_package(Qt5 COMPONENTS Core Gui Widgets Network REQUIRED)
 | 
			
		||||
 | 
			
		||||
# The following I do not undrstand completely...
 | 
			
		||||
# libQtCore.so uses some hardcoded library path inside which are incorrect after copying the file RPi file system
 | 
			
		||||
# Therefor, an extra path is needed on which to find the required libraries
 | 
			
		||||
LINK_DIRECTORIES(${LINK_DIRECTORIES} ${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
 | 
			
		||||
# Therefore, an extra path is needed on which to find the required libraries
 | 
			
		||||
IF ( EXISTS ${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf )
 | 
			
		||||
	LINK_DIRECTORIES(${LINK_DIRECTORIES} ${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
include_directories(${QT_INCLUDES})
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -420,7 +420,7 @@ void HyperionDaemon::createSystemFrameGrabber()
 | 
			
		||||
				// framebuffer -> if nothing other applies
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					type == "framebuffer";
 | 
			
		||||
					type = "framebuffer";
 | 
			
		||||
				}
 | 
			
		||||
				Info(  _log, "set screen capture device to '%s'", type.constData());
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,6 @@
 | 
			
		||||
#include <jsonserver/JsonServer.h>
 | 
			
		||||
#include <protoserver/ProtoServer.h>
 | 
			
		||||
#include <boblightserver/BoblightServer.h>
 | 
			
		||||
#include <webconfig/WebConfig.h>
 | 
			
		||||
#include <udplistener/UDPListener.h>
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
 | 
			
		||||
@@ -86,7 +85,6 @@ private:
 | 
			
		||||
	AmlogicWrapper*     _amlGrabber;
 | 
			
		||||
	FramebufferWrapper* _fbGrabber; 
 | 
			
		||||
	OsxWrapper*         _osxGrabber;
 | 
			
		||||
	WebConfig*          _webConfig;
 | 
			
		||||
	Hyperion*           _hyperion;
 | 
			
		||||
	
 | 
			
		||||
	unsigned            _grabber_width;
 | 
			
		||||
 
 | 
			
		||||
@@ -143,7 +143,7 @@ void setup_io()
 | 
			
		||||
   );
 | 
			
		||||
 | 
			
		||||
   if ((long)gpio_map < 0) {
 | 
			
		||||
      printf("mmap error %d\n", (long)gpio_map);
 | 
			
		||||
      printf("mmap error %ld\n", (long)gpio_map);
 | 
			
		||||
      exit (-1);
 | 
			
		||||
   }
 | 
			
		||||
   gpio = (volatile unsigned *)gpio_map;
 | 
			
		||||
@@ -166,10 +166,10 @@ void setup_io()
 | 
			
		||||
   );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   printf("SPI mapped from 0x%p to 0x%p\n",SPI0_BASE,spi0_map);
 | 
			
		||||
   printf("SPI mapped from 0x%d to 0x%p\n",SPI0_BASE,spi0_map);
 | 
			
		||||
 | 
			
		||||
   if ((long)spi0_map < 0) {
 | 
			
		||||
      printf("mmap error %d\n", (long)spi0_map);
 | 
			
		||||
      printf("mmap error %ld\n", (long)spi0_map);
 | 
			
		||||
      exit (-1);
 | 
			
		||||
   }
 | 
			
		||||
   spi0 = (volatile unsigned *)spi0_map;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user