X-Git-Url: https://git.toastfreeware.priv.at/gregoa/zavai.git/blobdiff_plain/12bed76dbed3c7c86193d1ec99cede84e801db93..a7d1a285763bffe81b29c854b905d8ca83e9a2bd:/src/clock.vala?ds=sidebyside diff --git a/src/clock.vala b/src/clock.vala index 394ff29..bcd25e7 100644 --- a/src/clock.vala +++ b/src/clock.vala @@ -25,186 +25,228 @@ namespace clock { public enum SourceType { - SYSTEM, - GPS + SYSTEM, + GPS } +/* +TODO: schedule alarms via at + +Uses the 'z' queue. + +atq -q z can be used to list the jobs (for example, at startup, or after a job has run) +at -c id can be used to query a job, parsing its contents (which can have + comments or variables being set) +zavai --notify ... can be used to notify the job (and start zavai if it's not running) + +Alarm needs to be able to serialize itself to an at invocation and to +deserialize itself from the output of at -c + +Alarm needs to deserialize also a job with no special markers whatsoever: a +generic at job. + + + +refresh_alarms() +{ + oldtime = next_alarm ? next_alarm.time : 0 + next_alarm = the first alarm from atq + if (oldtime != next_alarm.time) + { + remove existing triggers + (triggers can be skipped if we don't need to support non-zavai alarms) + schedule a trigger calling refresh_alarms() at next_alarm.time + 30 seconds + (triggers can be skipped if we don't need to support non-zavai alarms) + } +} + +at clock constructor: refresh_alarms() +inotifywait -e close /usr/bin/at -> refresh_alarms() (shows when someone has just used at) + (can be skipped if we don't need to support non-zavai alarms) +at alarm triggered through zavai: refresh_alarms() + + +*/ + + public class Alarm : Object { - public signal void trigger(); + // Notify of an alarm being triggered + //public static signal void trigger(string label); - public time_t deadline; - public string label; + // Schedule with at + public static void schedule(time_t deadline, string label); - public Alarm(time_t deadline, string label) - { - this.deadline = deadline; - this.label = label; - } + // Get the label of the job with the given at ID + public static string getLabel(int atID); } private int alarm_compare(void* a, void* b) { - return (int)(((Alarm*)a)->deadline - ((Alarm*)b)->deadline); + return (int)(((Alarm*)a)->deadline - ((Alarm*)b)->deadline); } [DBus (name = "org.freesmartphone.Notification")] public class AlarmNotification : Object { - public void Alarm () { - clock.check_alarms(); - } + public void Alarm () { + clock.check_alarms(); + } } public class Clock: zavai.Service { - protected time_t last_gps_time; - protected time_t last_gps_time_system_time; - protected time_t last_system_time; + protected time_t last_gps_time; + protected time_t last_gps_time_system_time; + protected time_t last_system_time; protected dynamic DBus.Object gps_time; - protected uint system_time_timeout; - protected time_t last_minute; - protected time_t chosen_time; - protected SourceType chosen_type; - protected AlarmNotification listener; + protected uint system_time_timeout; + protected time_t last_minute; + protected time_t chosen_time; + protected SourceType chosen_type; + protected AlarmNotification listener; protected dynamic DBus.Object otimed_alarm; - protected dynamic DBus.Object notification; - protected SList alarms; + protected dynamic DBus.Object rtc; + protected SList alarms; - // Ticks once a minute - public signal void minute_changed(long time, SourceType source); - public signal void schedule_changed(); + // Ticks once a minute + public signal void minute_changed(long time, SourceType source); + public signal void schedule_changed(); public Clock() { - name = "clock"; - alarms = null; - listener = new AlarmNotification(); - last_minute = 0; - last_gps_time = 0; - last_gps_time_system_time = 0; - last_system_time = time_t(); - chosen_time = last_system_time; - + Object(name: "clock"); + alarms = null; + listener = new AlarmNotification(); + last_minute = 0; + last_gps_time = 0; + last_gps_time_system_time = 0; + last_system_time = time_t(); + chosen_time = last_system_time; + gps_time = zavai.registry.sbus.get_object( - "org.freesmartphone.ogpsd", - "/org/freedesktop/Gypsy", - "org.freedesktop.Gypsy.Time"); - - // FSO alarm system - otimed_alarm = zavai.registry.sbus.get_object( - "org.freesmartphone.otimed", - "/org/freesmartphone/Time/Alarm", - "org.freesmartphone.Time.Alarm"); - if (otimed_alarm == null) - zavai.log.error("ALARM IS NULL"); - - zavai.registry.sbus.register_object("/", listener); - - //notification = zavai.registry.sbus.get_object( - // "org.freesmartphone", - // "org/freesmartphone/Notification", - // "org.freesmartphone.Notification"); - //notification.Alarm += on_alarm; + "org.freesmartphone.ogpsd", + "/org/freedesktop/Gypsy", + "org.freedesktop.Gypsy.Time"); + + // FSO alarm system + otimed_alarm = zavai.registry.sbus.get_object( + "org.freesmartphone.otimed", + "/org/freesmartphone/Time/Alarm", + "org.freesmartphone.Time.Alarm"); + + rtc = zavai.registry.sbus.get_object( + "org.freesmartphone.odeviced", + "/org/freesmartphone/Device/RTC/0", + "org.freesmartphone.Device.RealtimeClock"); + + zavai.registry.sbus.register_object("/", listener); + + } + + public Alarm? next_alarm() + { + if (alarms == null) + return null; + return alarms.data; } - public Alarm? next_alarm() - { - if (alarms == null) - return null; - return alarms.data; - } - - public void schedule(Alarm a) - { - alarms.insert_sorted(a, alarm_compare); - otimed_reschedule(); - } - - private void otimed_reschedule() - { - zavai.log.info("No alarms left to reschedule"); - if (alarms != null) - { - zavai.log.info("Scheduling next alarm: " + alarms.data.label + " at " + Time.local(alarms.data.deadline).to_string()); - - try { - otimed_alarm.ClearAlarm(zavai.registry.bus_name); - } catch (Error e) { - zavai.log.error("Cannot clear alarms: " + e.message); - } - try { - otimed_alarm.SetAlarm(zavai.registry.bus_name, (int)alarms.data.deadline); - } catch (Error e) { - zavai.log.error("Cannot reschedule alarms: " + e.message); - } - } - schedule_changed(); - } - - public void check_alarms() - { - last_system_time = time_t(); - update_time(); - while (alarms != null && alarms.data.deadline <= chosen_time) - { - Alarm a = alarms.data; - alarms.remove(a); - zavai.log.info("Triggering " + a.label); - a.trigger(); - } - - otimed_reschedule(); - } + public void schedule(Alarm a) + { + alarms.insert_sorted(a, alarm_compare); + otimed_reschedule(); + } + + private void otimed_reschedule() + { + if (alarms != null) + { + zavai.log.info("Scheduling next alarm: " + alarms.data.label + " at " + Time.local(alarms.data.deadline).to_string()); + zavai.log.info("Scheduling at abs " + "%d".printf((int)alarms.data.deadline)); + + try { + otimed_alarm.ClearAlarm(zavai.registry.bus_name); + } catch (Error e) { + zavai.log.error("Cannot clear alarms: " + e.message); + } + try { + otimed_alarm.SetAlarm(zavai.registry.bus_name, (int)alarms.data.deadline); + } catch (Error e) { + zavai.log.error("Cannot reschedule alarms: " + e.message); + } + + int t = rtc.GetCurrentTime(); + stderr.printf("Current time: %d, RTC time: %d\n", (int)time_t(), t); + t = rtc.GetWakeupTime(); + stderr.printf("Scheduled alarm: %d, RTC wakeup time: %d\n", (int)alarms.data.deadline, t); + } else + zavai.log.info("No alarms left to reschedule"); + schedule_changed(); + } + + public void check_alarms() + { + last_system_time = time_t(); + update_time(); + while (alarms != null && alarms.data.deadline <= chosen_time) + { + Alarm a = alarms.data; + alarms.remove(a); + zavai.log.info("Triggering " + a.label); + a.trigger(a); + } + + otimed_reschedule(); + } private void on_gps_time(dynamic DBus.Object pos, int t) { - if (t == 0) - { - last_gps_time_system_time = 0; - update_time(); - } else { - last_gps_time = (time_t)t; - last_gps_time_system_time = time_t(); - update_time(); - } + if (t == 0) + { + last_gps_time_system_time = 0; + update_time(); + } else { + last_gps_time = (time_t)t; + last_gps_time_system_time = time_t(); + update_time(); + } } - private bool on_system_time() - { - last_system_time = time_t(); - update_time(); - return true; - } - - private void update_time() - { - if (last_gps_time_system_time + 10 > last_system_time) - { - chosen_time = last_gps_time; - chosen_type = SourceType.GPS; - } - else - { - chosen_time = last_system_time; - chosen_type = SourceType.SYSTEM; - } - if (chosen_time / 60 != last_minute) - { - last_minute = chosen_time / 60; - minute_changed(chosen_time, chosen_type); - } - } + private bool on_system_time() + { + last_system_time = time_t(); + update_time(); + return true; + } + + private void update_time() + { + if (last_gps_time_system_time + 10 > last_system_time) + { + chosen_time = last_gps_time; + chosen_type = SourceType.GPS; + } + else + { + chosen_time = last_system_time; + chosen_type = SourceType.SYSTEM; + } + if (chosen_time / 60 != last_minute) + { + last_minute = chosen_time / 60; + minute_changed(chosen_time, chosen_type); + } + } /// Request GPS resource public override void start() { if (started) return; - system_time_timeout = Timeout.add(5000, on_system_time); + system_time_timeout = Timeout.add(5000, on_system_time); gps_time.TimeChanged += on_gps_time; - last_system_time = time_t(); - update_time(); + last_system_time = time_t(); + update_time(); base.start(); } @@ -213,7 +255,7 @@ public class Clock: zavai.Service { if (!started) return; - Source.remove(system_time_timeout); + Source.remove(system_time_timeout); gps_time.TimeChanged -= on_gps_time; base.stop(); @@ -224,7 +266,7 @@ public Clock clock = null; public void init() { - clock = new Clock(); + clock = new Clock(); zavai.registry.register_service(clock); }