Tuesday, November 8, 2011

Energizing Exercises: WattDepot Code Katas

If you have been keeping up with this blog, it should come as no surprise that energy-related research and software engineering go hand-in-hand and here we shall have our first glimpse at how these two seemingly unrelated fields can assist each other.  To recap, one way that software engineering can assist energy research is through data collection and analysis and software packages like WattDepot can be used to do just that (and more!).  As with the previous systems, we shall learn the basics of WattDepot through a set of simple exercises or katas to get some hands on experience as we get our feet wet.



Kata 1: SourceListing
Implement a class called SourceListing, whose main() method accepts one argument (the URL of the WattDepot server) and which writes out the URL argument and a list of all sources defined on that server and their descriptions, sorted in alphabetical order by source name.  Use the System.out.format method to provide a nicely formatted list. 
As the first exercise, Kata 1 was relatively simple.  It was made even simpler as the example program essentially does this already.  While the code itself was quick and easy, I was not sure if the sources retrieved from the server were always being retrieved in alphabetical order.  It took a while, but I eventually convinced myself that it was sorted and this uncertainty made exercise take about 25 minutes.


Kata 2: SourceLatency
Implement a class called SourceLatency, whose main() method accepts one argument (the URL of the WattDepot server) and which writes out the URL argument and a list of all sources defined on that server and the number of seconds since data was received for that source, sorted in ascending order by this latency value.  If no data has every been received for that source, indicate that.  Use the System.out.format method to provide a nicely formatted list.
The second exercise was rather straight forward as well.  It took a little bit of data manipulation to calculate the latency, but this was also shown in the example program.  The bulk of the time spent here was spent trying to figure out how to get the values sorted by latency.  After thinking about it for a few minutes I decided to implement a LatencyData class which stores a source name and latency value.  LatencyData implements the Comparable interface and contains methods to make it ordered on the latency value.  As a result, all I had to do was make a bunch of LatencyData objects, throw them into an ArrayList, use Collections.sort to get the results in the right order, and print them.  All of this took about 40 minutes since I had to override several methods for the LatencyData class.  However, I should have made a general sorting class to be used by the later exercises that require data to be sorted on a value other than name.  I chose to implement separate classes for each type of data in the later exercises (i.e. EnergyData and PowerData) and a general class would have saved time and effort.



Kata 3: SourceHierarchy
Implement a class called SourceHierarchy, whose main() method accepts one argument (the URL of the WattDepot server) and which writes out the URL argument and a hierarchical list of all sources defined on that server.  The hierarchy represents the source and subsource relationship between sources.
Here is where things started to get a bit more interesting.  Getting the subsources is rather simple using the getSubSources method, using the resulting object's getHref method, and then getting the subsource's name by retrieving the sub-string after the final '/', but making sure that the indentations were right and that subsources were not printed as top-level sources was a little bit trickier.  To print the subsources, I decided to write a recursive method that prints the name of the top-level source, then calls itself on each subsource with a larger indentation.  This way, it is guaranteed to print the hierarchy properly no matter how many levels of subsources are present.  In addition, the method removes any of the found subsources from the original source list, preventing the issue of them being printed again as top level sources.  All in all, this took about 45 minutes to figure out and implement.


Kata 4: EnergyYesterday
Implement a class called EnergyYesterday, whose main() method accepts one argument (the URL of the WattDepot server) and which writes out the URL argument and a list of all sources defined on that server and the amount of energy in watt-hours consumed by that source during the previous day, sorted in ascending order by watt-hours of consumption.  If no energy has every been consumed by that source, indicate zero.  Use the System.out.format method to provide a nicely formatted list.
Kata 4 was probably the most time consuming of them all.  While it seemed simple at first, getting the time stamps for the beginning and end of yesterday proved to be a little trickier than I thought.  To calculate the day of yesterday, I decided to use the java.util.Calendar class (though in hindsight, it would have been easier just to use the built in Tstamp functions).  I then used this Calendar object to create a string which would be used to make a time stamp to be passed to the getEnergyConsumed function.  However, I neglected to notice that the month field of the Calendar class was actually one less than the traditional numbering system (i.e. January is 0) so my time stamps were invalid.  This caused me to get a lot of BadXmlExceptions as the range I specified was outside of the stored sensor data.  It took me multiple sessions to figure this problem out and this exercise took at least 4 hours to complete.  On the bright side though, I was able to apply the same time stamp generation methods the following katas which made them much easier.


Kata 5: HighestRecordedPowerYesterday
Implement a class called HighestRecordedPowerYesterday, whose main() method accepts one argument (the URL of the WattDepot server) and which writes out the URL argument and a list of all sources defined on that server and the highest recorded power associated with that source during the previous day, sorted in ascending order by watts.  Also indicate the time when that power value was observed. If no power data is associated with that source, indicate that.  Use the System.out.format method to provide a nicely formatted list.
While this one sounded more complex than Kata 4 at first, it was relatively simple since I had the time stamps figured out.  The two main issues here concerned virtual sources (aggregates of non-virtual subsources) and finding the maximum power recorded.  Dealing with virtual sources can be tricky since they do not contain data points themselves and the subsources may not be synchronized.  However, this can be handled by sampling the data at large intervals to account for the discrepancies in synchronization (15 minutes in my case) allowing virtual sources to create data points by aggregating the data of its subsources.  The second issue of finding the maximum power is then easily brute-forced by iterating through all of the resulting data points and simply storing the one with the largest value.  Consequently, this one only took about 35 minutes to complete.


Kata 6: MondayAverageEnergy
Implement a class called MondayAverageEnergy, whose main() method accepts one argument (the URL of the WattDepot server) and which writes out the URL argument and a list of all sources defined on that server and the average energy consumed by that source during the previous two Mondays, sorted in ascending order by watt-hours.  Use the System.out.format method to provide a nicely formatted list.
Surprisingly, the final kata was not too difficult.  After playing the the Calendar class in the previous exercises, it was fairly straightforward to find the previous two Mondays.  The only tricky part was getting the previous week's Monday if today is Sunday or Monday since there would not be a complete data set for that week's Monday.  Other than that, getting the two energy consumed readings and averaging them was very simple.  As a result, this exercise was completed relatively quickly with a time of 25 minutes.




Overall, using these exercises as an introduction to WattDepot has shown me just how useful such tools can be in collecting and analyzing energy data.  With WattDepot, programmers do not have to go out of their way to get the data they want so they can spend their time doing meaningful analysis of that data.  While I did encounter a rather frustrating non-WattDepot related problem as I worked through these katas, the WattDepot API proved to be simple and painless to use.  So if you are interested in doing some energy data collection or analysis, WattDepot seems to be the way to go!

0 comments:

Post a Comment