Register
Submit a solution
The challenge is finished.

Challenge Overview

We are giving out bonus payments to every participant that submits and has a score +80. Thus, if you submit and you don't win but your score is +80, we will still pay you a bonus for your efforts.

 

Challenge Overview

The goal of the challenge is to aggregate consumption data with heterogeneous granularity across time into systematic intervals. These intervals are then either multiplied with a relevant tariff value then summed into daily totals, or directly summed into daily totals. The simplest example would be to sum hourly data into daily totals, subject to data completeness checks and multiply them with a single tariff number.

Challenge Requirements

We have developed a GreenButton Ruby gem library in a past challenge that consumes GreenButton REST API, parses the XML response and wraps it into Ruby classes. You will be using this library in this challenge to retrieve the consumption data, and do aggregation against the data returned by this library.

The information about how to aggregate the data will be provided as a JSON object described below.

General Notes

  • All input and output dates are in local time.

  • The Ruby GreenButton library includes a README file, please refer to it for more information about the usage of the library.

Expected SDK Usage

Sample usage would look like this :

require ‘bucketize’

bkt = gb.consumption_by_date(’20-Feb-2015’, tariff)

where tariff is a JSON formatted object

The returned bkt is a collection of [gb_data_description_id, date, value] items

Example 1: given the following tariff structure:

tariff = {

{utility_id:1, rate_class:R, start_date:nil, end_date:nil, time_start:1, time_end: 24, day_of_week:[1,2,3,4,5,6,7], kwh_low:0, kwh_high:1000,tariff:10},

{utility_id:1, rate_class:R, start_date:nil, end_date:nil, time_start:1, time_end: 24, day_of_week:[1,2,3,4,5,6,7], kwh_low:1000, kwh_high: nil ,tariff:20 }

}

bkt = gb.cost_from_month_start(‘February’, tariff)

The consumption intervals should be summed by day and multiplied with the appropriate tariff but as long as the consumption for the month is less than or equal to 1000kwh, the appropriate tariff is 10, beyond 1000kwh in a month, the tariff jumps to 20.

Example 2: given the following tariff structure

tariff = {

{utility_id:1, rate_class:R, start_date:nil, end_date:nil, time_start:1, time_end:12, day_of_week:[1,2,3,4], kwh_low:nil, kwh_high:nil, tariff:5},

{utility_id:1, rate_class:R, start_date:nil, end_date:nil,time_start:1, time_end:12, day_of_week:[5,6,7], kwh_low:nil, kwh_high:nil, tariff:7},

{utility_id:1, rate_class:R, start_date:nil, end_date:nil,time_start:13, time_end:24, day_of_week:[1,2,3,4], kwh_low:nil, kwh_high:nil, tariff:10},

{utility_id:1, rate_class:R, start_date:nil, end_date:nil,time_start:13, time_end:24, day_of_week:[5,6,7], kwh_low:nil, kwh_high:nil,tariff:12}

}

bkt = gb.cost_date_range(’05-February-2015’,’15-February-2015’, tariff)

daily costs should be calculated by summing the underlying consumption data into totals for the hour groups, and using the appropriate tariff based off of the day of the week.

Bucketize Module specification

