mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
259becea04
* whitespaces + typo fixes * JS / LGTM fixes * SSDP Handler crash fix * MessageForwarder handlePriorityChanges Slave fixes * use aboutToQuit Signal * complete rewriten Hue Entertainment API structure combined Philips Hue and Entertainment API with new MbedTLS based SSL UDP Provider * add required cross-compile submodules * logical rebuild fn: initLeds, setLights + new logs -more detailed checks and error handling inside iniLeds and setLights - logical script procedure before ProviderUdpSSL init - first steps for multiple ProviderUdpSSL usage - better fallback support to old RestAPI, if entertainment api is not supported - just 4 u LordGrey: new log fn for cosmetic config outputs ;) * add OSX CompileHowTo - undo from CrossCompileHowTo * whitespace fixes * lightID toString fix * fix unsigned int E-API + debug output * bugfixes, reworked black signal detection, wizard: - change device config field light-ids from int to string -> real unsigned int fix - add signal detection brightness minimum threshold value 0.0 for 0% brightness - 1.0 for 100% brightness to count for blacklight signal detection reason: input may not 100% black, like mine - i have a deep dark gray input signal -> my threshold value is set to 0.005 for 0.5% minimum brightness = 1 (from max 255) to count as black - wizard optimations, with fallback without entertainment support (beta state) - whitespace fixes * cleanup + minor fixes * change fixed Hue UPD SSL config to _devConfig paras * Hotfix SSL Connection, new light models, wizard: - Fix UPD SSL Connection failed Problems - add new supported gamut C light models: LCG002, LCA001, LCA002, LCA003 - wizard: extend fallback support to classic mode + hints * whitespace, typo fix * uncheck useEntertainmentAPI, if noAPISupport detected + hint * coredump fix -> add _blackLightsTimer nullptr init * code cleanup / remove old debugs + whitespacefixes * add gamut C LCP001, LCP002 * SSL UDP config made more flexible + remove qDebug -> switch to hyerion.ng _log -> replace logCommand with verbose -> code cleanups etc... * extended mbedtls debugging infos * add adjustable ssl timeout settings * error handling * streamdebugger bugfixes * UPDSSL psk / psk_identity bugfixes! + hue wizard fn typo fix + - verbose option available without dependencies - whitespace fixes * Philips Hue Assistant now recognizes non-original bridges better... + Added note if no clientkey is set when using the entertainment API + User creation (+ clientkey) for non-original bridges can now also be used + Minor changes and bug fixes * CMAKE mbedTLS detection * minor bug fixes + code cleanups * FindMbedTLS.cmake remove Path-Hints + wizard.js: ajax timeout handling Test - content_grabber.js: run relevant code only, if V4L2_AVAIL is true: conf_grabber don't displays other devices, if V4L2 is not available * compile mbedtls via cmake as static lib * remove libmbedtls-dev from compileHowto / scripts * Fix Windows build * Fix windows build (part 2) * removed unnecessary osx x11 include directory path * QTimer Shutdown bugfix * cmake win32 fix + minor bugfixes * cmake debug msg used mbedtls libs * Bugfix: noSignalDetection wasn't switchedOn again if no signal was previously detected * Some code fixes based on alerts from lgtm.com Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com>
273 lines
6.6 KiB
C++
273 lines
6.6 KiB
C++
#include <leddevice/LedDevice.h>
|
|
#include <sstream>
|
|
|
|
//QT include
|
|
#include <QResource>
|
|
#include <QStringList>
|
|
#include <QDir>
|
|
#include <QDateTime>
|
|
#include <QEventLoop>
|
|
#include <QTimer>
|
|
|
|
#include "hyperion/Hyperion.h"
|
|
#include <utils/JsonUtils.h>
|
|
|
|
LedDevice::LedDevice(const QJsonObject& config, QObject* parent)
|
|
: QObject(parent)
|
|
, _devConfig(config)
|
|
, _log(Logger::getInstance("LEDDEVICE"))
|
|
, _ledBuffer(0)
|
|
, _deviceReady(false)
|
|
, _deviceInError(false)
|
|
, _refresh_timer(new QTimer(this))
|
|
, _refresh_timer_interval(0)
|
|
, _last_write_time(QDateTime::currentMSecsSinceEpoch())
|
|
, _latchTime_ms(0)
|
|
, _componentRegistered(false)
|
|
, _enabled(false)
|
|
, _refresh_enabled(false)
|
|
{
|
|
// setup refreshTimer
|
|
_refresh_timer->setTimerType(Qt::PreciseTimer);
|
|
_refresh_timer->setInterval( _refresh_timer_interval );
|
|
connect(_refresh_timer, SIGNAL(timeout()), this, SLOT(rewriteLeds()));
|
|
}
|
|
|
|
LedDevice::~LedDevice()
|
|
{
|
|
_refresh_timer->deleteLater();
|
|
}
|
|
|
|
int LedDevice::open()
|
|
{
|
|
int retval = -1;
|
|
QString errortext;
|
|
_deviceReady = false;
|
|
|
|
// General initialisation and configuration of LedDevice
|
|
if ( init(_devConfig) )
|
|
{
|
|
// Everything is OK -> enable device
|
|
_deviceReady = true;
|
|
setEnable(true);
|
|
retval = 0;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
void LedDevice::setInError(const QString& errorMsg)
|
|
{
|
|
_deviceInError = true;
|
|
_deviceReady = false;
|
|
_enabled = false;
|
|
this->stopRefreshTimer();
|
|
|
|
Error(_log, "Device disabled, device '%s' signals error: '%s'", QSTRING_CSTR(_activeDeviceType), QSTRING_CSTR(errorMsg));
|
|
emit enableStateChanged(_enabled);
|
|
}
|
|
|
|
void LedDevice::close()
|
|
{
|
|
switchOff();
|
|
this->stopRefreshTimer();
|
|
}
|
|
|
|
void LedDevice::setEnable(bool enable)
|
|
{
|
|
if ( !_deviceReady && enable )
|
|
{
|
|
Debug(_log, "Device '%s' was not ready! Trying to re-open.", QSTRING_CSTR(_activeDeviceType));
|
|
if ( open() < 0 )
|
|
{
|
|
Error(_log, "Device '%s' cannot be enabled, as it is not ready!", QSTRING_CSTR(_activeDeviceType));
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// Open worked
|
|
_deviceInError = false;
|
|
}
|
|
}
|
|
|
|
// emit signal when state changed
|
|
if ( _enabled != enable )
|
|
{
|
|
emit enableStateChanged(enable);
|
|
}
|
|
// switch off device when disabled, default: set black to leds when they should go off
|
|
if ( _enabled && !enable )
|
|
{
|
|
switchOff();
|
|
}
|
|
else
|
|
{
|
|
// switch on device when enabled
|
|
if ( !_enabled && enable )
|
|
{
|
|
switchOn();
|
|
}
|
|
}
|
|
_enabled = enable;
|
|
}
|
|
|
|
void LedDevice::setActiveDeviceType(const QString& deviceType)
|
|
{
|
|
_activeDeviceType = deviceType;
|
|
}
|
|
|
|
bool LedDevice::init(const QJsonObject &deviceConfig)
|
|
{
|
|
//Debug(_log, "deviceConfig: [%s]", QString(QJsonDocument(_devConfig).toJson(QJsonDocument::Compact)).toUtf8().constData() );
|
|
|
|
_colorOrder = deviceConfig["colorOrder"].toString("RGB");
|
|
_activeDeviceType = deviceConfig["type"].toString("file").toLower();
|
|
setLedCount(static_cast<unsigned int>( deviceConfig["currentLedCount"].toInt(1) )); // property injected to reflect real led count
|
|
|
|
_latchTime_ms = deviceConfig["latchTime"].toInt( _latchTime_ms );
|
|
_refresh_timer_interval = deviceConfig["rewriteTime"].toInt( _refresh_timer_interval);
|
|
|
|
if ( _refresh_timer_interval > 0 )
|
|
{
|
|
_refresh_enabled = true;
|
|
|
|
if ( _refresh_timer_interval <= _latchTime_ms )
|
|
{
|
|
int new_refresh_timer_interval = _latchTime_ms + 10;
|
|
Warning(_log, "latchTime(%d) is bigger/equal rewriteTime(%d), set rewriteTime to %dms", _latchTime_ms, _refresh_timer_interval, new_refresh_timer_interval);
|
|
_refresh_timer_interval = new_refresh_timer_interval;
|
|
}
|
|
|
|
//Debug(_log, "Refresh interval = %dms",_refresh_timer_interval );
|
|
_refresh_timer->setInterval( _refresh_timer_interval );
|
|
|
|
_last_write_time = QDateTime::currentMSecsSinceEpoch();
|
|
|
|
this->startRefreshTimer();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void LedDevice::startRefreshTimer()
|
|
{
|
|
if ( _deviceReady )
|
|
{
|
|
_refresh_timer->start();
|
|
}
|
|
}
|
|
|
|
void LedDevice::stopRefreshTimer()
|
|
{
|
|
_refresh_timer->stop();
|
|
}
|
|
|
|
int LedDevice::updateLeds(const std::vector<ColorRgb>& ledValues)
|
|
{
|
|
int retval = 0;
|
|
if ( !_deviceReady || _deviceInError )
|
|
{
|
|
//std::cout << "LedDevice::updateLeds(), LedDevice NOT ready!" << std::endl;
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
qint64 elapsedTime = QDateTime::currentMSecsSinceEpoch() - _last_write_time;
|
|
if (_latchTime_ms == 0 || elapsedTime >= _latchTime_ms)
|
|
{
|
|
//std::cout << "LedDevice::updateLeds(), Elapsed time since last write (" << elapsedTime << ") ms > _latchTime_ms (" << _latchTime_ms << ") ms" << std::endl;
|
|
retval = write(ledValues);
|
|
_last_write_time = QDateTime::currentMSecsSinceEpoch();
|
|
|
|
// if device requires refreshing, save Led-Values and restart the timer
|
|
if ( _refresh_enabled )
|
|
{
|
|
this->startRefreshTimer();
|
|
_last_ledValues = ledValues;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//std::cout << "LedDevice::updateLeds(), Skip write. _latchTime_ms (" << _latchTime_ms << ") ms > elapsedTime (" << elapsedTime << ") ms" << std::endl;
|
|
if ( _refresh_enabled )
|
|
{
|
|
//Stop timer to allow for next non-refresh update
|
|
this->stopRefreshTimer();
|
|
}
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
int LedDevice::writeBlack()
|
|
{
|
|
return _deviceReady ? updateLeds(std::vector<ColorRgb>(static_cast<unsigned long>(_ledCount), ColorRgb::BLACK )) : -1;
|
|
}
|
|
|
|
int LedDevice::switchOff()
|
|
{
|
|
// Stop refresh timer to ensure that "write Black" is executed
|
|
this->stopRefreshTimer();
|
|
|
|
if ( _latchTime_ms > 0 )
|
|
{
|
|
// Wait latchtime before writing black
|
|
QEventLoop loop;
|
|
QTimer::singleShot( _latchTime_ms, &loop, SLOT( quit() ) );
|
|
loop.exec();
|
|
}
|
|
int rc = writeBlack();
|
|
return rc;
|
|
}
|
|
|
|
int LedDevice::switchOn()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void LedDevice::setLedCount(unsigned int ledCount)
|
|
{
|
|
_ledCount = ledCount;
|
|
_ledRGBCount = _ledCount * sizeof(ColorRgb);
|
|
_ledRGBWCount = _ledCount * sizeof(ColorRgbw);
|
|
}
|
|
|
|
void LedDevice::setLatchTime( int latchTime_ms )
|
|
{
|
|
_latchTime_ms = latchTime_ms;
|
|
Debug(_log, "LatchTime updated to %dms", this->getLatchTime());
|
|
}
|
|
|
|
int LedDevice::rewriteLeds()
|
|
{
|
|
int retval = -1;
|
|
|
|
if ( _deviceReady )
|
|
{
|
|
// qint64 elapsedTime = QDateTime::currentMSecsSinceEpoch() - _last_write_time;
|
|
// std::cout << "LedDevice::rewriteLeds(): Rewrite Leds now, elapsedTime [" << elapsedTime << "] ms" << std::endl;
|
|
// //:TESTING: Inject "white" output records to differentiate from normal writes
|
|
// _last_ledValues.clear();
|
|
// _last_ledValues.resize(static_cast<unsigned long>(_ledCount), ColorRgb::WHITE);
|
|
// printLedValues(_last_ledValues);
|
|
// //:TESTING:
|
|
|
|
retval = write(_last_ledValues);
|
|
_last_write_time = QDateTime::currentMSecsSinceEpoch();
|
|
}
|
|
else
|
|
{
|
|
// If Device is not ready stop timer
|
|
this->stopRefreshTimer();
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
void LedDevice::printLedValues(const std::vector<ColorRgb>& ledValues)
|
|
{
|
|
std::cout << "LedValues [" << ledValues.size() <<"] [";
|
|
for (const ColorRgb& color : ledValues)
|
|
{
|
|
std::cout << color;
|
|
}
|
|
std::cout << "]" << std::endl;
|
|
}
|