Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,478 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Xml Reader for Effect Configuration
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLTE, 2021-06-02
|
||||
*/
|
||||
|
||||
#include "xmlreader.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QUrlQuery>
|
||||
#include <QXmlStreamAttributes>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
|
||||
XmlReader::XmlReader(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("XmlReader"))
|
||||
{
|
||||
}
|
||||
|
||||
bool XmlReader::init(const QString &effectConfigFile)
|
||||
{
|
||||
m_contents.effects.clear();
|
||||
|
||||
QFile file(effectConfigFile);
|
||||
DEBUG_LOG(m_logger) << "open effectConfigFile: " << effectConfigFile;
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Couldn't open EffectConfigFile: " << effectConfigFile;
|
||||
return false;
|
||||
}
|
||||
|
||||
QXmlStreamReader xml(file.readAll());
|
||||
while (!xml.atEnd() && !xml.hasError())
|
||||
{
|
||||
QXmlStreamReader::TokenType token = xml.readNext();
|
||||
if (token == QXmlStreamReader::StartDocument)
|
||||
continue;
|
||||
else if (token == QXmlStreamReader::StartElement)
|
||||
{
|
||||
if (xml.name() == QStringLiteral("effects"))
|
||||
continue;
|
||||
else if (xml.name() == QStringLiteral("backgroundSoundVolume"))
|
||||
m_contents.bgSoundVolume = xml.readElementText().toInt();
|
||||
else if (xml.name() == QStringLiteral("hitSoundVolume"))
|
||||
m_contents.hitSoundVolume = xml.readElementText().toInt();
|
||||
else if (xml.name() == QStringLiteral("password"))
|
||||
m_contents.password = xml.readElementText();
|
||||
else if (xml.name() == QStringLiteral("port"))
|
||||
m_contents.port = xml.readElementText().toInt();
|
||||
else if (xml.name() == QStringLiteral("username"))
|
||||
m_contents.username = xml.readElementText();
|
||||
else if (xml.name() == QStringLiteral("updateRelayState"))
|
||||
m_contents.updateRelayState = xml.readElementText().toInt();
|
||||
|
||||
if (xml.name() == QStringLiteral("effect"))
|
||||
{
|
||||
Effect *e = this->parseEffect(xml);
|
||||
if (e)
|
||||
m_contents.effects.append(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xml.hasError())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Effect Config File had XML Errors:\n" << xml.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "Effect Config File Contents: " << m_contents.toString();
|
||||
createHttpRequests();
|
||||
return true;
|
||||
}
|
||||
|
||||
Effect *XmlReader::parseEffect(QXmlStreamReader &xml)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "- parseEffect Start";
|
||||
|
||||
if (xml.tokenType() != QXmlStreamReader::StartElement ||
|
||||
xml.name() != QStringLiteral("effect"))
|
||||
return {};
|
||||
|
||||
Effect *e = new Effect();
|
||||
QXmlStreamAttributes attributes = xml.attributes();
|
||||
|
||||
if (attributes.hasAttribute(QStringLiteral("type")))
|
||||
{
|
||||
QString typeString = attributes.value(QStringLiteral("type")).toString();
|
||||
if (typeString == QStringLiteral("relayAction"))
|
||||
e->effectType = ET_Relay;
|
||||
else if (typeString == QStringLiteral("backgroundSoundAction"))
|
||||
e->effectType = ET_BackgroundSound;
|
||||
else if (typeString == QStringLiteral("bsmFlashAction"))
|
||||
e->effectType = ET_BsmFlash;
|
||||
}
|
||||
xml.readNext();
|
||||
|
||||
while (!(xml.tokenType() == QXmlStreamReader::EndElement &&
|
||||
xml.name() == QStringLiteral("effect")))
|
||||
{
|
||||
if (xml.tokenType() == QXmlStreamReader::StartElement)
|
||||
{
|
||||
if (xml.name() == QStringLiteral("id"))
|
||||
{
|
||||
QXmlStreamAttributes attributesName = xml.attributes();
|
||||
if (attributesName.hasAttribute(QStringLiteral("name")))
|
||||
{
|
||||
e->name = attributesName.value(QStringLiteral("name")).toString();
|
||||
}
|
||||
e->id = xml.readElementText().toInt();
|
||||
}
|
||||
|
||||
if (xml.name() == QStringLiteral("category"))
|
||||
{
|
||||
e->category = static_cast<Category>(xml.readElementText().toInt());
|
||||
}
|
||||
|
||||
if (xml.name() == QStringLiteral("override"))
|
||||
{
|
||||
e->override = static_cast<EffectOverride>(xml.readElementText().toInt());
|
||||
}
|
||||
|
||||
if (xml.name() == QStringLiteral("range"))
|
||||
e->ranges.append(parseRange(xml));
|
||||
}
|
||||
xml.readNext();
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "- parseEffect: Name: " << e->id
|
||||
<< ", Type: " << e->effectType
|
||||
<< ", Category: " << e->category
|
||||
<< ", Name: " << e->name
|
||||
<< ", override: " << e->override;
|
||||
DEBUG_LOG(m_logger) << "- parseEffect End. It has " << e->ranges.size() << " ranges";
|
||||
return e;
|
||||
}
|
||||
|
||||
Range *XmlReader::parseRange(QXmlStreamReader &xml)
|
||||
{
|
||||
if (xml.tokenType() != QXmlStreamReader::StartElement ||
|
||||
xml.name() != QStringLiteral("range"))
|
||||
return {};
|
||||
|
||||
DEBUG_LOG(m_logger) << "-- parseRange Start";
|
||||
Range *r = new Range();
|
||||
|
||||
QXmlStreamAttributes attributes = xml.attributes();
|
||||
|
||||
if (attributes.hasAttribute(QStringLiteral("min")))
|
||||
r->min = attributes.value(QStringLiteral("min")).toInt();
|
||||
if (attributes.hasAttribute(QStringLiteral("max")))
|
||||
r->max = attributes.value(QStringLiteral("max")).toInt();
|
||||
if (attributes.hasAttribute(QStringLiteral("restartOnChange")))
|
||||
r->restartOnChange = attributes.value(QLatin1String("restartOnChange")).toString().toLower() == QLatin1String("true");
|
||||
|
||||
xml.readNext();
|
||||
/*
|
||||
* We're going to loop over the things because the order might change.
|
||||
* We'll continue the loop until we hit an EndElement named person.
|
||||
*/
|
||||
while (!(xml.tokenType() == QXmlStreamReader::EndElement &&
|
||||
xml.name() == QLatin1String("range")))
|
||||
{
|
||||
Action *a = parseAction(xml);
|
||||
if (a && a->aclass != AC_Unset)
|
||||
r->actions << a;
|
||||
|
||||
xml.readNext();
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "-- parseRange: [" << r->min << "-" << r->max << "]"
|
||||
<< ", restartOnChange: " <<r->restartOnChange
|
||||
<< ", ActionCount: " << r->actions.count();
|
||||
DEBUG_LOG(m_logger) << "-- parseRange End";
|
||||
return r;
|
||||
}
|
||||
|
||||
Action *XmlReader::parseAction(QXmlStreamReader &xml)
|
||||
{
|
||||
if (xml.tokenType() != QXmlStreamReader::StartElement)
|
||||
return {};
|
||||
|
||||
if (xml.name() == QStringLiteral("action"))
|
||||
return parseStandardAction(xml);;
|
||||
|
||||
if (xml.name() == QStringLiteral("pause"))
|
||||
return parsePauseAction(xml);
|
||||
|
||||
if (xml.name() == QStringLiteral("repeat"))
|
||||
return parseRepeatAction(xml);
|
||||
|
||||
if (xml.name() == QStringLiteral("bsm"))
|
||||
return parseBsmAction(xml);
|
||||
|
||||
WARNING_LOG(m_logger) << "--- parseUnknownAction with name '" << xml.name().string() << "'cannot be handled.";
|
||||
return {};
|
||||
}
|
||||
|
||||
PauseAction *XmlReader::parsePauseAction(QXmlStreamReader &xml)
|
||||
{
|
||||
if (xml.tokenType() != QXmlStreamReader::StartElement ||
|
||||
xml.name() != QLatin1String("pause"))
|
||||
return {};
|
||||
|
||||
DEBUG_LOG(m_logger) << "--- parsePauseAction Start";
|
||||
QXmlStreamAttributes attributes = xml.attributes();
|
||||
PauseAction *p = new PauseAction();
|
||||
p->atype = static_cast<ActionType>(attributes.value(QStringLiteral("type")).toInt());
|
||||
if (attributes.hasAttribute(QStringLiteral("comment")))
|
||||
p->comment = attributes.value(QStringLiteral("comment")).toString();
|
||||
p->pause = xml.readElementText().toInt();
|
||||
DEBUG_LOG(m_logger) << "--- parsePauseAction: "
|
||||
<< " Pause: " << p->pause
|
||||
<< ", Comment: " << p->comment;
|
||||
|
||||
DEBUG_LOG(m_logger) << "--- parsePauseAction End";
|
||||
return p;
|
||||
}
|
||||
|
||||
RepeatAction *XmlReader::parseRepeatAction(QXmlStreamReader &xml)
|
||||
{
|
||||
if (xml.tokenType() != QXmlStreamReader::StartElement ||
|
||||
xml.name() != QStringLiteral("repeat"))
|
||||
return {};
|
||||
DEBUG_LOG(m_logger) << "--- parseRepeatAction Start";
|
||||
RepeatAction *ra = new RepeatAction();
|
||||
QXmlStreamAttributes attributes = xml.attributes();
|
||||
|
||||
if (attributes.hasAttribute(QStringLiteral("count")))
|
||||
ra->count = attributes.value(QStringLiteral("count")).toInt();
|
||||
if (attributes.hasAttribute(QStringLiteral("comment")))
|
||||
ra->comment = attributes.value(QStringLiteral("comment")).toString();
|
||||
|
||||
if (ra->count == 0)
|
||||
ra->count = -1;
|
||||
|
||||
xml.readNext();
|
||||
|
||||
while (!(xml.tokenType() == QXmlStreamReader::EndElement &&
|
||||
xml.name() == QStringLiteral("repeat")))
|
||||
{
|
||||
Action *a = parseAction(xml);
|
||||
if (a && a->aclass != AC_Unset)
|
||||
ra->actions << a;
|
||||
xml.readNext();
|
||||
}
|
||||
|
||||
QString repetitions = QString::number(ra->count);
|
||||
if (ra->count < 0)
|
||||
repetitions = QLatin1String("Infinite");
|
||||
DEBUG_LOG(m_logger) << "--- parseRepeatAction: Repetitions: " << repetitions << ", Comment: " << ra->comment;
|
||||
DEBUG_LOG(m_logger) << "--- parseRepeatAction End";
|
||||
return ra;
|
||||
}
|
||||
|
||||
Action *XmlReader::parseStandardAction(QXmlStreamReader &xml)
|
||||
{
|
||||
|
||||
if (xml.tokenType() != QXmlStreamReader::StartElement ||
|
||||
xml.name() != QStringLiteral("action"))
|
||||
return {};
|
||||
|
||||
DEBUG_LOG(m_logger) << "--- parseStandardAction Start";
|
||||
|
||||
QXmlStreamAttributes attributes = xml.attributes();
|
||||
|
||||
if (!attributes.hasAttribute(QStringLiteral("type")))
|
||||
return {};
|
||||
|
||||
Action *a = new Action();
|
||||
// set explicitely, as Action itself is "unset"
|
||||
a->aclass = AC_Standard;
|
||||
a->atype = static_cast<ActionType>(attributes.value(QStringLiteral("type")).toInt());
|
||||
if (attributes.hasAttribute(QStringLiteral("comment")))
|
||||
a->comment = attributes.value(QStringLiteral("comment")).toString();
|
||||
DEBUG_LOG(m_logger) << "--- parseStandardAction: Type: " << a->atype
|
||||
<< ", Comment: " << a->comment;
|
||||
DEBUG_LOG(m_logger) << "--- parseStandardAction End";
|
||||
return a;
|
||||
}
|
||||
|
||||
BsmAction *XmlReader::parseBsmAction(QXmlStreamReader &xml)
|
||||
{
|
||||
QXmlStreamAttributes attributes = xml.attributes();
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "--- parseBsmAction Start";
|
||||
BsmAction *a = new BsmAction();
|
||||
a->atype = static_cast<ActionType>(attributes.value(QStringLiteral("type")).toInt());
|
||||
if (attributes.hasAttribute(QStringLiteral("comment")))
|
||||
a->comment = attributes.value(QStringLiteral("comment")).toString();
|
||||
|
||||
xml.readNext();
|
||||
while (!(xml.tokenType() == QXmlStreamReader::EndElement &&
|
||||
xml.name() == QStringLiteral("bsm")))
|
||||
{
|
||||
// What about count?
|
||||
if (xml.name() == QStringLiteral("pause"))
|
||||
a->pause = xml.readElementText().toInt();
|
||||
if (xml.name() == QStringLiteral("choplength"))
|
||||
a->choplength = xml.readElementText().toInt();
|
||||
if (xml.name() == QStringLiteral("pulses"))
|
||||
a->pulses = xml.readElementText().toInt();
|
||||
if (xml.name() == QStringLiteral("pulseduration"))
|
||||
a->pulseduration = xml.readElementText().toInt();
|
||||
xml.readNext();
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "--- parseBsmAction: Type: " << a->atype
|
||||
<< ", Pause: " << a->pause
|
||||
<< ", Choplength: " << a->choplength
|
||||
<< ", Count: " << a->count
|
||||
<< ", Pulses: " << a->pulses
|
||||
<< ", Pulseduration: " << a->pulseduration
|
||||
<< ", Comment: " << a->comment;
|
||||
DEBUG_LOG(m_logger) << "--- parseBsmAction End";
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void XmlReader::createHttpRequests()
|
||||
{
|
||||
for (const Effect *e : m_contents.constEffects())
|
||||
{
|
||||
for (const Range *r : e->constRanges())
|
||||
{
|
||||
generateUrls(e, r->actions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QUrl XmlReader::createPreparedUrl(const XmlContents &contents, const QString &hostname)
|
||||
{
|
||||
QUrl url;
|
||||
url.setScheme(QStringLiteral("http"));
|
||||
url.setUserName(contents.username);
|
||||
url.setPassword(contents.password);
|
||||
if (!hostname.isEmpty())
|
||||
url.setHost(hostname);
|
||||
url.setPort(contents.port);
|
||||
return url;
|
||||
}
|
||||
|
||||
void XmlReader::generateUrl(const Effect *e, Action *a)
|
||||
{
|
||||
switch (a->aclass)
|
||||
{
|
||||
case AC_Standard:
|
||||
{
|
||||
QUrl url = createPreparedUrl(m_contents);
|
||||
QUrlQuery query;
|
||||
|
||||
switch (e->effectType)
|
||||
{
|
||||
case ET_Relay:
|
||||
{
|
||||
url.setPath(QStringLiteral("/relay.php"));
|
||||
query.addQueryItem(QStringLiteral("state"), QString::number(a->atype));
|
||||
query.addQueryItem(QStringLiteral("number"), QString::number(e->id));
|
||||
break;
|
||||
}
|
||||
case ET_BackgroundSound:
|
||||
{
|
||||
url.setPath(QStringLiteral("/bgsound.php"));
|
||||
query.addQueryItem(QStringLiteral("category"), categoryName(e->category));
|
||||
query.addQueryItem(QStringLiteral("sound"), QString::number(e->id));
|
||||
query.addQueryItem(QStringLiteral("vol"), QString::number(m_contents.bgSoundVolume));
|
||||
switch (a->atype)
|
||||
{
|
||||
case AT_Off:
|
||||
query.addQueryItem(QStringLiteral("control"), QStringLiteral("2"));
|
||||
break;
|
||||
case AT_On:
|
||||
query.addQueryItem(QStringLiteral("control"), QStringLiteral("1"));
|
||||
break;
|
||||
case AT_Infinite:
|
||||
query.addQueryItem(QStringLiteral("control"), QStringLiteral("3"));
|
||||
break;
|
||||
case AT_Flash:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
url.setQuery(query);
|
||||
a->url = url;
|
||||
DEBUG_LOG(m_logger) << "Effect " << e->name << ", Action '" << a->comment << "' now has URL: " << url.toString();
|
||||
break;
|
||||
}
|
||||
case AC_Repeat:
|
||||
{
|
||||
const RepeatAction *ra = static_cast<const RepeatAction *>(a);
|
||||
generateUrls(e, ra->actions);
|
||||
break;
|
||||
}
|
||||
case AC_Unset:
|
||||
case AC_Pause:
|
||||
case AC_Bsm:
|
||||
default:
|
||||
DEBUG_LOG(m_logger) << "Effect " << e->name << ", Action '" << a->comment << "' of Type " << a->aclass << " needs no URL";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlReader::generateUrls(const Effect *e, const QVector<Action *> &actions)
|
||||
{
|
||||
for (Action *a : actions)
|
||||
generateUrl(e,a);
|
||||
}
|
||||
|
||||
|
||||
//QVector<Action *> Effect::getActionsByRange(int damagePercent) const
|
||||
//{
|
||||
// for (const Range *r : ranges)
|
||||
// {
|
||||
// if (r->fits(damagePercent))
|
||||
// return r->actions;
|
||||
// }
|
||||
// return {};
|
||||
//}
|
||||
|
||||
Range* Effect::getRangeByDamagePercent(int damagePercent) const
|
||||
{
|
||||
for (Range *r : ranges)
|
||||
{
|
||||
if (r->fits(damagePercent))
|
||||
return r;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString XmlReader::categoryName(Category c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case CT_BGS_Bahnhof:
|
||||
return QStringLiteral("bahnhof");
|
||||
case CT_BGS_Personen:
|
||||
return QStringLiteral("personen");
|
||||
case CT_BGS_Sonstige:
|
||||
return QStringLiteral("sonstige");
|
||||
case CT_BGS_Stadt:
|
||||
return QStringLiteral("stadt");
|
||||
case CT_BGS_Testsounds:
|
||||
return QStringLiteral("testsounds");
|
||||
case CT_BGS_Aircrafts:
|
||||
return QStringLiteral("Aircrafts");
|
||||
case CT_BGS_Battlefields:
|
||||
return QStringLiteral("Battlefields");
|
||||
case CT_BGS_Boats:
|
||||
return QStringLiteral("Boats");
|
||||
case CT_BGS_Explosions:
|
||||
return QStringLiteral("Explosions");
|
||||
case CT_BGS_Helicopter:
|
||||
return QStringLiteral("Helicopter");
|
||||
case CT_BGS_Motors_and_urban_traffic:
|
||||
return QStringLiteral("Motors_and_urban_traffic");
|
||||
case CT_BGS_InsideBuildings:
|
||||
return QStringLiteral("Inside_buildings");
|
||||
case CT_BGS_Vehicles:
|
||||
return QStringLiteral("Vehicles");
|
||||
case CT_Default:
|
||||
default:
|
||||
return QStringLiteral("Default");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // BuildingControlUnit
|
||||
Reference in new issue
Block a user