Leddevice refactoring the next next part (#263)

* switch rs232 provider to completly async transfer

* start of implementing a seperate init function for leddevices

* rename setconfig to init

* more fixes

* implement missing code

* fix code style

* remove debug  code

* remove  debug stuff

* set loglevel to original state
This commit is contained in:
redPanther 2016-10-08 08:14:36 +02:00 committed by GitHub
parent afed2e68e0
commit 5aac2be702
72 changed files with 542 additions and 452 deletions

View File

@ -51,9 +51,10 @@ public:
static int addToDeviceMap(std::string name, LedDeviceCreateFuncType funcPtr);
static const LedDeviceRegistry& getDeviceMap();
static void setActiveDevice(std::string dev);
static std::string activeDevice() { return _activeDevice; };
static std::string activeDevice() { return _activeDevice; }
static Json::Value getLedDeviceSchemas();
static void setLedCount(int ledCount);
static int getLedCount() { return _ledCount; }
protected:
///
/// Writes the RGB-Color values to the leds.
@ -66,12 +67,16 @@ protected:
/// The common Logger instance for all LedDevices
Logger * _log;
int _ledCount;
/// The buffer containing the packed RGB values
std::vector<uint8_t> _ledBuffer;
bool _deviceReady;
static std::string _activeDevice;
static LedDeviceRegistry _ledDeviceMap;
static int _ledCount;
static int _ledRGBCount;
static int _ledRGBWCount;
};

View File

@ -23,5 +23,5 @@ public:
/// @return The constructed LedDevice or nullptr if configuration is invalid. The ownership of
/// the constructed LedDevice is tranferred to the caller
///
static LedDevice * construct(const Json::Value & deviceConfig);
static LedDevice * construct(const Json::Value & deviceConfig, const int ledCount);
};

View File

@ -1,4 +1,13 @@
#pragma once
#include <utils/ColorRgb.h>
#include <utils/ColorRgbw.h>
void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm);
namespace RGBW {
enum WhiteAlgorithm { INVALID, SUBTRACT_MINIMUM, SUB_MIN_WARM_ADJUST, WHITE_OFF };
WhiteAlgorithm stringToWhiteAlgorithm(std::string str);
void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, const WhiteAlgorithm algorithm);
};

View File

@ -460,7 +460,6 @@ LedString Hyperion::createLedString(const QJsonValue& ledsConfig, const ColorOrd
}
// Get the order of the rgb channels for this led (default is device order)
const QJsonObject& colorOrder = ledConfigArray[i].toObject();
led.colorOrder = stringToColorOrder(index["colorOrder"].toString(deviceOrderStr));
ledString.leds().push_back(led);
}
@ -674,7 +673,7 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const QJsonObject &qjsonConfig
getComponentRegister().componentStateChanged(hyperion::COMP_FORWARDER, _messageForwarder->forwardingEnabled());
// initialize leddevices
_device = LedDeviceFactory::construct(jsonConfig["device"]);
_device = LedDeviceFactory::construct(jsonConfig["device"],_hwLedCount);
_deviceSmooth = createColorSmoothing(qjsonConfig["smoothing"].toObject(), _device);
getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState());
@ -968,7 +967,7 @@ void Hyperion::update()
if (_adjustmentEnabled) _raw2ledAdjustment->applyAdjustment(_ledBuffer);
if (_temperatureEnabled) _raw2ledTemperature->applyCorrection(_ledBuffer);
// init colororder vector, if nempty
// init colororder vector, if empty
if (_ledStringColorOrder.empty())
{
for (Led& led : _ledString.leds())

View File

@ -4,6 +4,8 @@
#include "LinearColorSmoothing.h"
#include <hyperion/Hyperion.h>
#include <cmath>
using namespace hyperion;
LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, double ledUpdateFrequency_hz, int settlingTime_ms, unsigned updateDelay, bool continuousOutput)
@ -91,21 +93,21 @@ void LinearColorSmoothing::updateLeds()
_writeToLedsEnable = true;
float k = 1.0f - 1.0f * deltaTime / (_targetTime - _previousTime);
int reddif = 0, greendif = 0, bluedif = 0;
int reddif = 0, greendif = 0, bluedif = 0;
for (size_t i = 0; i < _previousValues.size(); ++i)
{
ColorRgb & prev = _previousValues[i];
ColorRgb & target = _targetValues[i];
for (size_t i = 0; i < _previousValues.size(); ++i)
{
ColorRgb & prev = _previousValues[i];
ColorRgb & target = _targetValues[i];
reddif = target.red - prev.red;
greendif = target.green - prev.green;
bluedif = target.blue - prev.blue;
reddif = target.red - prev.red;
greendif = target.green - prev.green;
bluedif = target.blue - prev.blue;
prev.red += (reddif < 0 ? -1:1) * ceil(k * abs(reddif));
prev.green += (greendif < 0 ? -1:1) * ceil(k * abs(greendif));
prev.blue += (bluedif < 0 ? -1:1) * ceil(k * abs(bluedif));
}
prev.red += (reddif < 0 ? -1:1) * std::ceil(k * std::abs(reddif));
prev.green += (greendif < 0 ? -1:1) * std::ceil(k * std::abs(greendif));
prev.blue += (bluedif < 0 ? -1:1) * std::ceil(k * std::abs(bluedif));
}
_previousTime = now;
queueColors(_previousValues);

View File

@ -3,8 +3,7 @@
// STL includes
#include <string>
#include <vector>
#include <stdlib.h>
#include <math.h>
// Qt includes
#include <QTimer>

View File

@ -888,7 +888,6 @@ void JsonClientConnection::handleConfigCommand(const Json::Value & message, cons
}
else if (subcommand == "reload")
{
// restart hyperion, this code must be put in some own class ...
Process::restartHyperion();
sendErrorReply("failed to restart hyperion", full_command, tan);
}

View File

