Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+502
@@ -0,0 +1,502 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Effects (plural) handler, handles all effects at one EGCU or BSM
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLTE, 2021-06-02
|
||||
*/
|
||||
|
||||
#include "handeleffects.h"
|
||||
#include "handeleffect.h"
|
||||
#include "handle_http_request.h"
|
||||
#include <QTimer>
|
||||
#include <QUrlQuery>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QDateTime>
|
||||
#include <QJsonArray>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
|
||||
HandelEffects::HandelEffects(QObject *parent, const QString &loggerchannel)
|
||||
: QObject(parent)
|
||||
, m_sounds(EffectOverride::EO_Auto)
|
||||
, m_getRelayStateTimer(new QTimer(this))
|
||||
, m_logger(getLogger(QStringLiteral("HandelEffects.") + loggerchannel))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "HandelEffects::init loggerchannel=" << loggerchannel;
|
||||
// create a timer
|
||||
|
||||
// setup signal and slot
|
||||
connect(m_getRelayStateTimer, &QTimer::timeout,
|
||||
this, &HandelEffects::onRelayStateTimerTimeout);
|
||||
|
||||
}
|
||||
|
||||
HandelEffects::~HandelEffects()
|
||||
{
|
||||
}
|
||||
|
||||
void HandelEffects::init(const QString &controlEffectsCfg, const QString &hostname, EffectType et)
|
||||
|
||||
{
|
||||
m_xmlReader.init(controlEffectsCfg);
|
||||
|
||||
DEBUG_LOG(m_logger) << "HandelEffects::init";
|
||||
m_hostname = hostname;
|
||||
m_lastDamage = -1;
|
||||
m_effectType = et;
|
||||
// msec
|
||||
if (et == ET_Relay)
|
||||
m_getRelayStateTimer->start(contents().updateRelayState);
|
||||
}
|
||||
|
||||
void HandelEffects::startEffects(int damagePercent)
|
||||
{
|
||||
if (m_lastDamage == damagePercent)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "damagePercent=" << damagePercent
|
||||
<< " m_lastDamage=" << m_lastDamage
|
||||
<< " return";
|
||||
return;
|
||||
}
|
||||
|
||||
for (Effect *e : contents().constEffects())
|
||||
{
|
||||
// If this Instance does not handle BSM, skip BSM-Effects
|
||||
if (e->effectType == ET_BsmFlash && m_effectType != ET_BsmFlash)
|
||||
continue;
|
||||
|
||||
// If this Instance has BSM API, it is only for BSM, so skip sounds
|
||||
if (e->effectType == ET_BackgroundSound && m_effectType == ET_BsmFlash)
|
||||
continue;
|
||||
|
||||
// If this Instance has BSM API, it is only for BSM, so skip relays
|
||||
if (e->effectType == ET_Relay && m_effectType == ET_BsmFlash)
|
||||
continue;
|
||||
|
||||
DEBUG_LOG(m_logger) << "- HandelEffects::Starting Effect " << e << " of Type " << e->effectType << ". ----"
|
||||
<< " name=" << e->name;
|
||||
for (const Range *range : e->constRanges())
|
||||
{
|
||||
if (!range->fits(damagePercent))
|
||||
continue;
|
||||
|
||||
if (range->fits(m_lastDamage) && !range->restartOnChange)
|
||||
continue;
|
||||
|
||||
// We must restart the actions for that range. Either, because the range changed or because restart is commanded.
|
||||
// Thus, we kill the old HandelEffect and start over.
|
||||
createEffectHandler(e, range);
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "- End Effect ";
|
||||
}
|
||||
m_lastDamage = damagePercent;
|
||||
}
|
||||
|
||||
void HandelEffects::createEffectHandler(Effect *e, const Range *range)
|
||||
{
|
||||
HandelEffect *handelEffect = e->effectHandler;
|
||||
delete handelEffect; // This also deletes the child handelEffect in case of Repeat actions!
|
||||
|
||||
handelEffect = new HandelEffect(this, m_hostname.isEmpty() ? QLatin1String("BSM") : m_hostname);
|
||||
e->effectHandler = handelEffect;
|
||||
if (e->override == EO_Auto)
|
||||
{
|
||||
if (m_effectType == ET_BsmFlash)
|
||||
{
|
||||
INFO_LOG(m_logger) << "setOverrides connect Flashes" ;
|
||||
connect(handelEffect, &HandelEffect::triggerAllFlashlights, this, &HandelEffects::triggerAllFlashlights, Qt::UniqueConnection);
|
||||
}
|
||||
else
|
||||
connect(handelEffect, &HandelEffect::newHttpRequest, this, &HandelEffects::sendHttpRequest, Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
connect(handelEffect, &HandelEffect::effectReady, this, &HandelEffects::onEffectReady);
|
||||
|
||||
DEBUG_LOG(m_logger) << "-- HandelEffects::Starting Range " << range->min << " - " << range->max
|
||||
<< ". ----";
|
||||
|
||||
DEBUG_LOG(m_logger) << "-- Range has " << range->actions.count() << " actions";
|
||||
|
||||
handelEffect->init(range->actions, 1);
|
||||
|
||||
QTimer::singleShot(0, handelEffect, &HandelEffect::handleEffect);
|
||||
DEBUG_LOG(m_logger) << "-- End Range ";
|
||||
}
|
||||
|
||||
void HandelEffects::playHitSound(const int hitSoundId)
|
||||
{
|
||||
if (m_sounds == EffectOverride::EO_Off)
|
||||
return;
|
||||
|
||||
QUrl url = XmlReader::createPreparedUrl(contents(), m_hostname);
|
||||
url.setPath(QStringLiteral("/hitsound.php"));
|
||||
|
||||
QUrlQuery query;
|
||||
query.addQueryItem(QStringLiteral("sound"), QString::number(hitSoundId));
|
||||
query.addQueryItem(QStringLiteral("vol"), QString::number(contents().hitSoundVolume));
|
||||
url.setQuery(query);
|
||||
|
||||
emit newHttpRequest(url, HandleHttpQueueMessageStatus::MS_Single);
|
||||
}
|
||||
|
||||
void HandelEffects::switchRelay(const SwitchRelayValues &switchRelayValues)
|
||||
{
|
||||
QUrl url = XmlReader::createPreparedUrl(contents(), m_hostname);
|
||||
url.setPath(QStringLiteral("/relay.php"));
|
||||
|
||||
QUrlQuery query;
|
||||
query.addQueryItem(QStringLiteral("number"), QString::number(switchRelayValues.id));
|
||||
query.addQueryItem(QStringLiteral("state"), QString::number(switchRelayValues.bcuRelayState));
|
||||
if (switchRelayValues.bcuRelayState == BRS_Pulse)
|
||||
{
|
||||
query.addQueryItem(QStringLiteral("pulse"), QString::number(switchRelayValues.pulse));
|
||||
query.addQueryItem(QStringLiteral("repeat"), QString::number(switchRelayValues.count-1));
|
||||
query.addQueryItem(QStringLiteral("delay"), QString::number(switchRelayValues.delay));
|
||||
}
|
||||
url.setQuery(query);
|
||||
|
||||
emit newHttpRequest(url, HandleHttpQueueMessageStatus::MS_Single);
|
||||
}
|
||||
|
||||
|
||||
void HandelEffects::setOverrides(const QVector<BcuEffectState> &effectStates)
|
||||
{
|
||||
m_effectStates = effectStates; // Save effectStates to restore overrides
|
||||
DEBUG_LOG(m_logger) << "In set overrides for " << m_hostname << ", effectStates.size: " << effectStates.size();
|
||||
for(const auto &es : qAsConst(m_effectStates))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "m_effectStates: es.id=" << es.id
|
||||
<< ", es.type=" << es.type
|
||||
<< ", es.override=" << es.effectOverride;
|
||||
}
|
||||
m_sounds = EffectOverride::EO_Auto;
|
||||
DEBUG_LOG(m_logger) << "Nun die Schleife:";
|
||||
for(const auto &es : qAsConst(effectStates))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "es.id=" << es.id
|
||||
<< ", es.type=" << es.type
|
||||
<< ", es.override=" << es.effectOverride;
|
||||
switch (es.type) {
|
||||
case BET_BackgroundSound:
|
||||
{
|
||||
for (Effect *e : contents().constEffects())
|
||||
{
|
||||
if (e->effectType != ET_BackgroundSound)
|
||||
continue;
|
||||
EffectOverride eo = static_cast<EffectOverride>(es.effectOverride);
|
||||
e->override = eo;
|
||||
m_sounds = eo;
|
||||
|
||||
if (eo == EO_Auto)
|
||||
createEffectHandler(e,e->getRangeByDamagePercent(m_lastDamage));
|
||||
else
|
||||
{
|
||||
if (e->effectHandler)
|
||||
{
|
||||
disconnect(e->effectHandler, &HandelEffect::newHttpRequest, this, &HandelEffects::sendHttpRequest);
|
||||
INFO_LOG(m_logger) << "setOverrides emit triggerAllFlashlights(0,0,0,0)" ;
|
||||
emit triggerAllFlashlights(0,0,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (es.effectOverride == BEO_Off )
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "BEO_Off";
|
||||
// Stop all Sounds:
|
||||
QUrl url = XmlReader::createPreparedUrl(contents(), m_hostname);
|
||||
QUrlQuery query;
|
||||
url.setPath(QStringLiteral("/bgsound.php"));
|
||||
query.addQueryItem(QStringLiteral("control"), QString::number(BCS_Stop_All_Soundfiles));
|
||||
query.addQueryItem(QStringLiteral("category"), QStringLiteral("people")); // dummy for ICD
|
||||
query.addQueryItem(QStringLiteral("sound"), QStringLiteral("0")); // dummy for ICD
|
||||
|
||||
url.setQuery(query);
|
||||
sendHttpRequest(url);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BET_Relay:
|
||||
{
|
||||
for (Effect *e : contents().constEffects())
|
||||
{
|
||||
if (e->effectType != ET_Relay)
|
||||
continue;
|
||||
if (e->id != es.id)
|
||||
continue;
|
||||
EffectOverride eo = static_cast<EffectOverride>(es.effectOverride);
|
||||
if (eo == e->override)
|
||||
//continue;
|
||||
e->override = eo;
|
||||
if (es.effectOverride != BEO_Auto)
|
||||
{
|
||||
SwitchRelayValues relayValues;
|
||||
relayValues.id = e->id;
|
||||
relayValues.bcuRelayState = static_cast<BcuRelayState>(es.effectOverride);
|
||||
switchRelay(relayValues);
|
||||
if (e->effectHandler)
|
||||
disconnect(e->effectHandler, &HandelEffect::newHttpRequest, this, &HandelEffects::sendHttpRequest);
|
||||
}
|
||||
else
|
||||
createEffectHandler(e,e->getRangeByDamagePercent(m_lastDamage));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BET_BsmFlash:
|
||||
{
|
||||
if (m_effectType != ET_BsmFlash)
|
||||
break;
|
||||
for (Effect *e : contents().constEffects())
|
||||
{
|
||||
if (e->effectType != ET_BsmFlash)
|
||||
continue;
|
||||
EffectOverride eo = static_cast<EffectOverride>(es.effectOverride);
|
||||
if (eo == e->override)
|
||||
continue;
|
||||
e->override = eo;
|
||||
if (es.effectOverride != BEO_Off) // -1 for back to auto or 1 for permanently on which in this case shall also be "auto"...
|
||||
createEffectHandler(e,e->getRangeByDamagePercent(m_lastDamage));
|
||||
else
|
||||
{
|
||||
if (e->effectHandler)
|
||||
{
|
||||
INFO_LOG(m_logger) << "setOverrides disconnect Flashes" ;
|
||||
disconnect (e->effectHandler, &HandelEffect::triggerAllFlashlights, this, &HandelEffects::triggerAllFlashlights);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVector<BcuEffectState> HandelEffects::getOverrides()
|
||||
{
|
||||
QVector<BcuEffectState> overrides;
|
||||
for (Effect *effect : contents().constEffects())
|
||||
{
|
||||
BcuEffectState override;
|
||||
override.id = effect->id;
|
||||
switch (effect->effectType)
|
||||
{
|
||||
case BuildingControlUnit::ET_Unset:
|
||||
override.type = BET_Unset;
|
||||
break;
|
||||
case BuildingControlUnit::ET_Relay:
|
||||
override.type = BET_Relay;
|
||||
break;
|
||||
case BuildingControlUnit::ET_BackgroundSound:
|
||||
override.type = BET_BackgroundSound;
|
||||
break;
|
||||
case BuildingControlUnit::ET_BsmFlash:
|
||||
override.type = BET_BsmFlash;
|
||||
break;
|
||||
} // switch
|
||||
|
||||
switch (effect->override)
|
||||
{
|
||||
case EO_Auto:
|
||||
override.effectOverride = BEO_Auto;
|
||||
break;
|
||||
case EO_Off:
|
||||
override.effectOverride = BEO_Off;
|
||||
break;
|
||||
case EO_On:
|
||||
override.effectOverride = BEO_On;
|
||||
break;
|
||||
|
||||
} // switch
|
||||
DEBUG_LOG(m_logger) << "getOverrides "
|
||||
<< " id=" << override.id
|
||||
<< " type=" << override.type
|
||||
<< " override" << override.effectOverride;
|
||||
overrides.append(override);
|
||||
} // for
|
||||
return overrides;
|
||||
} // END getOverrides
|
||||
|
||||
void HandelEffects::onEffectReady()
|
||||
{
|
||||
// Effect will delete itself, but we have to remove the pointer from the corresponding effect.
|
||||
for (Effect *e : contents().constEffects())
|
||||
{
|
||||
if (e->effectHandler != sender())
|
||||
continue;
|
||||
|
||||
e->effectHandler = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void HandelEffects::sendHttpRequest(const QUrl &url)
|
||||
{
|
||||
QUrl copy = url;
|
||||
copy.setHost(m_hostname);
|
||||
DEBUG_LOG(m_logger) << "sendHttpRequest" << copy.toString();
|
||||
emit newHttpRequest(copy, HandleHttpQueueMessageStatus::MS_Single);
|
||||
}
|
||||
|
||||
void HandelEffects::onRelayStateTimerTimeout()
|
||||
{
|
||||
if ( m_offlineCounter == 3 )
|
||||
{
|
||||
m_offlineState = true;
|
||||
NOTICE_LOG(m_logger) << "!!!!!!!!! Send Offline State !!!!!!!!!!!!!!!! m_offlineState=" << m_offlineState;
|
||||
m_relayState.offlineTime = QDateTime::currentMSecsSinceEpoch();
|
||||
emit sendRelayState(m_relayState);
|
||||
m_overridesSend = false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "send get relay-State contents()=" << contents().toString()
|
||||
<< " m_offlineCounter=" << m_offlineCounter;
|
||||
QUrl url = XmlReader::createPreparedUrl(contents(), m_hostname);
|
||||
url.setPath(QStringLiteral("/relay.php"));
|
||||
QUrlQuery query;
|
||||
query.addQueryItem(QStringLiteral("state"), QString::number(BRS_State));
|
||||
url.setQuery(query);
|
||||
emit newHttpRequest(url, HandleHttpQueueMessageStatus::MS_Cyclic);
|
||||
m_offlineCounter++;
|
||||
}
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
void HandelEffects::handleEgcuReplyObject(const QString &host, const QByteArray &data)
|
||||
{
|
||||
bool relayStateChanged = false;
|
||||
TRACE_LOG(m_logger) << "handleEgcuReply Object:" << data
|
||||
<< " m_offlineState=" << m_offlineState;
|
||||
|
||||
if (m_offlineState)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "State wiederherstellen !!!!!!!!!!! m_offlineState=" << m_offlineState;
|
||||
m_offlineState = false;
|
||||
setOverrides(m_effectStates);
|
||||
}
|
||||
|
||||
RelayState lastRelayState = m_relayState;
|
||||
m_relayState.relayStates.clear();
|
||||
const QJsonObject jsonObject = QJsonDocument::fromJson(data).object();
|
||||
const QJsonObject stateObj = jsonObject[QStringLiteral("State")].toObject();
|
||||
for (auto it = stateObj.constBegin(); it != stateObj.constEnd(); ++it)
|
||||
{
|
||||
RelayStateInfo rsi;
|
||||
rsi.id = it.key().toInt();
|
||||
rsi.state = it.value().isString() ? (it.value().toString().compare(QLatin1String("on"), Qt::CaseInsensitive) == 0) : it.value().toBool(false);
|
||||
m_relayState.relayStates.append(rsi);
|
||||
TRACE_LOG(m_logger) << "id=" << rsi.id
|
||||
<< " state=" << rsi.state;
|
||||
}
|
||||
if ( m_relayState.relayStates.size() == lastRelayState.relayStates.size())
|
||||
{
|
||||
for (int i = 0; i < m_relayState.relayStates.size(); ++i)
|
||||
{
|
||||
if (m_relayState.relayStates[i].state != lastRelayState.relayStates[i].state)
|
||||
{
|
||||
TRACE_LOG(m_logger) << "Values relayStateChanged = true";
|
||||
relayStateChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_LOG(m_logger) << "Size relayStateChanged = true";
|
||||
relayStateChanged = true;
|
||||
}
|
||||
if ( m_offlineCounter > 1)
|
||||
{
|
||||
TRACE_LOG(m_logger) << "m_offlineCounter=" << m_offlineCounter;
|
||||
relayStateChanged = true;
|
||||
}
|
||||
|
||||
m_relayState.hostname = m_hostname;
|
||||
m_relayState.stateTime = QDateTime::currentMSecsSinceEpoch();
|
||||
m_relayState.offlineTime = 0;
|
||||
m_offlineCounter=0;
|
||||
DEBUG_LOG(m_logger) << "host=" << host.toLower()
|
||||
<< " relayStateChanged=" << relayStateChanged
|
||||
<< " m_overridesSend=" << m_overridesSend
|
||||
<< " m_offlineState=" << m_offlineState;
|
||||
// if ( m_relayState.hostname.toLower() == host.toLower() && relayStateChanged && m_overridesSend)
|
||||
|
||||
if ( m_offlineState)
|
||||
{
|
||||
NOTICE_LOG(m_logger) << "!!!!!!!!!!!!!!!! EGCU States wieder setzen !!!!!!!!!!!!!!!!!!";
|
||||
m_offlineState = false;
|
||||
}
|
||||
|
||||
if ( m_relayState.hostname.toLower() == host.toLower() && relayStateChanged)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "emit sendRelayState(m_relayState) relayStateChanged";
|
||||
emit sendRelayState(m_relayState);
|
||||
}
|
||||
}
|
||||
|
||||
void HandelEffects::handleEgcuReplyArray(const QString &host, const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED (host);
|
||||
TRACE_LOG(m_logger) << "handleEgcuReply Array:" << data;
|
||||
m_relayState.relayStates.clear();
|
||||
//parse the reply JSON and send result to svcBuilding
|
||||
const QJsonObject jsonObject = QJsonDocument::fromJson(data).object();
|
||||
if (!jsonObject.contains(QStringLiteral("State")) )
|
||||
return;
|
||||
|
||||
const QJsonArray stateArray = jsonObject[QStringLiteral("State")].toArray();
|
||||
for (int i = 0; i < stateArray.size(); ++i)
|
||||
{
|
||||
RelayStateInfo rsi;
|
||||
rsi.id = i;
|
||||
rsi.state = stateArray[i].isString() ? (stateArray[i].toString().compare(QLatin1String("on"), Qt::CaseInsensitive)== 0 ): stateArray[i].toBool(false);
|
||||
m_relayState.relayStates.append(rsi);
|
||||
TRACE_LOG(m_logger) << "id=" << rsi.id
|
||||
<< " state=" << rsi.state;
|
||||
}
|
||||
|
||||
m_relayState.hostname = m_hostname;
|
||||
m_relayState.stateTime = QDateTime::currentMSecsSinceEpoch();
|
||||
m_relayState.offlineTime = 0;
|
||||
m_offlineCounter=0;
|
||||
|
||||
// if ( m_relayState.hostname.toLower() == host.toLower() && relayStateChanged && m_overridesSend )
|
||||
// emit sendRelayState(m_relayState);
|
||||
}
|
||||
|
||||
|
||||
void HandelEffects::handleEgcuReply(const QString &host, const QByteArray &data)
|
||||
{
|
||||
//parse the reply JSON and send result to svcBuilding
|
||||
DEBUG_LOG(m_logger) << "HandelEffects::handleEgcuReply host=" << host
|
||||
<< " m_hostname=" << m_hostname
|
||||
<< " m_overridesSend=" << m_overridesSend;
|
||||
|
||||
if (host.toLower() != m_hostname.toLower())
|
||||
return;
|
||||
|
||||
const QJsonObject jsonObject = QJsonDocument::fromJson(data).object();
|
||||
if (!jsonObject.contains(QStringLiteral("State")) )
|
||||
{
|
||||
m_overridesSend = true;
|
||||
TRACE_LOG(m_logger) << "No State return";
|
||||
return;
|
||||
}
|
||||
const QJsonValue jsonValue = jsonObject[QStringLiteral("State")];
|
||||
if (jsonValue.isArray())
|
||||
{
|
||||
TRACE_LOG(m_logger) << "data isArray\n";
|
||||
handleEgcuReplyArray(host, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_LOG(m_logger) << "data isObject\n";
|
||||
handleEgcuReplyObject(host, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // BuildingControlUnit
|
||||
Reference in new issue
Block a user