+class ChargingLEDClock : Object {
+ const string MCE_SERVICE = "com.nokia.mce";
+ const string MCE_SIGNAL_PATH = "/com/nokia/mce/signal";
+ const string MCE_SIGNAL_IFACE = "com.nokia.mce.signal";
+ const string BME_SERVICE = "com.nokia.bme";
+ const string BME_SIGNAL_PATH = "/com/nokia/bme/signal";
+ const string BME_SIGNAL_IFACE = "com.nokia.bme.signal";
+ const string BME_REQUEST_PATH = "/com/nokia/bme/request";
+ const string BME_REQUEST_IFACE = "com.nokia.bme.request";
+
+ MainLoop loop;
+ dynamic DBus.Object mce;
+ dynamic DBus.Object bme;
+
+ bool display_off;
+ bool charger_connected;
+ bool battery_full;
+
+ bool sysfs_write (string filename, string contents) {
+ var f = FileStream.open (filename, "w");
+ if (f == null) {
+ stderr.printf ("failed to open '%s' for writing\n", filename);
+ return false;
+ }
+ f.printf ("%s", contents);
+ return true;
+ }
+
+ void set_led_pattern (bool on, Time time) {
+
+ print ("setting led pattern: %s\n", on ? "on" : "off");
+
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "disabled");
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "disabled");
+ sysfs_write ("/sys/class/leds/lp5523:r/brightness", "0");
+ sysfs_write ("/sys/class/leds/lp5523:g/brightness", "0");
+ sysfs_write ("/sys/class/leds/lp5523:b/brightness", "0");
+
+ if (!on)
+ return;
+
+ string pattern = "9d804000";
+ int jump = 2;
+ if (time.hour >= 20) {
+ pattern += "087f09ffa082";
+ jump += 3;
+ } else if (time.hour >= 10) {
+ pattern += "087f09ff";
+ jump += 2;
+ }
+ if ((time.hour % 10) > 1) {
+ pattern += "047f05ffa%03x".printf (((time.hour % 10 - 1) << 7) + jump);
+ jump += 3;
+ } else if ((time.hour % 10) == 1) {
+ pattern += "047f05ff";
+ jump += 2;
+ }
+ pattern += "11ff";
+ jump += 1;
+ if (time.minute >= 20)
+ pattern += "047f05ffa%03x".printf (((time.minute / 10 - 1) << 7) + jump);
+ else if (time.minute >= 10)
+ pattern += "047f05ff";
+ if ((time.minute % 10) >= 5)
+ pattern += "043f057f";
+ pattern += "71050000";
+
+ print ("setting pattern: %s\n", pattern);
+
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "load");
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_leds", battery_full ? "000001000" : "000001100");
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_load", pattern);
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "load");
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_leds", "000000000");
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_load", "9d800000");
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "run");
+ sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "run");
+ if (battery_full) {
+ sysfs_write ("/sys/class/leds/lp5523:r/led_current", "20");
+ sysfs_write ("/sys/class/leds/lp5523:g/led_current", "2");
+ sysfs_write ("/sys/class/leds/lp5523:b/led_current", "0");
+ } else {
+ sysfs_write ("/sys/class/leds/lp5523:r/led_current", "2");
+ sysfs_write ("/sys/class/leds/lp5523:g/led_current", "2");
+ sysfs_write ("/sys/class/leds/lp5523:b/led_current", "2");
+ }
+ }
+
+ bool update_led_pattern () {
+ TimeVal now = TimeVal ();
+ var time = Time.local (now.tv_sec);
+
+ print ("current time: %d:%02d h\n", time.hour, time.minute);
+
+ if (charger_connected && display_off) {
+ set_led_pattern (true, time);
+
+ Timeout.add (1000 * (60 - time.second), update_led_pattern);
+ } else {
+ set_led_pattern (false, time);
+ }
+
+ return false;
+ }
+
+ void on_mce_display_status_ind (dynamic DBus.Object mce, string mode) {
+ print ("display_status_ind: %s\n", mode);
+ display_off = (mode == "off");
+
+ if (charger_connected && display_off) {
+ print ("setting led pattern in 100 ms ...\n");
+ Timeout.add (100, update_led_pattern);
+ }
+ }
+
+ void on_bme_charger_connected (dynamic DBus.Object bme) {
+ print ("charger_connected\n");
+ charger_connected = true;
+ }
+
+ void on_bme_charger_disconnected (dynamic DBus.Object bme) {
+ print ("charger_disconnected\n");
+ charger_connected = false;
+ battery_full = false;
+ }
+
+ void on_bme_battery_full (dynamic DBus.Object bme) {
+ print ("battery_full\n");
+ battery_full = true;
+ }
+
+ public ChargingLEDClock (DBus.Connection bus) {
+ loop = new MainLoop (null);
+
+ mce = bus.get_object (MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IFACE);
+ mce.display_status_ind.connect (on_mce_display_status_ind);
+
+ bme = bus.get_object (BME_SERVICE, BME_SIGNAL_PATH, BME_SIGNAL_IFACE);
+ bme.charger_connected.connect (on_bme_charger_connected);
+ bme.charger_disconnected.connect (on_bme_charger_disconnected);
+ bme.battery_full.connect (on_bme_battery_full);
+
+ dynamic DBus.Object bme_req;
+ bme_req = bus.get_object (BME_SERVICE, BME_REQUEST_PATH, BME_REQUEST_IFACE);
+ bme_req.status_info_req ();
+ }
+
+ public int run () {
+ loop.run ();
+ return 0;
+ }
+
+ static int main (string[] args) {
+ try {
+ var bus = DBus.Bus.get (DBus.BusType.SYSTEM);
+ var app = new ChargingLEDClock (bus);
+ return app.run ();
+ } catch (DBus.Error e) {
+ stderr.printf ("Error: %s\n", e.message);
+ return 1;
+ }
+ }
+}
+