141 lines
4.3 KiB
C++
141 lines
4.3 KiB
C++
#include "olathread.h"
|
|
|
|
#include <ola/Callback.h>
|
|
|
|
olaThread::olaThread(QObject *parent)
|
|
{
|
|
Q_UNUSED(parent);
|
|
m_counter = 0;
|
|
gettimeofday(&m_last_data, NULL);
|
|
// Init the dmx buffer to 0
|
|
for (int i=0; i < LAYERS_NUMBER; i++)
|
|
{
|
|
for (int j=0; j < LAYER_CHANNELS; j++)
|
|
{
|
|
m_dmx[i][j] = 0;
|
|
}
|
|
}
|
|
init(); // start the ola connection
|
|
}
|
|
|
|
// --- DECONSTRUCTOR ---
|
|
olaThread::~olaThread() {
|
|
stop();
|
|
}
|
|
|
|
void olaThread::init()
|
|
{
|
|
if (ola::InitLogging(ola::OLA_LOG_INFO , ola::OLA_LOG_STDERR)) {
|
|
qDebug() << "ola logging debug working";
|
|
} else {
|
|
qWarning() << "Can not init ola logging";
|
|
}
|
|
m_clientWrapper = new ola::client::OlaClientWrapper;
|
|
Q_CHECK_PTR(m_clientWrapper);
|
|
if (!m_clientWrapper->Setup()) { qErrnoWarning("olaThread::olaStart| Failed Setup() in Client Wrapper"); }
|
|
m_client = m_clientWrapper->GetClient();
|
|
m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::NewDmx));
|
|
m_clientWrapper->GetSelectServer()->RegisterRepeatingTimeout(4000, ola::NewCallback(this, &olaThread::CheckDataLoss));
|
|
m_client->SetCloseHandler(ola::NewSingleCallback(this, &olaThread::socketClosed));
|
|
}
|
|
|
|
void olaThread::run()
|
|
{
|
|
emit toTerminal("Start reading DMX");
|
|
m_clientWrapper->GetSelectServer()->Run();
|
|
}
|
|
|
|
void olaThread::stop()
|
|
{
|
|
if (m_clientWrapper != NULL)
|
|
{
|
|
QSet<int> temp = Settings::getInstance()->getUniverses();
|
|
foreach (const int &i, temp) {
|
|
m_client->RegisterUniverse(i, ola::client::UNREGISTER, ola::NewSingleCallback(this, &olaThread::RegisterComplete));
|
|
}
|
|
m_clientWrapper->GetSelectServer()->Terminate();
|
|
m_clientWrapper = NULL;
|
|
m_client = NULL;
|
|
}
|
|
}
|
|
|
|
// ToDo: It can be more efficient making the dmx buffer a DmxBuffer class instead a int array and compare with the new if there is changes at start. Also all access to the buffer it should be get/set. I should profile this
|
|
void olaThread::NewDmx(const ola::client::DMXMetadata &data,
|
|
const ola::DmxBuffer &buffer)
|
|
{
|
|
m_counter++;
|
|
gettimeofday(&m_last_data, NULL);
|
|
uint universe = data.universe;
|
|
emit layerReceived();
|
|
foreach (const dmxSetting &i, Settings::getInstance()->getDmxSettings()) { // loop for reading the channels by layer.
|
|
if(i.universe == universe && i.address > -1) { // Compare if the layer is from this universe AND if the DMX address is 0 or greater, process this layer.
|
|
for (int j = 0; j < LAYER_CHANNELS; j++){
|
|
int value = buffer.Get((i.address) + j); // Get the value for this channel.
|
|
if (m_dmx[i.layer][j] != value) { // Compare the new value with the old value.
|
|
emit dmxOutput(i.layer,j,value);
|
|
m_dmx[i.layer][j] = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check for data loss each 4 seconds.
|
|
*/
|
|
|
|
bool olaThread::CheckDataLoss() {
|
|
struct timeval now, diff;
|
|
if (timerisset(&m_last_data)) {
|
|
gettimeofday(&now, NULL);
|
|
timersub(&now, &m_last_data, &diff);
|
|
if (diff.tv_sec > 4 || (diff.tv_sec == 4 && diff.tv_usec > 4000000)) {
|
|
// loss of data
|
|
qDebug()<< "olaThread| Can not read one or several universes";
|
|
emit toTerminal("olaThread: Can not read one universe");
|
|
// return false; // Retorna false para deshabilitar el callback
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void olaThread::resendDmx()
|
|
{
|
|
// qDebug() << "Resending DMX info";
|
|
for (int i = 0; i < Settings::getInstance()->getLayersNumber(); i++) { // loop for reading the channels by layer.
|
|
for (int j = 0; j < LAYER_CHANNELS; j++){
|
|
emit dmxOutput(i, j, m_dmx[i][j]); // Connected with dmx slot in olaInterface.
|
|
}
|
|
}
|
|
}
|
|
|
|
void olaThread::socketClosed()
|
|
{
|
|
qWarning("ola close the connection. Trying reopening it... ");
|
|
emit toTerminal("OLA closed the connection. Tryin reopening it... ");
|
|
// Qúe limpiamos? todo? el thread?
|
|
if (!m_client->Stop())
|
|
{
|
|
qWarning("Can not stop the ola client");
|
|
}
|
|
m_clientWrapper->GetSelectServer()->Terminate();
|
|
delete m_client;
|
|
m_client = NULL;
|
|
delete m_clientWrapper;
|
|
m_clientWrapper = NULL;
|
|
|
|
// set up ola connection
|
|
init();
|
|
|
|
// register all universes
|
|
registerUniverse();
|
|
|
|
// start the thread????
|
|
run();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|