Add system api to configure the system time

This gets rid of the locally kept time zone which caused issues
in plugins and the ScriptEngine.
This commit is contained in:
Michael Zanetti 2019-12-10 23:40:51 +01:00
parent 6cdcd47f9b
commit 9b07216768
12 changed files with 230 additions and 151 deletions

View File

@ -1026,12 +1026,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()) {

View File

@ -114,9 +114,6 @@ public:
signals:
void loaded();
public slots:
void timeTick();
private slots:
void loadPlugins();
void loadPlugin(DevicePlugin *pluginIface, const PluginMetadata &metaData);

View File

@ -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 &params) 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 &params) 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;

View File

@ -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);

View File

@ -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 the system running nymea:core is supported on this host. The property "
"\"updateManagement indicates whether system update features are available in this API. 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 \"serverTime\" and \"serverTimezone\" 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 settngs. 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 of 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().toSecsSinceEpoch());
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 &params)
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 &params) const
return createReply(returns);
}
JsonReply *SystemHandler::GetTime(const QVariantMap &params) 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().toSecsSinceEpoch());
returns.insert("timeZone", QTimeZone::systemTimeZoneId());
return createReply(returns);
}
JsonReply *SystemHandler::SetTime(const QVariantMap &params) 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::fromSecsSinceEpoch(params.value("time").toUInt());
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 &params) 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;

View File

@ -53,8 +53,13 @@ public:
Q_INVOKABLE JsonReply *GetRepositories(const QVariantMap &params) const;
Q_INVOKABLE JsonReply *EnableRepository(const QVariantMap &params) const;
Q_INVOKABLE JsonReply *GetTime(const QVariantMap &params) const;
Q_INVOKABLE JsonReply *SetTime(const QVariantMap &params) const;
Q_INVOKABLE JsonReply *GetTimeZones(const QVariantMap &params) const;
signals:
void CapabilitiesChanged(const QVariantMap &params);
void UpdateStatusChanged(const QVariantMap &params);
void PackageAdded(const QVariantMap &params);
void PackageChanged(const QVariantMap &params);
@ -63,6 +68,8 @@ signals:
void RepositoryChanged(const QVariantMap &params);
void RepositoryRemoved(const QVariantMap &params);
void TimeConfigurationChanged(const QVariantMap &params);
private slots:
void onCapabilitiesChanged();

View File

@ -98,6 +98,7 @@
#include "tagging/tagsstorage.h"
#include "platform/platform.h"
#include "experiences/experiencemanager.h"
#include "platform/platformsystemcontroller.h"
#include "devices/devicemanagerimplementation.h"
#include "devices/device.h"
@ -140,7 +141,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);
@ -199,7 +207,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);
}

View File

@ -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));
}
}

View File

@ -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;
};
}

View File

@ -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;
}

View File

@ -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")

View File

@ -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)