Results 1 to 12 of 12

Thread: Suggestions on how to make an alarmclock-like function

  1. #1
    Join Date
    Mar 2010
    Posts
    77
    Thanks
    17
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Suggestions on how to make an alarmclock-like function

    Hi!
    I'd like some suggestions from more experienced programmers on how to do this the right way. Let me first make clear that I could do this on my own but I'd like the opinions of others to choose more specifically how to go about it.

    What I need is for a program that is running on a server to write a report and send out by email upon a number of preset clock strikes scattered throughout the day at uneven intervals.

    This might seem like a mundane enough task but I have yet to find a solution that doesn't feel awkward.

    My current solution is a QList<QTimers> with timers that are initialized in the ctor of the program and are singleshot-started but it's rather bulky code and when the timeout-signal is shot the calling timer should simply be set to 24 hours (triggering the same time the day after) and then all is up'n'running but it feel like I'm overlooking some simpler solution?

    It feels like a rather common behavior and I've gotten so used to the convenience of the Qt framework I'm actually half expecting there to be a QAlarmClock where I can just pass a QList of QTime's or QTimeDate's and, presto! =)

    Any takers?
    Thanks
    /Tottish

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Suggestions on how to make an alarmclock-like function

    You mean you wish to have something that will notify you at given time?
    This should work:
    Qt Code:
    1. class AlarmClock : public QObject {
    2. public:
    3. AlarmClock(QObject *parent = 0) : QObject(parent), m_timer(0) {}
    4. public slots:
    5. void start() {
    6. if(m_timer!=0) return;
    7. m_timer = startTimer(1000); // 1s resolution
    8. }
    9. void stop() {
    10. if(m_timer==0) return;
    11. killTimer(m_timer);
    12. m_timer = 0;
    13. }
    14. void addAlarm(const QDateTime &dt) {
    15. QList<QDateTimer>::iterator iter = qLowerBound(m_alarms.begin(), m_alarms.end, dt);
    16. if(*iter != dt) m_alarms.insert(iter, dt);
    17. }
    18. signals:
    19. void alarm(const QDateTime &dt);
    20. protected:
    21. void timerEvent(QTimerEvent *ev) {
    22. if(ev->timerId()!=m_timer) { QObject::timerEvent(ev); return; }
    23. QDateTime current = QDateTime::currentDateTime();
    24. while(m_alarms.first()<=current) {
    25. emit alarm(m_alarms.first());
    26. m_alarms.removeFirst();
    27. }
    28. }
    29. private:
    30. QList<QDateTime> m_alarms;
    31. int m_timer;
    32. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. AlarmClock *alarms = new AlarmClock(this);
    2. alarms->addAlarm(QDateTime(QDate::currentDate(), QTime(10, 46, 53)));
    3. alarms->start();
    4. alarms->addAlarm(QDateTime(QDate::currentDate().addDays(1), QTime(9, 12, 00)));
    5. connect(alarms, SIGNAL(alarm(QDateTime)), ..., ...);
    To copy to clipboard, switch view to plain text mode 
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. The following user says thank you to wysota for this useful post:

    Tottish (6th March 2011)

  4. #3
    Join Date
    Mar 2010
    Posts
    77
    Thanks
    17
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Suggestions on how to make an alarmclock-like function

    Yeah, that looks like it should do it! It seems like it is working with daytimes rather than times which I would prefer since the alarms should be at the same time every day of the week. But hopefully it's just a minor tweak. =)
    I'll look into the code to get a deeper understanding on what it really does tomorrow or maybe the day after that since I've got my hands full of other stuff right now.

    Again; A very big 'Thank You', wysota!

    Cheers!
    /Tottish

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Suggestions on how to make an alarmclock-like function

    The problem with using only QTime is that if you have an alarm set to, say... 14:56 and the check is done at 14:57 then you don't know whether the 14:56 alarm was already triggered or not (in other words is it "today's" 14:56 or "tomorrow's"). Consistency demands that when you "miss" an alarm, you should fire it as soon as possible to "catch up" with the schedule. This situation can happen in practise when system is suspended, under heavy load, during synchronization with an NTP server or during change of timezone when daylight saving happens (then the same event might fire twice). You can easily have an off-by-one miss, especially that timerEvent() is triggered at approximately 1000ms and not exactly 1000ms (so it can fire at 14:55:59.999 and then at 14:56:01.001 completely skipping the 14:56:00 second). It is much better to schedule a new alarm at the end of handling the previous one. Then you can decide "on the fly" when the next alarm should occur.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #5
    Join Date
    Mar 2010
    Posts
    77
    Thanks
    17
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Suggestions on how to make an alarmclock-like function

    OK, I am actually having kind of the same problem right now for my temporary function. This is a really dirty one but a QTimer in the program is actually firing a signal every second for updating purposes so, in the connected slot, I'm just comparing QTime::CurrentTime with a bunch of preset values and send a report ("alarm") if the comparison is true.
    It actually misses quite a lot of reports which, as you are pointing out wysota, is to be expected because the program does a whole bunch of stuff other than setting the QTimer to 1000.

    Point taken. I'll set the timers on the fly.

    Thanks again!
    /Tottish

  7. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Suggestions on how to make an alarmclock-like function

    According to some signal-processing laws you could set the timer to 500ms to have a properly working 1000ms clock. Of course this wouldn't help in situations when intermediate processing takes longer than 500ms or when the system clock is changed by outside source (suspension, ntp, daylight saving, manual user intervention). I think my solution is more foul-proof.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #7
    Join Date
    Mar 2010
    Posts
    77
    Thanks
    17
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Suggestions on how to make an alarmclock-like function

    I think you're right, it sounds more convenient too. I'm back at the computer now so I'll get right on it!
    Cheers!
    /Tottish

  9. #8
    Join Date
    Mar 2010
    Posts
    77
    Thanks
    17
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Suggestions on how to make an alarmclock-like function

    So after some time I got it to work.

    I spent quite a bit of time trying to get the iterator in addAlarm to cooperate but I never quite got the hang of it so I did it in a way that seemed more familiar to me. Please let me know if my way is less suitable or if I misunderstood the purpose of the iterator.

    I also spent some time scratching my head before I realized why the program crashed if the alarm list goes empty. But it seems that that's what happens if one tries to read from list.first in an empty list so I built in protection for that too. Other than that it's pretty much the same as what wysota posted above.

    Should anyone else be building an alarm clock or timer of some sort, here is my version (I'm not guaranteeing anything but it seems pretty stable):
    Qt Code:
    1. #ifndef REPORTTIMER_H
    2. #define REPORTTIMER_H
    3.  
    4. #include <QtCore>
    5.  
    6. class ReportTimer : public QObject {
    7. Q_OBJECT
    8.  
    9. public:
    10. ReportTimer(QObject *parent = 0) : QObject(parent), m_timer(0) {}
    11. public slots:
    12. void start() {
    13. if(m_timer!=0) return;
    14. m_timer = startTimer(4000); // 4s resolution
    15. }
    16.  
    17. void stop() {
    18. if(m_timer==0) return;
    19. killTimer(m_timer);
    20. m_timer = 0;
    21. }
    22.  
    23. void addAlarm(const QDateTime &dt) {
    24. qDebug() << "in";
    25. if (m_alarms.indexOf(dt) != -1) return; //if already in list, return
    26. else {m_alarms.append(dt); qSort(m_alarms);}
    27. }
    28.  
    29. signals:
    30. void alarm(const QDateTime &dt);
    31.  
    32. protected:
    33. void timerEvent(QTimerEvent *ev) { qDebug() << "Fired" << m_alarms;
    34. if(ev->timerId()!=m_timer) { QObject::timerEvent(ev); return; }
    35. QDateTime current = QDateTime::currentDateTime();
    36. while(m_alarms.isEmpty() == false && m_alarms.first() <= current) {
    37. emit alarm(m_alarms.first());
    38. m_alarms.removeFirst();
    39. }
    40. }
    41.  
    42.  
    43. private:
    44. QList<QDateTime> m_alarms;
    45. int m_timer;
    46. };
    47.  
    48. #endif // REPORTTIMER_H
    To copy to clipboard, switch view to plain text mode 

    Cheers!
    /Tottish

  10. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Suggestions on how to make an alarmclock-like function

    I don't get why you replaced what I had with your line #26. It's suboptimal. The code just had two typos After correcting them it compiles and works fine. Here is the corrected code:
    Qt Code:
    1. #include <QtGui>
    2. #include <QObject>
    3.  
    4. class AlarmClock : public QObject {
    5. Q_OBJECT
    6. public:
    7. AlarmClock(QObject *parent = 0) : QObject(parent), m_timer(0) {}
    8. public slots:
    9. void start(int ms = 1000) {
    10. if(m_timer!=0) return;
    11. m_timer = startTimer(ms); // 1s resolution
    12. }
    13. void stop() {
    14. if(m_timer==0) return;
    15. killTimer(m_timer);
    16. m_timer = 0;
    17. }
    18. void addAlarm(const QDateTime &dt) {
    19. QList<QDateTime>::iterator iter = qLowerBound(m_alarms.begin(), m_alarms.end(), dt);
    20. if(iter==m_alarms.end() || *iter != dt) m_alarms.insert(iter, dt);
    21. }
    22. signals:
    23. void alarm(const QDateTime &dt);
    24. protected:
    25. void timerEvent(QTimerEvent *ev) {
    26. if(ev->timerId()!=m_timer) { QObject::timerEvent(ev); return; }
    27. QDateTime current = QDateTime::currentDateTime();
    28. while(!m_alarms.isEmpty() && m_alarms.first()<=current) {
    29. emit alarm(m_alarms.first());
    30. m_alarms.removeFirst();
    31. }
    32. }
    33. private:
    34. QList<QDateTime> m_alarms;
    35. int m_timer;
    36. };
    37.  
    38. class Dummy : public QObject {
    39. Q_OBJECT
    40. public slots:
    41. void onAlarm(const QDateTime &dt) {
    42. qDebug() << dt;
    43. }
    44. };
    45.  
    46. #include "main.moc"
    47.  
    48. int main(int argc, char **argv){
    49. QApplication app(argc, argv);
    50. AlarmClock alarms;
    51. Dummy d;
    52. d.connect(&alarms, SIGNAL(alarm(QDateTime)), &d, SLOT(onAlarm(QDateTime)));
    53. alarms.addAlarm(QDateTime(QDate::currentDate(), QTime::currentTime().addSecs(2)));
    54. alarms.addAlarm(QDateTime(QDate::currentDate(), QTime::currentTime().addSecs(6)));
    55. alarms.addAlarm(QDateTime(QDate::currentDate(), QTime::currentTime().addSecs(14)));
    56. alarms.addAlarm(QDateTime(QDate::currentDate(), QTime::currentTime().addSecs(10)));
    57. alarms.start();
    58. return app.exec();
    59. }
    To copy to clipboard, switch view to plain text mode 
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. The following user says thank you to wysota for this useful post:

    Tottish (9th March 2011)

  12. #10
    Join Date
    Mar 2010
    Posts
    77
    Thanks
    17
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Suggestions on how to make an alarmclock-like function

    Well, as I said, I changed it to a syntax that I felt more familiar with since I couldn't get the iterator to work/finding and correcting the "typo" =).
    "Suboptimal", I'm assuming you mean that the functionality/behavior is the same but your iterator way is faster? I'll take your word for it. *Changing code*
    In any case it was nice to find a solution on my own. Suboptimal as it may be. =)
    Thanks wysota!
    Have an awesome day!
    /Tottish

  13. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Suggestions on how to make an alarmclock-like function

    The difference is you are resorting the list when adding a new element while in fact the list is already sorted with exception of one element. My solution just looks for the proper place to insert the element in an already sorted array so it's faster. The use of iterators is irrelevant here, they are there only because there is no qLowerBound() version that returns an index.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  14. #12
    Join Date
    Mar 2010
    Posts
    77
    Thanks
    17
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Suggestions on how to make an alarmclock-like function

    OK, I see. Thank you for the clarification!
    /Tottish

Similar Threads

  1. Replies: 1
    Last Post: 15th December 2010, 13:20
  2. Replies: 6
    Last Post: 24th June 2009, 14:27
  3. Replies: 1
    Last Post: 12th January 2009, 18:05
  4. Design suggestions
    By vermarajeev in forum Qt Programming
    Replies: 1
    Last Post: 15th December 2006, 09:22
  5. Log browser suggestions?
    By NRGizeR in forum Qt Programming
    Replies: 3
    Last Post: 14th July 2006, 09:20

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.