mirror of https://github.com/nymea/nymea.git
Merge PR #238: Add System Time API
commit
44a403f0e4
|
|
@ -159,6 +159,9 @@ Multi-Arch: same
|
|||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
Replaces: libguh1
|
||||
Provides: nymea-update-plugin-api-1,
|
||||
nymea-zeroconf-plugin-api-1,
|
||||
nymea-system-plugin-api-1
|
||||
Description: An open source IoT server - core library
|
||||
The nymea daemon is a plugin based IoT (Internet of Things) server. The
|
||||
server works like a translator for devices, things and services and
|
||||
|
|
|
|||
|
|
@ -1040,12 +1040,6 @@ DeviceActionInfo *DeviceManagerImplementation::executeAction(const Action &actio
|
|||
return info;
|
||||
}
|
||||
|
||||
/*! Centralized time tick for the NymeaTimer resource. Ticks every second. */
|
||||
void DeviceManagerImplementation::timeTick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DeviceManagerImplementation::loadPlugins()
|
||||
{
|
||||
foreach (const QString &path, pluginSearchDirs()) {
|
||||
|
|
|
|||
|
|
@ -114,9 +114,6 @@ public:
|
|||
signals:
|
||||
void loaded();
|
||||
|
||||
public slots:
|
||||
void timeTick();
|
||||
|
||||
private slots:
|
||||
void loadPlugins();
|
||||
void loadPlugin(DevicePlugin *pluginIface, const PluginMetadata &metaData);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@
|
|||
#include "configurationhandler.h"
|
||||
#include "nymeacore.h"
|
||||
#include "nymeaconfiguration.h"
|
||||
#include "platform/platform.h"
|
||||
#include "platform/platformsystemcontroller.h"
|
||||
|
||||
namespace nymeaserver {
|
||||
|
||||
|
|
@ -80,21 +82,21 @@ ConfigurationHandler::ConfigurationHandler(QObject *parent):
|
|||
QString description; QVariantMap params; QVariantMap returns;
|
||||
description = "Get the list of available timezones.";
|
||||
returns.insert("timeZones", QVariantList() << enumValueName(String));
|
||||
registerMethod("GetTimeZones", description, params, returns);
|
||||
registerMethod("GetTimeZones", description, params, returns, "Use System.GetTimeZones instead.");
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "DEPRECATED - Use the locale property in the Handshake message instead - Returns a list of locale codes available for the server. i.e. en_US, de_AT";
|
||||
description = "Returns a list of locale codes available for the server. i.e. en_US, de_AT";
|
||||
returns.insert("languages", QVariantList() << enumValueName(String));
|
||||
registerMethod("GetAvailableLanguages", description, params, returns);
|
||||
registerMethod("GetAvailableLanguages", description, params, returns, "Use the locale property in the Handshake message instead.");
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Get all configuration parameters of the server.";
|
||||
QVariantMap basicConfiguration;
|
||||
basicConfiguration.insert("serverName", enumValueName(String));
|
||||
basicConfiguration.insert("serverUuid", enumValueName(Uuid));
|
||||
basicConfiguration.insert("serverTime", enumValueName(Uint));
|
||||
basicConfiguration.insert("timeZone", enumValueName(String));
|
||||
basicConfiguration.insert("language", enumValueName(String));
|
||||
basicConfiguration.insert("d:serverTime", enumValueName(Uint));
|
||||
basicConfiguration.insert("d:timeZone", enumValueName(String));
|
||||
basicConfiguration.insert("d:language", enumValueName(String));
|
||||
basicConfiguration.insert("debugServerEnabled", enumValueName(Bool));
|
||||
returns.insert("basicConfiguration", basicConfiguration);
|
||||
QVariantList tcpServerConfigurations;
|
||||
|
|
@ -123,13 +125,13 @@ ConfigurationHandler::ConfigurationHandler(QObject *parent):
|
|||
description = "Set the time zone of the server. See also: \"GetTimeZones\"";
|
||||
params.insert("timeZone", enumValueName(String));
|
||||
returns.insert("configurationError", enumRef<NymeaConfiguration::ConfigurationError>());
|
||||
registerMethod("SetTimeZone", description, params, returns);
|
||||
registerMethod("SetTimeZone", description, params, returns, "Use System.SetTimeZone instead.");
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "DEPRECATED - Use the locale property in the Handshake message instead - Sets the server language to the given language. See also: \"GetAvailableLanguages\"";
|
||||
description = "Sets the server language to the given language. See also: \"GetAvailableLanguages\"";
|
||||
params.insert("language", enumValueName(String));
|
||||
returns.insert("configurationError", enumRef<NymeaConfiguration::ConfigurationError>());
|
||||
registerMethod("SetLanguage", description, params, returns);
|
||||
registerMethod("SetLanguage", description, params, returns, "Use the locale property in the Handshake message instead.");
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Enable or disable the debug server.";
|
||||
|
|
@ -339,7 +341,7 @@ JsonReply *ConfigurationHandler::GetTimeZones(const QVariantMap ¶ms) const
|
|||
{
|
||||
Q_UNUSED(params)
|
||||
QVariantList timeZones;
|
||||
foreach (const QByteArray &timeZoneId, NymeaCore::instance()->timeManager()->availableTimeZones()) {
|
||||
foreach (const QByteArray &timeZoneId, QTimeZone::availableTimeZoneIds()) {
|
||||
timeZones.append(QString::fromUtf8(timeZoneId));
|
||||
}
|
||||
|
||||
|
|
@ -371,11 +373,18 @@ JsonReply *ConfigurationHandler::SetTimeZone(const QVariantMap ¶ms) const
|
|||
{
|
||||
qCDebug(dcJsonRpc()) << "Setting time zone to" << params.value("timeZone").toString();
|
||||
|
||||
QByteArray timeZone = params.value("timeZone").toString().toUtf8();
|
||||
if (!NymeaCore::instance()->timeManager()->setTimeZone(timeZone))
|
||||
return createReply(statusToReply(NymeaConfiguration::ConfigurationErrorInvalidTimeZone));
|
||||
QByteArray timeZoneName = params.value("timeZone").toString().toUtf8();
|
||||
|
||||
QTimeZone timeZone(timeZoneName);
|
||||
if (!timeZone.isValid()) {
|
||||
return createReply(statusToReply(NymeaConfiguration::ConfigurationErrorInvalidTimeZone));
|
||||
}
|
||||
|
||||
bool success = NymeaCore::instance()->platform()->systemController()->setTimeZone(timeZone);
|
||||
if (!success) {
|
||||
return createReply(statusToReply(NymeaConfiguration::ConfigurationErrorInvalidTimeZone));
|
||||
}
|
||||
|
||||
NymeaCore::instance()->configuration()->setTimeZone(timeZone);
|
||||
return createReply(statusToReply(NymeaConfiguration::ConfigurationErrorNoError));
|
||||
}
|
||||
|
||||
|
|
@ -658,7 +667,7 @@ QVariantMap ConfigurationHandler::packBasicConfiguration()
|
|||
basicConfiguration.insert("serverName", NymeaCore::instance()->configuration()->serverName());
|
||||
basicConfiguration.insert("serverUuid", NymeaCore::instance()->configuration()->serverUuid().toString());
|
||||
basicConfiguration.insert("serverTime", NymeaCore::instance()->timeManager()->currentDateTime().toTime_t());
|
||||
basicConfiguration.insert("timeZone", QString::fromUtf8(NymeaCore::instance()->timeManager()->timeZone()));
|
||||
basicConfiguration.insert("timeZone", QTimeZone::systemTimeZoneId());
|
||||
basicConfiguration.insert("language", NymeaCore::instance()->configuration()->locale().name());
|
||||
basicConfiguration.insert("debugServerEnabled", NymeaCore::instance()->configuration()->debugServerEnabled());
|
||||
return basicConfiguration;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ JsonValidator::Result JsonValidator::validateMap(const QVariantMap &map, const Q
|
|||
continue;
|
||||
}
|
||||
QString trimmedKey = key;
|
||||
trimmedKey.remove(QRegExp("^(o:|r:)"));
|
||||
trimmedKey.remove(QRegExp("^(o:|r:|d:)"));
|
||||
if (!map.contains(trimmedKey)) {
|
||||
return Result(false, "Missing required key: " + key, key);
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ JsonValidator::Result JsonValidator::validateMap(const QVariantMap &map, const Q
|
|||
// Is the key allowed in here?
|
||||
QVariant expectedValue = definition.value(key);
|
||||
foreach (const QString &definitionKey, definition.keys()) {
|
||||
QRegExp regExp = QRegExp("(o:|r:)*" + key);
|
||||
QRegExp regExp = QRegExp("(o:|r:|d:)*" + key);
|
||||
if (regExp.exactMatch(definitionKey)) {
|
||||
expectedValue = definition.value(definitionKey);
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ JsonValidator::Result JsonValidator::validateMap(const QVariantMap &map, const Q
|
|||
expectedValue = definition.value("o:" + key);
|
||||
}
|
||||
if (!expectedValue.isValid()) {
|
||||
expectedValue = definition.value("o:" + key);
|
||||
expectedValue = definition.value("d:" + key);
|
||||
}
|
||||
if (!expectedValue.isValid()) {
|
||||
return Result(false, "Invalid key: " + key);
|
||||
|
|
|
|||
|
|
@ -38,9 +38,14 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent):
|
|||
|
||||
// Methods
|
||||
QString description; QVariantMap params; QVariantMap returns;
|
||||
description = "Get the list of capabilites on this system. This allows reading whether things like rebooting or shutting down the system running nymea:core is supported on this host.";
|
||||
description = "Get the list of capabilites on this system. The property \"powerManagement\" indicates whether "
|
||||
"rebooting or shutting down is supported on this system. The property \"updateManagement indicates "
|
||||
"whether system update features are available in this system. The property \"timeManagement\" "
|
||||
"indicates whether the system time can be configured on this system. Note that GetTime will be "
|
||||
"available in any case.";
|
||||
returns.insert("powerManagement", enumValueName(Bool));
|
||||
returns.insert("updateManagement", enumValueName(Bool));
|
||||
returns.insert("timeManagement", enumValueName(Bool));
|
||||
registerMethod("GetCapabilities", description, params, returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
|
|
@ -116,6 +121,39 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent):
|
|||
returns.insert("success", enumValueName(Bool));
|
||||
registerMethod("EnableRepository", description, params, returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Get the system time and configuraton. The \"time\" and \"timeZone\" properties "
|
||||
"give the current server time and time zone. \"automaticTimeAvailable\" indicates whether "
|
||||
"this system supports automatically setting the clock (e.g. using NTP). \"automaticTime\" will "
|
||||
"be true if the system is configured to automatically update the clock.";
|
||||
returns.insert("time", enumValueName(Uint));
|
||||
returns.insert("timeZone", enumValueName(String));
|
||||
returns.insert("automaticTimeAvailable", enumValueName(Bool));
|
||||
returns.insert("automaticTime", enumValueName(Bool));
|
||||
registerMethod("GetTime", description, params, returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Set the system time configuraton. The system can be configured to update the time automatically "
|
||||
"by setting \"automaticTime\" to true. This will only work if the \"timeManagement\" capability is "
|
||||
"available on this system and \"GetTime\" indicates the availability of automatic time settings. If "
|
||||
"any of those requirements are not met, this method will return \"false\" in the \"success\" property. "
|
||||
"In order to manually configure the time, \"automaticTime\" should be set to false and \"time\" should "
|
||||
"be set. Note that if \"automaticTime\" is set to true and a manual \"time\" is still passed, the system "
|
||||
"will attempt to configure automatic time updates and only set the manual time if automatic mode fails. "
|
||||
"A time zone can always be passed optionally to change the system time zone and should be a IANA time zone "
|
||||
"id.";
|
||||
params.insert("o:automaticTime", enumValueName(Bool));
|
||||
params.insert("o:time", enumValueName(Uint));
|
||||
params.insert("o:timeZone", enumValueName(String));
|
||||
returns.insert("success", enumValueName(Bool));
|
||||
registerMethod("SetTime", description, params, returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Returns the list of IANA specified time zone IDs which can be used to select a time zone. It is not "
|
||||
"required to use this method if the client toolkit already provides means to obtain a list of IANA time "
|
||||
"zone ids.";
|
||||
returns.insert("timeZones", enumValueName(StringList));
|
||||
registerMethod("GetTimeZones", description, params, returns);
|
||||
|
||||
// Notifications
|
||||
params.clear();
|
||||
|
|
@ -160,6 +198,13 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent):
|
|||
params.insert("repositoryId", enumValueName(String));
|
||||
registerNotification("RepositoryRemoved", description, params);
|
||||
|
||||
params.clear();
|
||||
description = "Emitted whenever the time configuration is changed";
|
||||
params.insert("time", enumValueName(Uint));
|
||||
params.insert("timeZone", enumValueName(String));
|
||||
params.insert("automaticTimeAvailable", enumValueName(Bool));
|
||||
params.insert("automaticTime", enumValueName(Bool));
|
||||
registerNotification("TimeConfigurationChanged", description, params);
|
||||
|
||||
connect(m_platform->systemController(), &PlatformSystemController::availableChanged, this, &SystemHandler::onCapabilitiesChanged);
|
||||
connect(m_platform->updateController(), &PlatformUpdateController::availableChanged, this, &SystemHandler::onCapabilitiesChanged);
|
||||
|
|
@ -205,6 +250,14 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent):
|
|||
params.insert("repositoryId", repositoryId);
|
||||
emit RepositoryRemoved(params);
|
||||
});
|
||||
connect(m_platform->systemController(), &PlatformSystemController::timeConfigurationChanged, this, [this](){
|
||||
QVariantMap params;
|
||||
params.insert("time", QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000);
|
||||
params.insert("timeZone", QTimeZone::systemTimeZoneId());
|
||||
params.insert("automaticTimeAvailable", m_platform->systemController()->automaticTimeAvailable());
|
||||
params.insert("automaticTime", m_platform->systemController()->automaticTime());
|
||||
emit TimeConfigurationChanged(params);
|
||||
}, Qt::QueuedConnection); // Queued to give QDateTime a chance to sync itself to the system
|
||||
}
|
||||
|
||||
QString SystemHandler::name() const
|
||||
|
|
@ -218,6 +271,7 @@ JsonReply *SystemHandler::GetCapabilities(const QVariantMap ¶ms)
|
|||
QVariantMap data;
|
||||
data.insert("powerManagement", m_platform->systemController()->powerManagementAvailable());
|
||||
data.insert("updateManagement", m_platform->updateController()->updateManagementAvailable());
|
||||
data.insert("timeManagement", m_platform->systemController()->timeManagementAvailable());
|
||||
return createReply(data);
|
||||
}
|
||||
|
||||
|
|
@ -314,6 +368,62 @@ JsonReply *SystemHandler::EnableRepository(const QVariantMap ¶ms) const
|
|||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *SystemHandler::GetTime(const QVariantMap ¶ms) const
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
QVariantMap returns;
|
||||
returns.insert("automaticTimeAvailable", m_platform->systemController()->automaticTimeAvailable());
|
||||
returns.insert("automaticTime", m_platform->systemController()->automaticTime());
|
||||
returns.insert("time", QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000);
|
||||
returns.insert("timeZone", QTimeZone::systemTimeZoneId());
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *SystemHandler::SetTime(const QVariantMap ¶ms) const
|
||||
{
|
||||
QVariantMap returns;
|
||||
bool handled = false;
|
||||
bool automaticTime = params.value("automaticTime", false).toBool();
|
||||
if (params.contains("automaticTime") && m_platform->systemController()->automaticTimeAvailable()) {
|
||||
if (!m_platform->systemController()->setAutomaticTime(automaticTime)) {
|
||||
returns.insert("success", false);
|
||||
return createReply(returns);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
if (!automaticTime && params.contains("time")) {
|
||||
QDateTime time = QDateTime::fromMSecsSinceEpoch(params.value("time").toLongLong() * 1000);
|
||||
if (!m_platform->systemController()->setTime(time)) {
|
||||
returns.insert("success", false);
|
||||
return createReply(returns);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
if (params.contains("timeZone")) {
|
||||
QTimeZone timeZone(params.value("timeZone").toByteArray());
|
||||
if (!m_platform->systemController()->setTimeZone(timeZone)) {
|
||||
returns.insert("success", false);
|
||||
return createReply(returns);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
returns.insert("success", handled);
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *SystemHandler::GetTimeZones(const QVariantMap ¶ms) const
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
QVariantList timeZones;
|
||||
foreach (const QByteArray &timeZoneId, QTimeZone::availableTimeZoneIds()) {
|
||||
timeZones.append(QString::fromUtf8(timeZoneId));
|
||||
}
|
||||
|
||||
QVariantMap returns;
|
||||
returns.insert("timeZones", timeZones);
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
void SystemHandler::onCapabilitiesChanged()
|
||||
{
|
||||
QVariantMap caps;
|
||||
|
|
|
|||
|
|
@ -53,8 +53,13 @@ public:
|
|||
Q_INVOKABLE JsonReply *GetRepositories(const QVariantMap ¶ms) const;
|
||||
Q_INVOKABLE JsonReply *EnableRepository(const QVariantMap ¶ms) const;
|
||||
|
||||
Q_INVOKABLE JsonReply *GetTime(const QVariantMap ¶ms) const;
|
||||
Q_INVOKABLE JsonReply *SetTime(const QVariantMap ¶ms) const;
|
||||
Q_INVOKABLE JsonReply *GetTimeZones(const QVariantMap ¶ms) const;
|
||||
|
||||
signals:
|
||||
void CapabilitiesChanged(const QVariantMap ¶ms);
|
||||
|
||||
void UpdateStatusChanged(const QVariantMap ¶ms);
|
||||
void PackageAdded(const QVariantMap ¶ms);
|
||||
void PackageChanged(const QVariantMap ¶ms);
|
||||
|
|
@ -63,6 +68,8 @@ signals:
|
|||
void RepositoryChanged(const QVariantMap ¶ms);
|
||||
void RepositoryRemoved(const QVariantMap ¶ms);
|
||||
|
||||
void TimeConfigurationChanged(const QVariantMap ¶ms);
|
||||
|
||||
private slots:
|
||||
void onCapabilitiesChanged();
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
#include "tagging/tagsstorage.h"
|
||||
#include "platform/platform.h"
|
||||
#include "experiences/experiencemanager.h"
|
||||
#include "platform/platformsystemcontroller.h"
|
||||
|
||||
#include "scriptengine/scriptengine.h"
|
||||
#include "jsonrpc/scriptshandler.h"
|
||||
|
|
@ -143,7 +144,14 @@ void NymeaCore::init() {
|
|||
m_configuration = new NymeaConfiguration(this);
|
||||
|
||||
qCDebug(dcApplication()) << "Creating Time Manager";
|
||||
m_timeManager = new TimeManager(m_configuration->timeZone(), this);
|
||||
// Migration path: nymea < 0.18 doesn't use system time zone but stores its own time zone in the config
|
||||
// For migration, let's set the system's time zone to the config now to upgrade to the system time zone based nymea >= 0.18
|
||||
if (QTimeZone(m_configuration->timeZone()).isValid()) {
|
||||
if (m_platform->systemController()->setTimeZone(QTimeZone(m_configuration->timeZone()))) {
|
||||
m_configuration->setTimeZone("");
|
||||
}
|
||||
}
|
||||
m_timeManager = new TimeManager(this);
|
||||
|
||||
qCDebug(dcApplication) << "Creating Log Engine";
|
||||
m_logger = new LogEngine(m_configuration->logDBDriver(), m_configuration->logDBName(), m_configuration->logDBHost(), m_configuration->logDBUser(), m_configuration->logDBPassword(), m_configuration->logDBMaxEntries(), this);
|
||||
|
|
@ -206,7 +214,6 @@ void NymeaCore::init() {
|
|||
connect(m_ruleEngine, &RuleEngine::ruleConfigurationChanged, this, &NymeaCore::ruleConfigurationChanged);
|
||||
|
||||
connect(m_timeManager, &TimeManager::dateTimeChanged, this, &NymeaCore::onDateTimeChanged);
|
||||
connect(m_timeManager, &TimeManager::tick, m_deviceManager, &DeviceManagerImplementation::timeTick);
|
||||
|
||||
m_logger->logSystemEvent(m_timeManager->currentDateTime(), true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,71 +40,16 @@
|
|||
namespace nymeaserver {
|
||||
|
||||
/*! Constructs a new \l{TimeManager} with the given \a timeZone and \a parent. */
|
||||
TimeManager::TimeManager(const QByteArray &timeZone, QObject *parent) :
|
||||
TimeManager::TimeManager(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
m_dateTime = QDateTime::currentDateTimeUtc();
|
||||
m_dateTime.setTimeSpec(Qt::UTC);
|
||||
|
||||
setTimeZone(timeZone);
|
||||
|
||||
m_nymeaTimer = new QTimer(this);
|
||||
m_nymeaTimer->setInterval(1000);
|
||||
m_nymeaTimer->setSingleShot(false);
|
||||
|
||||
connect(m_nymeaTimer, &QTimer::timeout, this, &TimeManager::nymeaTimeout);
|
||||
|
||||
m_nymeaTimer->start();
|
||||
}
|
||||
|
||||
/*! Returns the time zone of this \l{TimeManager}. */
|
||||
QByteArray TimeManager::timeZone() const
|
||||
{
|
||||
return m_timeZone.id();
|
||||
}
|
||||
|
||||
/*! Sets the \a timeZone of this \l{TimeManager}. Allowed values according to the \l{http://www.iana.org/time-zones}{IANA database}.
|
||||
* Returns false if the given timezone is not valid. */
|
||||
bool TimeManager::setTimeZone(const QByteArray &timeZone)
|
||||
{
|
||||
if (!QTimeZone(timeZone).isValid()) {
|
||||
qCWarning(dcTimeManager()) << "Invalid time zone" << timeZone;
|
||||
qCWarning(dcTimeManager()) << "Using system time zone" << QTimeZone::systemTimeZoneId();
|
||||
m_timeZone = QTimeZone(QTimeZone::systemTimeZoneId());
|
||||
emit dateTimeChanged(currentDateTime());
|
||||
return false;
|
||||
}
|
||||
|
||||
qCDebug(dcTimeManager()) << "Set time zone" << timeZone;
|
||||
m_timeZone = QTimeZone(timeZone);
|
||||
qCDebug(dcTimeManager()) << "UTC" << m_dateTime.toString("dd.MM.yyyy hh:mm:ss");
|
||||
qCDebug(dcTimeManager) << "Zone time" << currentDateTime().toString("dd.MM.yyyy hh:mm:ss");
|
||||
emit dateTimeChanged(currentDateTime());
|
||||
return true;
|
||||
m_timerId = startTimer(1000, Qt::VeryCoarseTimer);
|
||||
}
|
||||
|
||||
/*! Returns the current dateTime of this \l{TimeManager}. */
|
||||
QDateTime TimeManager::currentDateTime() const
|
||||
{
|
||||
return QDateTime::currentDateTimeUtc().toTimeZone(m_timeZone);
|
||||
}
|
||||
|
||||
/*! Returns the current time of this \l{TimeManager}. */
|
||||
QTime TimeManager::currentTime() const
|
||||
{
|
||||
return QDateTime::currentDateTimeUtc().toTimeZone(m_timeZone).time();
|
||||
}
|
||||
|
||||
/*! Returns the current date of this \l{TimeManager}. */
|
||||
QDate TimeManager::currentDate() const
|
||||
{
|
||||
return QDateTime::currentDateTimeUtc().toTimeZone(m_timeZone).date();
|
||||
}
|
||||
|
||||
/*! Returns a list of available time zones on this system. */
|
||||
QList<QByteArray> TimeManager::availableTimeZones() const
|
||||
{
|
||||
return QTimeZone::availableTimeZoneIds();
|
||||
return QDateTime::currentDateTime().addSecs(m_overrideDifference);
|
||||
}
|
||||
|
||||
/*! Stop the time.
|
||||
|
|
@ -115,7 +60,7 @@ void TimeManager::stopTimer()
|
|||
{
|
||||
qCWarning(dcTimeManager()) << "TimeManager timer stopped. You should only see this in tests.";
|
||||
// Stop clock (used for testing)
|
||||
m_nymeaTimer->stop();
|
||||
killTimer(m_timerId);
|
||||
}
|
||||
|
||||
/*! Set the current time of this TimeManager to the given \a dateTime.
|
||||
|
|
@ -125,21 +70,22 @@ void TimeManager::stopTimer()
|
|||
void TimeManager::setTime(const QDateTime &dateTime)
|
||||
{
|
||||
qCWarning(dcTimeManager()) << "TimeManager time changed" << dateTime.toString("dd.MM.yyyy hh:mm:ss") << "You should only see this in tests.";
|
||||
m_overrideDifference = QDateTime::currentDateTime().secsTo(dateTime);
|
||||
// This method will only be called for testing to set the internal time
|
||||
emit tick();
|
||||
emit dateTimeChanged(dateTime);
|
||||
}
|
||||
|
||||
void TimeManager::nymeaTimeout()
|
||||
void TimeManager::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
// tick for deviceManager
|
||||
Q_UNUSED(event)
|
||||
|
||||
emit tick();
|
||||
|
||||
// Minute based nymea time
|
||||
QDateTime utcDateTime = QDateTime::currentDateTimeUtc();
|
||||
if (m_dateTime.time().minute() != utcDateTime.toTimeZone(m_timeZone).time().minute()) {
|
||||
m_dateTime = utcDateTime;
|
||||
emit dateTimeChanged(currentDateTime());
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
if (m_lastEvent.time().minute() != now.time().minute()) {
|
||||
m_lastEvent = now;
|
||||
emit dateTimeChanged(now.addSecs(m_overrideDifference));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,32 +32,27 @@ class TimeManager : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TimeManager(const QByteArray &timeZone, QObject *parent = 0);
|
||||
|
||||
QByteArray timeZone() const;
|
||||
bool setTimeZone(const QByteArray &timeZone = QTimeZone::systemTimeZoneId());
|
||||
explicit TimeManager(QObject *parent = nullptr);
|
||||
|
||||
QDateTime currentDateTime() const;
|
||||
QTime currentTime() const;
|
||||
QDate currentDate() const;
|
||||
|
||||
QList<QByteArray> availableTimeZones() const;
|
||||
|
||||
// For testability only
|
||||
void stopTimer();
|
||||
void setTime(const QDateTime &dateTime);
|
||||
|
||||
private:
|
||||
QTimeZone m_timeZone;
|
||||
QDateTime m_dateTime;
|
||||
QTimer *m_nymeaTimer;
|
||||
|
||||
signals:
|
||||
void tick();
|
||||
void dateTimeChanged(const QDateTime &dateTime);
|
||||
|
||||
private slots:
|
||||
void nymeaTimeout();
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
int m_timerId = 0;
|
||||
QDateTime m_lastEvent;
|
||||
|
||||
// For testability
|
||||
qint64 m_overrideDifference = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "platformsystemcontroller.h"
|
||||
|
||||
#include "loggingcategories.h"
|
||||
|
||||
PlatformSystemController::PlatformSystemController(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
|
|
@ -41,3 +43,39 @@ bool PlatformSystemController::shutdown()
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlatformSystemController::timeManagementAvailable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlatformSystemController::automaticTimeAvailable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlatformSystemController::automaticTime() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlatformSystemController::setTime(const QDateTime &time)
|
||||
{
|
||||
Q_UNUSED(time)
|
||||
qCWarning(dcPlatform()) << "setTime not implemented in platform plugin";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlatformSystemController::setAutomaticTime(bool automaticTime)
|
||||
{
|
||||
Q_UNUSED(automaticTime)
|
||||
qCWarning(dcPlatform()) << "setAutomaticTime not implemented in platform plugin";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlatformSystemController::setTimeZone(const QTimeZone &timeZone)
|
||||
{
|
||||
Q_UNUSED(timeZone)
|
||||
qCWarning(dcPlatform()) << "setTimeZone not implemented in platform plugin";
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#define PLATFORMSYSTEMCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimeZone>
|
||||
|
||||
class PlatformSystemController : public QObject
|
||||
{
|
||||
|
|
@ -36,8 +37,19 @@ public:
|
|||
virtual bool reboot();
|
||||
virtual bool shutdown();
|
||||
|
||||
virtual bool timeManagementAvailable() const;
|
||||
virtual bool automaticTimeAvailable() const;
|
||||
virtual bool automaticTime() const;
|
||||
virtual bool setTime(const QDateTime &time);
|
||||
virtual bool setAutomaticTime(bool automaticTime);
|
||||
virtual bool setTimeZone(const QTimeZone &timeZone);
|
||||
|
||||
|
||||
signals:
|
||||
void availableChanged();
|
||||
void timeZoneManagementAvailableChanged();
|
||||
|
||||
void timeConfigurationChanged();
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(PlatformSystemController, "io.nymea.PlatformSystemController")
|
||||
|
|
|
|||
|
|
@ -407,7 +407,8 @@
|
|||
}
|
||||
},
|
||||
"Configuration.GetAvailableLanguages": {
|
||||
"description": "DEPRECATED - Use the locale property in the Handshake message instead - Returns a list of locale codes available for the server. i.e. en_US, de_AT",
|
||||
"deprecated": "Use the locale property in the Handshake message instead.",
|
||||
"description": "Returns a list of locale codes available for the server. i.e. en_US, de_AT",
|
||||
"params": {
|
||||
},
|
||||
"returns": {
|
||||
|
|
@ -422,12 +423,12 @@
|
|||
},
|
||||
"returns": {
|
||||
"basicConfiguration": {
|
||||
"d:language": "String",
|
||||
"d:serverTime": "Uint",
|
||||
"d:timeZone": "String",
|
||||
"debugServerEnabled": "Bool",
|
||||
"language": "String",
|
||||
"serverName": "String",
|
||||
"serverTime": "Uint",
|
||||
"serverUuid": "Uuid",
|
||||
"timeZone": "String"
|
||||
"serverUuid": "Uuid"
|
||||
},
|
||||
"cloud": {
|
||||
"enabled": "Bool"
|
||||
|
|
@ -464,6 +465,7 @@
|
|||
}
|
||||
},
|
||||
"Configuration.GetTimeZones": {
|
||||
"deprecated": "Use System.GetTimeZones instead.",
|
||||
"description": "Get the list of available timezones.",
|
||||
"params": {
|
||||
},
|
||||
|
|
@ -492,7 +494,8 @@
|
|||
}
|
||||
},
|
||||
"Configuration.SetLanguage": {
|
||||
"description": "DEPRECATED - Use the locale property in the Handshake message instead - Sets the server language to the given language. See also: \"GetAvailableLanguages\"",
|
||||
"deprecated": "Use the locale property in the Handshake message instead.",
|
||||
"description": "Sets the server language to the given language. See also: \"GetAvailableLanguages\"",
|
||||
"params": {
|
||||
"language": "String"
|
||||
},
|
||||
|
|
@ -537,6 +540,7 @@
|
|||
}
|
||||
},
|
||||
"Configuration.SetTimeZone": {
|
||||
"deprecated": "Use System.SetTimeZone instead.",
|
||||
"description": "Set the time zone of the server. See also: \"GetTimeZones\"",
|
||||
"params": {
|
||||
"timeZone": "String"
|
||||
|
|
@ -1314,11 +1318,12 @@
|
|||
}
|
||||
},
|
||||
"System.GetCapabilities": {
|
||||
"description": "Get the list of capabilites on this system. This allows reading whether things like rebooting or shutting down the system running nymea:core is supported on this host.",
|
||||
"description": "Get the list of capabilites on this system. The property \"powerManagement\" indicates whether rebooting or shutting down is supported on this system. The property \"updateManagement indicates whether system update features are available in this system. The property \"timeManagement\" indicates whether the system time can be configured on this system. Note that GetTime will be available in any case.",
|
||||
"params": {
|
||||
},
|
||||
"returns": {
|
||||
"powerManagement": "Bool",
|
||||
"timeManagement": "Bool",
|
||||
"updateManagement": "Bool"
|
||||
}
|
||||
},
|
||||
|
|
@ -1338,6 +1343,25 @@
|
|||
"repositories": "$ref:Repositories"
|
||||
}
|
||||
},
|
||||
"System.GetTime": {
|
||||
"description": "Get the system time and configuraton. The \"time\" and \"timeZone\" properties give the current server time and time zone. \"automaticTimeAvailable\" indicates whether this system supports automatically setting the clock (e.g. using NTP). \"automaticTime\" will be true if the system is configured to automatically update the clock.",
|
||||
"params": {
|
||||
},
|
||||
"returns": {
|
||||
"automaticTime": "Bool",
|
||||
"automaticTimeAvailable": "Bool",
|
||||
"time": "Uint",
|
||||
"timeZone": "String"
|
||||
}
|
||||
},
|
||||
"System.GetTimeZones": {
|
||||
"description": "Returns the list of IANA specified time zone IDs which can be used to select a time zone. It is not required to use this method if the client toolkit already provides means to obtain a list of IANA time zone ids.",
|
||||
"params": {
|
||||
},
|
||||
"returns": {
|
||||
"timeZones": "StringList"
|
||||
}
|
||||
},
|
||||
"System.GetUpdateStatus": {
|
||||
"description": "Get the current status of the update system. \"busy\" indicates that the system is current busy with an operation regarding updates. This does not necessarily mean an actual update is running. When this is true, update related functions on the client should be marked as busy and no interaction with update components shall be allowed. An example for such a state is when the system queries the server if there are updates available, typically after a call to CheckForUpdates. \"updateRunning\" on the other hand indicates an actual update process is ongoing. The user should be informed about it, the system also might restart at any point while an update is running.",
|
||||
"params": {
|
||||
|
|
@ -1377,6 +1401,17 @@
|
|||
"success": "Bool"
|
||||
}
|
||||
},
|
||||
"System.SetTime": {
|
||||
"description": "Set the system time configuraton. The system can be configured to update the time automatically by setting \"automaticTime\" to true. This will only work if the \"timeManagement\" capability is available on this system and \"GetTime\" indicates the availability of automatic time settings. If any of those requirements are not met, this method will return \"false\" in the \"success\" property. In order to manually configure the time, \"automaticTime\" should be set to false and \"time\" should be set. Note that if \"automaticTime\" is set to true and a manual \"time\" is still passed, the system will attempt to configure automatic time updates and only set the manual time if automatic mode fails. A time zone can always be passed optionally to change the system time zone and should be a IANA time zone id.",
|
||||
"params": {
|
||||
"o:automaticTime": "Bool",
|
||||
"o:time": "Uint",
|
||||
"o:timeZone": "String"
|
||||
},
|
||||
"returns": {
|
||||
"success": "Bool"
|
||||
}
|
||||
},
|
||||
"System.Shutdown": {
|
||||
"description": "Initiate a shutdown of the system. The return value will indicate whether the procedure has been initiated successfully.",
|
||||
"params": {
|
||||
|
|
@ -1433,12 +1468,12 @@
|
|||
"description": "Emitted whenever the basic configuration of this server changes.",
|
||||
"params": {
|
||||
"basicConfiguration": {
|
||||
"d:language": "String",
|
||||
"d:serverTime": "Uint",
|
||||
"d:timeZone": "String",
|
||||
"debugServerEnabled": "Bool",
|
||||
"language": "String",
|
||||
"serverName": "String",
|
||||
"serverTime": "Uint",
|
||||
"serverUuid": "Uuid",
|
||||
"timeZone": "String"
|
||||
"serverUuid": "Uuid"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1743,6 +1778,15 @@
|
|||
"repositoryId": "String"
|
||||
}
|
||||
},
|
||||
"System.TimeConfigurationChanged": {
|
||||
"description": "Emitted whenever the time configuration is changed",
|
||||
"params": {
|
||||
"automaticTime": "Bool",
|
||||
"automaticTimeAvailable": "Bool",
|
||||
"time": "Uint",
|
||||
"timeZone": "String"
|
||||
}
|
||||
},
|
||||
"System.UpdateStatusChanged": {
|
||||
"description": "Emitted whenever the update status changes.",
|
||||
"params": {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ protected slots:
|
|||
private slots:
|
||||
void getConfigurations();
|
||||
|
||||
void testTimeZones();
|
||||
void testServerName();
|
||||
void testLanguages();
|
||||
|
||||
|
|
@ -81,101 +80,6 @@ void TestConfigurations::getConfigurations()
|
|||
QVERIFY(configurations.contains("webSocketServerConfigurations"));
|
||||
}
|
||||
|
||||
void TestConfigurations::testTimeZones()
|
||||
{
|
||||
enableNotifications({"Configuration"});
|
||||
|
||||
QVariantMap params; QVariant response; QVariantMap configurations; QVariantList configurationChangedNotifications;
|
||||
|
||||
QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
|
||||
|
||||
QVariantList timeZones = injectAndWait("Configuration.GetTimeZones").toMap().value("params").toMap().value("timeZones").toList();
|
||||
QVERIFY(timeZones.count() > 0);
|
||||
QVERIFY(timeZones.contains("America/Toronto"));
|
||||
QVERIFY(timeZones.contains("Europe/Vienna"));
|
||||
QVERIFY(timeZones.contains("Africa/Dakar"));
|
||||
|
||||
// Get current configurations
|
||||
QVariantMap basicConfigurationMap = loadBasicConfiguration();
|
||||
|
||||
// Set timezone unchainged
|
||||
params.clear(); response.clear(); configurations.clear();
|
||||
params.insert("timeZone", basicConfigurationMap.value("timeZone").toString());
|
||||
response = injectAndWait("Configuration.SetTimeZone", params);
|
||||
verifyConfigurationError(response);
|
||||
|
||||
// Check notification not emitted
|
||||
notificationSpy.wait(200);
|
||||
configurationChangedNotifications = checkNotifications(notificationSpy, "Configuration.BasicConfigurationChanged");
|
||||
QVERIFY2(configurationChangedNotifications.count() == 0, "Got Configuration.BasicConfigurationChanged notification but should have not.");
|
||||
|
||||
// Set new timezone (Africa/Dakar)
|
||||
QString newTimeZone("Africa/Dakar");
|
||||
params.clear(); response.clear(); configurations.clear(); notificationSpy.clear();
|
||||
params.insert("timeZone", newTimeZone);
|
||||
response = injectAndWait("Configuration.SetTimeZone", params);
|
||||
verifyConfigurationError(response);
|
||||
|
||||
notificationSpy.wait(200);
|
||||
configurationChangedNotifications = checkNotifications(notificationSpy, "Configuration.BasicConfigurationChanged");
|
||||
QVERIFY2(configurationChangedNotifications.count() == 1, "Should get only one Configuration.BasicConfigurationChanged notification");
|
||||
QVariantMap notificationContent = configurationChangedNotifications.first().toMap().value("params").toMap();
|
||||
|
||||
qDebug() << notificationContent;
|
||||
|
||||
QVERIFY2(notificationContent.contains("basicConfiguration"), "Notification does not contain basicConfiguration");
|
||||
QVariantMap basicConfigurationNotificationMap = notificationContent.value("basicConfiguration").toMap();
|
||||
QVERIFY2(basicConfigurationNotificationMap.contains("language"), "Notification does not contain key language");
|
||||
QVERIFY2(basicConfigurationNotificationMap.contains("serverName"), "Notification does not contain key serverName");
|
||||
QVERIFY2(basicConfigurationNotificationMap.contains("serverTime"), "Notification does not contain key serverTime");
|
||||
QVERIFY2(basicConfigurationNotificationMap.contains("serverUuid"), "Notification does not contain key serverUuid");
|
||||
QVERIFY2(basicConfigurationNotificationMap.contains("debugServerEnabled"), "Notification does not contain key debugServerEnabled");
|
||||
QVERIFY2(basicConfigurationNotificationMap.contains("timeZone"), "Notification does not contain key timeZone");
|
||||
QVERIFY2(basicConfigurationNotificationMap.value("timeZone").toString() == newTimeZone, "Notification does not contain the new timeZone");
|
||||
|
||||
// Get current timezone and time
|
||||
params.clear(); response.clear(); configurations.clear();
|
||||
configurations = injectAndWait("Configuration.GetConfigurations").toMap().value("params").toMap();
|
||||
QString currentTimeZone = configurations.value("basicConfiguration").toMap().value("timeZone").toString();
|
||||
int currentTime = configurations.value("basicConfiguration").toMap().value("serverTime").toInt();
|
||||
qDebug() << currentTimeZone << QDateTime::fromTime_t(currentTime);
|
||||
|
||||
// Set new timezone
|
||||
params.clear(); response.clear(); configurations.clear();
|
||||
params.insert("timeZone", "Moon/Darkside");
|
||||
response = injectAndWait("Configuration.SetTimeZone", params);
|
||||
verifyConfigurationError(response, NymeaConfiguration::ConfigurationErrorInvalidTimeZone);
|
||||
|
||||
// Set new timezone
|
||||
params.clear(); response.clear(); configurations.clear();
|
||||
params.insert("timeZone", "America/Toronto");
|
||||
response = injectAndWait("Configuration.SetTimeZone", params);
|
||||
verifyConfigurationError(response);
|
||||
|
||||
// Check new timezone
|
||||
params.clear(); response.clear(); configurations.clear();
|
||||
configurations = injectAndWait("Configuration.GetConfigurations").toMap().value("params").toMap();
|
||||
newTimeZone = configurations.value("basicConfiguration").toMap().value("timeZone").toString();
|
||||
int newTime = configurations.value("basicConfiguration").toMap().value("serverTime").toInt();
|
||||
qDebug() << newTimeZone << QDateTime::fromTime_t(newTime);
|
||||
QVERIFY(currentTimeZone != newTimeZone);
|
||||
|
||||
restartServer();
|
||||
|
||||
// Check loaded timezone
|
||||
configurations = injectAndWait("Configuration.GetConfigurations").toMap().value("params").toMap();
|
||||
QString reloadedTimeZone = configurations.value("basicConfiguration").toMap().value("timeZone").toString();
|
||||
QVERIFY(newTimeZone == reloadedTimeZone);
|
||||
|
||||
// Reset the timezone
|
||||
params.clear(); response.clear();
|
||||
params.insert("timeZone", "Europe/Vienna");
|
||||
response = injectAndWait("Configuration.SetTimeZone", params);
|
||||
verifyConfigurationError(response);
|
||||
|
||||
disableNotifications();
|
||||
}
|
||||
|
||||
void TestConfigurations::testServerName()
|
||||
{
|
||||
enableNotifications({"Configuration"});
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
#include "nymeacore.h"
|
||||
#include "servers/mocktcpserver.h"
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "platform/platformsystemcontroller.h"
|
||||
|
||||
using namespace nymeaserver;
|
||||
|
||||
class TestTimeManager: public NymeaTestBase
|
||||
|
|
@ -37,9 +40,6 @@ private:
|
|||
private slots:
|
||||
void initTestCase();
|
||||
|
||||
void changeTimeZone_data();
|
||||
void changeTimeZone();
|
||||
|
||||
void loadSaveTimeDescriptor_data();
|
||||
void loadSaveTimeDescriptor();
|
||||
|
||||
|
|
@ -142,41 +142,6 @@ void TestTimeManager::initTestCase()
|
|||
"TimeManager.debug=true");
|
||||
}
|
||||
|
||||
void TestTimeManager::changeTimeZone_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("timeZoneId");
|
||||
QTest::addColumn<bool>("valid");
|
||||
|
||||
QTest::newRow("valid timezone: Asia/Tokyo") << QByteArray("Asia/Tokyo") << true;
|
||||
QTest::newRow("valid timezone: America/Lima") << QByteArray("America/Lima") << true;
|
||||
QTest::newRow("valid timezone: Africa/Harare") << QByteArray("Africa/Harare") << true;
|
||||
QTest::newRow("invalid timezone: Mars/Diacria") << QByteArray("Mars/Diacria") << false;
|
||||
QTest::newRow("invalid timezone: Moon/Kepler") << QByteArray("Moon/Kepler") << false;
|
||||
}
|
||||
|
||||
void TestTimeManager::changeTimeZone()
|
||||
{
|
||||
QFETCH(QByteArray, timeZoneId);
|
||||
QFETCH(bool, valid);
|
||||
|
||||
QTimeZone currentTimeZone(NymeaCore::instance()->timeManager()->timeZone());
|
||||
QTimeZone newTimeZone(timeZoneId);
|
||||
|
||||
|
||||
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
||||
|
||||
NymeaCore::instance()->timeManager()->setTimeZone(timeZoneId);
|
||||
|
||||
QDateTime newDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
||||
|
||||
int offsetOriginal = currentTimeZone.offsetFromUtc(currentDateTime);
|
||||
int offsetNew = newTimeZone.offsetFromUtc(newDateTime);
|
||||
|
||||
if (valid)
|
||||
QVERIFY(offsetOriginal != offsetNew);
|
||||
|
||||
}
|
||||
|
||||
void TestTimeManager::loadSaveTimeDescriptor_data()
|
||||
{
|
||||
// Repeating options
|
||||
|
|
@ -2056,8 +2021,7 @@ void TestTimeManager::initTimeManager()
|
|||
removeAllRules();
|
||||
enableNotifications({"Rules", "Devices", "Events"});
|
||||
NymeaCore::instance()->timeManager()->stopTimer();
|
||||
qDebug() << NymeaCore::instance()->timeManager()->currentTime().toString();
|
||||
qDebug() << NymeaCore::instance()->timeManager()->currentDate().toString();
|
||||
qDebug() << NymeaCore::instance()->timeManager()->currentDateTime().toString();
|
||||
}
|
||||
|
||||
void TestTimeManager::verifyRuleExecuted(const ActionTypeId &actionTypeId)
|
||||
|
|
@ -2207,7 +2171,9 @@ void TestTimeManager::triggerMockEvent1()
|
|||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
|
||||
eventSpy.wait(200);
|
||||
if (eventSpy.isEmpty()) {
|
||||
eventSpy.wait();
|
||||
}
|
||||
QVariantList eventTriggerVariants = checkNotifications(eventSpy, "Events.EventTriggered");
|
||||
QVERIFY2(eventTriggerVariants.count() == 1, "Did not get Events.EventTriggered notification.");
|
||||
QVERIFY2(eventTriggerVariants.first().toMap().value("params").toMap().contains("event"), "Notification Events.EventTriggered does not contain event.");
|
||||
|
|
|
|||
Loading…
Reference in New Issue