Repository navigation
Conversation
HistoricalCarbonIntensity sets CARBON_INTENSITY to the average operating emissions rate (AOER) that the WattTime API publishes for the grid region of the cloud region, averaged over the usage period of the row. Credentials come from WATTTIME_USERNAME and WATTTIME_PASSWORD. The WattTime region of each cloud region and the figures of each month are fetched once per JVM. The usage period is read from the FOCUS columns, else the CUR ones. Rows outside the coverage of WattTime keep their previous value.
The usage period comes from the FOCUS columns, the CUR columns or the Azure date, which covers the whole day in UTC, through a new RowColumn.getInstant that reads Spark timestamps, Spark dates and ISO instants. A line item keeps its previous carbon intensity when its cloud region has no coordinates, when it has no usable date, when its usage ends before it starts or when it spans two months. The module logs in again once when its token has expired. The WattTime URL is no longer configurable. modules.md describes the module, its scope (AOER excludes lifecycle emissions), the account it needs and how to configure it.
RowColumn.getInstant now also reads Spark instants, timestamps without a time zone and the date strings getDate reads, such as the 06/23/2026 of Azure CSV exports, which shares the parsing with getDate. When the account has no access to the figures of a WattTime region, its line items keep the previous value and the module logs a warning. A failed login stops the job with its own message, so that its HTTP status is not taken for missing figures. The watttime package gets its package-info.
jnioche
reviewed
Oct 27, 2026
The WattTime region of each cloud region now comes from watttime/regions.csv, generated by scripts/fetch_watttime_regions.sh, instead of a call to /v3/region-from-loc while the job runs. The module becomes an abstract class reading the usage period of FOCUS reports, with a subclass for AWS, reading the CUR dates, and one for Azure, reading the day of usage. The Javadoc of the average explains why a line item gets the mean of the hourly figures.
jnioche
requested changes
Oct 28, 2026
Collaborator
Author
|
Added some parametrized tests where I can to cut duplication |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #6, for WattTime.
Adds optional modules which take the carbon intensity of a line item from the WattTime API, for the time of its usage. It replaces the yearly Ember or monthly NESO figures.
What it does
watttime.aws.HistoricalCarbonIntensityandwatttime.azure.HistoricalCarbonIntensity, for custom configurations only. As discussed in Module for accurate carbon intensity factors from ElectricityMaps / Watttime #6, they call the API while the job runs, with the user's own account, and keep the data in memory only.WATTTIME_USERNAMEandWATTTIME_PASSWORDenvironment variables. On a cluster, set them on the executors.scripts/fetch_watttime_regions.shmaps each cloud region to its WattTime region with/v3/region-from-loc, from the coordinates incloud_regions.json, and writeswatttime/regions.csv./v3/historicalreturns the figures one calendar month (UTC) at a time, cached on each executor.AbstractHistoricalCarbonIntensityreadsChargePeriodStart/ChargePeriodEndfor FOCUS. The AWS subclass readsline_item_usage_start_date/line_item_usage_end_datefor CUR, the Azure one the whole UTC day ofDate. WattTime publishes AOER for each hour, so a line item gets the mean of the hourly figures within its period.ember.AverageCarbonIntensityandneso.MonthlyCarbonIntensity, as suggested in Module for accurate carbon intensity factors from ElectricityMaps / Watttime #6, these line items get no operational emissions. The docs also describe adding it after them. The output then mixes lifecycle figures with figures for direct emissions only.RowColumn.getInstantreads a usage date from a Spark timestamp, a Spark date or a string, including theMM/dd/yyyydates of Azure CSV exports.docs/src/modules.md, plus the overview table and the pipeline diagram.scripts/README.mddescribes the new script.Written with the help of Claude Code 🤖