@ -7,12 +7,15 @@
LedDeviceRegistry LedDevice::_ledDeviceMap = LedDeviceRegistry();
std::string LedDevice::_activeDevice = "";
int LedDevice::_ledCount = 0;
int LedDevice::_ledRGBCount = 0;
int LedDevice::_ledRGBWCount= 0;
LedDevice::LedDevice()
: QObject()
, _log(Logger::getInstance("LedDevice"))
, _ledCount(0)
, _ledBuffer(0)
, _deviceReady(true)
{
LedDevice::getLedDeviceSchemas();
@ -71,14 +74,18 @@ Json::Value LedDevice::getLedDeviceSchemas()
int LedDevice::setLedValues(const std::vector<ColorRgb>& ledValues)
{
_ledCount = ledValues.size();
return write(ledValues);
return _deviceReady ? write(ledValues) : -1;
}
int LedDevice::switchOff()
{
return write(std::vector<ColorRgb>(_ledCount, ColorRgb::BLACK ));
return _deviceReady ? write(std::vector<ColorRgb>(_ledCount, ColorRgb::BLACK )) : -1;
}
void LedDevice::setLedCount(int ledCount)
{
_ledCount = ledCount;
_ledRGBCount = _ledCount * sizeof(ColorRgb);
_ledRGBWCount = _ledCount * sizeof(ColorRgbw);
}

View File

@ -1,9 +1,9 @@
#include "LedDeviceAPA102.h"
LedDeviceAPA102::LedDeviceAPA102(const Json::Value &deviceConfig)
: ProviderSpi(deviceConfig)
: ProviderSpi()
{
_latchTime_ns = 500000; // fixed latchtime
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceAPA102::construct(const Json::Value &deviceConfig)
@ -11,20 +11,26 @@ LedDevice* LedDeviceAPA102::construct(const Json::Value &deviceConfig)
return new LedDeviceAPA102(deviceConfig);
}
int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
bool LedDeviceAPA102::init(const Json::Value &deviceConfig)
{
ProviderSpi::init(deviceConfig);
_latchTime_ns = 500000; // fixed latchtime
const unsigned int startFrameSize = 4;
const unsigned int endFrameSize = std::max<unsigned int>(((_ledCount + 15) / 16), 4);
const unsigned int APAbufferSize = (_ledCount * 4) + startFrameSize + endFrameSize;
if(_ledBuffer.size() != APAbufferSize){
_ledBuffer.resize(APAbufferSize, 0xFF);
_ledBuffer[0] = 0x00;
_ledBuffer[1] = 0x00;
_ledBuffer[2] = 0x00;
_ledBuffer[3] = 0x00;
}
_ledBuffer.resize(APAbufferSize, 0xFF);
_ledBuffer[0] = 0x00;
_ledBuffer[1] = 0x00;
_ledBuffer[2] = 0x00;
_ledBuffer[3] = 0x00;
return true;
}
int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
{
for (signed iLed=0; iLed < _ledCount; ++iLed) {
const ColorRgb& rgb = ledValues[iLed];
_ledBuffer[4+iLed*4] = 0xFF;

View File

@ -13,13 +13,12 @@ public:
///
/// Constructs specific LedDevice
///
/// @param deviceConfig json device config
///
LedDeviceAPA102(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
private:
///
/// Writes the led color values to the led-device

View File

@ -1,16 +1,10 @@
#include "LedDeviceAdalight.h"
LedDeviceAdalight::LedDeviceAdalight(const Json::Value &deviceConfig)
: ProviderRs232(deviceConfig)
, _timer()
{
// setup the timer
_timer.setSingleShot(false);
_timer.setInterval(5000);
connect(&_timer, SIGNAL(timeout()), this, SLOT(rewriteLeds()));
: ProviderRs232()
// start the timer
_timer.start();
{
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceAdalight::construct(const Json::Value &deviceConfig)
@ -18,37 +12,27 @@ LedDevice* LedDeviceAdalight::construct(const Json::Value &deviceConfig)
return new LedDeviceAdalight(deviceConfig);
}
bool LedDeviceAdalight::init(const Json::Value &deviceConfig)
{
ProviderRs232::init(deviceConfig);
_ledBuffer.resize(6 + _ledRGBCount);
_ledBuffer[0] = 'A';
_ledBuffer[1] = 'd';
_ledBuffer[2] = 'a';
_ledBuffer[3] = (((unsigned int)_ledCount - 1) >> 8) & 0xFF; // LED count high byte
_ledBuffer[4] = ((unsigned int)_ledCount - 1) & 0xFF; // LED count low byte
_ledBuffer[5] = _ledBuffer[3] ^ _ledBuffer[4] ^ 0x55; // Checksum
Debug( _log, "Adalight header for %d leds: %c%c%c 0x%02x 0x%02x 0x%02x", _ledCount,
_ledBuffer[0], _ledBuffer[1], _ledBuffer[2], _ledBuffer[3], _ledBuffer[4], _ledBuffer[5]
);
return true;
}
int LedDeviceAdalight::write(const std::vector<ColorRgb> & ledValues)
{
if (_ledBuffer.size() == 0)
{
_ledBuffer.resize(6 + 3*ledValues.size());
_ledBuffer[0] = 'A';
_ledBuffer[1] = 'd';
_ledBuffer[2] = 'a';
_ledBuffer[3] = ((ledValues.size() - 1) >> 8) & 0xFF; // LED count high byte
_ledBuffer[4] = (ledValues.size() - 1) & 0xFF; // LED count low byte
_ledBuffer[5] = _ledBuffer[3] ^ _ledBuffer[4] ^ 0x55; // Checksum
Debug( _log, "Adalight header for %d leds: %c%c%c 0x%02x 0x%02x 0x%02x",
ledValues.size(),
_ledBuffer[0],
_ledBuffer[1],
_ledBuffer[2],
_ledBuffer[3],
_ledBuffer[4],
_ledBuffer[5]
);
}
// restart the timer
_timer.start();
// write data
memcpy(6 + _ledBuffer.data(), ledValues.data(), ledValues.size() * 3);
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}
void LedDeviceAdalight::rewriteLeds()
{
writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -1,9 +1,5 @@
#pragma once
// Qt includes
#include <QTimer>
// hyperion include
#include "ProviderRs232.h"
///
@ -24,11 +20,9 @@ public:
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
private slots:
/// Write the last data to the leds again
void rewriteLeds();
virtual bool init(const Json::Value &deviceConfig);
protected:
private:
///
/// Writes the led color values to the led-device
///
@ -36,10 +30,5 @@ protected:
/// @return Zero on succes else negative
///
virtual int write(const std::vector<ColorRgb> & ledValues);
/// Timer object which makes sure that led data is written at a minimum rate
/// The Adalight device will switch off when it does not receive data at least
/// every 15 seconds
QTimer _timer;
};

View File

@ -1,8 +1,9 @@
#include "LedDeviceAdalightApa102.h"
LedDeviceAdalightApa102::LedDeviceAdalightApa102(const Json::Value &deviceConfig)
: LedDeviceAdalight(deviceConfig)
: ProviderRs232()
{
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceAdalightApa102::construct(const Json::Value &deviceConfig)
@ -10,12 +11,10 @@ LedDevice* LedDeviceAdalightApa102::construct(const Json::Value &deviceConfig)
return new LedDeviceAdalightApa102(deviceConfig);
}
//comparing to ws2801 adalight, the following changes were needed:
// 1- differnt data frame (4 bytes instead of 3)
// 2 - in order to accomodate point 1 above, number of leds sent to adalight is increased by 1/3rd
int LedDeviceAdalightApa102::write(const std::vector<ColorRgb> & ledValues)
bool LedDeviceAdalightApa102::init(const Json::Value &deviceConfig)
{
ProviderRs232::init(deviceConfig);
const unsigned int startFrameSize = 4;
const unsigned int endFrameSize = std::max<unsigned int>(((_ledCount + 15) / 16), 4);
const unsigned int mLedCount = (_ledCount * 4) + startFrameSize + endFrameSize;
@ -32,6 +31,14 @@ int LedDeviceAdalightApa102::write(const std::vector<ColorRgb> & ledValues)
_ledBuffer[0], _ledBuffer[1], _ledBuffer[2], _ledBuffer[3], _ledBuffer[4], _ledBuffer[5] );
}
return true;
}
//comparing to ws2801 adalight, the following changes were needed:
// 1- differnt data frame (4 bytes instead of 3)
// 2 - in order to accomodate point 1 above, number of leds sent to adalight is increased by 1/3rd
int LedDeviceAdalightApa102::write(const std::vector<ColorRgb> & ledValues)
{
for (signed iLed=1; iLed<=_ledCount; iLed++)
{
const ColorRgb& rgb = ledValues[iLed-1];
@ -40,9 +47,6 @@ int LedDeviceAdalightApa102::write(const std::vector<ColorRgb> & ledValues)
_ledBuffer[iLed*4+2+6] = rgb.green;
_ledBuffer[iLed*4+3+6] = rgb.blue;
}
// restart the timer
_timer.start();
// write data
return writeBytes(_ledBuffer.size(), _ledBuffer.data());

View File

@ -6,7 +6,7 @@
///
/// Implementation of the LedDevice interface for writing to an Adalight led device for APA102.
///
class LedDeviceAdalightApa102 : public LedDeviceAdalight
class LedDeviceAdalightApa102 : public ProviderRs232
{
Q_OBJECT
@ -22,7 +22,9 @@ public:
/// create leddevice when type in config is set to this type
static LedDevice* construct(const Json::Value &deviceConfig);
protected:
virtual bool init(const Json::Value &deviceConfig);
private:
///
/// Writes the led color values to the led-device
///

View File

@ -2,13 +2,9 @@
#include "LedDeviceAtmo.h"
LedDeviceAtmo::LedDeviceAtmo(const Json::Value &deviceConfig)
: ProviderRs232(deviceConfig)
: ProviderRs232()
{
_ledBuffer.resize(4 + 5*3); // 4-byte header, 5 RGB values
_ledBuffer[0] = 0xFF; // Startbyte
_ledBuffer[1] = 0x00; // StartChannel(Low)
_ledBuffer[2] = 0x00; // StartChannel(High)
_ledBuffer[3] = 0x0F; // Number of Databytes send (always! 15)
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceAtmo::construct(const Json::Value &deviceConfig)
@ -16,18 +12,27 @@ LedDevice* LedDeviceAtmo::construct(const Json::Value &deviceConfig)
return new LedDeviceAtmo(deviceConfig);
}
int LedDeviceAtmo::write(const std::vector<ColorRgb> &ledValues)
bool LedDeviceAtmo::init(const Json::Value &deviceConfig)
{
// The protocol is shomehow limited. we always need to send exactly 5 channels + header
// (19 bytes) for the hardware to recognize the data
ProviderRs232::init(deviceConfig);
if (_ledCount != 5)
{
Error( _log, "%d channels configured. This should always be 5!", _ledCount);
return 0;
}
// write data
_ledBuffer.resize(4 + 5*3); // 4-byte header, 5 RGB values
_ledBuffer[0] = 0xFF; // Startbyte
_ledBuffer[1] = 0x00; // StartChannel(Low)
_ledBuffer[2] = 0x00; // StartChannel(High)
_ledBuffer[3] = 0x0F; // Number of Databytes send (always! 15)
return true;
}
int LedDeviceAtmo::write(const std::vector<ColorRgb> &ledValues)
{
memcpy(4 + _ledBuffer.data(), ledValues.data(), _ledCount * sizeof(ColorRgb));
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -19,6 +19,8 @@ public:
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
private:
///
/// Writes the led color values to the led-device

View File

@ -19,7 +19,7 @@ AtmoOrbLight::AtmoOrbLight(unsigned int id) {
LedDeviceAtmoOrb::LedDeviceAtmoOrb(const Json::Value &deviceConfig)
: LedDevice()
{
setConfig(deviceConfig);
init(deviceConfig);
_manager = new QNetworkAccessManager();
_groupAddress = QHostAddress(_multicastGroup);
@ -29,7 +29,7 @@ LedDeviceAtmoOrb::LedDeviceAtmoOrb(const Json::Value &deviceConfig)
joinedMulticastgroup = _udpSocket->joinMulticastGroup(_groupAddress);
}
bool LedDeviceAtmoOrb::setConfig(const Json::Value &deviceConfig)
bool LedDeviceAtmoOrb::init(const Json::Value &deviceConfig)
{
_multicastGroup = deviceConfig["output"].asString().c_str();
_useOrbSmoothing = deviceConfig.get("useOrbSmoothing", false).asBool();

View File

@ -53,7 +53,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -3,9 +3,15 @@
#include <time.h>
LedDeviceDMX::LedDeviceDMX(const Json::Value &deviceConfig)
: ProviderRs232(deviceConfig)
: ProviderRs232()
, _dmxDeviceType(0)
, _dmxStart(1)
, _dmxSlotsPerLed(3)
, _dmxLedCount(0)
, _dmxChannelCount(0)
{
std::string _dmxString = deviceConfig.get("dmxdevice", "invalid").asString();
ProviderRs232::init(deviceConfig);
std::string _dmxString = deviceConfig.get("dmxdevice", "invalid").asString();
if (_dmxString == "raw")
{
_dmxDeviceType = 0;
@ -22,8 +28,18 @@ LedDeviceDMX::LedDeviceDMX(const Json::Value &deviceConfig)
{
Error(_log, "unknown dmx device type %s", _dmxString.c_str());
}
Debug(_log, "_dmxString \"%s\", _dmxDeviceType %d", _dmxString.c_str(), _dmxDeviceType );
_rs232Port.setStopBits(QSerialPort::TwoStop);
_dmxLedCount = std::min(_ledCount, 512/_dmxSlotsPerLed);
_dmxChannelCount = 1 + _dmxSlotsPerLed * _dmxLedCount;
Debug(_log, "_dmxStart %d, _dmxSlotsPerLed %d", _dmxStart, _dmxSlotsPerLed);
Debug(_log, "_ledCount %d, _dmxLedCount %d, _dmxChannelCount %d", _ledCount, _dmxLedCount, _dmxChannelCount);
_ledBuffer.resize(_dmxChannelCount, 0);
_ledBuffer[0] = 0x00; // NULL START code
}
LedDevice* LedDeviceDMX::construct(const Json::Value &deviceConfig)
@ -33,18 +49,6 @@ LedDevice* LedDeviceDMX::construct(const Json::Value &deviceConfig)
int LedDeviceDMX::write(const std::vector<ColorRgb> &ledValues)
{
if ( (_ledBuffer.size() != _dmxChannelCount) || (_ledBuffer.size() == 0) )
{
_dmxLedCount = std::min(_ledCount, 512/_dmxSlotsPerLed);
_dmxChannelCount = 1 + _dmxSlotsPerLed * _dmxLedCount;
Debug(_log, "_dmxStart %d, _dmxSlotsPerLed %d", _dmxStart, _dmxSlotsPerLed);
Debug(_log, "_ledCount %d, _dmxLedCount %d, _dmxChannelCount %d", _ledCount, _dmxLedCount, _dmxChannelCount);
_ledBuffer.resize(_dmxChannelCount, 0);
_ledBuffer[0] = 0x00; // NULL START code
}
switch (_dmxDeviceType) {
case 0:
memcpy(_ledBuffer.data()+1, ledValues.data(), _dmxChannelCount-1);
@ -56,7 +60,7 @@ int LedDeviceDMX::write(const std::vector<ColorRgb> &ledValues)
_ledBuffer[l++] = ledValues[d].red;
_ledBuffer[l++] = ledValues[d].green;
_ledBuffer[l++] = ledValues[d].blue;
_ledBuffer[l++] = 0xff;
_ledBuffer[l++] = 255;
}
break;
}

View File

@ -30,6 +30,6 @@ private:
int _dmxDeviceType = 0;
int _dmxStart = 1;
int _dmxSlotsPerLed = 3;
int _dmxLedCount = 0;;
int _dmxLedCount = 0;
unsigned int _dmxChannelCount = 0;
};

View File

@ -57,7 +57,7 @@
#include "LedDeviceWS281x.h"
#endif
LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig, const int ledCount)
{
Logger * log = Logger::getInstance("LedDevice");
std::stringstream ss;
@ -67,56 +67,62 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
std::string type = deviceConfig.get("type", "UNSPECIFIED").asString();
std::transform(type.begin(), type.end(), type.begin(), ::tolower);
// set amount of led to leddevice
LedDevice::setLedCount(ledCount);
#define REGISTER(className) LedDevice::addToDeviceMap(QString(#className).toLower().toStdString(), LedDevice##className::construct);
// rs232 devices
LedDevice::addToDeviceMap("adalight" , LedDeviceAdalight::construct);
LedDevice::addToDeviceMap("adalightapa102", LedDeviceAdalightApa102::construct);
LedDevice::addToDeviceMap("sedu" , LedDeviceSedu::construct);
LedDevice::addToDeviceMap("dmx" , LedDeviceDMX::construct);
LedDevice::addToDeviceMap("tpm2" , LedDeviceTpm2::construct);
LedDevice::addToDeviceMap("atmo" , LedDeviceAtmo::construct);
LedDevice::addToDeviceMap("fadecandy" , LedDeviceFadeCandy::construct);
REGISTER(Adalight);
REGISTER(AdalightApa102);
REGISTER(Sedu);
REGISTER(DMX);
REGISTER(Tpm2);
REGISTER(Atmo);
// spi devices
#ifdef ENABLE_SPIDEV
LedDevice::addToDeviceMap("apa102" , LedDeviceAPA102::construct);
LedDevice::addToDeviceMap("lpd6803" , LedDeviceLpd6803::construct);
LedDevice::addToDeviceMap("lpd8806" , LedDeviceLpd8806::construct);
LedDevice::addToDeviceMap("p9813" , LedDeviceP9813::construct);
LedDevice::addToDeviceMap("ws2801" , LedDeviceWs2801::construct);
LedDevice::addToDeviceMap("ws2812spi" , LedDeviceWs2812SPI::construct);
LedDevice::addToDeviceMap("sk6812rgbw-spi", LedDeviceSk6812SPI::construct);
REGISTER(APA102);
REGISTER(Lpd6803);
REGISTER(Lpd8806);
REGISTER(P9813);
REGISTER(Ws2801);
REGISTER(Ws2812SPI);
REGISTER(Sk6812SPI);
#endif
// pwm devices
#ifdef ENABLE_WS2812BPWM
LedDevice::addToDeviceMap("ws2812b", LedDeviceWS2812b::construct);
REGISTER(WS2812b);
#endif
#ifdef ENABLE_WS281XPWM
LedDevice::addToDeviceMap("ws281x", LedDeviceWS281x::construct);
REGISTER(WS281x);
#endif
// network lights
LedDevice::addToDeviceMap("tpm2net", LedDeviceTpm2net::construct);
LedDevice::addToDeviceMap("udpraw", LedDeviceUdpRaw::construct);
LedDevice::addToDeviceMap("e131", LedDeviceUdpE131::construct);
REGISTER(FadeCandy);
REGISTER(Tpm2net);
REGISTER(UdpRaw);
REGISTER(UdpE131);
REGISTER(UdpH801);
REGISTER(PhilipsHue);
REGISTER(AtmoOrb);
#ifdef ENABLE_TINKERFORGE
LedDevice::addToDeviceMap("tinkerforge", LedDeviceTinkerforge::construct);
REGISTER(Tinkerforge);
#endif
LedDevice::addToDeviceMap("philipshue", LedDevicePhilipsHue::construct);
LedDevice::addToDeviceMap("atmoorb", LedDeviceAtmoOrb::construct);
LedDevice::addToDeviceMap("h801", LedDeviceUdpH801::construct);
// direct usb
LedDevice::addToDeviceMap("hyperion-usbasp", LedDeviceHyperionUsbasp::construct);
LedDevice::addToDeviceMap("rawhid", LedDeviceRawHID::construct);
LedDevice::addToDeviceMap("paintpack", LedDevicePaintpack::construct);
LedDevice::addToDeviceMap("lightpack", LedDeviceLightpack::construct);
LedDevice::addToDeviceMap("multi-lightpack", LedDeviceMultiLightpack::construct);
REGISTER(HyperionUsbasp);
REGISTER(RawHID);
REGISTER(Paintpack);
REGISTER(Lightpack);
REGISTER(MultiLightpack);
// other
LedDevice::addToDeviceMap("file", LedDeviceFile::construct);
LedDevice::addToDeviceMap("piblaster", LedDevicePiBlaster::construct);
REGISTER(File);
REGISTER(PiBlaster);
#undef REGISTER
const LedDeviceRegistry& devList = LedDevice::getDeviceMap();
LedDevice* device = nullptr;
try

View File

@ -9,7 +9,7 @@ static const unsigned OPC_HEADER_SIZE = 4; // OPC header size
LedDeviceFadeCandy::LedDeviceFadeCandy(const Json::Value &deviceConfig)
: LedDevice()
{
setConfig(deviceConfig);
_deviceReady = init(deviceConfig);
}
@ -24,10 +24,16 @@ LedDevice* LedDeviceFadeCandy::construct(const Json::Value &deviceConfig)
}
bool LedDeviceFadeCandy::setConfig(const Json::Value &deviceConfig)
bool LedDeviceFadeCandy::init(const Json::Value &deviceConfig)
{
_client.close();
if (_ledCount > MAX_NUM_LEDS)
{
Error(_log, "fadecandy/opc: Invalid attempt to write led values. Not more than %d leds are allowed.", MAX_NUM_LEDS);
return false;
}
_host = deviceConfig.get("output", "127.0.0.1").asString();
_port = deviceConfig.get("port", 7890).asInt();
_channel = deviceConfig.get("channel", 0).asInt();
@ -50,11 +56,11 @@ bool LedDeviceFadeCandy::setConfig(const Json::Value &deviceConfig)
_whitePoint_b = whitePointConfig[2].asDouble();
}
_opc_data.resize( OPC_HEADER_SIZE );
_opc_data.resize( _ledRGBCount + OPC_HEADER_SIZE );
_opc_data[0] = _channel;
_opc_data[1] = OPC_SET_PIXELS;
_opc_data[2] = 0;
_opc_data[3] = 0;
_opc_data[2] = _ledRGBCount >> 8;
_opc_data[3] = _ledRGBCount & 0xff;
return true;
}
@ -85,21 +91,6 @@ bool LedDeviceFadeCandy::tryConnect()
int LedDeviceFadeCandy::write( const std::vector<ColorRgb> & ledValues )
{
ssize_t led_data_size = _ledCount * 3; // 3 color bytes
ssize_t opc_data_size = led_data_size + OPC_HEADER_SIZE;
if (_ledCount > MAX_NUM_LEDS)
{
Error(_log, "fadecandy/opc: Invalid attempt to write led values. Not more than %d leds are allowed.", MAX_NUM_LEDS);
return -1;
}
if ( opc_data_size != _opc_data.size() )
_opc_data.resize( opc_data_size );
_opc_data[2] = led_data_size >> 8;
_opc_data[3] = led_data_size & 0xff;
uint idx = OPC_HEADER_SIZE;
for (const ColorRgb& color : ledValues)
{

View File

@ -53,7 +53,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
///
/// Writes the led color values to the led-device

View File

@ -3,7 +3,7 @@
LedDeviceFile::LedDeviceFile(const Json::Value &deviceConfig)
: LedDevice()
{
setConfig(deviceConfig);
init(deviceConfig);
}
LedDeviceFile::~LedDeviceFile()
@ -15,7 +15,7 @@ LedDevice* LedDeviceFile::construct(const Json::Value &deviceConfig)
return new LedDeviceFile(deviceConfig);
}
bool LedDeviceFile::setConfig(const Json::Value &deviceConfig)
bool LedDeviceFile::init(const Json::Value &deviceConfig)
{
if ( _ofs.is_open() )
{

View File

@ -33,7 +33,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
virtual bool setConfig(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
protected:
///

View File

@ -16,7 +16,7 @@ LedDeviceHyperionUsbasp::LedDeviceHyperionUsbasp(const Json::Value &deviceConfig
, _libusbContext(nullptr)
, _deviceHandle(nullptr)
{
setConfig(deviceConfig);
init(deviceConfig);
}
LedDeviceHyperionUsbasp::~LedDeviceHyperionUsbasp()
@ -37,7 +37,7 @@ LedDeviceHyperionUsbasp::~LedDeviceHyperionUsbasp()
}
}
bool LedDeviceHyperionUsbasp::setConfig(const Json::Value &deviceConfig)
bool LedDeviceHyperionUsbasp::init(const Json::Value &deviceConfig)
{
std::string ledType = deviceConfig.get("output", "ws2801").asString();
if (ledType != "ws2801" && ledType != "ws2812")

View File

@ -35,7 +35,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -48,7 +48,7 @@ LedDeviceLightpack::LedDeviceLightpack(const std::string & serialNumber)
LedDeviceLightpack::LedDeviceLightpack(const Json::Value &deviceConfig)
: LedDevice()
{
setConfig(deviceConfig);
init(deviceConfig);
}
LedDeviceLightpack::~LedDeviceLightpack()
@ -69,7 +69,7 @@ LedDeviceLightpack::~LedDeviceLightpack()
}
}
bool LedDeviceLightpack::setConfig(const Json::Value &deviceConfig)
bool LedDeviceLightpack::init(const Json::Value &deviceConfig)
{
_serialNumber = deviceConfig.get("output", "").asString();

View File

@ -33,7 +33,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -1,8 +1,9 @@
#include "LedDeviceLpd6803.h"
LedDeviceLpd6803::LedDeviceLpd6803(const Json::Value &deviceConfig)
: ProviderSpi(deviceConfig)
: ProviderSpi()
{
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceLpd6803::construct(const Json::Value &deviceConfig)
@ -10,23 +11,26 @@ LedDevice* LedDeviceLpd6803::construct(const Json::Value &deviceConfig)
return new LedDeviceLpd6803(deviceConfig);
}
bool LedDeviceLpd6803::init(const Json::Value &deviceConfig)
{
ProviderSpi::init(deviceConfig);
unsigned messageLength = 4 + 2*_ledCount + _ledCount/8 + 1;
// Initialise the buffer
_ledBuffer.resize(messageLength, 0x00);
return true;
}
int LedDeviceLpd6803::write(const std::vector<ColorRgb> &ledValues)
{
unsigned messageLength = 4 + 2*_ledCount + _ledCount/8 + 1;
// Reconfigure if the current connfiguration does not match the required configuration
if (messageLength != _ledBuffer.size())
{
// Initialise the buffer
_ledBuffer.resize(messageLength, 0x00);
}
// Copy the colors from the ColorRgb vector to the Ldp6803 data vector
for (unsigned iLed=0; iLed<(unsigned)_ledCount; ++iLed)
{
const ColorRgb& rgb = ledValues[iLed];
const ColorRgb& color = ledValues[iLed];
_ledBuffer[4 + 2 * iLed] = 0x80 | ((rgb.red & 0xf8) >> 1) | (rgb.green >> 6);
_ledBuffer[5 + 2 * iLed] = ((rgb.green & 0x38) << 2) | (rgb.blue >> 3);
_ledBuffer[4 + 2 * iLed] = 0x80 | ((color.red & 0xf8) >> 1) | (color.green >> 6);
_ledBuffer[5 + 2 * iLed] = ((color.green & 0x38) << 2) | (color.blue >> 3);
}
// Write the data

View File

@ -27,6 +27,8 @@ public:
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
private:
///
/// Writes the led color values to the led-device

View File

@ -1,8 +1,9 @@
#include "LedDeviceLpd8806.h"
LedDeviceLpd8806::LedDeviceLpd8806(const Json::Value &deviceConfig)
: ProviderSpi(deviceConfig)
: ProviderSpi()
{
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceLpd8806::construct(const Json::Value &deviceConfig)
@ -10,28 +11,29 @@ LedDevice* LedDeviceLpd8806::construct(const Json::Value &deviceConfig)
return new LedDeviceLpd8806(deviceConfig);
}
bool LedDeviceLpd8806::init(const Json::Value &deviceConfig)
{
ProviderSpi::init(deviceConfig);
const unsigned clearSize = _ledCount/32+1;
unsigned messageLength = _ledRGBCount + clearSize;
// Initialise the buffer
_ledBuffer.resize(messageLength, 0x00);
// Perform an initial reset to start accepting data on the first led
return writeBytes(clearSize, _ledBuffer.data()) >= 0;
}
int LedDeviceLpd8806::write(const std::vector<ColorRgb> &ledValues)
{
const unsigned clearSize = _ledCount/32+1;
unsigned messageLength = 3*_ledCount + clearSize;
// Reconfigure if the current connfiguration does not match the required configuration
if (messageLength != _ledBuffer.size())
{
// Initialise the buffer
_ledBuffer.resize(messageLength, 0x00);
// Perform an initial reset to start accepting data on the first led
writeBytes(clearSize, _ledBuffer.data());
}
// Copy the colors from the ColorRgb vector to the Ldp8806 data vector
for (unsigned iLed=0; iLed<(unsigned)_ledCount; ++iLed)
{
const ColorRgb& rgb = ledValues[iLed];
const ColorRgb& color = ledValues[iLed];
_ledBuffer[iLed*3] = 0x80 | (rgb.red >> 1);
_ledBuffer[iLed*3+1] = 0x80 | (rgb.green >> 1);
_ledBuffer[iLed*3+2] = 0x80 | (rgb.blue >> 1);
_ledBuffer[iLed*3] = 0x80 | (color.red >> 1);
_ledBuffer[iLed*3+1] = 0x80 | (color.green >> 1);
_ledBuffer[iLed*3+2] = 0x80 | (color.blue >> 1);
}
// Write the data

View File

@ -88,6 +88,8 @@ public:
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
private:
///
/// Writes the led color values to the led-device

View File

@ -1,8 +1,9 @@
#include "LedDeviceP9813.h"
LedDeviceP9813::LedDeviceP9813(const Json::Value &deviceConfig)
: ProviderSpi(deviceConfig)
: ProviderSpi()
{
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceP9813::construct(const Json::Value &deviceConfig)
@ -10,13 +11,17 @@ LedDevice* LedDeviceP9813::construct(const Json::Value &deviceConfig)
return new LedDeviceP9813(deviceConfig);
}
bool LedDeviceP9813::init(const Json::Value &deviceConfig)
{
ProviderSpi::init(deviceConfig);
_ledBuffer.resize(_ledCount * 4 + 8, 0x00);
return true;
}
int LedDeviceP9813::write(const std::vector<ColorRgb> &ledValues)
{
if (_ledBuffer.size() == 0)
{
_ledBuffer.resize(ledValues.size() * 4 + 8, 0x00);
}
uint8_t * dataPtr = _ledBuffer.data();
for (const ColorRgb & color : ledValues)
{

View File

@ -19,6 +19,8 @@ public:
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
private:
///
/// Writes the led color values to the led-device

View File

@ -2,9 +2,14 @@
// Use out report HID device
LedDevicePaintpack::LedDevicePaintpack(const Json::Value &deviceConfig)
: ProviderHID(deviceConfig)
: ProviderHID()
{
ProviderHID::init(deviceConfig);
_useFeature = false;
_ledBuffer.resize(_ledRGBCount + 2, uint8_t(0));
_ledBuffer[0] = 3;
_ledBuffer[1] = 0;
}
LedDevice* LedDevicePaintpack::construct(const Json::Value &deviceConfig)
@ -14,14 +19,6 @@ LedDevice* LedDevicePaintpack::construct(const Json::Value &deviceConfig)
int LedDevicePaintpack::write(const std::vector<ColorRgb> & ledValues)
{
unsigned newSize = 3*_ledCount + 2;
if (_ledBuffer.size() < newSize)
{
_ledBuffer.resize(newSize, uint8_t(0));
_ledBuffer[0] = 3;
_ledBuffer[1] = 0;
}
auto bufIt = _ledBuffer.begin()+2;
for (const ColorRgb & color : ledValues)
{

View File

@ -164,7 +164,7 @@ CiColor PhilipsHueLight::rgbToCiColor(float red, float green, float blue)
LedDevicePhilipsHue::LedDevicePhilipsHue(const Json::Value &deviceConfig)
: LedDevice()
{
setConfig(deviceConfig);
_deviceReady = init(deviceConfig);
manager = new QNetworkAccessManager();
timer.setInterval(3000);
@ -177,7 +177,7 @@ LedDevicePhilipsHue::~LedDevicePhilipsHue()
delete manager;
}
bool LedDevicePhilipsHue::setConfig(const Json::Value &deviceConfig)
bool LedDevicePhilipsHue::init(const Json::Value &deviceConfig)
{
host = deviceConfig["output"].asString().c_str();
username = deviceConfig.get("username", "newdeveloper").asString().c_str();

View File

@ -127,7 +127,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -26,7 +26,7 @@ LedDevicePiBlaster::LedDevicePiBlaster(const Json::Value &deviceConfig)
_gpio_to_color[i] = 'z';
}
setConfig(deviceConfig);
_deviceReady = init(deviceConfig);
}
LedDevicePiBlaster::~LedDevicePiBlaster()
@ -40,7 +40,7 @@ LedDevicePiBlaster::~LedDevicePiBlaster()
}
bool LedDevicePiBlaster::setConfig(const Json::Value &deviceConfig)
bool LedDevicePiBlaster::init(const Json::Value &deviceConfig)
{
_deviceName = deviceConfig.get("output", "").asString();
Json::Value gpioMapping = deviceConfig.get("gpiomap", Json::nullValue);
@ -65,6 +65,7 @@ bool LedDevicePiBlaster::setConfig(const Json::Value &deviceConfig)
Warning( _log, "IGNORING gpio %d ledindex %d color %c", gpio,ledindex, ledcolor[0]);
}
}
return true;
}

View File

@ -20,7 +20,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -2,10 +2,12 @@
// Use feature report HID device
LedDeviceRawHID::LedDeviceRawHID(const Json::Value &deviceConfig)
: ProviderHID(deviceConfig)
: ProviderHID()
, _timer()
{
ProviderHID::init(deviceConfig);
_useFeature = true;
_ledBuffer.resize(_ledRGBCount);
// setup the timer
_timer.setSingleShot(false);
@ -23,18 +25,11 @@ LedDevice* LedDeviceRawHID::construct(const Json::Value &deviceConfig)
int LedDeviceRawHID::write(const std::vector<ColorRgb> & ledValues)
{
// Resize buffer if required
unsigned bufferSize = _ledCount * 3;
if (_ledBuffer.size() < bufferSize)
{
_ledBuffer.resize(bufferSize);
}
// restart the timer
_timer.start();
// write data
memcpy(_ledBuffer.data(), ledValues.data(), bufferSize);
memcpy(_ledBuffer.data(), ledValues.data(), _ledRGBCount);
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -7,8 +7,9 @@ struct FrameSpec
};
LedDeviceSedu::LedDeviceSedu(const Json::Value &deviceConfig)
: ProviderRs232(deviceConfig)
: ProviderRs232()
{
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceSedu::construct(const Json::Value &deviceConfig)
@ -16,34 +17,36 @@ LedDevice* LedDeviceSedu::construct(const Json::Value &deviceConfig)
return new LedDeviceSedu(deviceConfig);
}
int LedDeviceSedu::write(const std::vector<ColorRgb> &ledValues)
bool LedDeviceSedu::init(const Json::Value &deviceConfig)
{
if (_ledBuffer.size() == 0)
ProviderRs232::init(deviceConfig);
std::vector<FrameSpec> frameSpecs{{0xA1, 256}, {0xA2, 512}, {0xB0, 768}, {0xB1, 1536}, {0xB2, 3072} };
for (const FrameSpec& frameSpec : frameSpecs)
{
std::vector<FrameSpec> frameSpecs{{0xA1, 256}, {0xA2, 512}, {0xB0, 768}, {0xB1, 1536}, {0xB2, 3072} };
const unsigned reqColorChannels = _ledCount * sizeof(ColorRgb);
for (const FrameSpec& frameSpec : frameSpecs)
if ((unsigned)_ledRGBCount <= frameSpec.size)
{
if (reqColorChannels <= frameSpec.size)
{
_ledBuffer.clear();
_ledBuffer.resize(frameSpec.size + 3, 0);
_ledBuffer[0] = 0x5A;
_ledBuffer[1] = frameSpec.id;
_ledBuffer.back() = 0xA5;
break;
}
}
if (_ledBuffer.size() == 0)
{
Warning(_log, "More rgb-channels required then available");
return -1;
_ledBuffer.clear();
_ledBuffer.resize(frameSpec.size + 3, 0);
_ledBuffer[0] = 0x5A;
_ledBuffer[1] = frameSpec.id;
_ledBuffer.back() = 0xA5;
break;
}
}
if (_ledBuffer.size() == 0)
{
Warning(_log, "More rgb-channels required then available");
return false;
}
return true;
}
int LedDeviceSedu::write(const std::vector<ColorRgb> &ledValues)
{
memcpy(_ledBuffer.data()+2, ledValues.data(), ledValues.size() * sizeof(ColorRgb));
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -18,6 +18,8 @@ public:
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
private:
///

View File

@ -1,17 +1,16 @@
#include "LedDeviceSk6812SPI.h"
LedDeviceSk6812SPI::LedDeviceSk6812SPI(const Json::Value &deviceConfig)
: ProviderSpi(deviceConfig)
: ProviderSpi()
, _whiteAlgorithm(RGBW::INVALID)
, bitpair_to_byte {
0b10001000,
0b10001100,
0b11001000,
0b11001100,
}
{
setConfig(deviceConfig);
Debug( _log, "whiteAlgorithm : %s", _whiteAlgorithm.c_str());
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceSk6812SPI::construct(const Json::Value &deviceConfig)
@ -19,33 +18,39 @@ LedDevice* LedDeviceSk6812SPI::construct(const Json::Value &deviceConfig)
return new LedDeviceSk6812SPI(deviceConfig);
}
bool LedDeviceSk6812SPI::setConfig(const Json::Value &deviceConfig)
bool LedDeviceSk6812SPI::init(const Json::Value &deviceConfig)
{
ProviderSpi::setConfig(deviceConfig,3000000);
std::string whiteAlgorithm = deviceConfig.get("white_algorithm","white_off").asString();
_whiteAlgorithm = RGBW::stringToWhiteAlgorithm(whiteAlgorithm);
_whiteAlgorithm = deviceConfig.get("white_algorithm","").asString();
if (_whiteAlgorithm == RGBW::INVALID)
{
Error(_log, "unknown whiteAlgorithm %s", whiteAlgorithm.c_str());
return false;
}
Debug( _log, "whiteAlgorithm : %s", whiteAlgorithm.c_str());
_baudRate_Hz = 3000000;
if ( !ProviderSpi::init(deviceConfig) )
{
return false;
}
const int SPI_BYTES_PER_COLOUR = 4;
const int SPI_FRAME_END_LATCH_BYTES = 3;
_ledBuffer.resize(_ledRGBWCount * SPI_BYTES_PER_COLOUR + SPI_FRAME_END_LATCH_BYTES, 0x00);
return true;
}
int LedDeviceSk6812SPI::write(const std::vector<ColorRgb> &ledValues)
{
// 4 colours, 4 spi bytes per colour + 3 frame end latch bytes
#define COLOURS_PER_LED 4
#define SPI_BYTES_PER_COLOUR 4
#define SPI_BYTES_PER_LED COLOURS_PER_LED * SPI_BYTES_PER_COLOUR
unsigned spi_size = _ledCount * SPI_BYTES_PER_LED + 3;
if(_ledBuffer.size() != spi_size)
{
_ledBuffer.resize(spi_size, 0x00);
}
unsigned spi_ptr = 0;
static const int SPI_BYTES_PER_LED = 4;
for (const ColorRgb& color : ledValues)
{
Rgb_to_Rgbw(color, &_temp_rgbw, _whiteAlgorithm);
RGBW::Rgb_to_Rgbw(color, &_temp_rgbw, _whiteAlgorithm);
uint32_t colorBits =
((uint32_t)_temp_rgbw.red << 24) +
((uint32_t)_temp_rgbw.green << 16) +
@ -63,5 +68,5 @@ int LedDeviceSk6812SPI::write(const std::vector<ColorRgb> &ledValues)
_ledBuffer[spi_ptr++] = 0;
_ledBuffer[spi_ptr++] = 0;
return writeBytes(spi_size, _ledBuffer.data());
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -24,7 +24,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
private:
///
@ -35,7 +35,7 @@ private:
///
virtual int write(const std::vector<ColorRgb> &ledValues);
std::string _whiteAlgorithm;
RGBW::WhiteAlgorithm _whiteAlgorithm;
uint8_t bitpair_to_byte[4];

View File

@ -15,7 +15,7 @@ LedDeviceTinkerforge::LedDeviceTinkerforge(const Json::Value &deviceConfig)
, _ledStrip(nullptr)
, _colorChannelSize(0)
{
setConfig(deviceConfig);
init(deviceConfig);
}
LedDeviceTinkerforge::~LedDeviceTinkerforge()
@ -31,13 +31,27 @@ LedDeviceTinkerforge::~LedDeviceTinkerforge()
delete _ledStrip;
}
bool LedDeviceTinkerforge::setConfig(const Json::Value &deviceConfig)
bool LedDeviceTinkerforge::init(const Json::Value &deviceConfig)
{
_host = deviceConfig.get("output", "127.0.0.1").asString();
_port = deviceConfig.get("port", 4223).asInt();
_uid = deviceConfig["uid"].asString();
_interval = deviceConfig["rate"].asInt();
if ((unsigned)_ledCount > MAX_NUM_LEDS)
{
Error(_log,"Invalid attempt to write led values. Not more than %d leds are allowed.", MAX_NUM_LEDS);
return -1;
}
if (_colorChannelSize < (unsigned)_ledCount)
{
_redChannel.resize(_ledCount, uint8_t(0));
_greenChannel.resize(_ledCount, uint8_t(0));
_blueChannel.resize(_ledCount, uint8_t(0));
}
_colorChannelSize = _ledCount;
return true;
}
@ -82,20 +96,6 @@ int LedDeviceTinkerforge::open()
int LedDeviceTinkerforge::write(const std::vector<ColorRgb> &ledValues)
{
if ((unsigned)_ledCount > MAX_NUM_LEDS)
{
Error(_log,"Invalid attempt to write led values. Not more than %d leds are allowed.", MAX_NUM_LEDS);
return -1;
}
if (_colorChannelSize < (unsigned)_ledCount)
{
_redChannel.resize(_ledCount, uint8_t(0));
_greenChannel.resize(_ledCount, uint8_t(0));
_blueChannel.resize(_ledCount, uint8_t(0));
}
_colorChannelSize = _ledCount;
auto redIt = _redChannel.begin();
auto greenIt = _greenChannel.begin();
auto blueIt = _blueChannel.begin();

View File

@ -29,7 +29,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -2,8 +2,9 @@
LedDeviceTpm2::LedDeviceTpm2(const Json::Value &deviceConfig)
: ProviderRs232(deviceConfig)
: ProviderRs232()
{
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceTpm2::construct(const Json::Value &deviceConfig)
@ -11,19 +12,22 @@ LedDevice* LedDeviceTpm2::construct(const Json::Value &deviceConfig)
return new LedDeviceTpm2(deviceConfig);
}
bool LedDeviceTpm2::init(const Json::Value &deviceConfig)
{
ProviderRs232::init(deviceConfig);
_ledBuffer.resize(5 + 3*_ledCount);
_ledBuffer[0] = 0xC9; // block-start byte
_ledBuffer[1] = 0xDA; // DATA frame
_ledBuffer[2] = ((3 * _ledCount) >> 8) & 0xFF; // frame size high byte
_ledBuffer[3] = (3 * _ledCount) & 0xFF; // frame size low byte
_ledBuffer.back() = 0x36; // block-end byte
return true;
}
int LedDeviceTpm2::write(const std::vector<ColorRgb> &ledValues)
{
if (_ledBuffer.size() == 0)
{
_ledBuffer.resize(5 + 3*_ledCount);
_ledBuffer[0] = 0xC9; // block-start byte
_ledBuffer[1] = 0xDA; // DATA frame
_ledBuffer[2] = ((3 * _ledCount) >> 8) & 0xFF; // frame size high byte
_ledBuffer[3] = (3 * _ledCount) & 0xFF; // frame size low byte
_ledBuffer.back() = 0x36; // block-end byte
}
// write data
memcpy(4 + _ledBuffer.data(), ledValues.data(), _ledCount * 3);
memcpy(4 + _ledBuffer.data(), ledValues.data(), _ledRGBCount);
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -19,6 +19,8 @@ public:
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
private:
///
/// Writes the led color values to the led-device

View File

@ -3,13 +3,17 @@
LedDeviceTpm2net::LedDeviceTpm2net(const Json::Value &deviceConfig)
: ProviderUdp()
{
setConfig(deviceConfig);
_deviceReady = init(deviceConfig);
}
bool LedDeviceTpm2net::setConfig(const Json::Value &deviceConfig)
bool LedDeviceTpm2net::init(const Json::Value &deviceConfig)
{
ProviderUdp::setConfig(deviceConfig, TPM2_DEFAULT_PORT, 104000);
_LatchTime_ns = 104000;
_port = TPM2_DEFAULT_PORT;
ProviderUdp::init(deviceConfig);
_tpm2_max = deviceConfig.get("max-packet", 170).asInt();
_tpm2ByteCount = 3 * _ledCount;
_tpm2TotalPackets = 1 + _tpm2ByteCount / _tpm2_max;
return true;
}
@ -24,13 +28,10 @@ LedDevice* LedDeviceTpm2net::construct(const Json::Value &deviceConfig)
int LedDeviceTpm2net::write(const std::vector<ColorRgb> &ledValues)
{
uint8_t * _tpm2_buffer = (uint8_t*) malloc(_tpm2_max+7);
uint8_t * tpm2_buffer = (uint8_t*) malloc(_tpm2_max+7);
int retVal = 0;
_tpm2ByteCount = 3 * _ledCount;
_tpm2TotalPackets = 1 + _tpm2ByteCount / _tpm2_max;
int _thisPacketBytes = 0;
_tpm2ThisPacket = 1;
@ -43,21 +44,21 @@ int LedDeviceTpm2net::write(const std::vector<ColorRgb> &ledValues)
_thisPacketBytes = (_tpm2ByteCount - rawIdx < _tpm2_max) ? _tpm2ByteCount % _tpm2_max : _tpm2_max;
// is this the last packet? ? ^^ last packet : ^^ earlier packets
_tpm2_buffer[0] = 0x9c; // Packet start byte
_tpm2_buffer[1] = 0xda; // Packet type Data frame
_tpm2_buffer[2] = (_thisPacketBytes >> 8) & 0xff; // Frame size high
_tpm2_buffer[3] = _thisPacketBytes & 0xff; // Frame size low
_tpm2_buffer[4] = _tpm2ThisPacket++; // Packet Number
_tpm2_buffer[5] = _tpm2TotalPackets; // Number of packets
tpm2_buffer[0] = 0x9c; // Packet start byte
tpm2_buffer[1] = 0xda; // Packet type Data frame
tpm2_buffer[2] = (_thisPacketBytes >> 8) & 0xff; // Frame size high
tpm2_buffer[3] = _thisPacketBytes & 0xff; // Frame size low
tpm2_buffer[4] = _tpm2ThisPacket++; // Packet Number
tpm2_buffer[5] = _tpm2TotalPackets; // Number of packets
}
_tpm2_buffer [6 + rawIdx%_tpm2_max] = rawdata[rawIdx];
tpm2_buffer [6 + rawIdx%_tpm2_max] = rawdata[rawIdx];
// is this the last byte of last packet || last byte of other packets
if ( (rawIdx == _tpm2ByteCount-1) || (rawIdx %_tpm2_max == _tpm2_max-1) )
{
_tpm2_buffer [6 + rawIdx%_tpm2_max +1] = 0x36; // Packet end byte
retVal &= writeBytes(_thisPacketBytes+7, _tpm2_buffer);
tpm2_buffer [6 + rawIdx%_tpm2_max +1] = 0x36; // Packet end byte
retVal &= writeBytes(_thisPacketBytes+7, tpm2_buffer);
}
}

View File

@ -23,7 +23,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -7,12 +7,14 @@
LedDeviceUdpE131::LedDeviceUdpE131(const Json::Value &deviceConfig)
: ProviderUdp()
{
setConfig(deviceConfig);
_deviceReady = init(deviceConfig);
}
bool LedDeviceUdpE131::setConfig(const Json::Value &deviceConfig)
bool LedDeviceUdpE131::init(const Json::Value &deviceConfig)
{
ProviderUdp::setConfig(deviceConfig, 104000, 5568);
_LatchTime_ns = 104000;
_port = 5568;
ProviderUdp::init(deviceConfig);
_e131_universe = deviceConfig.get("universe",1).asInt();
_e131_source_name = deviceConfig.get("source-name","hyperion on "+QHostInfo::localHostName().toStdString()).asString();
QString _json_cid = QString::fromStdString(deviceConfig.get("cid","").asString());
@ -73,38 +75,38 @@ void LedDeviceUdpE131::prepare(const unsigned this_universe, const unsigned this
int LedDeviceUdpE131::write(const std::vector<ColorRgb> &ledValues)
{
int retVal = 0;
int _thisChannelCount = 0;
int _dmxChannelCount = 3 * _ledCount;
int thisChannelCount = 0;
int dmxChannelCount = _ledRGBCount;
const uint8_t * rawdata = reinterpret_cast<const uint8_t *>(ledValues.data());
_e131_seq++;
for (int rawIdx = 0; rawIdx < _dmxChannelCount; rawIdx++)
for (int rawIdx = 0; rawIdx < dmxChannelCount; rawIdx++)
{
if (rawIdx % DMX_MAX == 0) // start of new packet
{
_thisChannelCount = (_dmxChannelCount - rawIdx < DMX_MAX) ? _dmxChannelCount % DMX_MAX : DMX_MAX;
// is this the last packet? ? ^^ last packet : ^^ earlier packets
thisChannelCount = (dmxChannelCount - rawIdx < DMX_MAX) ? dmxChannelCount % DMX_MAX : DMX_MAX;
// is this the last packet? ? ^^ last packet : ^^ earlier packets
prepare(_e131_universe + rawIdx / DMX_MAX, _thisChannelCount);
prepare(_e131_universe + rawIdx / DMX_MAX, thisChannelCount);
e131_packet.sequence_number = _e131_seq;
}
e131_packet.property_values[1 + rawIdx%DMX_MAX] = rawdata[rawIdx];
// is this the last byte of last packet || last byte of other packets
if ( (rawIdx == _dmxChannelCount-1) || (rawIdx %DMX_MAX == DMX_MAX-1) )
if ( (rawIdx == dmxChannelCount-1) || (rawIdx %DMX_MAX == DMX_MAX-1) )
{
#undef e131debug
#if e131debug
Debug (_log, "send packet: rawidx %d dmxchannelcount %d universe: %d, packetsz %d"
, rawIdx
, _dmxChannelCount
, dmxChannelCount
, _e131_universe + rawIdx / DMX_MAX
, E131_DMP_DATA + 1 + _thisChannelCount
, E131_DMP_DATA + 1 + thisChannelCount
);
#endif
retVal &= writeBytes(E131_DMP_DATA + 1 + _thisChannelCount, e131_packet.raw);
retVal &= writeBytes(E131_DMP_DATA + 1 + thisChannelCount, e131_packet.raw);
}
}

View File

@ -112,7 +112,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -3,13 +3,15 @@
LedDeviceUdpH801::LedDeviceUdpH801(const Json::Value &deviceConfig)
: ProviderUdp()
{
setConfig(deviceConfig);
_deviceReady = init(deviceConfig);
}
bool LedDeviceUdpH801::setConfig(const Json::Value &deviceConfig)
bool LedDeviceUdpH801::init(const Json::Value &deviceConfig)
{
/* The H801 port is fixed */
ProviderUdp::setConfig(deviceConfig, 10000000, 30977, "255.255.255.255");
_LatchTime_ns = 10000000;
_port = 30977;
ProviderUdp::init(deviceConfig, "255.255.255.255");
_ids.clear();
for (Json::Value::ArrayIndex i = 0; i < deviceConfig["lightIds"].size(); i++)

View File

@ -29,7 +29,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);

View File

@ -3,7 +3,9 @@
LedDeviceUdpRaw::LedDeviceUdpRaw(const Json::Value &deviceConfig)
: ProviderUdp()
{
setConfig(deviceConfig, 500000, 5568);
_LatchTime_ns = 500000;
_port = 5568;
init(deviceConfig);
}
LedDevice* LedDeviceUdpRaw::construct(const Json::Value &deviceConfig)
@ -13,8 +15,7 @@ LedDevice* LedDeviceUdpRaw::construct(const Json::Value &deviceConfig)
int LedDeviceUdpRaw::write(const std::vector<ColorRgb> &ledValues)
{
const unsigned dataLen = _ledCount * sizeof(ColorRgb);
const uint8_t * dataPtr = reinterpret_cast<const uint8_t *>(ledValues.data());
return writeBytes(dataLen, dataPtr);
return writeBytes((unsigned)_ledRGBCount, dataPtr);
}

View File

@ -146,7 +146,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value&) {return true;};
bool init(const Json::Value&) {return true;};
/// constructs leddevice
static LedDevice* construct(const Json::Value &);

View File

@ -2,24 +2,31 @@
#include "LedDeviceWS281x.h"
// Constructor
LedDeviceWS281x::LedDeviceWS281x(const Json::Value &deviceConfig)
: LedDevice()
, _initialized(false)
{
setConfig(deviceConfig);
Debug( _log, "whiteAlgorithm : %s", _whiteAlgorithm.c_str());
if (ws2811_init(&_led_string) < 0)
{
throw std::runtime_error("Unable to initialize ws281x library.");
}
_initialized = true;
_deviceReady = init(deviceConfig);
}
bool LedDeviceWS281x::setConfig(const Json::Value &deviceConfig)
LedDeviceWS281x::~LedDeviceWS281x()
{
_whiteAlgorithm = deviceConfig.get("white_algorithm","").asString();
if (_deviceReady)
{
ws2811_fini(&_led_string);
}
}
bool LedDeviceWS281x::init(const Json::Value &deviceConfig)
{
std::string whiteAlgorithm = deviceConfig.get("white_algorithm","white_off").asString();
_whiteAlgorithm = RGBW::stringToWhiteAlgorithm(whiteAlgorithm);
Debug( _log, "whiteAlgorithm : %s", whiteAlgorithm.c_str());
if (_whiteAlgorithm == RGBW::INVALID)
{
Error(_log, "unknown whiteAlgorithm %s", whiteAlgorithm.c_str());
return false;
}
_channel = deviceConfig.get("pwmchannel", 0).asInt();
if (_channel != 0 && _channel != 1)
{
@ -40,6 +47,12 @@ bool LedDeviceWS281x::setConfig(const Json::Value &deviceConfig)
_led_string.channel[!_channel].brightness = 0;
_led_string.channel[!_channel].strip_type = WS2811_STRIP_RGB;
if (ws2811_init(&_led_string) < 0)
{
throw std::runtime_error("Unable to initialize ws281x library.");
}
return true;
}
@ -48,13 +61,9 @@ LedDevice* LedDeviceWS281x::construct(const Json::Value &deviceConfig)
return new LedDeviceWS281x(deviceConfig);
}
// Send new values down the LED chain
int LedDeviceWS281x::write(const std::vector<ColorRgb> &ledValues)
{
if (!_initialized)
return -1;
int idx = 0;
for (const ColorRgb& color : ledValues)
{
@ -85,12 +94,3 @@ int LedDeviceWS281x::write(const std::vector<ColorRgb> &ledValues)
return ws2811_render(&_led_string) ? -1 : 0;
}
// Destructor
LedDeviceWS281x::~LedDeviceWS281x()
{
if (_initialized)
{
ws2811_fini(&_led_string);
}
_initialized = false;
}

View File

@ -23,7 +23,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
bool init(const Json::Value &deviceConfig);
/// constructs leddevice
static LedDevice* construct(const Json::Value &deviceConfig);
@ -39,7 +39,6 @@ private:
ws2811_t _led_string;
int _channel;
bool _initialized;
std::string _whiteAlgorithm;
RGBW::WhiteAlgorithm _whiteAlgorithm;
ColorRgbw _temp_rgbw;
};

View File

@ -1,8 +1,9 @@
#include "LedDeviceWs2801.h"
LedDeviceWs2801::LedDeviceWs2801(const Json::Value &deviceConfig)
: ProviderSpi(deviceConfig)
: ProviderSpi()
{
_deviceReady = ProviderSpi::init(deviceConfig);
}
LedDevice* LedDeviceWs2801::construct(const Json::Value &deviceConfig)

View File

@ -9,7 +9,7 @@ LedDeviceWs2812SPI::LedDeviceWs2812SPI(const Json::Value &deviceConfig)
0b11001100,
}
{
setConfig(deviceConfig);
_deviceReady = init(deviceConfig);
}
LedDevice* LedDeviceWs2812SPI::construct(const Json::Value &deviceConfig)
@ -17,9 +17,10 @@ LedDevice* LedDeviceWs2812SPI::construct(const Json::Value &deviceConfig)
return new LedDeviceWs2812SPI(deviceConfig);
}
bool LedDeviceWs2812SPI::setConfig(const Json::Value &deviceConfig)
bool LedDeviceWs2812SPI::init(const Json::Value &deviceConfig)
{
ProviderSpi::setConfig(deviceConfig,3000000);
_baudRate_Hz = 3000000;
ProviderSpi::init(deviceConfig);
WarningIf(( _baudRate_Hz < 2050000 || _baudRate_Hz > 4000000 ), _log, "SPI rate %d outside recommended range (2050000 -> 4000000)", _baudRate_Hz);
return true;

View File

@ -24,7 +24,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
private:
///

View File

@ -9,12 +9,11 @@
// Local Hyperion includes
#include "ProviderHID.h"
ProviderHID::ProviderHID(const Json::Value &deviceConfig)
ProviderHID::ProviderHID()
: _useFeature(false)
, _deviceHandle(nullptr)
, _blockedForDelay(false)
{
setConfig(deviceConfig);
}
ProviderHID::~ProviderHID()
@ -28,7 +27,7 @@ ProviderHID::~ProviderHID()
hid_exit();
}
bool ProviderHID::setConfig(const Json::Value &deviceConfig)
bool ProviderHID::init(const Json::Value &deviceConfig)
{
_delayAfterConnect_ms = deviceConfig.get("delayAfterConnect", 0 ).asInt();
auto VendorIdString = deviceConfig.get("VID", "0x2341").asString();

View File

@ -21,7 +21,7 @@ public:
///
/// @param deviceConfig json device config
///
ProviderHID(const Json::Value &deviceConfig);
ProviderHID();
///
/// Destructor of the LedDevice; closes the output device if it is open
@ -33,7 +33,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
virtual bool setConfig(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
///
/// Opens and configures the output device

View File

@ -9,7 +9,7 @@
// Local Hyperion includes
#include "ProviderRs232.h"
ProviderRs232::ProviderRs232(const Json::Value &deviceConfig)
ProviderRs232::ProviderRs232()
: _rs232Port(this)
, _blockedForDelay(false)
, _stateChanged(true)
@ -17,19 +17,28 @@ ProviderRs232::ProviderRs232(const Json::Value &deviceConfig)
, _bytesWritten(0)
, _frameDropCounter(0)
, _lastError(QSerialPort::NoError)
, _timer()
{
setConfig(deviceConfig);
// setup timer
_timer.setSingleShot(false);
_timer.setInterval(1000);
connect(&_timer, SIGNAL(timeout()), this, SLOT(rewriteLeds()));
// start the timer
_timer.start();
connect(&_rs232Port, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(error(QSerialPort::SerialPortError)));
connect(&_rs232Port, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWritten(qint64)));
connect(&_rs232Port, SIGNAL(readyRead()), this, SLOT(readyRead()));
}
bool ProviderRs232::setConfig(const Json::Value &deviceConfig)
bool ProviderRs232::init(const Json::Value &deviceConfig)
{
closeDevice();
_deviceName = deviceConfig["output"].asString();
_baudRate_Hz = deviceConfig["rate"].asInt();
_delayAfterConnect_ms = deviceConfig.get("delayAfterConnect",250).asInt();
_timer.setInterval ( deviceConfig.get("rewriteTime",5000).asInt() );
return true;
}
@ -148,11 +157,13 @@ bool ProviderRs232::tryOpen(const int delayAfterConnect_ms)
int ProviderRs232::writeBytes(const qint64 size, const uint8_t * data)
{
// restart the timer
_timer.start();
if (! _blockedForDelay)
{
if (!_rs232Port.isOpen())
{
return tryOpen(3000) ? 0 : -1;
return tryOpen(5000) ? 0 : -1;
}
if (_frameDropCounter > 0)
@ -184,3 +195,8 @@ void ProviderRs232::unblockAfterDelay()
{
_blockedForDelay = false;
}
int ProviderRs232::rewriteLeds()
{
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -2,6 +2,7 @@
#include <QObject>
#include <QSerialPort>
#include <QTimer>
// Leddevice includes
#include <leddevice/LedDevice.h>
@ -17,16 +18,14 @@ public:
///
/// Constructs specific LedDevice
///
/// @param deviceConfig json device config
///
ProviderRs232(const Json::Value &deviceConfig);
ProviderRs232();
///
/// Sets configuration
///
/// @param deviceConfig the json device config
/// @return true if success
virtual bool setConfig(const Json::Value &deviceConfig);
virtual bool init(const Json::Value &deviceConfig);
///
/// Destructor of the LedDevice; closes the output device if it is open
@ -57,13 +56,16 @@ protected:
QSerialPort _rs232Port;
private slots:
/// Write the last data to the leds again
int rewriteLeds();
/// Unblock the device after a connection delay
void unblockAfterDelay();
void error(QSerialPort::SerialPortError error);
void bytesWritten(qint64 bytes);
void readyRead();
private:
protected:
// tries to open device if not opened
bool tryOpen(const int delayAfterConnect_ms);
@ -87,4 +89,9 @@ private:
qint64 _bytesWritten;
qint64 _frameDropCounter;
QSerialPort::SerialPortError _lastError;
/// Timer object which makes sure that led data is written at a minimum rate
/// e.g. Adalight device will switch off when it does not receive data at least
/// every 15 seconds
QTimer _timer;
};

View File

@ -14,14 +14,15 @@
#include <utils/Logger.h>
ProviderSpi::ProviderSpi(const Json::Value &deviceConfig)
ProviderSpi::ProviderSpi()
: LedDevice()
, _deviceName("/dev/spidev0.0")
, _baudRate_Hz(1000000)
, _latchTime_ns(0)
, _fid(-1)
, _spiMode(SPI_MODE_0)
, _spiDataInvert(false)
{
if (deviceConfig != Json::nullValue)
{
setConfig(deviceConfig);
}
memset(&_spi, 0, sizeof(_spi));
}
@ -30,13 +31,13 @@ ProviderSpi::~ProviderSpi()
// close(_fid);
}
bool ProviderSpi::setConfig(const Json::Value &deviceConfig, int defaultBaudRateHz)
bool ProviderSpi::init(const Json::Value &deviceConfig)
{
_deviceName = deviceConfig.get("output","/dev/spidev0.0").asString();
_baudRate_Hz = deviceConfig.get("rate",defaultBaudRateHz).asInt();
_latchTime_ns = deviceConfig.get("latchtime",0).asInt();
_spiMode = deviceConfig.get("spimode",SPI_MODE_0).asInt();
_spiDataInvert = deviceConfig.get("invert",false).asBool();
_deviceName = deviceConfig.get("output",_deviceName).asString();
_baudRate_Hz = deviceConfig.get("rate",_baudRate_Hz).asInt();
_latchTime_ns = deviceConfig.get("latchtime",_latchTime_ns).asInt();
_spiMode = deviceConfig.get("spimode",_spiMode).asInt();
_spiDataInvert = deviceConfig.get("invert",_spiDataInvert).asBool();
return true;
}

View File

@ -15,16 +15,14 @@ public:
///
/// Constructs specific LedDevice
///
/// @param deviceConfig json device config
///
ProviderSpi(const Json::Value &deviceConfig=Json::nullValue);
ProviderSpi();
///
/// Sets configuration
///
/// @param deviceConfig the json device config
/// @return true if success
virtual bool setConfig(const Json::Value &deviceConfig, int defaultBaudRateHz=1000000);
virtual bool init(const Json::Value &deviceConfig);
///
/// Destructor of the LedDevice; closes the output device if it is open

View File

@ -18,7 +18,7 @@
ProviderUdp::ProviderUdp()
: LedDevice()
, _LatchTime_ns(-1)
, _port(0)
, _port(1)
{
_udpSocket = new QUdpSocket();
}
@ -28,7 +28,7 @@ ProviderUdp::~ProviderUdp()
_udpSocket->close();
}
bool ProviderUdp::setConfig(const Json::Value &deviceConfig, int defaultLatchTime, int defaultPort, std::string defaultHost)
bool ProviderUdp::init(const Json::Value &deviceConfig, std::string defaultHost)
{
QString host = QString::fromStdString(deviceConfig.get("host",defaultHost).asString());
@ -49,7 +49,7 @@ bool ProviderUdp::setConfig(const Json::Value &deviceConfig, int defaultLatchTim
_address = info.addresses().first();
}
_port = deviceConfig.get("port", defaultPort).asUInt();
_port = deviceConfig.get("port", _port).asUInt();
if ( _port<=0 || _port > 65535)
{
throw std::runtime_error("invalid target port");
@ -57,7 +57,7 @@ bool ProviderUdp::setConfig(const Json::Value &deviceConfig, int defaultLatchTim
Debug( _log, "UDP using %s:%d", _address.toString().toStdString().c_str() , _port );
_LatchTime_ns = deviceConfig.get("latchtime", defaultLatchTime).asInt();
_LatchTime_ns = deviceConfig.get("latchtime", _LatchTime_ns).asInt();
return true;
}

View File

@ -27,7 +27,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool setConfig(const Json::Value &deviceConfig, int defaultLatchTime=-1, int defaultPort=0, std::string defaultHost="127.0.0.1");
bool init(const Json::Value &deviceConfig, std::string defaultHost="127.0.0.1");
///
/// Opens and configures the output device

View File

@ -1,25 +1,48 @@
#include <utils/ColorRgb.h>
#include <utils/ColorRgbw.h>
#include <utils/RgbToRgbw.h>
#include <utils/Logger.h>
void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm) {
if (_whiteAlgorithm == "subtract_minimum") {
output->white = std::min(input.red, input.green);
output->white = std::min(output->white, input.blue);
output->red = input.red - output->white;
output->green = input.green - output->white;
output->blue = input.blue - output->white;
}
else if (_whiteAlgorithm == "sub_min_warm_adjust") {
}
else if ( (_whiteAlgorithm == "") || (_whiteAlgorithm == "white_off") ) {
output->red = input.red;
output->green = input.green;
output->blue = input.blue;
output->white = 0;
}
else {
Error(Logger::getInstance("RGBtoRGBW"), "unknown whiteAlgorithm %s", _whiteAlgorithm.c_str());
namespace RGBW {
WhiteAlgorithm stringToWhiteAlgorithm(std::string str)
{
if (str == "subtract_minimum") return SUBTRACT_MINIMUM;
if (str == "sub_min_warm_adjust") return SUB_MIN_WARM_ADJUST;
if (str.empty() || str == "white_off") return WHITE_OFF;
return INVALID;
}
void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, const WhiteAlgorithm algorithm)
{
switch (algorithm)
{
case SUBTRACT_MINIMUM:
{
output->white = std::min(std::min(input.red, input.green), input.blue);
output->red = input.red - output->white;
output->green = input.green - output->white;
output->blue = input.blue - output->white;
break;
}
case SUB_MIN_WARM_ADJUST:
{
Error(Logger::getInstance("RGBtoRGBW"), "white algorithm 'sub_min_warm_adjust' is not implemented yet." );
break;
}
case WHITE_OFF:
{
output->red = input.red;
output->green = input.green;
output->blue = input.blue;
output->white = 0;
break;
}
default:
break;
}
}
};

View File

@ -56,6 +56,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, QObject *parent)
_hyperion = Hyperion::initInstance(_config, _qconfig, configFile.toStdString());
/*
if (Logger::getLogLevel() == Logger::WARNING)
{
if (_qconfig.contains("logger"))
@ -74,7 +75,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, QObject *parent)
{
WarningIf(_qconfig.contains("logger"), Logger::getInstance("LOGGER"), "Logger settings overriden by command line argument");
}
*/
Info(_log, "Hyperion initialised");
}