The gem should have a single module Bucketize with the following methods:

  • consumption_from_month_start(month, tariff)

    • input parameters :

      • month - required

      • tariff - the following are required fields :

        • utility_id

        • rate_class

        • time_start

        • time_end

        • day_of_week – array, Monday is 1, Sunday is 7

        • kwh_low

        • kwh_high

        • tariff

        • sample input :
          tariff = {
          {utility_id:1, rate_class: ‘R’, start_date:nil, end_date:nil, time_start:1, time_end: 24, day_of_week:[1,2,3,4,5,6,7], kwh_low:0, kwh_high:1000,tariff:10},
          {utility_id:1, rate_class: ‘R’, start_date:nil, end_date:nil, time_start:1, time_end: 24, day_of_week:[1,2,3,4,5,6,7], kwh_low:1000, kwh_high: nil ,tariff:20 }}

      • access token - this is needed to be passed to the ruby greenbutton gem

      • subscriptionURI - this is needed to be passed to the ruby greenbutton gem

    • logic :

      • The consumption intervals should be summed by the hours of the day relevant to the tariff, here all hours, and summed to daily values.

    • returns  a collection of [gb_data_description_id, date, value] items.

      • date is ruby date (format : mm/DD/yyyy)

      • gb_data_description_id is the gb_data_description’s id of processed data in greenbutton gem library

      • value is the calculated consumption value

  • consumption_by_date(date, tariff)

    • input parameters :

      • date - required

      • tariff - the following are required fields :

        • utility_id

        • rate_class

        • time_start

        • time_end

        • tariff

        • sample input :
          tariff = {
          {utility_id:1, rate_class: ‘R’, start_date:nil, end_date:nil, time_start:1, time_end: 3, day_of_week:nil, kwh_low:nil, kwh_high:nil,tariff:10},
          {utility_id:1, rate_class: ‘R’, start_date:nil, end_date:nil, time_start:4, time_end: 24, day_of_week:nil, kwh_low:nil, kwh_high: nil ,tariff:20 }}

      • access token - this is needed to be passed to the ruby greenbutton gem

      • subscriptionURI - this is needed to be passed to the ruby greenbutton gem

    • logic :

      • The consumption is calculated by summing the consumption data in totals of hours groups and summed to daily values. .

    • returns :

      • a collection of [gb_data_description_id, date, value] items

        • date is ruby date (format : mm/DD/yyyy HH:mm:ss)

        • gb_data_description_id is the gb_data_description’s id of processed data in greenbutton gem library

        • value is the calculated consumption value

  • consumption_date_range(date1, date2, tariff)

    • input parameters :

      • date1 - required

      • date2 - required

      • tariff

        • utility_id

        • rate_class

        • time_start

        • time_end

        • day_of_week

        • tariff

        • sample input :
          tariff = {{utility_id:1,rate_class: ‘R’,start_date:nil, end_date:nil, time_start:1, time_end:12, day_of_week:[1,2,3,4], kwh_low:nil, kwh_high:nil, tariff:5},
          {utility_id:1, rate_class: ‘R’,start_date:nil, end_date:nil,time_start:1, time_end:12, day_of_week:[5,6,7], kwh_low:nil, kwh_high:nil, tariff:7},
          {utility_id:1, rate_class: ‘R’,start_date:nil, end_date:nil,time_start:13, time_end:24, day_of_week:[1,2,3,4], kwh_low:nil, kwh_high:nil, tariff:10},
          {utility_id:1, rate_class: ‘R’,start_date:nil, end_date:nil,time_start:13, time_end:24, day_of_week:[5,6,7], kwh_low:nil, kwh_high:nil,tariff:12}}

      • access token - this is needed to be passed to the ruby greenbutton gem

      • subscriptionURI - this is needed to be passed to the ruby greenbutton gem

    • logic :

      • daily consumption should be calculated by summing the consumption data into totals for the hour groups. These hour groups are summed to daily values..

    • returns a collection of [gb_data_description_id, date, value] items

      • date is ruby date (format : mm/DD/yyyy HH:mm:ss)

      • gb_data_description_id is the gb_data_description’s id of processed data in greenbutton gem library

      • value is the calculated consumption value

  • cost_from_month_start(month, tariff)

    • input parameters :

      • month - required, this is a Ruby date, first of the month.

      • tariff - the following are required fields :

        • utility_id

        • rate_class

        • time_start

        • time_end

        • day_of_week – array, Monday is 1, Sunday is 7

        • kwh_low

        • kwh_high

        • tariff

        • sample :
          tariff = {
          {utility_id:1, start_date:nil, end_date:nil, time_start:1, time_end: 24, day_of_week:[1,2,3,4,5,6,7], kwh_low:0, kwh_high:1000,tariff:10},
          {utility_id:1, start_date:nil, end_date:nil, time_start:1, time_end: 24, day_of_week:[1,2,3,4,5,6,7], kwh_low:1000, kwh_high: nil ,tariff:20 }}

      • access token - this is needed to be passed to the ruby greenbutton gem

      • subscriptionURI - this is needed to be passed to the ruby geenutton gem

    • logic :

      • The consumption intervals should be summed by the hours of the day relevant to the tariff, here all hours,  and summed to daily values. Daily consumption values are multiplied with the appropriate tariff for the day of the week to get costs, here all days. Tariff selection varies depending on the consumption total since when the beginning of the month falls, here tariff = 10 between 0 and 1000, then 20 above that.

    • returns  a collection of [gb_data_description_id, date, cost] items.

      • date is ruby date (format : mm/DD/yyyy)

      • gb_data_description_id is the gb_data_description’s id of processed data in greenbutton gem library

      • value is the calculated cost value

  • cost_by_date(date,tariff)

    • input parameters :

      • date - required

      • tariff - the following are required fields :

        • utility_id

        • rate_class

        • time_start

        • time_end

        • tariff

        • sample input :
          tariff = {
          {utility_id:1, rate_class:R,start_date:nil, end_date:nil, time_start:1, time_end: 3, day_of_week:nil, kwh_low:nil, kwh_high:nil,tariff:10}
          }

      • access token - this is needed to be passed to the ruby greenbutton gem

      • subscriptionURI - this is needed to be passed to the ruby greenbutton gem

    • logic :

      • The consumption is calculated by summing the consumption data in totals of hours groups and summed to daily values. Daily values are multiplied with the appropriate tariff for the day of the week, here all days.

    • returns :

      • a collection of [gb_data_description_id, date, cost] items

        • date is ruby date (format : mm/DD/yyyy HH:mm:ss)

        • gb_data_description_id is the gb_data_description’s id of processed data in greenbutton gem library

        • value is the calculated cost value

  • cost_date_range(date1, date2, tariff)

    • input parameters :

      • date1 - required

      • date2 - required

      • tariff

        • utility_id

        • rate_class

        • time_start

        • time_end

        • day_of_week

        • tariff

        • sample input :
          tariff = {{utility_id:1,rate_class:R,start_date:nil, end_date:nil, time_start:1, time_end:12, day_of_week:[1,2,3,4], kwh_low:nil, kwh_high:nil, tariff:5},
          {utility_id:1, rate_class:R,start_date:nil, end_date:nil,time_start:1, time_end:12, day_of_week:[5,6,7], kwh_low:nil, kwh_high:nil, tariff:7},
          {utility_id:1, rate_class:R,start_date:nil, end_date:nil,time_start:13, time_end:24, day_of_week:[1,2,3,4], kwh_low:nil, kwh_high:nil, tariff:10},
          {utility_id:1, rate_class:R,start_date:nil, end_date:nil,time_start:13, time_end:24, day_of_week:[5,6,7], kwh_low:nil, kwh_high:nil,tariff:12}}

      • access token - this is needed to be passed to the ruby greenbutton gem

      • subscriptionURI - this is needed to be passed to the ruby greenbutton gem

    • logic :

      • Daily cost should be calculated by summing the consumption data into totals for the hour groups, and using the appropriate tariff based off of the day of the week and hour group.

    • returns a collection of [gb_data_description_id, date, cost] items

      • date is ruby date (format : mm/DD/yyyy)

      • gb_data_description_id is the gb_data_description’s id of processed data in greenbutton gem library

      • value is the calculated cost value

