Degree Days

Degree Days

Weather Data for Energy Professionals

Access the Degree Days.net API using JavaScript in Node.js

This page has some sample code showing how to use JavaScript running in Node.js to specify a JSON request, send it to our API servers (past the security system), and process the JSON response that comes back.

It's not a full client library (like we have for Java, .NET, and Python), but, thanks to Node's excellent support for JSON, it should be pretty easy to adapt it to suit your needs.

See the JSON API docs for more about specifying the data you want in the JSON request. There are lots of options, and the request included in the JavaScript code below is just a simple example. The JSON docs also explain more about the data you can expect back in the response.

You might also find the JSON API test tool useful for testing different JSON requests and seeing the JSON responses that come back.

Also please note that we have a separate code sample for calling the API with client-side JavaScript running in a web browser.

const crypto = require('crypto'), // built-in module, no need to npm install
    fetch = require('node-fetch'); // install with npm install node-fetch

// The test API access keys are described at www.degreedays.net/api/test
// They will let you access data from the Cape Cod area only.
// To fetch data from locations worldwide, sign up for a proper API account at
// www.degreedays.net/api/ and copy your API access keys here.
const accountKey = 'test-test-test';
const securityKey = 'test-test-test-test-test-test-test-test-test-test-test-test-test';
// You can call the API over HTTP using http://apiv1.degreedays.net/json or
// over HTTPS using https://apiv1.degreedays.net/json - set the endpoint URL
// below as appropriate.
const endpoint = 'http://apiv1.degreedays.net/json';



// ************* STEP 1: Create the request ************************************
// First we create a JSON request that specifies what we want from the API.
// See www.degreedays.net/api/json#request for more on this.

// You can fetch data from a station ID, a longitude/latitude position, or a 
// postal/zip code.
const location = {
    type: 'PostalCodeLocation',
    postalCode: '02532',
    countryCode: 'US'
};
// In this example we fetch both HDD and CDD, using the same breakdown (daily
// data covering the last 7 days) for both. For more breakdown options see
// www.degreedays.net/api/json#breakdown
const breakdown = {
    type: 'DailyBreakdown',
    period: {
        type: 'LatestValuesPeriod',
        numberOfValues: 7
    }
};
const locationDataRequest = {
    type: 'LocationDataRequest',
    location: location,
    dataSpecs: {
        // Here we specify 2 DataSpec items: one for HDD and one for CDD.  You
        // can specify up to 100 DataSpec items in one request (e.g. to fetch
        // data in lots of base temperatures).  Give each DataSpec a unique name
        // so you can get the corresponding DataSet from the response.
        myHDD: {
            type: 'DatedDataSpec',
            calculation: {
                type: 'HeatingDegreeDaysCalculation',
                baseTemperature: {
                    unit: 'F',
                    value: 60
                }
            },
            breakdown: breakdown
        },
        myCDD: {
            type: 'DatedDataSpec',
            calculation: {
                type: 'CoolingDegreeDaysCalculation',
                baseTemperature: {
                    unit: 'F',
                    value: 70
                }
            },
            breakdown: breakdown
        }
    }
};
const fullRequest = {
    securityInfo: {
        endpoint: endpoint,
        accountKey: accountKey,
        timestamp: new Date().toISOString(),
        random: Buffer.from(crypto.randomBytes(12)).toString('hex')
    },
    request: locationDataRequest
};
const fullRequestJson = JSON.stringify(fullRequest);
// Now our JSON request is ready.  Uncomment the line below to log the JSON:
//console.log(fullRequestJson);



// ************* STEP 2: Send the request to the API ***************************
// Next we sign the JSON request and package everything together into an HTTP
// request which we send to the Degree Days.net API.  This follows the spec at
// www.degreedays.net/api/json#send
const signatureBytes = 
    crypto.createHmac('sha256', securityKey).update(fullRequestJson).digest();
// The API requires the JSON request and the signature to be base64url encoded.
function base64urlEncode(unencoded) {
    return Buffer.from(unencoded).toString('base64')
        .replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
}
// Send the HTTP request to the API servers using node-fetch.  You could change
// this to use another HTTP library if you wanted.
fetch(endpoint, {
        method: 'POST',
        body: 'request_encoding=base64url' +
            '&signature_method=HmacSHA256' +
            '&signature_encoding=base64url' +
            '&encoded_request=' + base64urlEncode(fullRequestJson) +
            '&encoded_signature=' + base64urlEncode(signatureBytes),
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
        }
    })
    .then(response => {
        if (!response.ok) {
            throw new Error(response.status + ': ' + response.statusText);
        }
        return response.json();
    })
    .catch(err => console.error('Problem connecting to API:', err))
    .then(parsedObject => handleResponse(parsedObject))
    .catch(err => console.error('Problem handling API response:', err));



// ************* STEP 3: Process the response from the API *********************
// The JSON response is explained at www.degreedays.net/api/json#response
function handleResponse(fullResponse) {
    // fullResponse.metadata has some rate limit info, but we are mainly
    // interested in fullResponse.response (a LocationDataResponse in this case).
    const response = fullResponse.response;
    if (response.type === 'Failure') {
        // See www.degreedays.net/api/json#failure for more about failures.
        console.log('Request failure:', response);
    } else {
        // The response contains a lot of useful info, as shown in the JSON docs
        // at www.degreedays.net/api/json#response
        console.log('Station ID: ', response.stationId);
        // "myHDD" is the name we gave the HDD DataSpec in our request.
        const hddData = response.dataSets.myHDD;
        if (hddData.type === 'Failure') {
            console.log('Failure for HDD DataSet:', hddData);
        } else {
            console.log('HDD:');
            for (var v of hddData.values) {
                console.log(v.d + ': ' + v.v);
            }
        }
        const cddData = response.dataSets.myCDD;
        if (hddData.type === 'Failure') {
            console.log('Failure for CDD DataSet:', cddData);
        } else {
            console.log('CDD:');
            for (var v of cddData.values) {
                console.log(v.d + ': ' + v.v);
            }
        }
    }
}

Dependencies

crypto is a built-in Node module so you shouldn't need to install anything for that.

node-fetch, however, is a dependency that you will need to install to use the sample code as is. You can do this by running npm install node-fetch in your Node.js project folder.

We looked at quite a few HTTP modules and decided to use node-fetch because:

If you're not already using node-fetch in your project, and you don't want an extra dependency, it should be easy enough to replace it with another library for the step-2 part of the example code above. Feel free to email us if you want to use the built-in http / https modules as we can give you an alternative (and considerably longer) code sample that uses those instead.

Problems?

Hopefully the example code above, the JSON API docs, and the JSON API test tool will be enough to get you going, but please feel free to email us if you'd like more help.

Higher level integration details

It is also worth reading the higher-level integration guide for tips on the various approaches to integrating with the API. We have helped a lot of businesses integrate their software with our API so we are very familiar with the patterns that work well for common use cases.

Choose your Plan and Sign Up Today!

© 2019 BizEE Software - About | Contact | Privacy | Web Tool | API | Integration Guide | API FAQ | API Sign-Up