public final class DataApi
extends java.lang.Object
To get a DataApi
object and use it, you would typically
create a DegreeDaysApi
object, get the DataApi
object
from that, then call the method you want. For example, to send a
LocationDataRequest
to the API and get a LocationDataResponse
back:
DegreeDaysApi api = new DegreeDaysApi(
new AccountKey(yourStringAccountKey),
new SecurityKey(yourStringSecurityKey));
LocationDataResponse response =
api.dataApi().getLocationData(yourLocationDataRequest);
See getLocationData(LocationDataRequest)
and
getLocationInfo(LocationInfoRequest)
for much more info and sample
code.
getLocationData(LocationDataRequest)
,
getLocationInfo(LocationInfoRequest)
This class is designed to be safe for use from multiple concurrent threads. However, if you create a customized instance of this class (using a RequestProcessor
that you have written or customized), then the thread-safety of its operation will depend on the thread-safety of that RequestProcessor
.
Constructor and Description |
---|
DataApi(RequestProcessor requestProcessor)
Constructs a
DataApi object that uses the specified
RequestProcessor internally. |
Modifier and Type | Method and Description |
---|---|
LocationDataResponse |
getLocationData(LocationDataRequest request)
Sends your
request for data (for a specified location) to
the API servers, returning a response containing data you requested, or
throwing an appropriate subclass of DegreeDaysApiException
if something goes wrong. |
LocationInfoResponse |
getLocationInfo(LocationInfoRequest request)
A lightweight alternative to
getLocationData(LocationDataRequest) that returns info about the
station(s) that would be used to satisfy an equivalent
LocationDataRequest , but not the data itself. |
public DataApi(RequestProcessor requestProcessor)
DataApi
object that uses the specified
RequestProcessor
internally.
Instead of using this constructor, you would usually create a
DegreeDaysApi
object and get the DataApi
object from
that, as in this example.
requestProcessor
- the non-null RequestProcessor
that
the new DataApi
object should use internally for its
processing.java.lang.NullPointerException
- if requestProcessor
is
null
.public LocationDataResponse getLocationData(LocationDataRequest request) throws DegreeDaysApiException
request
for data (for a specified location) to
the API servers, returning a response containing data you requested, or
throwing an appropriate subclass of DegreeDaysApiException
if something goes wrong.
LocationDataRequest
/LocationDataResponse
codeHere's a simple example showing how to fetch monthly 65°F-base-temperature heating degree days, covering the 12 months of 2024, for an automatically-selected weather station near US zip code 02633 (which is on Cape Cod so you can use the free test API account). The HDD figures are output to the command line:
DegreeDaysApi api = new DegreeDaysApi(
new AccountKey("test-test-test"),
new SecurityKey("test-test-test-test-test-test-test-test-test-test-test-test-test"));
DayRange dayRange = Day.of(2024, 1, 1).to(Day.of(2024, 12, 31));
DatedDataSpec hddSpec = DataSpec.dated(
Calculation.heatingDegreeDays(Temperature.fahrenheit(65)),
DatedBreakdown.monthly(Period.dayRange(dayRange)));
LocationDataRequest request = new LocationDataRequest(
Location.postalCode("02532", "US"),
new DataSpecs(hddSpec));
LocationDataResponse response = api.dataApi().getLocationData(request);
DatedDataSet hddData = response.dataSets().getDated(hddSpec);
for (DatedDataValue v : hddData.getValues()) {
System.out.println(v.firstDay() + ": " + v.value());
}
And here is a more complex example that fetches HDD, CDD, and hourly temperature data, covering just the latest available day, for a longitude/latitude position on Cape Cod, Massachusetts (again chosen so you can try out this code using the free test API account):
DegreeDaysApi api = new DegreeDaysApi(
new AccountKey("test-test-test"),
new SecurityKey("test-test-test-test-test-test-test-test-test-test-test-test-test"));
DatedBreakdown breakdown = DatedBreakdown.daily(Period.latestValues(1));
DatedDataSpec hddSpec = DataSpec.dated(
Calculation.heatingDegreeDays(Temperature.celsius(15.5)),
breakdown);
DatedDataSpec cddSpec = DataSpec.dated(
Calculation.coolingDegreeDays(Temperature.celsius(21)),
breakdown);
TimeSeriesDataSpec hourlyTempsSpec = DataSpec.timeSeries(
TimeSeriesCalculation.hourlyTemperature(TemperatureUnit.CELSIUS),
breakdown);
LocationDataRequest request = new LocationDataRequest(
Location.longLat(new LongLat(-70.305634, 41.695475)),
new DataSpecs(hddSpec, cddSpec, hourlyTempsSpec));
LocationDataResponse response = api.dataApi().getLocationData(request);
DatedDataSet hddData = response.dataSets().getDated(hddSpec);
DatedDataSet cddData = response.dataSets().getDated(cddSpec);
TimeSeriesDataSet hourlyTempsData =
response.dataSets().getTimeSeries(hourlyTempsSpec);
System.out.println("StationID: " + response.stationId());
for (DatedDataValue v : hddData.getValues()) {
System.out.println(v.firstDay() + " HDD: " + v.value());
}
for (DatedDataValue v : cddData.getValues()) {
System.out.println(v.firstDay() + " CDD: " + v.value());
}
for (TimeSeriesDataValue v : hourlyTempsData.getValues()) {
System.out.println(v.offsetDayTime() + ": " + v.value() + " C");
}
Both examples above specify a location on Cape Cod, Massachusetts, so you can try them out using the free test API account. To access data for locations worldwide (whether station IDs, postal/zip codes, or longitude/latitude positions), you can sign up for a full API account on our website, swap your own account key and security key into the code samples above, then change the location however you wish.
The examples above are just a starting point...
LocationDataRequest
is highly configurable:
Location
you want data for as a
weather-station ID or a geographic location (postal/zip code, or
longitude/latitude position). For geographic locations the API will
automatically select the best weather station to satisfy your request.
DataSpec
can be either a
DatedDataSpec
(for daily/weekly/monthly/yearly/custom degree
days), an AverageDataSpec
(for average degree days), or a
TimeSeriesDataSpec
(for hourly temperature data). Each of these
is configured with objects that determine the data Calculation
(or TimeSeriesCalculation
), the Breakdown
, and the
Period
of coverage that you want.DataSpecs
in your request with multiple different DataSpec
items.LocationDataResponse
also contains information about the
weather station(s) used to generate the returned data. If you request
data for a geographic location initially, you might want to use the
station ID to fetch updates later. If you are specifying geographic
locations, but storing data by station ID, you can avoid re-fetching data
unnecessarily by using getLocationInfo(LocationInfoRequest)
to
get the station ID that would be returned by an equivalent call to
getLocationData(LocationDataRequest)
. We call this two-stage data
fetching.DegreeDaysApiException
will cover everything that
you should be prepared for, but it's often useful to get more detail.
Check the list of exceptions for this method further below and the
getXXX
methods of DataSets
to see exactly what
subclasses of DegreeDaysApiException
can be thrown.It's worth understanding the rules that govern what you can get in response to a request for one or more sets of data for a particular location:
Stations that data can come from:
StationIdLocation
(created via
Location.stationId(String)
) then the API will only ever return
data for that station. It will never substitute in data from another
station.GeographicLocation
, the API will
choose which station(s) to use automatically. The choice will depend on
the data you requested as well as the location you requested it for. Some
stations have more data than others, and the quality of a station's data
can vary over time. The API will choose the station(s) that can best
satisfy your specific request.LocationDataResponse
for an
inactive station. An inactive station is one that hasn't sent any usable
weather reports for roughly 10 days or more (10 being an approximate
number that is subject to change). See
LocationException.isDueToLocationNotSupported()
for
more information on inactive stations. If you request data for an
inactive station, or for a GeographicLocation
for which no active
station can be found, you will get a LocationException
to
indicate that the location is not supported.When you request more data than is available:
LocationDataResponse
. But, if any of the DataSpec
objects
that you specified cannot be satisfied (either fully or partially), you
will get a SourceDataException
each time you try to get the
corresponding DataSet
from the DataSets
object held by
the response.SourceDataException
(see
above) than any partially-complete DataSet
, make sure to specify
the
minimum number of values or the
minimum day range for the Period
objects in your request. Unless
you specify minimums, the API will return the best it can from within the
specifications you give.Other data guarantees:
DayRangePeriod
(created with
Period.dayRange(DayRange)
) is specified imprecisely, the API will
never return more data than you asked for, or data from outside of the
range that you asked for.NaN
, 0, -1, 9999 etc. If a station
has small gaps in its source temperature data, the API will fill
those gaps with estimates before calculating any degree days. But
larger gaps are not tolerated, and the API will only ever use
data from after such gaps. If a larger gap is ongoing (i.e.
there is no good data after it), the station will be declared inactive
(see above). This approach ensures that active stations will always have
contiguous sets of data that run through to recent days.request
- specifies the data you want and the location you want it
for. Cannot be null
.LocationDataResponse
containing the data
you requested or as much of it as was available for the location
you specified (given the rules explained above).LocationException
- if the request fails because of problems
relating to the specified
Location
.ServiceException
- if the request fails because of a problem with
the API service (sorry!).RateLimitException
- if you hit the RateLimit
for your
account's plan, and need to wait a little while before it's
reset.InvalidRequestException
- if the request that is sent to the API
servers is invalid (e.g. if it is authenticated with invalid API access keys).TransportException
- if there's a problem sending the request to
the API servers, or a problem getting the API's response back.DegreeDaysApiException
- the superclass of all the exceptions
listed above.java.lang.NullPointerException
- if request
is null
.public LocationInfoResponse getLocationInfo(LocationInfoRequest request) throws DegreeDaysApiException
getLocationData(LocationDataRequest)
that returns info about the
station(s) that would be used to satisfy an equivalent
LocationDataRequest
, but not the data itself. Typically you would
specify a GeographicLocation
in the LocationInfoRequest
,
using this getLocationInfo(LocationInfoRequest)
method to
map postal/zip codes or longitude/latitude positions to station IDs.
This getLocationInfo(LocationInfoRequest)
method can be
useful if you have a database of data stored by station ID, but are using
GeographicLocation
types (postal/zip codes or longitude/latitude
positions) to determine which station ID to use for each of your
real-world locations. A call to this
getLocationInfo(LocationInfoRequest)
method will only ever
take one request unit, whilst a call to
getLocationData(LocationDataRequest)
can take many more
(depending on how much data it fetches), so it often makes sense to use
this method to avoid the overhead of re-fetching data that you already
have stored. We call this
two-stage data
fetching.
Note, however, that this returns nothing that isn't also returned by a
call to getLocationData(LocationDataRequest)
. So, if you know
you'll be fetching data anyway, you might as well use
getLocationData(LocationDataRequest)
from the start.
LocationInfoRequest
/LocationInfoResponse
code
DegreeDaysApi api = new DegreeDaysApi(
new AccountKey("test-test-test"),
new SecurityKey("test-test-test-test-test-test-test-test-test-test-test-test-test"));
DatedDataSpec hddSpec = DataSpec.dated(
Calculation.heatingDegreeDays(Temperature.fahrenheit(65)),
DatedBreakdown.yearly(Period.latestValues(10)));
LocationInfoRequest request = new LocationInfoRequest(
Location.postalCode("02532", "US"),
new DataSpecs(hddSpec));
LocationInfoResponse response = api.dataApi().getLocationInfo(request);
System.out.println("Station ID: " + response.stationId());
The exceptions thrown by this
getLocationInfo(LocationInfoRequest)
method are the same as
those thrown by getLocationData(LocationDataRequest)
, and they
are thrown under exactly the same circumstances.
However, because the LocationInfoResponse
returned by this method
does not contain any data (i.e. no DataSets
), there's no way to
tell from this whether an equivalent LocationDataResponse
would
actually contain any or all of the data you want. So, although you can
call this method to determine what station ID the API would use for an
equivalent call to getLocationData(LocationDataRequest)
, you
would have to actually make that call to be sure that you could get all
the data you wanted.
request
- specifies the location you want data for and the data that
you want (as this can affect the station-selection process for
geographic locations). Cannot be
null
.LocationInfoResponse
containing info about the
station(s) that would be used to satisfy an equivalent
LocationDataRequest
.LocationException
- if the request fails because of problems
relating to the specified
Location
.ServiceException
- if the request fails because of a problem with
the API service (sorry!).RateLimitException
- if you hit the RateLimit
for your
account's plan, and need to wait a little while before it's
reset.InvalidRequestException
- if the request that is sent to the API
servers is invalid (e.g. if it is authenticated with invalid
API access keys).TransportException
- if there's a problem sending the request to
the API servers, or a problem getting the API's response back.DegreeDaysApiException
- the superclass of all the exceptions
listed above.java.lang.NullPointerException
- if request
is null
.
See www.degreedays.net/api/ for more about the Degree Days.net API.
You can sign up for a Degree Days.net API account and read the integration guide that is useful and applicable whether you are using Java or not.