Fix LED currents for charging and battery full colours
[chledclk] / chledclk.vala
1 class ChargingLEDClock : Object {
2         const string MCE_SERVICE = "com.nokia.mce";
3         const string MCE_SIGNAL_PATH = "/com/nokia/mce/signal";
4         const string MCE_SIGNAL_IFACE = "com.nokia.mce.signal";
5         const string BME_SERVICE = "com.nokia.bme";
6         const string BME_SIGNAL_PATH = "/com/nokia/bme/signal";
7         const string BME_SIGNAL_IFACE = "com.nokia.bme.signal";
8         const string BME_REQUEST_PATH = "/com/nokia/bme/request";
9         const string BME_REQUEST_IFACE = "com.nokia.bme.request";
10
11         MainLoop loop;
12         dynamic DBus.Object mce;
13         dynamic DBus.Object bme;
14
15         bool display_off;
16         bool charger_connected;
17         bool battery_full;
18
19         bool sysfs_write (string filename, string contents) {
20                 var f = FileStream.open (filename, "w");
21                 if (f == null) {
22                         stderr.printf ("failed to open '%s' for writing\n", filename);
23                         return false;
24                 }
25                 f.printf ("%s", contents);
26                 return true;
27         }
28
29         void set_led_pattern (bool on, Time time) {
30
31                 print ("setting led pattern: %s\n", on ? "on" : "off");
32
33                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "disabled");
34                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "disabled");
35                 sysfs_write ("/sys/class/leds/lp5523:r/brightness", "0");
36                 sysfs_write ("/sys/class/leds/lp5523:g/brightness", "0");
37                 sysfs_write ("/sys/class/leds/lp5523:b/brightness", "0");
38
39                 if (!on)
40                         return;
41
42                 string pattern = "9d804000";
43                 int jump = 2;
44                 if (time.hour >= 20) {
45                         pattern += "0c7f0dffa082";
46                         jump += 3;
47                 } else if (time.hour >= 10) {
48                         pattern += "0c7f0dff";
49                         jump += 2;
50                 }
51                 if ((time.hour % 10) > 1) {
52                         pattern += "047f05ffa%03x".printf (((time.hour % 10 - 1) << 7) + jump);
53                         jump += 3;
54                 } else if ((time.hour % 10) == 1) {
55                         pattern += "047f05ff";
56                         jump += 2;
57                 }
58                 pattern += "11ff";
59                 jump += 1;
60                 if (time.minute >= 20)
61                         pattern += "047f05ffa%03x".printf (((time.minute / 10 - 1) << 7) + jump);
62                 else if (time.minute >= 10)
63                         pattern += "047f05ff";
64                 if ((time.minute % 10) >= 5)
65                         pattern += "043f057f";
66                 pattern += "21ff0000";
67
68                 print ("setting pattern: %s\n", pattern);
69
70                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "load");
71                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_leds", battery_full ? "000001000" : "000001100");
72                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_load", pattern);
73                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "load");
74                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_leds", "000000000");
75                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_load", "9d800000");
76                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "run");
77                 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "run");
78                 if (battery_full) {
79                         sysfs_write ("/sys/class/leds/lp5523:r/led_current", "2");
80                         sysfs_write ("/sys/class/leds/lp5523:g/led_current", "2");
81                         sysfs_write ("/sys/class/leds/lp5523:b/led_current", "2");
82                 } else {
83                         sysfs_write ("/sys/class/leds/lp5523:r/led_current", "20");
84                         sysfs_write ("/sys/class/leds/lp5523:g/led_current", "2");
85                         sysfs_write ("/sys/class/leds/lp5523:b/led_current", "0");
86                 }
87         }
88
89         bool update_led_pattern () {
90                 TimeVal now = TimeVal ();
91                 var time = Time.local (now.tv_sec);
92
93                 print ("current time: %d:%02d h\n", time.hour, time.minute);
94
95                 if (charger_connected && display_off) {
96                         set_led_pattern (true, time);
97
98                         Timeout.add (1000 * (60 - time.second), update_led_pattern);
99                 } else {
100                         set_led_pattern (false, time);
101                 }
102
103                 return false;
104         }
105
106         void on_mce_display_status_ind (dynamic DBus.Object mce, string mode) {
107                 print ("display_status_ind: %s\n", mode);
108                 display_off = (mode == "off");
109
110                 if (charger_connected && display_off) {
111                         print ("setting led pattern in 100 ms ...\n");
112                         Timeout.add (100, update_led_pattern);
113                 }
114         }
115
116         void on_bme_charger_connected (dynamic DBus.Object bme) {
117                 print ("charger_connected\n");
118                 charger_connected = true;
119         }
120
121         void on_bme_charger_disconnected (dynamic DBus.Object bme) {
122                 print ("charger_disconnected\n");
123                 charger_connected = false;
124                 battery_full = false;
125         }
126
127         void on_bme_battery_full (dynamic DBus.Object bme) {
128                 print ("battery_full\n");
129                 battery_full = true;
130         }
131
132         public ChargingLEDClock (DBus.Connection bus) {
133                 loop = new MainLoop (null);
134
135                 mce = bus.get_object (MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IFACE);
136                 mce.display_status_ind.connect (on_mce_display_status_ind);
137
138                 bme = bus.get_object (BME_SERVICE, BME_SIGNAL_PATH, BME_SIGNAL_IFACE);
139                 bme.charger_connected.connect (on_bme_charger_connected);
140                 bme.charger_disconnected.connect (on_bme_charger_disconnected);
141                 bme.battery_full.connect (on_bme_battery_full);
142
143                 dynamic DBus.Object bme_req;
144                 bme_req = bus.get_object (BME_SERVICE, BME_REQUEST_PATH, BME_REQUEST_IFACE);
145                 bme_req.status_info_req ();
146         }
147
148         public int run () {
149                 loop.run ();
150                 return 0;
151         }
152
153         static int main (string[] args) {
154                 try {
155                         var bus = DBus.Bus.get (DBus.BusType.SYSTEM);
156                         var app = new ChargingLEDClock (bus);
157                         return app.run ();
158                 } catch (DBus.Error e) {
159                         stderr.printf ("Error: %s\n", e.message);
160                         return 1;
161                 }
162         }
163 }
164