Analytics
Clarity Grid offers several different analytical methods as part of our Bill Calculation APIs. Our most basic form of Analytics, comparing a retail bill to wholesale rates, requires no extra input from the user. By providing extra inputs, however, our Bill Calculation API can also run bills with a Battery, and Solar.
Compare To Wholesale
By default, our Bill Calculation endpoint calculates both retail and wholesale rates when running a bill. Below are the fields relevant to wholesale:
Field Name | Data Type | Description | Example |
wholesalePrices | Collection | Collection of wholesale rates at the price node; Contains floating point rates organized by EPOCH timestamps |
“wholesalePrices“: { “1670742000000”: 0.06797 }, |
wholesaleMonthlyCapacityCost | Collection | Collection of monthly wholesale capacity costs; Contains floating point prices |
“wholesaleMonthlyCapacityCost“: [ 148.62430519557364, 148.69999995043148, 148.70000000479627, 148.70000002973822, 148.69999996162528, 148.70000002398342, 148.6999999405179, 148.69999997601562, 148.6999999157351, 148.70000012951243, 0.0, 0.0 ], |
wholesaleAnnualCosts | Float | Annual wholesale costs | “wholesaleAnualCosts“: 10569.87733570417, |
wholesaleMonthlyCosts | Collection | Collection of monthly wholesale costs; Contains floating point prices |
“wholesaleMonthlyCosts“: [ 605.8108123179012, 664.1562031596636, 809.5949789730257, 783.7244161368138, 988.5094984823705, 1096.3652948592771, 830.9927288534416, 587.5345760740726, 602.8701871954299, 1122.5842078880357, 445.0472227220754, 545.7629039141297 ], |
wholesaleMonthlyDistributionCosts | Collection | Collection of monthly wholesale distribution costs; Contains floating point prices |
“wholesaleMonthlyDistributionCosts“: [ 613.1283114503843, 656.7499998403605, 552.6500000120891, 680.4400000919547, 639.9399998917925, 580.6400000580635, 562.3399998633154, 755.0499999068998, 605.9877633338978, 612.8500003788695, 564.9500000499474, 564.9500000829483 ], |
wholesaleAnnualCostsCombined | Float | Combined annual wholesale price. | “wholesaleAnualCostsCombined“: 28392.715391743724, |
wholesaleMonthlyDemandCosts | Collection | Collection of monthly wholesale demand costs; Contains floating point prices |
“wholesaleMonthlyDemandCosts“: [ 780.1189875709644, 742.0710961033238, 633.7925298999971, 855.0212115833223, 833.1439430354802, 867.5125364387056, 851.777748729989, 820.0493230096739, 907.6482875966553, 1051.7691781032215, 954.8653311612861, 1135.3918078464224 ], |
averageNextDayaheadPrice | Float | Average next-day dayahead price | “averageNextDayDayaheadPrice“: 0.049950589439699405, |
Compare Two Tariffs
Our API makes it possible to compare the rates of two tariffs, and it’s as simple as running two bills with our Bill Calculation endpoint and comparing the responses. The response is described in our section on the Calculate Custom Economy endpoint, and information regarding wholesale rates is described above in the Compare to Wholesale section. Below we have provided some sample Python code using the following Python libraries (requests, simplejson, sys, datetime, calendar) to demonstrate how you could use our API to compare two bills:
#The following Python code will run two retail bills for comparing two tariffs.
import requests
import simplejson as json
import sys
import datetime
from calendar import monthrange
#Set hostname and apikey
host = ‘https://map.claritygrid.net’
apikey = “yourApiKeyHere”
#Login to get session (cookie) using your api secret
url = host + ‘/ecservice/login’
postbody = {}
postbody[“uu_id”] = apikey
postbody[“app_group”] = “API”
header = {“content-type”: “application/json”}
response = requests.post(url,data=json.dumps(postbody),headers=header, verify=True)
authcookie=response.cookies
#Set start and end dates, as well as monthly usage (in kWh)
startDate = “2023-05-01”
endDate = “2023-05-31”
monthlyUsg = 10000
#Initialize first set of params
params1 = {}
params1[“price_node_id”] = 2966
#Initialize second set of params
params2 = {}
params2[“price_node_id”] = 2966
usgByMthList = []
hourly_customer_load = {}
#Convert start and end dates into Python datetime format
usg_start = datetime.datetime.strptime(startDate, ‘%Y-%m-%d‘)
usg_end = datetime.datetime.strptime(endDate, ‘%Y-%m-%d‘)
#Get years and months from start and end dates
year = usg_start.year
endYear = usg_end.year
month = usg_start.month
endMonth = usg_end.month
#Build usage profile to be used for both bills
while year <= endYear: #Loop through each year
for i in range(month – 1, endMonth, 1): #Loop through the months between month and endMonth
mon = i + 1 #Create “mon” variable
if year == endYear & mon > endMonth:
break
#Create string for month, and make sure it is in 2-digit format if it is below 10 (ex. 01-09, not 1-9)
monString = str(mon).zfill(2)
#Get number of days in the current month
daysInMon = monthrange(year, mon)
#Create usage_by_month parameter
usage_by_month = {}
usage_by_month[‘startDate’] = str(year) + ‘-‘ + monString + ‘-01’
usage_by_month[‘endDate’] = str(year) + ‘-‘ + monString + ‘-‘ + str(daysInMon[1])
usage_by_month[‘usage’] = str(monthlyUsg)
usage_by_month[‘actual_usage’] = False
usage_by_month[‘year’] = str(year)
usage_by_month[‘month’] = monString
#Create perHour parameter
perHour = {}
#Calculate usage per hour by dividing monthly usage by the number of days in the month, and dividing that by 24 (for the hours in a day)
usgPerHour = ((monthlyUsg / daysInMon[1]) / 24)
#Create incrementing day var
dy = 1
#Loop through days in month
while dy <= daysInMon[1]:
hr = 0
#Create string for day similar to monString
dyString = str(dy).zfill(2)
while hr <= 23:
hrString = str(hr).zfill(2) #Create string for hour similar to monString and dyString
#Create key for perHour in the following format: 2023-05-01 00:00
key = str(year) + ‘-‘ + monString + ‘-‘ + dyString + ‘ ‘ + hrString + ‘:00’
perHour[key] = usgPerHour
hr += 1
dy += 1
#Set usage_by_month perHour parameter
usage_by_month[‘perHour’] = perHour
#Append usage_by_month to usgByMthList
usgByMthList.append(usage_by_month)
year += 1
#Build first set of params
params1[‘usage_by_month’] = usgByMthList
params1[‘distributor_id’] = ”
params1[‘distributor_tariff_id’] = “5927”
params1[‘latitude’] = 41.56819
params1[‘longitude’] = –73.83502
params1[‘hourly_customer_load’] = hourly_customer_load
#Write first payload to a JSON file – optional
with open(‘compareTrf1Payload.json’, ‘w’, encoding=‘utf-8’) as file:
json.dump(params1, file)
print(“First bill payload written to “ + file.name + “\n“)
#Build second set of params
params2[‘usage_by_month’] = usgByMthList
params2[‘distributor_id’] = ”
params2[‘distributor_tariff_id’] = “200”
params2[‘latitude’] = 41.56819
params2[‘longitude’] = –73.83502
params2[‘hourly_customer_load’] = hourly_customer_load
#Write second payload to a JSON file – optional
with open(‘compareTrf2Payload.json’, ‘w’, encoding=‘utf-8’) as file:
json.dump(params2, file)
print(“Second bill payload written to “ + file.name + “\n“)
url = host + ‘/ecservice/calculate_custom_economy’
header = {“content-type”: “application/json”}
#Make first call to bill calculation endpoint
response1 = requests.post(url, data = json.dumps(params1), headers = header, verify= True, cookies= authcookie)
if response1.text == “{Unauthorized}“:
sys.exit(“First API call failed. Bad authentication.”)
#Make second call to bill calculation endpoint
response2 = requests.post(url, data = json.dumps(params2), headers = header, verify= True, cookies= authcookie)
if response2.text == “{Unauthorized}“:
sys.exit(“Second API call failed. Bad authentication.”)
#Write first response to a file
f = open(“compareTrf1.json”, “w”)
f.write(response1.text)
print(“First output written to “ + f.name + “\n“)
#Write second response to a file
f = open(“compareTrf2.json”, “w”)
f.write(response2.text)
print(“Second output written to “ + f.name + “\n“)
#Close file
f.close()
The following JSON payloads are created from the above sample code. When sent to our API, they will compare the R-6 TOU and R-1 Tariffs from Central Hudson Gas & Electric Corp. in NYISO.
{
“price_node_id“: 2966,
“usage_by_month“:
[
{
“startDate“: “2023-05-01”,
“endDate“: “2023-05-31”,
“usage“: “10000”,
“actual_usage“: false,
“year“: “2023”,
“month“: “05”,
“perHour“:
{
“2023-05-01 00:00“: 13.440860215053762,
}
}
],
“distributor_id“: “”,
“distributor_tariff_id“: “5927”,
“latitude“: 41.56819,
“longitude“: -73.83502,
“hourly_customer_load“:
{}
}
{
“price_node_id“: 2966,
“usage_by_month“:
[
{
“startDate“: “2023-05-01”,
“endDate“: “2023-05-31”,
“usage“: “10000”,
“actual_usage“: false,
“year“: “2023”,
“month“: “05”,
“perHour“:
{
“2023-05-01 00:00“: 13.440860215053762,
}
}
],
“distributor_id“: “”,
“distributor_tariff_id“: “200”,
“latitude“: 41.56819,
“longitude“: -73.83502,
“hourly_customer_load“:
{}
}
The payload is described in the table below:
Field Name | Data Type | Description | Example |
price_node_id | Integer | Unique Clarity Grid identifier assigned to the price node that you’d like to run a bill with. | “price_node_id“: 2966, |
usage_by_month | Collection | Collection of monthly usage data. |
“usage_by_month“: [ { “startDate“: “2023-05-01”, “endDate“: “2023-05-31”, “usage“: “10000”, “actual_usage“: false, “year“: “2023”, “month“: “05”, “perHour“: { “2023-05-01 00:00“: 13.440860215053762, } } ], |
startDate | String | Start date of the month of data. | “startDate“: “2023-05-01”, |
endDate | String | End date of the month of data. | “endDate“: “2023-05-31”, |
usage | String | Usage (in kWh) for the month. | “usage“: “10000”, |
actual_usage | Boolean | Whether or not the usage this month is actual metered usage or an estimate. | “actual_usage“: false, |
year | String | Year of the data. | “year“: “2023”, |
month | String | Month of the data. | “month“: “05”, |
perHour | Collection | Collection of hourly data for the month, calculated by dividing the monthly usage by the number of days between the start and end dates, and dividing that by 24 (the hours in a day). (Only necessary when using estimated usage) |
“perHour“: { “2023-05-01 00:00“: 13.440860215053762, } |
distributor_id | String | Unique Clarity Grid identifier for the Distributor of the Tariff a user is running a bill for (can be left blank). | “distributor_id“: “”, |
distributor_tariff_id | String | Unique Clarity Grid identifier for the Tariff a user is running a bill for. | “distributor_tariff_id“: “200”, |
latitude | Float | Latitude of the price node a user is running a bill with. | “latitude“: 41.56819, |
longitude | Float | Longitude of the price node a user is running a bill with. | “longitude“: -73.83502, |
hourly_customer_load | Collection | Collection of hourly usage data for the time range. (Only necessary when using actual usage) |
“hourly_customer_load“: {} |
Compare to Battery
Our API allows users to run a bill using a battery (if available). This gives users the ability to compare a retail bill (as shown in our section on the Calculate Custom Economy endpoint to a bill run with a battery. In order to use this functionality, a user needs only to make a slight modification to the payload, as shown in the following sample code using the same Python libraries as described in the Compare Two Tariffs example.
#The following Python code will run a retail bill without a battery to compare to a bill with a battery using the Clarity Grid Bill Calculation API
import requests
import simplejson as json
import sys
import datetime
from calendar import monthrange
#Set hostname and apikey
host = ‘https://map.claritygrid.net’
apikey = “yourApiKeyHere”
#Login to get session (cookie) using your api secret
url = host + ‘/ecservice/login’
postbody = {}
postbody[“uu_id”] = apikey
postbody[“app_group”] = “API”
header = {“content-type”: “application/json”}
response = requests.post(url,data=json.dumps(postbody),headers=header, verify=True)
authcookie=response.cookies
#Set start and end dates, as well as monthly usage (in kWh)
startDate = “2023-05-01”
endDate = “2023-05-31”
monthlyUsg = 1000000
#Initialize first set of params
params = {}
params[“price_node_id”] = 2966
batteryParams = {}
batteryParams[“price_node_id”] = 2966
usgByMthList = []
hourly_customer_load = {}
#Convert start and end dates into Python datetime format
usg_start = datetime.datetime.strptime(startDate, ‘%Y-%m-%d‘)
usg_end = datetime.datetime.strptime(endDate, ‘%Y-%m-%d‘)
#Get years and months from start and end dates
year = usg_start.year
endYear = usg_end.year
month = usg_start.month
endMonth = usg_end.month
#Build usage profile to be used for both bills
while year <= endYear: #Loop through each year
for i in range(month – 1, endMonth, 1): #Loop through the months between month and endMonth
mon = i + 1 #Create “mon” variable
if year == endYear & mon > endMonth:
break
#Create string for month, and make sure it is in 2-digit format if it is below 10 (ex. 01-09, not 1-9)
monString = str(mon).zfill(2)
#Get number of days in the current month
daysInMon = monthrange(year, mon)
#Create usage_by_month parameter
usage_by_month = {}
usage_by_month[‘startDate’] = str(year) + ‘-‘ + monString + ‘-01’
usage_by_month[‘endDate’] = str(year) + ‘-‘ + monString + ‘-‘ + str(daysInMon[1])
usage_by_month[‘usage’] = str(monthlyUsg)
usage_by_month[‘actual_usage’] = False
usage_by_month[‘year’] = str(year)
usage_by_month[‘month’] = monString
#Create perHour parameter
perHour = {}
#Calculate usage per hour by dividing monthly usage by the number of days in the month, and dividing that by 24 (for the hours in a day)
usgPerHour = ((monthlyUsg / daysInMon[1]) / 24)
#Create incrementing day var
dy = 1
#Loop through days in month
while dy <= daysInMon[1]:
hr = 0
#Create string for day similar to monString
dyString = str(dy).zfill(2)
while hr <= 23:
hrString = str(hr).zfill(2) #Create string for hour similar to monString and dyString
#Create key for perHour in the following format: 2023-05-01 00:00
key = str(year) + ‘-‘ + monString + ‘-‘ + dyString + ‘ ‘ + hrString + ‘:00’
perHour[key] = usgPerHour
hr += 1
dy += 1
#Set usage_by_month perHour parameter
usage_by_month[‘perHour’] = perHour
#Append usage_by_month to usgByMthList
usgByMthList.append(usage_by_month)
year += 1
#Build first set of params
params[‘usage_by_month’] = usgByMthList
params[‘distributor_id’] = ”
params[‘distributor_tariff_id’] = “5927”
params[‘latitude’] = 41.56819
params[‘longitude’] = –73.83502
params[‘hourly_customer_load’] = hourly_customer_load
#Write first payload to a JSON file – optional
with open(‘compareBattPayload1.json’, ‘w’, encoding=‘utf-8’) as file:
json.dump(params, file)
print(“First bill payload written to “ + file.name + “\n“)
#Build second set of params (battery)
batteryParams[‘usage_by_month’] = usgByMthList
batteryParams[‘distributor_id’] = ”
batteryParams[‘distributor_tariff_id’] = “5927”
batteryParams[‘latitude’] = 41.56819
batteryParams[‘longitude’] = –73.83502
batteryParams[‘hourly_customer_load’] = hourly_customer_load
#Set battery_duration and battery_id to run a bill using a battery
batteryParams[‘battery_duration’] = ‘4’
batteryParams[‘battery_id’] = 0
#Write second payload to a JSON file – optional
with open(‘compareBattPayload2.json’, ‘w’, encoding=‘utf-8’) as file:
json.dump(batteryParams, file)
print(“Second bill payload written to “ + file.name + “\n“)
url = host + ‘/ecservice/calculate_custom_economy’
header = {“content-type”: “application/json”}
#Make first call to bill calculation endpoint
response1 = requests.post(url, data = json.dumps(params), headers=header, verify=True, cookies=authcookie)
if response1.text == “{Unauthorized}“:
sys.exit(“First API call failed. Bad authentication.”)
#Make second call to bill calculation endpoint
response2 = requests.post(url, data=json.dumps(batteryParams), headers=header, verify=True, cookies=authcookie)
if response2.text == “{Unauthorized}“:
sys.exit(“Second API call failed. Bad authentication.”)
#Write first response to a file
f = open(“compareBatt1.json”, “w”)
f.write(response1.text)
print(“First output written to “ + f.name + “\n“)
#Write second response to a file
f = open(“compareBatt2.json”, “w”)
f.write(response2.text)
print(“Second output written to “ + f.name + “\n“)
#Close file
f.close()
The sample code above generates the following payloads. The first of which runs a normal retail bill, while the second runs a bill with a battery.
{
“price_node_id“: 2966,
“usage_by_month“:
[
{
“startDate“: “2023-05-01”,
“endDate“: “2023-05-31”,
“usage“: “1000000”,
“actual_usage“: false,
“year“: “2023”,
“month“: “05”,
“perHour“:
{
“2023-05-01 00:00“: 1344.0860215053765,
}
}
],
“distributor_id“: “”,
“distributor_tariff_id“: “5927”,
“latitude“: 41.56819,
“longitude“: -73.83502,
“hourly_customer_load“:
{}
}
{
“price_node_id“: 2966,
“usage_by_month“:
[
{
“startDate“: “2023-05-01”,
“endDate“: “2023-05-31”,
“usage“: “1000000”,
“actual_usage“: false,
“year“: “2023”,
“month“: “05”,
“perHour“:
{
“2023-05-01 00:00“: 1344.0860215053765,
}
}
],
“distributor_id“: “”,
“distributor_tariff_id“: “5927”,
“latitude“: 41.56819,
“longitude“: -73.83502,
“hourly_customer_load“:
{},
“battery_duration“: “4”,
“battery_id“: 0
}
The payload is described in the table below:
Field Name | Data Type | Description | Example |
price_node_id | Integer | Unique Clarity Grid identifier assigned to the price node that you’d like to run a bill with. | “price_node_id“: 2966, |
usage_by_month | Collection | Collection of monthly usage data. |
“usage_by_month“: [ { “startDate“: “2023-05-01”, “endDate“: “2023-05-31”, “usage“: “1000000”, “actual_usage“: false, “year“: “2023”, “month“: “05”, “perHour“: { “2023-05-01 00:00“: 1344.0860215053765, } } ], |
startDate | String | Start date of the month of data. | “startDate“: “2023-05-01”, |
endDate | String | End date of the month of data. | “endDate“: “2023-05-31”, |
usage | String | Usage (in kWh) for the month. | “usage“: “1000000”, |
actual_usage | Boolean | Whether or not the usage this month is actual metered usage or an estimate. | “actual_usage“: false, |
year | String | Year of the data. | “year“: “2023”, |
month | String | Month of the data. | “month“: “05”, |
perHour | Collection | Collection of hourly data for the month, calculated by dividing the monthly usage by the number of days between the start and end dates, and dividing that by 24 (the hours in a day). (Only necessary when using estimated usage) |
“perHour“: { “2023-05-01 00:00“: 1344.0860215053765, } |
distributor_id | String | Unique Clarity Grid identifier for the Distributor of the Tariff a user is running a bill for (can be left blank). | “distributor_id“: “”, |
distributor_tariff_id | String | Unique Clarity Grid identifier for the Tariff a user is running a bill for. | “distributor_tariff_id“: “5927”, |
latitude | Float | Latitude of the price node a user is running a bill with. | “latitude“: 41.56819, |
longitude | Float | Longitude of the price node a user is running a bill with. | “longitude“: -73.83502, |
hourly_customer_load | Collection | Collection of hourly usage data for the time range. (Only necessary when using actual usage) |
“hourly_customer_load“: {} |
battery_duration | String | Duration of battery discharge (in hours) | “battery_duration“: “4”, |
battery_id | Integer | Id of the battery to be used in the bill calculations. (Entering ‘0’ will choose a battery based on the duration entered) | “battery_id“: 0 |
The fields in the API’s response that are relevant to Battery are as follows:
Field Name | Data Type | Description | Example |
batteryDispatchHours | Collection | Collection of battery dispatch hours ranging from 0 to 23 |
“batteryDispatchHours“: [ 18, 19, 20, 21 ] |
batteryChargingHours | Collection | Collection of battery charging hours ranging from 0 to 23 |
“batteryChargingHours“: [ 1, 2, 3, 4 ], |
batteryNetSavings | Collection | Collection of battery net savings; Contains floating point prices |
“batteryNetSavings“: [ 3908.4906178167835 ], |
availableBatteries | Collection | Collection of available batteries |
“availableBatteries“: [ { “duration“: 4.0, “charging_kwh“: 2000.0, “cost“: 28413.0, “name“: “2000 Kw. 4 Hour”, “disch_kwh“: 2000.0, “id“: 20 }, ], |
batteryDetails | Collection | Contains information about the battery currently being used in the bill calculations. |
“batteryDetails“: { “duration“: 4.0, “charging_kwh“: 2000.0, “cost“: 28413.0, “name“: “2000 Kw. 4 Hour”, “disch_kwh“: 2000.0, “id“: 20 }, |
batteryMonthlyCosts | Collection | Collection of monthly battery costs; Contains floating point prices |
“batteryMonthlyCosts“: [ 28413.0 ], |
as1-6tot | Float | For Battery: Placeholders for up to 6 Ancillary Service total revenue amounts. The names of the Ancillary Services are in the AS_columns collection | “as1tot“: 737.7600000000001, |
AS_Columns | Collection | Each ISO has different Ancillary Services; This collection contains the names of those Services |
“AS_columns“: [ “tmsr”, “tmnsr”, “opsrv”, “regcap”, “regmov” ], |
Compare to Solar
The last analytical tool our API features is the ability to run a bill against solar, similar to the battery functionality. An example of this functionality is shown in the following sample code (once again using the same Python libraries as previous examples):
#The following Python code will run a retail bill without solar to compare to a bill with solar using the Clarity Grid Bill Calculation API
import requests
import simplejson as json
import sys
import datetime
from calendar import monthrange
#Set hostname and apikey
host = ‘https://map.claritygrid.net’
apikey = “yourApiKeyHere”
#Login to get session (cookie) using your api secret
url = host + ‘/ecservice/login’
postbody = {}
postbody[“uu_id”] = apikey
postbody[“app_group”] = “API”
header = {“content-type”: “application/json”}
response = requests.post(url,data=json.dumps(postbody),headers=header, verify=True)
authcookie=response.cookies
#Set start and end dates, as well as monthly usage (in kWh)
startDate = “2023-05-01”
endDate = “2023-05-31”
monthlyUsg = 100000
#Initialize first set of params
params = {}
params[“price_node_id”] = 2966
solarParams = {}
solarParams[“price_node_id”] = 2966
usgByMthList = []
hourly_customer_load = {}
#Convert start and end dates into Python datetime format
usg_start = datetime.datetime.strptime(startDate, ‘%Y-%m-%d‘)
usg_end = datetime.datetime.strptime(endDate, ‘%Y-%m-%d‘)
#Get years and months from start and end dates
year = usg_start.year
endYear = usg_end.year
month = usg_start.month
endMonth = usg_end.month
#Build usage profile to be used for both bills
while year <= endYear: #Loop through each year
for i in range(month – 1, endMonth, 1): #Loop through the months between month and endMonth
mon = i + 1 #Create “mon” variable
if year == endYear & mon > endMonth:
break
#Create string for month, and make sure it is in 2-digit format if it is below 10 (ex. 01-09, not 1-9)
monString = str(mon).zfill(2)
#Get number of days in the current month
daysInMon = monthrange(year, mon)
#Create usage_by_month parameter
usage_by_month = {}
usage_by_month[‘startDate’] = str(year) + ‘-‘ + monString + ‘-01’
usage_by_month[‘endDate’] = str(year) + ‘-‘ + monString + ‘-‘ + str(daysInMon[1])
usage_by_month[‘usage’] = str(monthlyUsg)
usage_by_month[‘actual_usage’] = False
usage_by_month[‘year’] = str(year)
usage_by_month[‘month’] = monString
#Create perHour parameter
perHour = {}
#Calculate usage per hour by dividing monthly usage by the number of days in the month, and dividing that by 24 (for the hours in a day)
usgPerHour = ((monthlyUsg / daysInMon[1]) / 24)
#Create incrementing day var
dy = 1
#Loop through days in month
while dy <= daysInMon[1]:
hr = 0
#Create string for day similar to monString
dyString = str(dy).zfill(2)
while hr <= 23:
hrString = str(hr).zfill(2) #Create string for hour similar to monString and dyString
#Create key for perHour in the following format: 2023-05-01 00:00
key = str(year) + ‘-‘ + monString + ‘-‘ + dyString + ‘ ‘ + hrString + ‘:00’
perHour[key] = usgPerHour
hr += 1
dy += 1
#Set usage_by_month perHour parameter
usage_by_month[‘perHour’] = perHour
#Append usage_by_month to usgByMthList
usgByMthList.append(usage_by_month)
year += 1
#Build first set of params
params[‘usage_by_month’] = usgByMthList
params[‘distributor_id’] = ”
params[‘distributor_tariff_id’] = “5927”
params[‘latitude’] = 41.56819
params[‘longitude’] = –73.83502
params[‘hourly_customer_load’] = hourly_customer_load
#Write first payload to a JSON file – optional
with open(‘compareSolarPayload1.json’, ‘w’, encoding=‘utf-8’) as file:
json.dump(params, file)
print(“First bill payload written to “ + file.name + “\n“)
#Build second set of params (solar)
solarParams[‘usage_by_month’] = usgByMthList
solarParams[‘distributor_id’] = ”
solarParams[‘distributor_tariff_id’] = “5927”
solarParams[‘latitude’] = 41.56819
solarParams[‘longitude’] = –73.83502
solarParams[‘hourly_customer_load’] = hourly_customer_load
#Set the following params to run a bill with solar
solarParams[‘battery_duration’] = ‘0’
solarParams[‘battery_id’] = 0
solarParams[‘additional_fixed_charge’] = 500 # $
solarParams[‘ppa’] = 50 # $(kWh)
solarParams[‘system_size’] = 1000 # kW
#Write second payload to a JSON file – optional
with open(‘compareSolarPayload2.json’, ‘w’, encoding=‘utf-8’) as file:
json.dump(solarParams, file)
print(“Second bill payload written to “ + file.name + “\n“)
url = host + ‘/ecservice/calculate_custom_economy’
header = {“content-type”: “application/json”}
#Make first call to bill calculation endpoint
response1 = requests.post(url, data = json.dumps(params), headers=header, verify=True, cookies=authcookie)
if response1.text == “{Unauthorized}“:
sys.exit(“First API call failed. Bad authentication.”)
#Make second call to bill calculation endpoint
response2 = requests.post(url, data=json.dumps(solarParams), headers=header, verify=True, cookies=authcookie)
if response2.text == “{Unauthorized}“:
sys.exit(“Second API call failed. Bad authentication.”)
#Write first response to a file
f = open(“compareSolar1.json”, “w”)
f.write(response1.text)
print(“First output written to “ + f.name + “\n“)
#Write second response to a file
f = open(“compareSolar2.json”, “w”)
f.write(response2.text)
print(“Second output written to “ + f.name + “\n“)
#Close file
f.close()
The sample code above generates the following payloads. The first of which runs a normal retail bill, while the second runs a bill with solar.
{
“price_node_id“: 2966,
“usage_by_month“:
[
{
“startDate“: “2023-05-01”,
“endDate“: “2023-05-31”,
“usage“: “1000”,
“actual_usage“: false,
“year“: “2023”,
“month“: “05”,
“perHour“:
{
“2023-05-01 00:00“: 1.3440860215053763,
}
}
],
“distributor_id“: “”,
“distributor_tariff_id“: “5927”,
“latitude“: 41.56819,
“longitude“: -73.83502,
“hourly_customer_load“:
{}
}
{
“price_node_id“: 2966,
“usage_by_month“:
[
{
“startDate“: “2023-05-01”,
“endDate“: “2023-05-31”,
“usage“: “1000”,
“actual_usage“: false,
“year“: “2023”,
“month“: “05”,
“perHour“:
{
“2023-05-01 00:00“: 1.3440860215053763,
}
}
],
“distributor_id“: “”,
“distributor_tariff_id“: “5927”,
“latitude“: 41.56819,
“longitude“: -73.83502,
“hourly_customer_load“:
{},
“battery_duration“: “0”,
“battery_id“: 0,
“additional_fixed_charge“: 500,
“ppa“: 50,
“system_size“: 1000
}
The payload is described in the table below:
Field Name |
Data Type |
Description |
Example |
price_node_id |
Integer |
Unique Clarity Grid identifier assigned to the price node that you’d like to run a bill with. |
“price_node_id“: 2966, |
usage_by_month |
Collection |
Collection of monthly usage data. |
“usage_by_month“: [ { “startDate“: “2023-05-01”, “endDate“: “2023-05-31”, “usage“: “100000”, “actual_usage“: false, “year“: “2023”, “month“: “05”, “perHour“: { “2023-05-01 00:00“: 1.3440860215053763, } } ], |
startDate |
String |
Start date of the month of data. |
“startDate“: “2023-05-01”, |
endDate |
String |
End date of the month of data. |
“endDate“: “2023-05-31”, |
usage |
String |
Usage (in kWh) for the month. |
“usage“: “1000”, |
actual_usage |
Boolean |
Whether or not the usage this month is actual metered usage or an estimate. |
“actual_usage“: false, |
year |
String |
Year of the data. |
“year“: “2023”, |
month |
String |
Month of the data. |
“month“: “05”, |
perHour |
Collection |
Collection of hourly data for the month, calculated by dividing the monthly usage by the number of days between the start and end dates, and dividing that by 24 (the hours in a day). (Only necessary when using estimated usage) |
“perHour“: { “2023-05-01 00:00“: 1.3440860215053763, } |
distributor_id |
String |
Unique Clarity Grid identifier for the Distributor of the Tariff a user is running a bill for (can be left blank). |
“distributor_id“: “”, |
distributor_tariff_id |
String |
Unique Clarity Grid identifier for the Tariff a user is running a bill for. |
“distributor_tariff_id“: “5927”, |
latitude |
Float |
Latitude of the price node a user is running a bill with. |
“latitude“: 41.56819, |
longitude |
Float |
Longitude of the price node a user is running a bill with. |
“longitude“: -73.83502, |
hourly_customer_load |
Collection |
Collection of hourly usage data for the time range. (Only necessary when using actual usage) |
“hourly_customer_load“: {} |
battery_duration |
String |
Duration of battery discharge (in hours) |
“battery_duration“: “0”, |
battery_id |
Integer |
Id of the battery to be used in the bill calculations. (Entering ‘0’ will choose a battery based on the duration entered) |
“battery_id“: 0 |
additional_fixed_charge |
Float |
Increases the monthly fixed charges by this amount. |
“additional_fixed_charge“: 500, |
ppa |
Float |
Power Purchase Agreement amount ($/kWh) |
“ppa“: 50, |
system_size |
Integer |
DC system size (in kW). |
“system_size“: 1000 |
The fields in the API’s response that are relevant to Solar are as follows:
Field Name |
Data Type |
Description |
Example |
monthlyPPA |
Collection |
Collection of PPA prices for each month of the bill. |
“monthlyPPA“: [ 6585601.440000007 ], |
ppacost |
Integer |
Sum of all prices in the monthlyPPA collection. |
“ppacost“: 6585601.440000007, |