Data Validation

As part of the data aggregation process:

  • Check for zero/null/NaN values in the data and filter them, and apply the following gaps logic to these values if applicable.

  • 15 minutes and hourly data:

    • data gaps of duration less than 4 hours should be handled via interpolation

    • data gaps of greater than 4 hours should return an error code

Abstracting

Please make sure to create mixin to include the common code/functionality.

Setting Up the Gem

Use Bundler to take care of gem dependencies.

A standard folder structure would look like this :

  • Gemfile
  • LICENSE.txt
  • README.md
  • Rakefile
  • benzinator.gemspec
  • lib
    • bucketize
      • model
        • <model-name>.rb
      • <class-name>.rb
      • version.rb
    • bucketize.rb (the module entry point)

 

Writing Tests

All of your code should be test covered (RSpec preferred).

Please refer to the provided GreenButton Ruby Gem library to understand how to use the GreenButton Sandbox or local sample data to test your solution.

If you see any problem with sandbox stopped behaving normally, post in challenge forums, and we will reset it (Sandbox).

Documentation

Because other programmers will be working with your code, and incorporating it into their projects, all functions must be documented in detail in the code (TomDoc preferred - In order to generate HTML properly you will need to use Yard TomDoc).

Coding Standard

Follow coding standards listed here:

https://github.com/copycopter/style-guide

Readme

Provide a detailed readme file using Markdown language with following information :

  • Overview

  • Setup Prerequisites

  • How to install

  • Usage Example

  • Reference this Ruby Gem’s Documentation

  • Any details about any limitations of your solution.

Please note, we're judging this competition not just on the code, but also on the quality of the documentation, test coverage, and ease of use.

Documents

The GreenButton Wrapper Gem library will be provided in the challenge forums.

Appendix B: The Utility Tariff Class

  • utility

  • utility_tariff

    • A subclass of utility to handle the tariff details

    • This holds the tariff structure

    • Attributes are:

    • Utility_id

    • Rate_class

    • Start_date [can be blank]

    • End_date [can be blank]

    • time_start – in local time  - defaults to 1

    • time_end – in local time – defaults to 24

    • day_of_week – array, Monday is 1, Sunday is 7

    • kwh_low [can be blank]

    • kwh_high [can be blank]

    • tariff



Final Submission Guidelines

Deliverable

  • All source code files and scripts that address the challenge requirement.

  • Detailed readme file as clarified above.

ELIGIBLE EVENTS:

2015 topcoder Open

Review style

Final Review

Community Review Board

Approval

User Sign-Off

ID: 30049243