/*! * * Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * \file VDateTime.cpp * \author (last) Vy * \date (last) 16-Aug-2023 * \author (original) Behrouz NematiPour * \date (original) 16-Apr-2021 * */ #include "VDateTime.h" // Qt #include // Project #include "GuiController.h" #include "ApplicationController.h" using namespace View; VIEW_DEF_CLASS(VDateTime) void VDateTime::initConnections() { startTimer(_timerInterval); ACTION_VIEW_CONNECTION(AdjustHDDateTimeResponseData); ACTION_VIEW_CONNECTION(AdjustDGDateTimeResponseData); ACTION_VIEW_CONNECTION(HDRTCEpochData); ADJUST_VIEW_CONNECTION( AdjustHDDateTimeRequestData); ADJUST_VIEW_CONNECTION( AdjustDGDateTimeRequestData); connect(&_process, SIGNAL( finished(int)), this, SLOT(onSetDateUIFinished(int))); connect(&_process, SIGNAL( errorOccurred(QProcess::ProcessError)), this, SLOT(onSetDateUIErrored(QProcess::ProcessError))); } /*! * \brief VDateTime::onSetDateUIErrored * The slot for when the set datetime script errors, log the error */ void VDateTime::onSetDateUIErrored(QProcess::ProcessError error){ QString mScript = Storage::Scripts_Path_Name(); mScript += Storage::Date_Time_Set_Sh; QString errorString = QString("%1 errored. Error %2").arg(mScript).arg(error); LOG_DEBUG(errorString); status(errorString); } /*! * \brief VDateTime::doCurrentTime * Reads and displays the current date and time */ void VDateTime::doInit() { _acceptHD = NOT_SET; _acceptDG = NOT_SET; _acceptUI = NOT_SET; QDateTime _currentTime = QDateTime::currentDateTime(); hour (_currentTime.toString("HH" )); minute(_currentTime.toString("mm" )); second(_currentTime.toString("ss" )); day (_currentTime.toString("dd" )); month (_currentTime.toString("MM" )); year (_currentTime.toString("yyyy" )); timeFormat (_Settings.timeFormat()); dateFormat (_Settings.dateFormat()); timezone(QTimeZone::systemTimeZone().abbreviation(_currentTime)); status(""); } /*! * \brief doConfirm * \details Issues request to save the current date and time to UI, HD and DG */ void VDateTime::doConfirm( const QString &vYear , const QString &vMonth , const QString &vDay , const QString &vHour , const QString &vMinute , const bool &vNTP ) { year ( vYear ); month ( vMonth ); day ( vDay ); hour ( vHour ); minute ( vMinute ); ntp ( vNTP ); const QDateTime currentDateTimeLocal ( QDate(_year .toInt() , _month .toInt() , _day .toInt()) , QTime(_hour .toInt() , _minute .toInt())); const QString dateTimeLocalStr = currentDateTimeLocal.toString(_updateFormat); // sudo date -s requires this format // Get the current UTC datetime const QDateTime currentDateTimeUTC = currentDateTimeLocal.toUTC(); const quint32 epochUTC_sec = currentDateTimeUTC.toSecsSinceEpoch(); LOG_DEBUG(tr("SetDateTime %1").arg(dateTimeLocalStr)); status("Setting date and time ..."); dateTimeUI(dateTimeLocalStr, vNTP ); dateTimeHD(epochUTC_sec ); // ??? TODO dateTimeDG(epochUTC_sec ); // ??? TODO } /*! * \brief VDateTime::onFinishedSetDateUI * Called when the process that sets the UI date and time has finished. * \param vExitCode - (int) the exit code of the process */ void VDateTime::onSetDateUIFinished(const int &vExitCode) { if ( vExitCode ) { _acceptUI = FAILED; LOG_DEBUG(QString("SetDataTime[%1]").arg(vExitCode)); } else { _acceptUI = SUCCEED; LOG_DEBUG("SetDateTime Succeed"); } updateStatus(); } /*! * \brief VDateTime::onActionReceive * Called when we receive a response back from the HD after requesting to * set the epoch * \param vData (AdjustHDDateTimeResponseData) - the response data */ void VDateTime::onActionReceive(const AdjustHDDateTimeResponseData &vData) { _acceptHD = vData.mAccepted ? SUCCEED : FAILED; _reasonHD = vData.mReason ; updateStatus(); } /*! * \brief VDateTime::onActionReceive * Called when we receive a response back from the DG after requesting to * set the epoch * \param vResponse (AdjustDGDateTimeResponseData) - the response */ void VDateTime::onActionReceive(const AdjustDGDateTimeResponseData &vData) { _acceptDG = vData.mAccepted ? SUCCEED : FAILED; _reasonDG = vData.mReason ; updateStatus(); } /*! * \brief VDateTime::dateTimeHD * \details Requests HD to set the date/time * \param epoch - the epoch parameter which FW understands to set date/time */ void VDateTime::dateTimeHD(quint32 epoch) { AdjustHDDateTimeRequestData data; data.mEpoch = epoch; emit didAdjustment(data); } /*! * \brief VDateTime::dateTimeDG * \details Requests DG to set the date/time * \param epoch - the epoch parameter which FW understands to set date/time */ void VDateTime::dateTimeDG(quint32 epoch) { AdjustDGDateTimeRequestData data; data.mEpoch = epoch; emit didAdjustment(data); } /*! * \brief VDateTime::dateTimeUI * \details starts the shell script in a process defined in Storage::Date_Time_Set_Sh to update the device date/time */ void VDateTime::dateTimeUI(const QString &vDateTime, const bool &vNTP) { if ( _process.state() != QProcess::NotRunning ) { return; } QString mScript = Storage::Scripts_Path_Name(); mScript += Storage::Date_Time_Set_Sh; QStringList arguments; arguments << vDateTime << (vNTP ? "true" : "false"); _process.start(mScript, arguments); } /*! * \brief VDateTime::status * \details Returns the appropriate string for the date/time adjustment status * \param vStatus - the status of the adjustment * \param vReason - the reason if the adjustment has been rejected. * \return the status string */ QString VDateTime::status(VDateTime::DateTimeSetStatus vStatus, quint8 vReason) { QString mNotSet = tr("Not Set"); QString mSucceed = tr("Succeed"); QString mFailed = tr("Failed" ) + " [%1]"; switch (vStatus) { case SUCCEED: return mSucceed; case FAILED: return mFailed.arg(vReason); default: return mNotSet; } } /*! * \brief VDateTime::updateStatus * Update the notification bar's status */ void VDateTime::updateStatus() { status(QString("HD: %1, DG: %2, UI: %3") .arg(status(_acceptHD, _reasonHD)) .arg(status(_acceptDG, _reasonDG)) .arg(status(_acceptUI, _reasonUI)) ); } /*! * \brief VDateTime::greeting * \details sets the greeting property string to be used on the standby/home screen regarding the device's current time of the day. * \param vMilitaryTime */ void VDateTime::greeting(quint16 vMilitaryTime) { if ( eMorningMin /* 05:00 AM */ <= vMilitaryTime && vMilitaryTime < eMorningMax /* 12:00 PM */ ) { greeting(tr("Good Morning!" )); return; } if ( eAfternoonMin /* 12:00 PM */ <= vMilitaryTime && vMilitaryTime < eAfternoonMax /* 18:00 PM */ ) { greeting(tr("Good Afternoon!")); return; } /* 18:00 PM */ /* 05:00 AM */ greeting(tr("Good Evening!" )); } /*! * \brief VDateTime::timerEvent * \details The overloaded member function of the QObject to send the current date/time to the UI. * \note The interval has been set in _timerInterval as 1000 ms (1sec). */ void VDateTime::timerEvent(QTimerEvent *) { _currentDateTime = QDateTime::currentDateTime(); time (_currentDateTime.toString(_Settings.timeFormat())); date (_currentDateTime.toString(_Settings.dateFormat())); current (_currentDateTime.toString(_Settings.getDatetimeFormat())); timezone(QTimeZone::systemTimeZone().abbreviation(_currentDateTime)); quint16 military = _currentDateTime.time().hour() * 100 + _currentDateTime.time().minute(); greeting(military); } /*! * * \brief VHDPOSTData::onActionReceive * \details received response model data handler * \param vData - model data */ void VDateTime::onActionReceive(const HDRTCEpochData &vData) { // Doing a single update of the HD-UI RTC sync on start-up static bool _hasDoneHDSyncRTC = false; if ( !_hasDoneHDSyncRTC ) { QDateTime hdRTCTime_localZone; // Default timespec is Qt::localTime / local time zoned hdRTCTime_localZone.setSecsSinceEpoch(vData.mEpoch); const QString newDateTimeString = hdRTCTime_localZone.toString(_Settings.getDatetimeFormat()); dateTimeUI(newDateTimeString, false); _hasDoneHDSyncRTC = true; // indicate HD-UI RTC sync'd //DEBUG: qDebug() << "Sync HD->UI RTC | HD Epoch: " << vData.mEpoch << " | HD datetime (local zone): " << hdRTCTime_localZone.toString(_Settings.getDatetimeFormat()) <<" | local datetime : " << newDateTimeString; } }