feat: get datacenter carbon intensity

This commit is contained in:
f
2023-01-22 20:42:55 -03:00
parent 0e0657d4b7
commit 0e89fb5329
3 changed files with 47 additions and 2 deletions

View File

@ -69,6 +69,10 @@ describe SWD do
it "should be renewable when specified" do
SWD.new(AVERAGE_WEBSITE_IN_BYTES, true).datacenter_carbon_intensity.should(eq SWD::RENEWABLES_GRID_INTENSITY)
end
it "can be initialized with a country iso code" do
SWD.new(AVERAGE_WEBSITE_IN_BYTES, false, "AR").datacenter_carbon_intensity.should(eq SWD::IntensityData.by_iso("AR"))
end
end
describe "#device_carbon_intensity" do

View File

@ -10,9 +10,14 @@
# smaller and we don't need to make assumptions.
#
# @see https://sustainablewebdesign.org/calculating-digital-emissions/
require "./swd/intensity_data"
class SWD
getter bytes : Int8 | Int16 | Int32 | Int64 | UInt8 | UInt16 | UInt32 | UInt64
getter renewable : Bool
getter datacenter_iso_code : String?
getter intensity_calculator : Symbol
GIGABYTE = 1000.0 * 1000.0 * 1000.0
KWH_PER_GB = 0.81
@ -36,7 +41,7 @@ class SWD
@datacenter_co2 : Float32? | Float64? = nil
@total_co2 : Float32? | Float64? = nil
def initialize(@bytes, @renewable = false); end
def initialize(@bytes, @renewable = false, @datacenter_iso_code = nil, @intensity_calculator = :marginal); end
def transfered_bytes_to_gb
@transfered_bytes_to_gb ||= @bytes / GIGABYTE
@ -66,8 +71,10 @@ class SWD
@datacenter_energy ||= energy_usage * DATACENTER_ENERGY
end
# Returns the carbon intensity depending on renewable status and
# location, by default uses global grid intensity.
def datacenter_carbon_intensity : Float
renewable ? RENEWABLES_GRID_INTENSITY : GLOBAL_GRID_INTENSITY
renewable ? RENEWABLES_GRID_INTENSITY : (localized_datacenter_intensity || GLOBAL_GRID_INTENSITY)
end
def device_carbon_intensity : Float
@ -101,4 +108,10 @@ class SWD
def total_co2
@total_co2 ||= production_co2 + network_co2 + datacenter_co2 + consumer_device_co2
end
def localized_datacenter_intensity : Float64?
return unless datacenter_iso_code
SWD::IntensityData.by_iso(datacenter_iso_code || "", intensity_calculator)
end
end

28
src/swd/intensity_data.cr Normal file
View File

