Initial commit: 0.0.1-1
[chledclk] / chledclk.vala
diff --git a/chledclk.vala b/chledclk.vala
new file mode 100644 (file)
index 0000000..2420fcc
--- /dev/null
@@ -0,0 +1,164 @@
+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;
+               }
+       }
+}
+