Circadian Rhythms, F.lux, and DDC/CI (PART II)
Yesterday I threw together a quick implementation of the DDC/CI vs sunlight idea that I described the other day.This isn’t a full implementation – it is not aware of the monitor’s brightness is, save for the time after execution of its own commands – but I will attack this project methodically & iteratively. After all, I’m learning a ton about C++ & C#!
Overview of the code (high-level):
Keep in mind that it’s a hack, and this was the first time I have written in C# 🙂
There is some code that should be ignored, DllImport for example, that has no functional role.
The main method does only one thing, mapLight() – I purposefully abstracted as much as possible.
mapLight() very roughly maps hourly solar intensity (~0-600) over the range of possible brightnesses (0-100). Then, setBright() runs a commandline program – ScreenBright – to actually set the screen’s brightness.
A closer look at the code:
The lazy way of mapping hours -> brightness that I used is simply a hardcoded, 24 long int[] array “Light”, followed by an ugly switch/case structure to call setBright() with the array Light indexed by the hour of the day, as retrieved earlier with DateTime.Now.Hour .
setBright() then compares both parameters, and calls dimm() or light() appropriately.
Then, dimm() or light() will run “ScreenBright.exe – set brightness” in a command window, to incrementally change the screen’s brightness to the desired value.
Raw code:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; namespace dimming { using System.Threading; public class dimming { public static void Main(){mapLight();} private static void mapLight() { int hour = DateTime.Now.Hour; System.Console.WriteLine("hour is: " + hour); Thread.Sleep(500); int[] Light = new int[] { 0, 0, 0, 0, 0, 0, 10, 15, 30, 60, 85, 95, 100, 100, 100, 95, 85, 60, 25, 15, 10, 0, 0, 0 }; switch (hour){ case 0://0 of 600 setBright(0, Light[hour]); break; #region ugly switch/case construct case 1://0 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 2://0 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 3://0 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 4://0 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 5://0 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 6://50 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 7://100 of 600 W/m^2 setBright(Light[(hour - 1)], Light[hour]); break; case 8://200 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 9://400 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 10://500 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 11://550 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 12://600 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 13://600 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 14://600 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 15://550 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 16://500 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 17://400 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 18://300 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 19://200 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 20://100 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 21://0 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 22://0 of 600 setBright(Light[(hour - 1)], Light[hour]); break; case 23://0 of 600 setBright(Light[(hour - 1)], Light[hour]); break; #endregion default: System.Console.WriteLine("Time out of range!??! What the hell!" + hour); break; } } #region low-level handling (setBright, dimm, light, getnowBright) private static void setBright(int startat, int endat){ if (startat > endat) { dimm(startat, endat); } else if (endat < startat) { light(startat, endat); } else if (endat == startat) { System.Console.WriteLine("startat=endat"); Thread.Sleep(5000); } else { System.Console.WriteLine("What the hell?!?!?! startat ? endat neither greater nor less nor equal thereto!"); } Thread.Sleep(500);} private static void dimm(int startat, int endat){ System.Console.WriteLine("startat > endat"); Thread.Sleep(500); for (int i = startat; i > (endat); i -= 10) { string sb = "-set brightness " + i.ToString(); System.Diagnostics.Process.Start(@"C:\Users\Alexander Riccio\Downloads\ScreenBright\ScreenBright.exe", sb); System.Console.WriteLine("Dimming to: " + sb); Thread.Sleep(5000); } } private static void light(int startat, int endat){ System.Console.WriteLine("startat < endat"); Thread.Sleep(500); for (int i = startat; i < (endat+1); i += 10) { string sb = "-set brightness " + i.ToString(); System.Diagnostics.Process.Start(@"C:\Users\Alexander Riccio\Downloads\ScreenBright\ScreenBright.exe", sb); System.Console.WriteLine("Increasing Brightness to: " + sb); Thread.Sleep(5000); } } #endregion }//class bracket }//namespace
Moving forward:
At the low level: It looks like I will have to port this to unmanaged C++ code, which seems like the only easy way to interface with the windows APIs. It seems P/Invoke could allow me to work in C#, but I simply don’t know enough about it. Then I can implement the SetMonitorBrightness function — and I’ll be 90% done.
Hi,
nice work. A short comment on the switch/case: If you check the range of the time beforehand and you can remove the whole switch/case block:
if(hour > 23)
{
System.Console.WriteLine(“Time out of range!??! What the hell!” + hour);
}
else
{
if(hour < 1)
{
setBright(0, Light[hour]);
}
else
{
setBright(Light[(hour – 1)], Light[hour]);
}
}
LikeLike
Thanks! That’s far more elegant – I said it was a hack 😉
What I am aiming for, eventually, is to track down an accurate measurement of hourly/continuous 24-hour solar intensity that would be far more natural than the values I have for development.
Thanks again!
LikeLike
[…] toyed with the idea of automated window blinds – its another product of the modern world that just won't agree with the circadian rhythm – however, I don't have access to the headers on my blinds (think: parents) and haven't […]
LikeLike
Automated Window Blinds with Arduino | Alexander Riccio said this on April 12, 2013 at 1:34 am |
[…] you’ve been following this blog, you’ve probably already read parts one & two. If you haven’t, read about it after the […]
LikeLike
Circadian Rhythms, F.lux, and DDC/CI (PART III) WORKING ALPHA!!! | Alexander Riccio said this on May 4, 2013 at 9:52 pm |