WattDepot Katas

Last week's post about energy in Hawaii was a precursor to today's task. I had briefly mentioned WattDepot, which is a web service that can collect and store energy and power data from smart meters. That data can then be analyzed and displayed for purposes of research, experimentation, and awareness. I've completed six katas using a WattDepot API.

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. 
This kata was very simple (and therefore a good place to start). It took about ten minutes to get used to the API and generate the correct output. It only required one API call to the server to get the list of sources, and then a loop through the list of sources to print the name and description. Nothing difficult to report - just a good way to get the most basic operation of the API down and get familiar with the data.



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. 
This second kata provided a bit more difficulty. Like all of the katas here, it started with a call to the API to get the list of sources. However, for each source I had to make another API call to find the most recent data retrieved from the sensor. A comparison to the time of retrieval calculated the latency of the data. Getting the correct data took about 15 minutes. Next, I had to figure out how to sort that data by latency.

As I looked ahead, a few other katas require sorting by various values so I decided to make a generic solution that could be used for all of them. I spent half an hour on a generic class called SortingObject that can store two or three attributes, one of which must implement Comparable. After finding the latency for each source, I created a SortingObject for it and added it to a TreeSet. The TreeSet automatically sorts based on the Comparable attribute (in this case, latency). All that was left was to loop through the TreeSet and print out the results.

The first result here shows up as a negative time, which I am assuming is caused by differences in the clock time of my computer and the WattDepot server.



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. 
I found two ways to complete this task. The first is a naive solution that depends on a certain ordering of the Sources to work. For the data set I am working with, it presents the correct results. This solution only took about 10 or 15 minutes to write. However, it is not a good solution because it could easily produce the wrong output on other servers. To do this in a more generic way, I created a tree structure.


The output here shows that Ilima is a virtual source, made up of 10 sub-sources. Ilima-A is another virtual source, with 2 sub-sources. In this case, Ilima-A's sub-sources are a subset of Ilima's sub-sources. It seems like it would make more sense if Ilima-A was a sub-source of Ilima, but I'm not sure if virtual sources are allowed to be sub-sources in WattDepot. I decided to add an option to generate what I consider a "logical" hierarchy by finding matching subsets in the sub-sources.


I lost track of time working on this kata because it spanned multiple coding sessions, but it was definitely more than I spent on all of the other katas.

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.
The most difficult part of this kata for me was dealing with dates. WattDepot requires the XMLGregorianCalendar date type, which I found to be clumsy to work with since regular formatting functions wouldn't work on it. Combined with that was the fact that I don't remember ever working with dates in Java before; as a result, it took an embarrassing amount of time just to find yesterday's date at midnight. I ended up with this:



If there is an easier way to go about that, please let me know! Once I had the date, the task was fairly straightforward. Like in the second kata, I made an API call to get the desired information from each source and stored them in a TreeSet of SortingObjects in order to output in ascending order. It took about 25 minutes overall.

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.
This is a little tricky due to the presence of both virtual and non-virtual sources. For non-virtual sources, you could retrieve all of the sensor data and just iterate through to find the maximum power value. However, virtual sources represent an aggregate of non-virtual sources, so there is no sensor data associated with them directly, and it is unlikely that the sensor data timestamps for its constituent sources will be synchronized exactly.
One reasonable way to deal with this is to request the computed power at (say) 15 minute intervals for the entire day, which provides 96 data points per source whether it is virtual or non-virtual.

As the kata describes, this requires making many API calls to the server. Since power is the rate at which we use energy, it only makes sense to collect power data for a particular time. I decided to query for the power used every 30 minutes because when I used 15, as suggested, I received errors that the server had timed out. This class takes about five minutes to run since it is collecting 48 data points for each of the 64 sources, resulting in over 3,000 calls to the server. It might be more efficient if I knew which sources were virtual and which were not, so I could use a single server call to get all of the sensor data and only have to make multiple calls for the virtual sources. I imagine that querying power consumption over a specified time period would be a key component to creating visualizations like graphs to show patterns in power usage. My solution took far too long to be accepted by end-users, so I am curious how this could be done more efficiently.  It took about 15 minutes to implement this code.


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. 
This kata didn't require much more work than the fourth one. I simply made two calls to the server - one for each Monday that I wanted data from - and computed the average. This took approximately ten minutes.



Overall, working with the WattDepot API was pretty easy. I did have some problems with the JavaDocs, but I'm not sure if that was a problem on my end or not. Also, as shown below, not all of the parameters were named clearly. However, the method names were self-explanatory and the parameters were consistent between methods so I usually knew what to do.

The ability to accurately record energy and power usage at sub-minute intervals and then display this data for researchers and consumers makes WattDepot an important tool for energy conservation.

Comments

  1. Your code for Kata 4 looks good. I would have done it the same way too.

    ReplyDelete

Post a Comment

Popular posts from this blog

Working with Esper: Problems and Solutions

Writing and Testing FizzBuzz in Eclipse