@ -0,0 +1,28 @@
class SWD
module IntensityData
# @see {co2.js/data/output/average-intensities-2021.json}
AVERAGE_INTENSITY_BY_ISO_CODE = {"AR": 365.292, "AM": 206.522, "AU": 526.876, "AT": 145.083, "AZ": 536.585, "BD": 559.606, "BY": 472.727, "BE": 156.063, "BO": 311.475, "BA": 470.982, "BR": 144.677, "BG": 364.136, "BI": 275.862, "CA": 123.859, "CL": 395.565, "CN": 549.288, "CR": 30.903, "HR": 212.161, "CY": 601.19, "CZ": 401.272, "DK": 240.419, "EC": 132.964, "EG": 470.879, "SV": 180.87, "EE": 488.529, "FI": 152.651, "FR": 67.781, "GE": 105.685, "DE": 363.982, "GR": 363.388, "HU": 236.271, "IN": 632.656, "IE": 361.274, "IT": 340.937, "JP": 460.647, "KZ": 656.097, "KE": 104.0, "LV": 226.351, "LT": 247.475, "LU": 183.824, "MT": 452.055, "MX": 391.582, "MD": 642.512, "MN": 725.26, "ME": 335.958, "NL": 386.189, "MK": 444.191, "NO": 26.131, "PK": 363.065, "PE": 241.492, "PH": 579.689, "PL": 657.138, "PT": 222.632, "RO": 255.718, "RU": 355.431, "SA": 568.967, "SN": 540.098, "RS": 549.083, "SG": 488.21, "SK": 173.854, "SI": 241.956, "ZA": 706.991, "KR": 442.389, "ES": 193.737, "SE": 43.9, "CH": 58.952, "TW": 565.629, "TJ": 72.823, "TH": 503.034, "TN": 470.848, "TR": 432.293, "UA": 240.28, "GB": 268.255, "US": 378.625, "VN": 491.192}
# @see {co2.js/data/output/marginal-intensities-2021.json}
MARGINAL_INTENSITY_BY_ISO_CODE = {"AF": 414.0, "AL": 0.0, "DZ": 528.0, "AS": 753.0, "AD": 188.0, "AO": 1476.0, "AI": 753.0, "AG": 753.0, "AR": 478.0, "AM": 390.0, "AW": 753.0, "AU": 808.0, "AT": 242.0, "AZ": 534.0, "BS": 753.0, "BH": 726.0, "BD": 528.0, "BB": 749.0, "BY": 400.0, "BE": 252.0, "BZ": 403.0, "BJ": 745.0, "BM": 753.0, "BT": 0.0, "BO": 604.0, "BQ": 753.0, "BA": 1197.0, "BW": 1486.0, "BR": 284.0, "VG": 753.0, "BN": 681.0, "BG": 911.0, "BF": 753.0, "BI": 414.0, "KH": 1046.0, "CM": 659.0, "CA": 372.0, "KY": 753.0, "CV": 753.0, "CY": 751.0, "CF": 188.0, "TD": 753.0, "CL": 657.0, "CN": 899.0, "CO": 410.0, "KM": 753.0, "CD": 0.0, "CG": 659.0, "CK": 753.0, "CR": 108.0, "CI": 466.0, "HR": 294.0, "CU": 559.0, "CW": 876.0, "CZ": 902.0, "DK": 362.0, "DJ": 753.0, "DM": 753.0, "DO": 601.0, "EC": 560.0, "EG": 554.0, "SV": 547.0, "GQ": 632.0, "ER": 915.0, "EE": 1057.0, "SZ": 0.0, "ET": 0.0, "FK": 753.0, "FO": 753.0, "FJ": 640.0, "FI": 267.0, "FR": 158.0, "GF": 423.0, "PF": 753.0, "GA": 946.0, "GM": 753.0, "GE": 289.0, "DE": 650.0, "GH": 495.0, "GI": 779.0, "GR": 507.0, "GL": 264.0, "GD": 753.0, "GP": 753.0, "GU": 753.0, "GT": 798.0, "GN": 753.0, "GW": 753.0, "GY": 847.0, "HT": 1048.0, "HN": 662.0, "HU": 296.0, "IS": 0.0, "IN": 951.0, "ID": 783.0, "IR": 592.0, "IQ": 1080.0, "IE": 380.0, "IM": 436.0, "IL": 394.0, "IT": 414.0, "JM": 711.0, "JP": 471.0, "JO": 529.0, "KZ": 797.0, "KE": 574.0, "KI": 753.0, "KP": 754.0, "KR": 555.0, "XK": 1145.0, "KW": 675.0, "KG": 217.0, "LA": 1069.0, "LV": 240.0, "LB": 794.0, "LS": 0.0, "LR": 677.0, "LY": 668.0, "LI": 151.0, "LT": 211.0, "LU": 220.0, "MG": 876.0, "MW": 489.0, "MY": 551.0, "MV": 753.0, "ML": 1076.0, "MT": 520.0, "MH": 753.0, "MQ": 753.0, "MR": 753.0, "MU": 700.0, "YT": 753.0, "MX": 531.0, "FM": 753.0, "MD": 541.0, "MC": 158.0, "MN": 1366.0, "ME": 899.0, "MS": 753.0, "MA": 729.0, "MZ": 234.0, "MM": 719.0, "NA": 355.0, "NR": 753.0, "NP": 0.0, "NL": 326.0, "NC": 779.0, "NZ": 246.0, "NI": 675.0, "NE": 772.0, "NG": 526.0, "NU": 753.0, "MK": 851.0, "MP": 753.0, "NO": 47.0, "OM": 479.0, "PK": 592.0, "PW": 753.0, "PS": 719.0, "PA": 477.0, "PG": 597.0, "PY": 0.0, "PE": 473.0, "PH": 672.0, "PL": 828.0, "PT": 389.0, "PR": 596.0, "QA": 503.0, "RE": 772.0, "RO": 489.0, "RU": 476.0, "RW": 712.0, "SH": 753.0, "KN": 753.0, "LC": 753.0, "MF": 753.0, "PM": 753.0, "VC": 753.0, "WS": 753.0, "SM": 414.0, "ST": 753.0, "SA": 592.0, "SN": 870.0, "RS": 1086.0, "SC": 753.0, "SL": 489.0, "SG": 379.0, "SX": 753.0, "SK": 332.0, "SI": 620.0, "SB": 753.0, "SO": 753.0, "ZA": 1070.0, "SS": 890.0, "ES": 402.0, "LK": 731.0, "SD": 736.0, "SR": 1029.0, "SE": 68.0, "CH": 48.0, "SY": 713.0, "TW": 484.0, "TJ": 255.0, "TZ": 531.0, "TH": 450.0, "TL": 753.0, "TG": 859.0, "TO": 753.0, "TT": 559.0, "TN": 468.0, "TR": 376.0, "TM": 927.0, "TC": 753.0, "TV": 753.0, "UG": 279.0, "UA": 768.0, "AE": 556.0, "GB": 380.0, "US": 416.0, "UY": 174.0, "UZ": 612.0, "VU": 753.0, "VE": 711.0, "VN": 560.0, "VI": 650.0, "YE": 807.0, "ZM": 416.0, "ZW": 1575.0}
# Return the marginal intensity for a country when provided an ISO
# code
def self.marginal_by_iso(iso : String) : Float64?
MARGINAL_INTENSITY_BY_ISO_CODE[iso]
end
# Return the average intensity for a country when provided an ISO
# code
def self.average_by_iso(iso : String) : Float64?
AVERAGE_INTENSITY_BY_ISO_CODE[iso]
end
def self.by_iso(iso : String, type : Symbol = :marginal) : Float64?
case type
when :average then average_by_iso(iso)
else marginal_by_iso(iso)
end
end
end
end