Integrating Hourly Energy Pricing into Powerwall-Dashboard #466
Replies: 2 comments 5 replies
-
Hi @SCHibbard I am also in the Chicago area on the hourly pricing plan (since AMI meter installed in 2015) and just got my 2x PW3 + enphase panels w/IQ8X inverters installed awaiting final inspection. I currently ingest the hourly pricing data into an influx DB for historical consumption/price monitoring but looking to get more sophisticated now that I will be generating credits. I presume you setup a separate datasource? Did you end up leveraging the Powerwall-Dashboard tools->mysql connector or did you go a different route. Anything you are willing to share (such as schema/grafana queries) or even potentially collaborate on would be appreciated. Thanks! |
Beta Was this translation helpful? Give feedback.
-
For folks like myself with sufficient battery storage that will be operating in self powered mode, I would likely value my generation at the fixed rate price since I can use my generated power at any time. So I would compute savings = (ComEd Generated Credit) + (kWh_locally_consumed * (Distribution_Facility_Charge + IL_Elec_Dist_Charge + PriceToCompareRate)) (See below for where I get these values). I am hoping I can programmatically get the ComEd Generated Credit from their website but if not, its one value I would have to inject into InfluxDB monthly and the other values only change year (Starting in June I believe). As for taxes and fees, I don't think the data entry is worth it and maybe a timeseries the latest fixed percentage can be used instead. For example, with my bills, it appears that 25% of the computed "savings" would get you pretty close. Anyways, on with the data dump..... In my mind, essentially what you are trying to do is come up with two things (savings and actual cost) and will need to balance between manual data entry and automation. SavingsThis is the "value" that your solar system provided. I think there are two ways to think about this. If you are on the BHES (ComEd's TOU plan), you can actually use the value of the credit you generated that month since you are not credited kWH but rather the cash value at the time of generation. Until my system is operational and starts to generate $ based credits, I won't know if this will be exposed anywhere in the various ComEd apis. There is a site that the NREL referenced that has detailed rate information APIs but appears to be horribly out of date (https://apps.openei.org/services/doc/rest/util_rates/?version=7) after I signed up for key to look around. Last update seems around 2016 and the source pages for the rates are all in the old site format (looks like you used to be able to get your rate information right from the site once you logged in). Electric Costs == Generation + TransmissionThe other option or if you are on the standard BES plan is to lookup the Price To Compare price as this factors in both electricity cost and transmission cost. PlugInIllinois lists the current Fixed Rate Electric cost + Transmission cost. Delivery == ComEd's last mile distributionGo to https://www.comed.com/current-rates-tariffs then click on your appropriate rate tariff and select A Guide to the Retail Customer’s Billed Delivery Service Charges (PDF) And its a PDF printout of a excel doc because OF COURSE.... so you will need a process to manually key this in every 3 months. The last column matches up with my bill. Tariff and FeesEach line item in this section has its own document. If you go to https://www.comed.com/current-rates-tariffs you can see the PDFs corresponding to the actual adjustments although the docs can be named slightly differently so human involvement will be required. Actual costsThis is what ComED is actually charging you. I was hoping to dig around find a way to get my bill in a format that is consumable by an API. ComEd actually uses Oracles Opower platform which has the capability to do such things however it appears that each utility has their own instance which has been customized to their own needs and wants. ComEd does not seem to have any endpoints that I can find that expose line item details however I am not sure that is exactly necessary. There is an endpoint that exposes a massive JSON with just about everything ComEd knows about you and powers the My Bill Details of the ComEd Dashboard. The tricky part is figuring out how to get to it. I was happy to stumble on a python module called Opower which is used by Home Assistant. I was hoping I could use it directly but as its a module designed to do one thing (get very basic consumption metrics), I couldn't easily leverage as a library import with my limited python skills so I opted to look how the comed (aka excelon) connector is implemented. I apologize for the python that is about to follow as I am sure it will make more experienced folks eyes bleed. Being more of a C# developer, I never really spent much time in python other than quick and dirty things. Most of the steps required to actually get logged in and get all the appropriate bearer/csrf/etc tokens was from the Exelon specific OPower connector. You just need to set the three variables at the top with your account specific credentials and account number ( I didn't feel like implementing account lookup for this quick POC ). All the usual disclaimers around lack of robust error checking, handling multiple accounts, non residential accounts, MFA, or other edge cases I can't even think of. Hopefully this could be a jumping off point to something more robust. If there is a way to directly leverage the connector, that would be awesome as I am sure that project will be much better at keeping it up to date as the site changes (they implemented significant changes earlier this year that resulted in them being down for well over a week if I recall) I would be really curious what this looks like for someone that has a month of production credits? # USER EDIT VARS
accountid = "0000000000" #must be quoted, get this from your bill PDF or the My Account page of the dashboard
username = '[email protected]' #What you use to login to comed's site
password = 'superdupersecrets'
# END USER EDIT VARS
import requests
import json
import re
import urllib3
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
url = 'https://secure.comed.com/Pages/Login.aspx?/login'
login_domain = 'secure.comed.com'
headers = {'User-Agent': USER_AGENT}
session = requests.Session()
response = session.get(url, headers=headers)
result = response.text
parsedResponseUrl = urllib3.util.parse_url(response.url)
if parsedResponseUrl.path.endswith("/authorize"):
settings_match = re.search(r"var SETTINGS = ({.*});", result)
assert settings_match
settings = json.loads(settings_match.group(1))
login_post_domain = parsedResponseUrl.host
assert login_post_domain
response = session.post(
"https://" + login_post_domain + settings["hosts"]["tenant"] + "/SelfAsserted",
params={
"tx": settings["transId"],
"p": settings["hosts"]["policy"]
},
data={
"request_type": "RESPONSE",
"signInName": username,
"password": password
},
headers={
"X-CSRF-TOKEN": settings["csrf"],
"User-Agent": USER_AGENT
}
)
result_json = json.loads(response.text)
if result_json["status"] != "200":
print("Login Failed")
print(result_json["message"])
response = session.get(
"https://"
+ login_post_domain
+ settings["hosts"]["tenant"]
+ "/api/"
+ settings["api"]
+ "/confirmed",
params={
"rememberMe": settings["config"]["enableRememberMe"],
"csrf_token": settings["csrf"],
"tx": settings["transId"],
"p": settings["hosts"]["policy"],
"diags": json.dumps(
{
"pageViewId": settings["pageViewId"],
"pageId": settings["api"],
"trace": []
}
)
},
headers={"User-Agent": USER_AGENT}
)
# We are now logged in but have to acquire a bearer token
response = session.get(
"https://"
+ login_domain
+ "/api/Services/MyAccountService.svc/GetSession",
headers={"User-Agent": USER_AGENT}
)
result_json = json.loads(response.text)
bearer_token = result_json["token"]
#print(json.dumps(result_json, indent=2))
response = session.get(
"https://" + login_domain
+ "/.euapi/mobile/custom/auth/accounts/"
+ accountid
+ "?payments=false",
headers={
"User-Agent": USER_AGENT,
"Authorization": "Bearer " + bearer_token
}
)
accountJson = json.loads(response.text)
#print(json.dumps(accountJson))
#print(json.dumps(accountJson["data"]["BillingInfo"], indent=2))
print("Supply: $" + str(accountJson["data"]["BillingInfo"]["supplyCharges"]))
print("Delivery: $" + str(accountJson["data"]["BillingInfo"]["deliveryCharges"]))
print("Taxes And Fees: $" + str(accountJson["data"]["BillingInfo"]["taxesAndFees"])) |
Beta Was this translation helpful? Give feedback.
-
@jasonacox suggested I post some dashboard panels I have added to Powerwall-Dashboard. The first set is for energy pricing. Commonwealth Edison, the main Northern Illinois energy provider, offers hourly pricing rates (https://hourlypricing.comed.com). They also offer an API to pull current pricing (see https://hourlypricing.comed.com/hp-api). They publish pricing updates every 5-minutes. The rate used for billing is based on an hourly average of the 5-minute prices (:00 to :55) for the hour the energy was consumed. ComEd’s API offers an Hourly Average, but the value is incorrect, as it calculates the past hour average, not top of hour to 55 past. So just the 5-minute value is pulled from the API, an hourly average is calculated from :00 to :55 and applied to energy used/credited/saved for that same hour. The Grafana Panels currently in use to display results are below. Note that are a bunch of other charges in a ComEd bill that are based mainly on KW consumption, crediting (if on net metering), or percentage of bill (taxes). Unfortunately many do not have a month-to-month rate consistency that can be reduced to a calculation. I wish the bills were as cheap as the one panel shows, but they are normally 5-7x that (!) Plan to investigate that more one of these days.
Beta Was this translation helpful? Give feedback.
All reactions