├── .DS_Store ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── Carbon_Aware_API ├── README.md ├── __pycache__ │ ├── constant_definitions.cpython-39.pyc │ └── wsgi.cpython-37.pyc ├── app-reference.py ├── app │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-37.pyc │ │ ├── __init__.cpython-38.pyc │ │ ├── __init__.cpython-39.pyc │ │ ├── data.cpython-38.pyc │ │ ├── data.cpython-39.pyc │ │ ├── utils.cpython-37.pyc │ │ ├── utils.cpython-38.pyc │ │ └── utils.cpython-39.pyc │ ├── caches │ │ ├── AzureDataCenter.py │ │ └── __pycache__ │ │ │ └── AzureDataCenter.cpython-39.pyc │ ├── cluster.py │ ├── data.py │ ├── routes │ │ ├── __pycache__ │ │ │ ├── ci_data.cpython-37.pyc │ │ │ ├── ci_data.cpython-38.pyc │ │ │ ├── ci_data.cpython-39.pyc │ │ │ ├── shift.cpython-37.pyc │ │ │ ├── shift.cpython-38.pyc │ │ │ ├── shift.cpython-39.pyc │ │ │ ├── static.cpython-37.pyc │ │ │ ├── static.cpython-38.pyc │ │ │ └── static.cpython-39.pyc │ │ ├── ci_data.py │ │ ├── shift.py │ │ └── static.py │ ├── services │ │ └── cron_service.py │ ├── static │ │ ├── GPU_Energy.csv │ │ ├── Region-SKU-Tags.csv │ │ ├── az_regions.json │ │ ├── azure_mlsetup_cost.csv │ │ ├── azure_network_latency.csv │ │ ├── css │ │ │ └── main.css │ │ ├── display_to_name.json │ │ ├── login_creds.json │ │ ├── name_to_display.json │ │ ├── swagger5.yaml │ │ └── yearly_region_avg.csv │ ├── templates │ │ ├── api_docs.html │ │ ├── api_use.html │ │ ├── appendix.html │ │ ├── az_error.html │ │ ├── az_find.html │ │ ├── ba_error.html │ │ ├── bad_loc.html │ │ ├── case_study.html │ │ ├── ci_error.html │ │ ├── ci_find.html │ │ ├── data_error.html │ │ ├── datachoice_combo.html │ │ ├── deck.html │ │ ├── docs_page.html │ │ ├── footprint.html │ │ ├── kb_cite.html │ │ ├── kb_summary.html │ │ ├── load_shift_eval.html │ │ ├── load_shift_eval_2.html │ │ ├── load_shift_eval_2_master.html │ │ ├── load_shift_eval_geotime.html │ │ ├── load_shift_eval_master.html │ │ ├── load_shift_geo_eval.html │ │ ├── loc_error.html │ │ ├── miro.html │ │ ├── monitor_docs.html │ │ ├── monitor_docs2.html │ │ ├── monitor_setup.html │ │ ├── overview.html │ │ ├── pred_error.html │ │ ├── pred_shift_find.html │ │ ├── pred_shift_find_hidden.html │ │ ├── prediction_made.html │ │ ├── region.html │ │ ├── region_bad_freq.html │ │ ├── report_final.html │ │ ├── report_final_util.html │ │ ├── start.html │ │ └── template.html │ └── utils.py ├── constant_definitions.py ├── historical_zipfiles │ ├── CAISO_NORTH_historical.zip │ ├── None_historical.zip │ └── Placeholder_zip.zip ├── local_files │ ├── all_regions_forecasts.json │ ├── data_for_table.json │ ├── time_series_table_data.csv │ └── usage_data.json ├── requirements.txt ├── target │ └── pylist.json ├── uploads │ └── Metrics_energy.xlsx └── wsgi.py ├── Carbon_Aware_Core_UI ├── .DS_Store ├── README.html ├── README.md └── React_Interface │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── green-icon.png │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt │ └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── components │ ├── footer │ │ ├── Footer.css │ │ └── Footer.js │ └── nav │ │ ├── Nav.css │ │ └── Nav.js │ ├── img │ ├── accept.png │ ├── desc_img.jpeg │ ├── error.png │ ├── home_title.png │ ├── intensity.jpg │ ├── logo.png │ ├── logo2.png │ ├── shifting.png │ └── split.png │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── pages │ ├── accept │ │ ├── Accept.css │ │ └── Accept.js │ ├── carbon_intensity │ │ ├── CarbonIntensity.css │ │ └── CarbonIntensity.js │ ├── documentation │ │ ├── Documentation.css │ │ ├── Documentation.js │ │ └── resources │ │ │ ├── DocumentationContent.css │ │ │ ├── api_docs │ │ │ ├── ApiDocs.css │ │ │ └── ApiDocs.js │ │ │ ├── api_use │ │ │ ├── ApiUse.css │ │ │ └── ApiUse.js │ │ │ ├── case_study │ │ │ ├── CaseStudy.css │ │ │ └── CaseStudy.js │ │ │ ├── deck │ │ │ ├── Deck.css │ │ │ └── Deck.js │ │ │ ├── kb_cite │ │ │ ├── KbCite.css │ │ │ └── KbCite.js │ │ │ ├── kb_summary │ │ │ ├── KbSummary.css │ │ │ └── KbSummary.js │ │ │ ├── miro │ │ │ ├── Miro.css │ │ │ └── Miro.js │ │ │ └── monitor │ │ │ ├── Monitor.css │ │ │ └── Monitor.js │ ├── home │ │ ├── Home.css │ │ └── Home.js │ └── shifting │ │ ├── Shifting.css │ │ └── Shifting.js │ ├── reportWebVitals.js │ ├── setupTests.js │ └── utils │ └── fade-in-out.js ├── Documentation ├── Appendices.md ├── Case Studies │ ├── Carbon_trigger │ │ ├── README.md │ │ ├── carbon_trigger_eval.py │ │ └── time_shifting_eval_1P-2.py │ ├── Organizational_Shifting │ │ ├── README.md │ │ ├── geo_shifting_eval_1P.py │ │ └── time_shifting_eval_1P.py │ └── README.md ├── Methods.md ├── References.md └── Validation │ └── README.md ├── LICENSE ├── README.md └── Retrieve_Energy_Metrics ├── AzureMonitorQuery ├── AzureMonitorFileDownload.md ├── README.md ├── query.py ├── requirements.txt └── unpack.py └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/.DS_Store -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | 134 | # pytype static type analyzer 135 | .pytype/ 136 | 137 | # Cython debug symbols 138 | cython_debug/ 139 | 140 | .idea -------------------------------------------------------------------------------- /Carbon_Aware_API/README.md: -------------------------------------------------------------------------------- 1 | # API Architecture 2 | 3 | ![Slide1](https://user-images.githubusercontent.com/80305894/133732784-a3cf30d2-577d-4efd-81e0-c5cc4211fc1c.jpg) 4 | Carbon Aware API 5 |

6 | 7 | 8 | ![Slide2](https://user-images.githubusercontent.com/80305894/133732786-353f6794-32ca-4049-a2ed-b0103005efb2.jpg) 9 | wsgi.py 10 |          11 | app 12 |          13 |

14 | 15 | ![Slide3](https://user-images.githubusercontent.com/80305894/133735224-0cc694e5-61fd-4d47-8df6-2213ca32a4c3.jpg) 16 | utils.py 17 |          18 | data.py 19 |          20 | services 21 |          22 | routes 23 |

24 | 25 | 26 | ![Slide4](https://user-images.githubusercontent.com/80305894/133736223-e47cbe41-d5e5-4ab0-9aea-ad829763f1a9.jpg) 27 | ci_data.py 28 |          29 | shift.py 30 |

31 | -------------------------------------------------------------------------------- /Carbon_Aware_API/__pycache__/constant_definitions.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/__pycache__/constant_definitions.cpython-39.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/__pycache__/wsgi.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/__pycache__/wsgi.cpython-37.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, jsonify, make_response, request, render_template, redirect, send_from_directory, url_for, Response 2 | from flask_swagger_ui import get_swaggerui_blueprint 3 | from os import path 4 | import json 5 | 6 | from flask_apscheduler import APScheduler 7 | 8 | SWAGGER_URL = '/swagger' 9 | API_URL = '/static/swagger5.yaml' 10 | 11 | swaggerui_blueprint = get_swaggerui_blueprint( 12 | SWAGGER_URL, 13 | API_URL, 14 | config={ 15 | 'app_name': "Carbon API testing" 16 | } 17 | ) 18 | 19 | """ 20 | DEFINING CONSTANTS 21 | """ 22 | 23 | 24 | """ 25 | Changing design pattern from monolith to application factory 26 | By returning an instance of the app instead of a monolith, it 27 | separates the dependency of app configuration and the app itself. 28 | 29 | For testing and maintainability, we could experiment with diff 30 | environments, URL routing, etc. by just specifying which config 31 | file to use. 32 | 33 | Default, it'll create the app as it did in the first iteration. 34 | """ 35 | 36 | 37 | def create_flask_app(config=None): 38 | app = Flask(__name__) 39 | if config: 40 | app.config.from_pyfile(config) 41 | else: 42 | current_directory = path.dirname(path.realpath('__file__')) 43 | upload_directory = path.join(current_directory, 'uploads') 44 | print(upload_directory) 45 | app.config['UPLOAD_FOLDER'] = upload_directory 46 | app.config['ROOT_DIR'] = current_directory 47 | app.register_blueprint(swaggerui_blueprint, url_prefix=SWAGGER_URL) 48 | scheduler = APScheduler() 49 | scheduler.init_app(app) 50 | scheduler.start() 51 | app.config['SCHEDULER'] = scheduler 52 | return app 53 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__pycache__/data.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/__pycache__/data.cpython-38.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__pycache__/data.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/__pycache__/data.cpython-39.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__pycache__/utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/__pycache__/utils.cpython-37.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__pycache__/utils.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/__pycache__/utils.cpython-38.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/__pycache__/utils.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/__pycache__/utils.cpython-39.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/caches/AzureDataCenter.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import requests 4 | from openpyxl.compat.singleton import Singleton 5 | from flask import request, make_response 6 | from requests.auth import HTTPBasicAuth 7 | from collections import namedtuple 8 | from datetime import datetime 9 | from datetime import timedelta 10 | from constant_definitions import DATA_CENTER_INFO_LOCATION 11 | 12 | 13 | def get_password(): 14 | if 'WT_PASSWORD' not in os.environ: 15 | print("Please set WT_PASSWORD as environment variable.") 16 | exit(-1) 17 | 18 | return os.environ['WT_PASSWORD'] 19 | 20 | 21 | def get_username(): 22 | if 'WT_USERNAME' not in os.environ: 23 | print("Please set WT_USERNAME as environment variable.") 24 | exit(-1) 25 | 26 | return os.environ['WT_USERNAME'] 27 | 28 | 29 | class AzureDataCenterInfo(metaclass=Singleton): 30 | """This class provide an interface to get all azure data center""" 31 | 32 | def __init__(self): 33 | self.data_center_info = [] 34 | # wattime token will expired in 30 minutes cache the token for 29 minutes before requesting another token. 35 | self.max_age = timedelta(minutes=29) 36 | self.CacheData = namedtuple("CacheData", "value createdDateTime") 37 | self.cache = {} 38 | self.login_url = 'https://api2.watttime.org/v2/login' 39 | 40 | def get_az(self): 41 | """ 42 | this gets Data Center information from a static file. 43 | work around to implementing OAUTH2 login for a live feed of Azure regions 44 | slowly changing list 45 | file is JSON of data stream from: subprocess.check_output("az account list-locations", shell=True) 46 | """ 47 | 48 | if not self.data_center_info: 49 | self.data_center_info = json.load(open(DATA_CENTER_INFO_LOCATION)) 50 | 51 | return self.data_center_info 52 | 53 | def get_token(self, username=get_username(), password=get_password()): 54 | """ 55 | This gets user name and password for WattTime from static file 56 | uses the credentials to ping WattTime API to generate a token to retrieve data 57 | """ 58 | 59 | if 'token' in self.cache and self.cache['token'].createdDateTime + self.max_age >= datetime.utcnow(): 60 | return self.cache.get('token').value 61 | 62 | # WattTime ping with creds 63 | token = requests.get(self.login_url, auth=requests.auth.HTTPBasicAuth(username, password)).json()['token'] 64 | self.cache['token'] = self.CacheData(token, datetime.utcnow()) 65 | return token 66 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/caches/__pycache__/AzureDataCenter.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/caches/__pycache__/AzureDataCenter.cpython-39.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/cluster.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from requests.auth import HTTPBasicAuth 3 | from app.caches.AzureDataCenter import AzureDataCenterInfo 4 | from openpyxl.compat.singleton import Singleton 5 | 6 | 7 | class Cluster(metaclass=Singleton): 8 | 9 | def __init__(self): 10 | self.wt_regions = [] 11 | self.azure_data_center_info = AzureDataCenterInfo() 12 | self.region_url = 'https://api2.watttime.org/v2/ba-from-loc' 13 | 14 | def get_wt_regions(self): 15 | if not self.wt_regions: 16 | self.convert_azure_cluster_to_wt_region() 17 | return self.wt_regions 18 | 19 | def get_header(self): 20 | return {'Authorization': 'Bearer {}'.format(self.azure_data_center_info.get_token())} 21 | 22 | def convert_azure_cluster_to_wt_region(self): 23 | azure_data_center = self.azure_data_center_info.get_az() 24 | login_url = 'https://api2.watttime.org/v2/login' 25 | token = requests.get(login_url, auth=HTTPBasicAuth("wibuchan", "greenAI")).json()['token'] 26 | headers = {'Authorization': 'Bearer {}'.format(token)} 27 | headers = self.get_header() 28 | for i in range(len(azure_data_center)): 29 | params = {'latitude': azure_data_center[i]['metadata']['latitude'], 30 | 'longitude': azure_data_center[i]['metadata']['longitude']} 31 | rsp = requests.get(self.region_url, headers=headers, params=params) 32 | self.wt_regions.append(rsp.text) -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/ci_data.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/ci_data.cpython-37.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/ci_data.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/ci_data.cpython-38.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/ci_data.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/ci_data.cpython-39.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/shift.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/shift.cpython-37.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/shift.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/shift.cpython-38.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/shift.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/shift.cpython-39.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/static.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/static.cpython-37.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/static.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/static.cpython-38.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/__pycache__/static.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/app/routes/__pycache__/static.cpython-39.pyc -------------------------------------------------------------------------------- /Carbon_Aware_API/app/routes/static.py: -------------------------------------------------------------------------------- 1 | # app/routes/static 2 | 3 | from flask import Blueprint, redirect 4 | from flask.helpers import url_for 5 | from flask.templating import render_template 6 | 7 | """ 8 | Meant to serve to hold static pages such as documentation or the start page 9 | """ 10 | 11 | static_bp = Blueprint('static_bp', __name__) 12 | 13 | 14 | @static_bp.route("/home") 15 | def home(): 16 | 17 | return render_template('start.html') 18 | 19 | 20 | @static_bp.route("/") 21 | def start(): 22 | return redirect(url_for('static_bp.home')) 23 | 24 | 25 | @static_bp.route('/docs_page') 26 | def docs_page(): 27 | return render_template('appendix.html') 28 | 29 | 30 | @static_bp.route('/deck') 31 | def deck(): 32 | return render_template('deck.html') 33 | 34 | 35 | @static_bp.route('/api_docs') 36 | def api_docs(): 37 | return render_template('api_docs.html') 38 | 39 | 40 | @static_bp.route('/monitor_docs') 41 | def monitor_docs(): 42 | return render_template('monitor_docs2.html') 43 | 44 | 45 | @static_bp.route('/case_study') 46 | def case_study(): 47 | return render_template('case_study.html') 48 | 49 | 50 | @static_bp.route('/kb_cite') 51 | def kb_cite(): 52 | return render_template('kb_cite.html') 53 | 54 | 55 | @static_bp.route('/kb_summary') 56 | def kb_summary(): 57 | return render_template('kb_summary.html') 58 | 59 | 60 | @static_bp.route('/api_use') 61 | def api_use(): 62 | return render_template('api_use.html') 63 | 64 | 65 | @static_bp.route('/other') 66 | def other(): 67 | return render_template('miro.html') 68 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/services/cron_service.py: -------------------------------------------------------------------------------- 1 | # this will hold cron-service files -------------------------------------------------------------------------------- /Carbon_Aware_API/app/static/Region-SKU-Tags.csv: -------------------------------------------------------------------------------- 1 | country,R_Tag_lock,region,sku 2 | Brazil,,Brazil South,"[""M60""]" 3 | Canada,Canada,Canada Central,"[""V100"",""MI25""]" 4 | Canada,Canada,Canada East,0 5 | United States,US,Central US,0 6 | United States,US,East US,"[""K80"",""T4"",""P100"",""V100"",""P40"",""M60"",""MI25"",""A100""]" 7 | United States,US,East US 2,"[""K80"",""T4"",""V100"",""M60"",""MI25""]" 8 | United States,US,North Central US,"[""K80"",""T4"",""M60"",""MI25""]" 9 | United States,US,South Central US,"[""K80"",""T4"",""P100"",""V100"",""M60"",""MI25""]" 10 | United States,US,West Central US,0 11 | United States,US,West US,"[""T4"",""V100"",""M60""]" 12 | United States,US,West US 2,"[""K80"",""T4"",""P100"",""V100"",""P40"",""M60"",""MI25"",""A100""]" 13 | United States,US,West US 3,0 14 | Germany,EU,Germany West Central,0 15 | Germany,EU,Germany North,0 16 | Netherlands,EU,West Europe,"[""K80"",""T4"",""P100"",""V100"",""P40"",""M60"",""MI25"",""A100""]" 17 | Australia,Australia,Australia Southeast,0 18 | Australia,Australia,Australia Central,0 19 | Australia,Australia,Australia East,"[""K80"",""T4"",""V100"",""M60"",""MI25""]" 20 | Australia,Australia,Australia Central 2,0 21 | United Kingdom,UK,UK South,"[""K80"",""T4"",""V100"",""M60"",""MI25""]" 22 | Ireland,EU,North Europe,"[""K80"",""T4"",""V100"",""M60"",""MI25""]" 23 | France,EU,France Central,"[""V100"",""M60""]" 24 | France,EU,France South,0 25 | Norway,EU,Norway East,0 26 | Norway,EU,Norway West,0 27 | United Kingdom,,UK West,0 28 | Switzerland,,Switzerland North,"[""V100"",""M60""]" 29 | Switzerland,,Switzerland West,0 30 | Korea,,Korea Central,"[""T4"",""V100"",""MI25""]" 31 | Japan,,Japan East,"[""T4"",""V100"",""M60"",""MI25""]" 32 | Korea,,Korea South,0 33 | Japan,,Japan West,0 34 | United Arab Emirates,,UAE North,"[""M60""]" 35 | United Arab Emirates,,UAE Central,0 36 | India,,Jio India West,0 37 | India,,West India,0 38 | India,,Central India,"[""T4"",""V100"",""M60"",""MI25""]" 39 | India,,South India,0 40 | Singapore,,Southeast Asia,"[""T4"",""P100"",""V100"",""P40"",""M60"",""MI25""]" 41 | South Africa,,South Africa West,0 42 | South Africa,,South Africa North,"[""M60""]" 43 | China,,East Asia,0 44 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/static/azure_mlsetup_cost.csv: -------------------------------------------------------------------------------- 1 | Regions,Cost 2 | Australia Central,1636 3 | Australia Central 2,1469 4 | Australia East,1418 5 | Australia Southeast,1354 6 | Brazil South,1798 7 | Canada Central,1258 8 | Canada East,1354 9 | Central India,1218 10 | Central US,1275 11 | East Asia,1749 12 | East US,1127 13 | East US 2,1127 14 | France Central,1318 15 | France South,1715 16 | Germany North,1757 17 | Germany West Central,1358 18 | Japan East,1458 19 | Japan West,1603 20 | Korea Central,1388 21 | Korea South,1302 22 | North Central US,1127 23 | North Europe,1258 24 | Norway East,1552 25 | Norway West,2017 26 | South Central US,1466 27 | Southeast Asia,1408 28 | South India,1590 29 | Southafrica West,1975 30 | South Africa North,1512 31 | Switzerland North,1490 32 | Switzerland West,1937 33 | UAE Central,1834 34 | UAE North,1490 35 | UK South,1307 36 | UK West,1364 37 | West Central US,1353 38 | West Europe,1358 39 | West India,1388 40 | West US,1327 41 | West US 2,1127 42 | Central US EUAP,1275 43 | East US 2 EUAP,1127 44 | West US 3,1327 45 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 5 auto; 3 | font-family: sans-serif; 4 | 5 | } -------------------------------------------------------------------------------- /Carbon_Aware_API/app/static/display_to_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "East US": "eastus", 3 | "East US 2": "eastus2", 4 | "South Central US": "southcentralus", 5 | "West US 2": "westus2", 6 | "Australia East": "australiaeast", 7 | "Southeast Asia": "southeastasia", 8 | "North Europe": "northeurope", 9 | "UK South": "uksouth", 10 | "West Europe": "westeurope", 11 | "Central US": "centralus", 12 | "North Central US": "northcentralus", 13 | "West US": "westus", 14 | "South Africa North": "southafricanorth", 15 | "Central India": "centralindia", 16 | "East Asia": "eastasia", 17 | "Japan East": "japaneast", 18 | "Korea Central": "koreacentral", 19 | "Canada Central": "canadacentral", 20 | "France Central": "francecentral", 21 | "Germany West Central": "germanywestcentral", 22 | "Norway East": "norwayeast", 23 | "Switzerland North": "switzerlandnorth", 24 | "UAE North": "uaenorth", 25 | "Brazil South": "brazilsouth", 26 | "Central US (Stage)": "centralusstage", 27 | "East US (Stage)": "eastusstage", 28 | "East US 2 (Stage)": "eastus2stage", 29 | "North Central US (Stage)": "northcentralusstage", 30 | "South Central US (Stage)": "southcentralusstage", 31 | "West US (Stage)": "westusstage", 32 | "West US 2 (Stage)": "westus2stage", 33 | "Asia": "asia", 34 | "Asia Pacific": "asiapacific", 35 | "Australia": "australia", 36 | "Brazil": "brazil", 37 | "Canada": "canada", 38 | "Europe": "europe", 39 | "Global": "global", 40 | "India": "india", 41 | "Japan": "japan", 42 | "United Kingdom": "uk", 43 | "United States": "unitedstates", 44 | "East Asia (Stage)": "eastasiastage", 45 | "Southeast Asia (Stage)": "southeastasiastage", 46 | "Central US EUAP": "centraluseuap", 47 | "East US 2 EUAP": "eastus2euap", 48 | "West Central US": "westcentralus", 49 | "West US 3": "westus3", 50 | "South Africa West": "southafricawest", 51 | "Australia Central": "australiacentral", 52 | "Australia Central 2": "australiacentral2", 53 | "Australia Southeast": "australiasoutheast", 54 | "Japan West": "japanwest", 55 | "Korea South": "koreasouth", 56 | "South India": "southindia", 57 | "West India": "westindia", 58 | "Canada East": "canadaeast", 59 | "France South": "francesouth", 60 | "Germany North": "germanynorth", 61 | "Norway West": "norwaywest", 62 | "Switzerland West": "switzerlandwest", 63 | "UK West": "ukwest", 64 | "UAE Central": "uaecentral", 65 | "Brazil Southeast": "brazilsoutheast" 66 | } -------------------------------------------------------------------------------- /Carbon_Aware_API/app/static/login_creds.json: -------------------------------------------------------------------------------- 1 | { 2 | "username": "######", 3 | "password": "######" 4 | } 5 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/static/name_to_display.json: -------------------------------------------------------------------------------- 1 | { 2 | "eastus": "East US", 3 | "eastus2": "East US 2", 4 | "southcentralus": "South Central US", 5 | "westus2": "West US 2", 6 | "australiaeast": "Australia East", 7 | "southeastasia": "Southeast Asia", 8 | "northeurope": "North Europe", 9 | "uksouth": "UK South", 10 | "westeurope": "West Europe", 11 | "centralus": "Central US", 12 | "northcentralus": "North Central US", 13 | "westus": "West US", 14 | "southafricanorth": "South Africa North", 15 | "centralindia": "Central India", 16 | "eastasia": "East Asia", 17 | "japaneast": "Japan East", 18 | "koreacentral": "Korea Central", 19 | "canadacentral": "Canada Central", 20 | "francecentral": "France Central", 21 | "germanywestcentral": "Germany West Central", 22 | "norwayeast": "Norway East", 23 | "switzerlandnorth": "Switzerland North", 24 | "uaenorth": "UAE North", 25 | "brazilsouth": "Brazil South", 26 | "centralusstage": "Central US (Stage)", 27 | "eastusstage": "East US (Stage)", 28 | "eastus2stage": "East US 2 (Stage)", 29 | "northcentralusstage": "North Central US (Stage)", 30 | "southcentralusstage": "South Central US (Stage)", 31 | "westusstage": "West US (Stage)", 32 | "westus2stage": "West US 2 (Stage)", 33 | "asia": "Asia", 34 | "asiapacific": "Asia Pacific", 35 | "australia": "Australia", 36 | "brazil": "Brazil", 37 | "canada": "Canada", 38 | "europe": "Europe", 39 | "global": "Global", 40 | "india": "India", 41 | "japan": "Japan", 42 | "uk": "United Kingdom", 43 | "unitedstates": "United States", 44 | "eastasiastage": "East Asia (Stage)", 45 | "southeastasiastage": "Southeast Asia (Stage)", 46 | "centraluseuap": "Central US EUAP", 47 | "eastus2euap": "East US 2 EUAP", 48 | "westcentralus": "West Central US", 49 | "westus3": "West US 3", 50 | "southafricawest": "South Africa West", 51 | "australiacentral": "Australia Central", 52 | "australiacentral2": "Australia Central 2", 53 | "australiasoutheast": "Australia Southeast", 54 | "japanwest": "Japan West", 55 | "koreasouth": "Korea South", 56 | "southindia": "South India", 57 | "westindia": "West India", 58 | "canadaeast": "Canada East", 59 | "francesouth": "France South", 60 | "germanynorth": "Germany North", 61 | "norwaywest": "Norway West", 62 | "switzerlandwest": "Switzerland West", 63 | "ukwest": "UK West", 64 | "uaecentral": "UAE Central", 65 | "brazilsoutheast": "Brazil Southeast" 66 | } -------------------------------------------------------------------------------- /Carbon_Aware_API/app/static/yearly_region_avg.csv: -------------------------------------------------------------------------------- 1 | Region,year_avg 2 | East US,606.9565521 3 | East US 2,606.4348987 4 | Central US,693.2553941 5 | North Central US,596.624364 6 | South Central US,527.7079339 7 | West Central US,689.5728817 8 | West US,385.4330786 9 | West US 2,503.7510696 10 | West US 3,471.4558392 11 | Australia Central,667.3571836 12 | Australia Central 2,667.3571836 13 | Australia East,667.3571836 14 | Australia Southeast,667.3571836 15 | France Central,275.4113306 16 | France South,275.4113306 17 | Germany Central,475.5329648 18 | Germany North,475.5329648 19 | North Europe,432.052215 20 | Norway East,369.2946084 21 | Norway West,369.2946084 22 | UK South,398.9655842 23 | West Europe,429.9341371 24 | Canada Central,362.6003748 25 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/api_docs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Azure GreenAPI 6 | 7 | 8 | 102 | 103 | 104 |
105 | 116 |
117 | 118 | 119 |
120 |
121 |

Accepted Input Formats for Timestamps

122 |
123 |

Preconfigured as ISO format preferred

124 |

125 |

Easy input with the following constraints:

126 |
    127 |
  • Possible value separators:
  • 128 |
      129 |
    • Spaces, Dashes, Backslashes
    • 130 |
    131 |


132 | Date: 133 |
  • If Month is written in english
  • 134 | 135 |
      136 |
    • month-day-year     ex: July 24 2020
    • 137 |
    • year-month-day     ex: 2020 July 24
    • 138 |
    • month-year-day     ex: July 2020 24
    • 139 |
    • day-year-month     ex: 24 2020 July
    • 140 |
    • year-day-month     ex: 2020 24 July
    • 141 |
    142 |
  • If month is numeric representation, day and month need to be connected with month preceding day
  • 143 |
      144 |
    • month-day-year     ex: 7/24/2020
    • 145 |
    • year-month-day     ex: 2020/7/24
    • 146 |
    147 |

    148 | Time - accepts both 12 and 24-hour clocks formats
    149 |
      150 |
    • Default input is 24-hour clock
    • 151 |
    • 12-hour am/pm designations accepted
    • 152 |
    153 |
    154 |
    Precision Designation:
    155 |
      156 |
    • Needs only 1 digit in hour position
    • 157 |
    • Must use colons to separate time precision levels
    • 158 |
    • Can specify time to only 2 digits of precision for each time position, down to seconds marker
    • 159 |
        160 |
      • Time precision format HH:MM:SS
      • 161 |
      • Ex: If 1 is input, it assumes 01:00:00
      • 162 |
      • Ex: If 1pm in input, it assumes 13:00:00
      • 163 |
      164 |
    165 |
    166 |
    Time Zone:
    167 |
  • Input with a ISO numeric offset
  • 168 |
      169 |
    • Ex: Time input as: 13:00:00-0800
    • 170 |
    171 |
  • If not preconfigured ISO:
  • 172 |
      173 |
    • A space is needed between datetime and time zone
    • 174 |
    • Explicitly designate time zone via standard abbreviation
    • 175 |
        176 |
      • Ex: PST, CST, PDT, etc.
      • 177 |
      178 |
    • Time zone is an optional time input
    • 179 | 180 |
    • If none designated, default assumption is UTC
    • 181 |
    182 | 183 |

    If no given datetime stamp is given for an endpoint that requires one as a parameter, defaults to current datetime as input.

    184 |
    185 |
    186 |
    187 |


    188 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/appendix.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Appendices 6 | 7 | 8 | 10 | 151 | 152 |
    153 | 164 |
    165 | 166 |
    167 |
    168 | 202 | 203 |
    204 |
    205 |
    206 |
    207 |
    208 | 209 |
    210 |
    211 |
    212 |
    213 |
    214 |
    215 | 216 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/az_error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 404 Error 4 | 107 | 108 | 109 |
    110 | 121 |
    122 | 123 |
    124 |

    Error! 404

    125 |

    Oops, this Azure region was not found, please try a different search method.

    126 | Back 127 | 128 |
    129 | 130 | 131 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/ba_error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 404 Error 4 | 107 | 108 | 109 |
    110 | 121 |
    122 | 123 |
    124 |

    Error! 404

    125 |

    Oops, this balancing authoruty does not support an Azure Region, please try a different search method.

    126 | Back 127 | 128 |
    129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/bad_loc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 404 Error 4 | 107 | 108 | 109 |
    110 | 121 |
    122 | 123 |
    124 |

    Error! 404

    125 |

    Oops, this is not a valid latitude-longitude pair. Please verify entry or try a different search method.

    126 | Back 127 | 128 |
    129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/case_study.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 404 Error 4 | 113 | 114 | 115 |
    116 | 127 |
    128 | 129 |
    130 | 131 |
    132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/ci_error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 404 Error 4 | 110 | 111 | 112 |
    113 | 124 |
    125 | 126 |
    127 |

    Error!

    128 |

    Oops, the data was not available, please {{msg}}

    129 | Begin Search 130 |
    131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/data_error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 404 Error 4 | 109 | 110 |
    111 |
    112 | 123 |
    124 | 125 |
    126 |

    Error!

    127 |

    Oops, the data was not available, please {{msg}}

    128 | Begin Search 129 |
    130 |
    131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/deck.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Azure GreenAI Carbon-Intensity API 6 | 7 | 8 | 10 | 161 | 162 |
    163 | 174 |
    175 | 176 |
    177 |
    178 |

    Project Slide Decks

    179 |
    180 |
    181 | 182 |
    183 |
    184 |

    Project Checkpoint Slide Deck

    185 |
    186 | 187 | 188 | 189 |
    190 |

    Slide deck for the halfway checkpoint of the project. Covers motivation for using marginal emissions as a metric and high-level architecture of the API. At this time, construction was beginning for load shifting features and calculating Azure emissions using WattTime grid records.

    191 |

    192 | 193 |
    194 |


    195 |
    196 |

    Project Conclusion Slide Deck

    197 |
    198 | 199 |
    200 | 201 | 202 | 203 |
    204 |

    Slide deck for the end of the project. Brief recap of project space and use of marginal emission metrics, followed by an outline of the project tools and methods. Ends with an exposition of the features Carbon Intensity API offers, recommended use cases, and an outline of work to take the project forward. At this stage, the Carbon Intensity API can deliver and analyze WattTime data, provide emissions profiles for energy profiles, and offer load shifting suggestions across regions or time.

    205 | 206 |
    207 |
    208 |
    209 | 210 | 211 | 212 |
    213 |
    214 |
    215 |
    216 |
    217 |
    218 | 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/docs_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Azure GreenAI Carbon-Intensity API 6 | 116 | 117 |
    118 | 129 |
    130 | 131 | 132 |
    133 | Mountain Image 134 |
    135 |

    Azure Carbon-Intelligent API Documentation

    136 | 137 |
    138 |
    139 | 140 |
    141 |

    To view Swagger, click here

    142 |

    To view Sources, click here

    143 |

    To view Appendices, click here

    144 |

    To view Team Info, click here

    145 |
    146 |



    147 | 148 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/load_shift_eval.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Azure GreenAI Carbon-Intensity API 4 | 5 | 6 | 8 | 9 | 177 | 178 |
    179 | 190 |
    191 | 192 |
    193 |
    194 |

    Time Shifting Prediction Results


    195 |
    196 |
    197 | 198 |

    Recommended Green Start Time

    199 |

    {{data.shiftTime}} UTC on {{data.shiftDate}}


    200 |
    201 | 202 |
    203 | 204 |

    Azure Region

    205 |

    {{data.shift_choice}}


    206 |
    207 | 208 |
    209 | 210 |

    Supporting Balancing Authority

    211 |

    {{data.shiftBA}}


    212 |
    213 |
    214 |

    Run Emissions: Reduced by {{data.shift_perc}}% by Time Shifting with a window size of {{data.window_size}}

    215 |

    Time (HH:MM:SS) Until Greenest Start Time: {{data.shift_delta}}


    216 |
    217 |
    218 |


    219 | 220 |
    221 |
    222 | Begin Another Search
    223 |
    224 |
    225 | Accept Suggestion 226 |
    227 |
    228 | 229 | 238 |



    239 | 240 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/load_shift_eval_2_master.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Error 5 | 6 | 7 | 9 | 10 | 126 | 127 |
    128 | 139 |
    140 | 141 |
    142 |
    143 |

    Load Shifting Prediction Results


    144 |

    New Azure Region: {{data.shiftAZ}}


    145 |

    New BA: {{data.shiftBA}}


    146 |

    Starting Emissions: Reduced by {{data.shift_perc}}%


    147 |


    148 | 149 | 150 |
    151 |
    152 | Begin Another Search
    153 |
    154 |
    155 | Accept Suggestion 156 |
    157 |
    158 | 159 | 168 | 169 | 170 |
    171 |
    172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/load_shift_eval_master.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Azure Carbon Intelligence API 5 | 6 | 7 | 9 | 10 | 131 | 132 |
    133 | 144 |
    145 | 146 |
    147 |
    148 |

    Load Shifting Prediction Results


    149 |

    New Start Time: {{data.shiftTime}} UTC on {{data.shiftDate}}


    150 |

    New Region: {{data.shift_choice}}


    151 |

    New BA: {{data.shiftBA}}


    152 |

    Starting Emissions: Reduced by {{data.shift_perc}}%


    153 |

    Time (HH:MM:SS) until greenest start: {{data.shift_delta}}


    154 | 155 | 156 | 157 |

    158 |
    159 |
    160 |
    161 | 162 | 163 |
    164 |
    165 | Begin Another Search
    166 |
    167 |
    168 | Accept Suggestion 169 |
    170 |
    171 | 172 | 181 | 182 |
    183 |
    184 | 185 |


    186 |
    187 | 190 |
    191 |



    192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/load_shift_geo_eval.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Azure GreenAI Carbon-Intensity API 4 | 5 | 6 | 8 | 9 | 184 | 185 | 186 |
    187 | 198 |
    199 | 200 |
    201 |
    202 |

    Geographic Shifting Prediction Results


    203 |
    204 |
    205 | 206 |

    Suggested Azure Region

    207 |

    {{data.shiftAZ}}


    208 |
    209 | 210 |
    211 | 212 |

    Supporting Balancing Authority

    213 |

    {{data.shiftBA}}


    214 |
    215 |
    216 | 217 |

    Starting Emissions: Reduced by {{data.shift_perc}}% if switched from {{data.inputRegion}} with a window size of {{data.window_size_in_minutes}} minutes.


    218 |
    219 | 220 | 221 |
    222 |
    223 | Begin Another Search
    224 |
    225 |
    226 | Accept Suggestion 227 |
    228 |
    229 | 230 | 239 |
    240 |
    241 | 242 | 243 | 244 | 245 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/loc_error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 404 Error 6 | 111 | 112 |
    113 | 124 |
    125 | 126 |
    127 |

    Error! 404

    128 |

    Oops, this Azure Region does not have an associated WattTime balancing authority, please try a different search method.

    129 | Back 130 |
    131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/miro.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Azure GreenAI Carbon-Intensity API 6 | 88 | 89 |
    90 | 101 |
    102 | 103 | 104 | 105 |
    106 |

    Design Diagram

    107 | 108 |
    109 | 110 |
    111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/monitor_setup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Azure GreenAI Carbon-Intensity API 6 | 87 | 88 |
    89 | 100 |
    101 | 102 |
    103 |
    104 | 105 |
    106 |
    107 | 108 |
    109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Azure GreenAPI 6 | 7 | 9 | Azure GreenAI Carbon-Intensity API 10 | 106 | 107 | 108 | 109 |
    110 | 121 |
    122 | 123 |
    124 |
    125 |

    {{data.name}}

    126 |
    127 |
    128 | 129 |
    130 |
    131 |
    132 | 133 |
    134 |
    135 |
    136 |
    137 |
    138 |

    Real-time emission:

    139 |

    Real-time emission: {{data.moer_value}}

    140 |
    141 |
    142 |
    143 |
    144 |
    145 | 146 | 147 |
    148 |
    149 |
    150 |
    151 |
    152 |

    Percentage times MOER is 0

    153 |

    Percentage: {{data.percent_zeros}}%

    154 |
    155 |
    156 |
    157 |
    158 |
    159 | 160 | 161 |
    162 |
    163 |
    164 |
    165 |
    166 |

    Average emission for last year

    167 |

    Average: {{data.aoer_value}}

    168 |
    169 |
    170 |
    171 |
    172 |
    173 |
    174 |
    -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/pred_error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Error 5 | 111 | 112 |
    113 |
    114 | 125 |
    126 | 127 | 128 |
    129 |

    Error!

    130 |

    Oops, the data was not available, please {{msg}}

    131 | Begin Search 132 |
    133 |
    134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/prediction_made.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Enter your title here 6 | 7 | 8 | 10 | 11 | 12 | 101 | 102 |
    103 | 114 |
    115 | 116 |
    117 |
    118 | 119 |
    120 |
    121 | 122 |
    123 |

    Thank You for Thinking Green!

    124 |

    Fun Fact!! Users on average reduce their cloud carbon footprint by {{data.carbon_to_date}}%

    125 | Back 126 | 127 |
    128 | 129 | 130 |
    131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /Carbon_Aware_API/app/templates/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Enter your title here 6 | 7 | 8 | 10 | 11 | 12 | 93 | 94 |
    95 | 106 |
    107 | 108 |
    109 |
    110 | 111 |
    112 |
    113 | 114 |
    115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /Carbon_Aware_API/constant_definitions.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | SITE_ROOT = os.path.dirname(os.path.abspath( 4 | __file__)) # This is your Project Root 5 | 6 | # Data center json data location 7 | DATA_CENTER_INFO_LOCATION = json_url2 = os.path.join( 8 | SITE_ROOT, "app", "static", "az_regions.json") 9 | -------------------------------------------------------------------------------- /Carbon_Aware_API/historical_zipfiles/CAISO_NORTH_historical.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/historical_zipfiles/CAISO_NORTH_historical.zip -------------------------------------------------------------------------------- /Carbon_Aware_API/historical_zipfiles/None_historical.zip: -------------------------------------------------------------------------------- 1 | {"error": "Invalid query parameters", "message": "must provide ba OR lat/long parameter"} -------------------------------------------------------------------------------- /Carbon_Aware_API/historical_zipfiles/Placeholder_zip.zip: -------------------------------------------------------------------------------- 1 | {"error": "Invalid query parameters", "message": "must provide ba OR lat/long parameter"} -------------------------------------------------------------------------------- /Carbon_Aware_API/local_files/data_for_table.json: -------------------------------------------------------------------------------- 1 | [{"Azure Region": {"0": "West US 2", "1": "West Central US", "2": "Canada Central", "3": "Germany North", "4": "Germany West Central", "5": "East US", "6": "North Central US", "7": "East US 2 EUAP", "8": "East US 2", "9": "South Central US", "10": "Central US EUAP", "11": "Central US", "12": "West US", "13": "Canada East", "14": "West Europe", "15": "Australia Southeast", "16": "Australia Central 2", "17": "Australia East", "18": "Australia Central", "19": "UK South", "20": "North Europe", "21": "France South", "22": "France Central", "23": "Norway East", "24": "Norway West", "25": "West US 3"}, "MOER Value": {"0": 1147, "1": 1501, "2": 1082, "3": 1291, "4": 1291, "5": 1477, "6": 1477, "7": 1477, "8": 1477, "9": 1175, "10": 1642, "11": 1642, "12": 949, "13": 1092, "14": 853, "15": 943, "16": 943, "17": 943, "18": 943, "19": 789, "20": 1105, "21": 616, "22": 616, "23": 1006, "24": 1006, "25": 908}}, {"Azure Region": {"0": "West US 2", "1": "West Central US", "2": "Canada Central", "3": "Germany North", "4": "Germany West Central", "5": "East US", "6": "North Central US", "7": "East US 2 EUAP", "8": "East US 2", "9": "South Central US", "10": "Central US EUAP", "11": "Central US", "12": "West US", "13": "Canada East", "14": "West Europe", "15": "Australia Southeast", "16": "Australia Central 2", "17": "Australia East", "18": "Australia Central", "19": "UK South", "20": "North Europe", "21": "France South", "22": "France Central", "23": "Norway East", "24": "Norway West", "25": "West US 3"}, "MOER Value": {"0": 1141, "1": 1646, "2": 1082, "3": 1364, "4": 1364, "5": 1475, "6": 1475, "7": 1475, "8": 1475, "9": 1191, "10": 1642, "11": 1642, "12": 967, "13": 1092, "14": 859, "15": 1619, "16": 1619, "17": 1619, "18": 1619, "19": 789, "20": 1105, "21": 616, "22": 616, "23": 1006, "24": 1006, "25": 914}}, {"Azure Region": {"0": "West US 2", "1": "West Central US", "2": "Canada Central", "3": "Germany North", "4": "Germany West Central", "5": "East US", "6": "North Central US", "7": "East US 2 EUAP", "8": "East US 2", "9": "South Central US", "10": "Central US EUAP", "11": "Central US", "12": "West US", "13": "Canada East", "14": "West Europe", "15": "Australia Southeast", "16": "Australia Central 2", "17": "Australia East", "18": "Australia Central", "19": "UK South", "20": "North Europe", "21": "France South", "22": "France Central", "23": "Norway East", "24": "Norway West", "25": "West US 3"}, "MOER Value": {"0": 1141, "1": 1646, "2": 1082, "3": 1364, "4": 1364, "5": 1475, "6": 1475, "7": 1475, "8": 1475, "9": 1191, "10": 1642, "11": 1642, "12": 967, "13": 1092, "14": 859, "15": 1619, "16": 1619, "17": 1619, "18": 1619, "19": 789, "20": 1105, "21": 616, "22": 616, "23": 1006, "24": 1006, "25": 914}}] -------------------------------------------------------------------------------- /Carbon_Aware_API/local_files/time_series_table_data.csv: -------------------------------------------------------------------------------- 1 | ,Carbon Emitted (lbs),Time,Energy (MWh) 2 | 0,0.0,2021-06-29 08:45:00,0.0 3 | 1,0.008372866698288,2021-06-29 08:50:00,5.719171242e-06 4 | 2,0.012598136745168,2021-06-29 08:55:00,8.605284662e-06 5 | 3,0.0,2021-06-29 09:00:00,0.0 6 | 4,0.001664894665248,2021-06-29 09:05:00,1.137223132e-06 7 | 5,0.0008535940162080001,2021-06-29 09:10:00,5.83056022e-07 8 | 6,0.0,2021-06-29 09:15:00,0.0 9 | 7,0.0,2021-06-29 09:20:00,0.0 10 | 8,0.002944675689072,2021-06-29 09:25:00,2.011390498e-06 11 | 9,0.002424548606304,2021-06-29 09:30:00,1.656112436e-06 12 | 10,0.0,2021-06-29 09:35:00,0.0 13 | 11,0.000118340094672,2021-06-29 09:40:00,8.0833398e-08 14 | 12,0.005611361433529999,2021-06-29 09:45:00,3.830280841999999e-06 15 | 13,0.00192403487256,2021-06-29 09:50:00,1.313334384e-06 16 | 14,0.0,2021-06-29 09:55:00,0.0 17 | -------------------------------------------------------------------------------- /Carbon_Aware_API/local_files/usage_data.json: -------------------------------------------------------------------------------- 1 | [{"usage":0 , "payload":{ 2 | "current_region" : "regionName", 3 | "current_region_avg" : "current_region_avg", 4 | "current_starttime" : "current_time", 5 | "greenest_region" : "minimum_region", "greenest_starttime" : "greenest_starttime", 6 | "greenest_region_BA" : "ba", 7 | "minimum_avg_moer" : "minimum_avg_moer", "percentage_decrease" : 0 , 8 | "window_size_in_minutes": 60 9 | }}] -------------------------------------------------------------------------------- /Carbon_Aware_API/requirements.txt: -------------------------------------------------------------------------------- 1 | APScheduler==3.7.0 2 | az==0.1.0.dev1 3 | bokeh 4 | certifi==2020.12.5 5 | chardet==4.0.0 6 | click==7.1.2 7 | colorama==0.4.4 8 | Flask==1.1.2 9 | flask-swagger-ui==3.36.0 10 | idna==2.10 11 | itsdangerous==1.1.0 12 | Jinja2==2.11.3 13 | Markdown==3.3.4 14 | MarkupSafe==1.1.1 15 | numpy==1.20.2 16 | packaging==20.9 17 | pandas==1.2.4 18 | path==15.1.2 19 | Pillow==8.2.0 20 | plotly==4.14.3 21 | PyJWT==2.0.1 22 | pyparsing==2.4.7 23 | python-dateutil==2.8.1 24 | pytz==2021.1 25 | PyYAML==5.4.1 26 | requests==2.25.1 27 | retrying==1.3.3 28 | six==1.15.0 29 | tornado==6.1 30 | typing-extensions==3.10.0.0 31 | urllib3==1.26.4 32 | Werkzeug==1.0.1 33 | xlrd >= 1.0.0 34 | openpyxl 35 | zipp==3.5.0 36 | charset-normalizer==2.0.3 37 | Flask-APScheduler==1.12.2 38 | -------------------------------------------------------------------------------- /Carbon_Aware_API/target/pylist.json: -------------------------------------------------------------------------------- 1 | [{"package": "flask", "version": "1.1.2", "deps": [{"package": "itsdangerous", "version": "1.1.0"}, {"package": "click", "version": "7.1.2"}, {"package": "markupsafe", "version": "1.1.1"}, {"package": "jinja2", "version": "2.11.3"}, {"package": "werkzeug", "version": "0.16.1"}]}] -------------------------------------------------------------------------------- /Carbon_Aware_API/uploads/Metrics_energy.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_API/uploads/Metrics_energy.xlsx -------------------------------------------------------------------------------- /Carbon_Aware_API/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | File declaration for web server. This will act as the "main.py" / "app.py" 3 | """ 4 | 5 | from app import create_flask_app 6 | from app.routes.static import static_bp 7 | from app.routes.ci_data import ci_bp 8 | from app.routes.shift import shift_bp 9 | from app.utils import * 10 | import datetime 11 | from flask_apscheduler import APScheduler 12 | 13 | app = create_flask_app() 14 | scheduler = APScheduler() 15 | scheduler.init_app(app) 16 | scheduler.start() 17 | 18 | ################################################ 19 | # CRON SCHEDULED JOBS 20 | ################################################ 21 | 22 | """ 23 | Will fire off every 15th minute. E.g. 3:00, 3:15, 3:30, 3:45, 4:00, and on. 24 | """ 25 | 26 | 27 | # If it doesn't fire off within 30 seconds, it'll redo it. 28 | @scheduler.task('cron', id="Updates forecast data for all AZ Regions", month="*", day="*", hour="*", minute="*/15", misfire_grace_time=30) 29 | def update_all_regions_forecast_data(): 30 | print("AMULET ENDPOINT: Updating All Regions Forecast Data") 31 | all_regions_forecasts = {} 32 | pattern = r'(\d{4}-\d{1,2}-\d{1,2}).*(\d{2}:\d{2}:\d{2})' 33 | for az_coords, ba in zip(az_coords_WT_joined[0], az_coords_WT_joined[1]): 34 | ba = json.loads(ba) 35 | # Using an iterator is much faster than converting the keys to a list, indexing, then comparing. Can compare directly. 36 | if next(iter(ba.keys())) == 'error': 37 | continue 38 | region_name = az_coords['name'] # Used as keys 39 | display_name = az_coords['displayName'] 40 | #print(region_name, display_name) 41 | region_data = get_region_forcast(ba['abbrev']) 42 | try: 43 | forecast_data = region_data['forecast'] 44 | except KeyError: 45 | continue 46 | """ 47 | Any region that isn't a primary key within the JSON file means there is no forecast data for it. 48 | """ 49 | # if not forecast_data: # Empty list == no available data 50 | # continue 51 | all_regions_forecasts[region_name] = {} 52 | all_regions_forecasts[region_name]['point_times'], all_regions_forecasts[region_name]['values'] = [ 53 | ], [] 54 | all_regions_forecasts[region_name]['ba'] = f"{ba['name']}, {ba['abbrev']}" 55 | all_regions_forecasts[region_name]['displayName'] = display_name 56 | for data in forecast_data: 57 | match = re.search(pattern, data['point_time']) 58 | year, month, day = [int(ymd) for ymd in match.group( 59 | 1).split("-")] # ymd = year month date 60 | hour, minute, second = [int(hms) 61 | for hms in match.group(2).split(":")] 62 | # Need to save in isoformat. Incompatible with json otherwise 63 | all_regions_forecasts[region_name]['point_times'].append( 64 | datetime.datetime(year, month, day, hour, minute, second).isoformat()) 65 | all_regions_forecasts[region_name]['values'].append(data['value']) 66 | all_regions_forecasts_json = json.dumps(all_regions_forecasts) 67 | if not os.path.isdir("./local_files"): 68 | os.mkdir("./local_files") 69 | with open("./local_files/all_regions_forecasts.json", "w") as all_regions_forecasts: 70 | json.dump(all_regions_forecasts_json, all_regions_forecasts, indent=4) 71 | return all_regions_forecasts_json 72 | 73 | 74 | if __name__ == '__main__': 75 | update_all_regions_forecast_data() 76 | app.register_blueprint(static_bp) 77 | app.register_blueprint(ci_bp) 78 | app.register_blueprint(shift_bp) 79 | app.run(debug=True) 80 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/.DS_Store -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Carbon Aware API UI 3 | 1. [Website Structure](#web_structure) 4 | 2. [User Flow Diagram](#user_flow) 5 | 3. [Style Guide](#style_guide) 6 | 4. [Design Principles](#design_principle) 7 | 5. [Get Started](#get_started) 8 | 9 | ## Website Structure 10 |
    11 | website structure 12 | 13 | ## User Flow Diagram 14 |
    15 | user flow diagram 16 | 17 | ## Style Guide 18 | - Primary Colors: 19 |
    20 | primary colors 21 | 22 | - Secondary Colors: 23 |
    24 | secondary colors 25 | 26 | - Font: "Segoe UI" 27 | 28 | ## Design Principles 29 | - Simplicity: easy to navigate, only include necessary elements 30 | - Usability: allow users to use the website without any hindrance 31 | - Comprehensibility: allow users to understand what is going on during their interactions 32 | - Elegance: create visuals that are beautiful, clean, and simple 33 | 34 | ## Get Started 35 | #### 1. Clone or download the app folder 36 | #### 2. Install all the dependencies and libraries 37 | - open your terminal 38 | - `cd` to the app folder directory 39 | - _Example: `cd ~/Desktop/app-folder-name`_ 40 | - use `npm install` to install npm 41 | - install the following react libraries 42 | - `npm install react-bootstrap` 43 | - `npm install react-dom` 44 | - `npm install react-icons` 45 | - `npm install react-plotly.js` 46 | - `npm install react-router-dom` 47 | - `npm install react-scroll-motion` 48 | - `npm install react-spinners` 49 | - `npm install react-tooltip` 50 | 51 | #### 3. Start the app 52 | - use `npm start` in your terminal to start the application 53 | 54 | #### _Please visit the "Documents" webpage in the React app for further information about the application or api routes_ 55 | 56 | user flow diagram 57 | 58 | 59 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "carbon-api", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.14.1", 7 | "@testing-library/react": "^11.2.7", 8 | "@testing-library/user-event": "^12.8.3", 9 | "bootstrap": "^5.1.2", 10 | "http-proxy-middleware": "^2.0.1", 11 | "react": "^17.0.2", 12 | "react-bootstrap": "^1.6.4", 13 | "react-dom": "^17.0.2", 14 | "react-icons": "^4.3.1", 15 | "react-plotly.js": "^2.5.1", 16 | "react-router-dom": "^5.3.0", 17 | "react-scripts": "^1.1.5", 18 | "react-scroll-motion": "^0.2.1", 19 | "react-spinners": "^0.11.0", 20 | "react-tooltip": "^4.2.21", 21 | "web-vitals": "^1.1.2" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build": "react-scripts build", 26 | "test": "react-scripts test", 27 | "eject": "react-scripts eject" 28 | }, 29 | "eslintConfig": { 30 | "extends": [ 31 | "react-app", 32 | "react-app/jest" 33 | ] 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.2%", 38 | "not op_mini all" 39 | ], 40 | "development": [ 41 | "last 1 chrome version", 42 | "last 1 firefox version", 43 | "last 1 safari version" 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /public/favicon.ico -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /public/green-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /public/green-icon.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Carbon Aware API 28 | 29 | 30 | 31 |
    32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /public/logo192.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /public/logo512.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/App.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: "Segoe UI"; 3 | } 4 | 5 | .App { 6 | text-align: center; 7 | } 8 | 9 | .App-logo { 10 | height: 40vmin; 11 | pointer-events: none; 12 | } 13 | 14 | .content { 15 | margin-top: 4.7rem; 16 | } 17 | 18 | @media (prefers-reduced-motion: no-preference) { 19 | .App-logo { 20 | animation: App-logo-spin infinite 20s linear; 21 | } 22 | } 23 | 24 | .App-header { 25 | background-color: #282c34; 26 | min-height: 100vh; 27 | display: flex; 28 | flex-direction: column; 29 | align-items: center; 30 | justify-content: center; 31 | font-size: calc(10px + 2vmin); 32 | color: white; 33 | } 34 | 35 | .App-link { 36 | color: #61dafb; 37 | } 38 | 39 | @keyframes App-logo-spin { 40 | from { 41 | transform: rotate(0deg); 42 | } 43 | to { 44 | transform: rotate(360deg); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { Route, Switch, Redirect } from 'react-router-dom'; 3 | import Nav from './components/nav/Nav' 4 | import Home from './pages/home/Home' 5 | // import Explore from './pages/explore/Explore' 6 | import Shifting from './pages/shifting/Shifting' 7 | import Documentation from './pages/documentation/Documentation' 8 | import Monitor from './pages/documentation/resources/monitor/Monitor' 9 | import ApiDocs from './pages/documentation/resources/api_docs/ApiDocs' 10 | import ApiUse from './pages/documentation/resources/api_use/ApiUse' 11 | import KbSummary from './pages/documentation/resources/kb_summary/KbSummary' 12 | import KbCite from './pages/documentation/resources/kb_cite/KbCite' 13 | import CaseStudy from './pages/documentation/resources/case_study/CaseStudy' 14 | import Deck from './pages/documentation/resources/deck/Deck' 15 | import Miro from './pages/documentation/resources/miro/Miro' 16 | import CarbonIntensity from './pages/carbon_intensity/CarbonIntensity' 17 | import fade_in_out from './utils/fade-in-out' 18 | import Accept from './pages/accept/Accept' 19 | import Footer from './components/footer/Footer' 20 | import './App.css' 21 | 22 | const App = () => { 23 | 24 | useEffect(fade_in_out, []) 25 | 26 | return ( 27 |
    28 |
    51 | ) 52 | }; 53 | 54 | export default App; 55 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/components/footer/Footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | margin-top: -5rem; 3 | background-color: #007fff; 4 | height: 15vh; 5 | } 6 | 7 | .footer-desc { 8 | margin-top: 3rem; 9 | margin-bottom: 3rem; 10 | } -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/components/footer/Footer.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import './Footer.css' 3 | 4 | 5 | const Footer = () => { 6 | 7 | return ( 8 |
    9 |

    Having trouble?

    10 |
    11 | ) 12 | }; 13 | 14 | export default Footer; -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/components/nav/Nav.css: -------------------------------------------------------------------------------- 1 | .navbar { 2 | font-size: 16px; 3 | } 4 | 5 | .nav { 6 | position: sticky; 7 | top: 0; 8 | left: 0; 9 | width: 100%; 10 | height: 4.8rem; 11 | padding: 0.2rem; 12 | padding-bottom: 10px; 13 | z-index: 6; 14 | background: transparent; 15 | } 16 | 17 | 18 | .nav.active { 19 | background: linear-gradient(90deg, #1a1a1f 0%, #1a1a1f 100%); 20 | } 21 | 22 | a { 23 | color: #007fff; 24 | text-decoration: none; 25 | } 26 | 27 | .navLink { 28 | color: white; 29 | text-decoration: none; 30 | padding: .8rem; 31 | vertical-align: middle; 32 | margin-bottom: 1rem; 33 | } 34 | 35 | a.navLink:hover { 36 | color: #3989D0; 37 | } 38 | 39 | ul { 40 | margin: 0; 41 | padding: 0; 42 | padding-top: .5rem; 43 | display: inline-block; 44 | } 45 | 46 | li { 47 | margin-bottom: 1rem; 48 | margin-left: 1rem; 49 | } 50 | 51 | .logo { 52 | padding-left: 1em; 53 | padding-right: 1em; 54 | height: 30px; 55 | vertical-align: middle; 56 | margin-bottom: 0.6rem; 57 | } 58 | 59 | 60 | 61 | ul.horizontal-list { 62 | min-width: 696px; 63 | list-style: none; 64 | } 65 | ul.horizontal-list li { 66 | display: inline; 67 | padding-bottom: 0.8rem; 68 | } 69 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/components/nav/Nav.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import logo from '../../img/logo.png' 4 | import logo2 from '../../img/logo2.png' 5 | 6 | import './Nav.css'; 7 | 8 | const Nav = () => { 9 | // Set up to change the navbar background color 10 | const [navbar, setNavBar] = useState(false); 11 | 12 | const changeBackground = () => { 13 | if(window.scrollY >= 80) { 14 | setNavBar(true); 15 | } else { 16 | setNavBar(false); 17 | } 18 | } 19 | 20 | window.addEventListener('scroll', changeBackground); 21 | 22 | // Return the navbar 23 | return ( 24 |
    25 | 37 |
    38 |
    39 | ); 40 | }; 41 | 42 | export default Nav; -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/accept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/accept.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/desc_img.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/desc_img.jpeg -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/error.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/home_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/home_title.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/intensity.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/intensity.jpg -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/logo.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/logo2.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/shifting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/shifting.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/img/split.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/img/split.png -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import reportWebVitals from './reportWebVitals'; 5 | import {BrowserRouter} from 'react-router-dom' 6 | import 'bootstrap/dist/css/bootstrap.css'; 7 | 8 | 9 | ReactDOM.render( 10 | 11 | 12 | 13 | 14 | , 15 | document.getElementById('root') 16 | ); 17 | 18 | // If you want to start measuring performance in your app, pass a function 19 | // to log results (for example: reportWebVitals(console.log)) 20 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 21 | reportWebVitals(); 22 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/accept/Accept.css: -------------------------------------------------------------------------------- 1 | .thank-you { 2 | font-size: 2.5rem; 3 | text-align: center; 4 | } 5 | 6 | div.icon-card { 7 | background-color: #E3E3E7; 8 | text-align: center; 9 | border-radius: 3rem; 10 | margin:3rem; 11 | padding-top: 1.5rem; 12 | padding-bottom: 1.5rem; 13 | width: 12rem; 14 | } 15 | 16 | .robot { 17 | margin-right: .5rem; 18 | border-radius: 3rem; 19 | } 20 | 21 | .thank-space { 22 | padding: 6.5rem; 23 | } -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/accept/Accept.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Accept.css' 3 | import acceptImg from '../../img/accept.png' 4 | import { Link } from 'react-router-dom'; 5 | 6 | const Accept = () => { 7 | 8 | return( 9 |
    10 |
    11 | {/* Add spacing */} 12 |
    13 |
    14 |
    15 | 16 | {/* Robot icon */} 17 |
    18 |
    19 | 20 |
    21 |
    22 |
    23 | 24 | {/* Thank you message */} 25 |

    Thank You for Thinking Green!!

    26 | 27 | {/* Add spacing */} 28 |
    29 |
    30 |
    31 | 32 | {/* Direct users to the main page */} 33 |
    34 | 35 |
    36 | 37 | {/* Add spacing */} 38 |
    39 |
    40 |
    41 |
    42 |
    43 | ); 44 | } 45 | 46 | export default Accept; 47 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/carbon_intensity/CarbonIntensity.css: -------------------------------------------------------------------------------- 1 | /* The whole shifting page */ 2 | .intensity { 3 | background-color: #1a1a1f; 4 | color: #E3E3E7; 5 | margin-top: -10rem; 6 | } 7 | 8 | /* Title Section */ 9 | .intensity-title-container { 10 | position: relative; 11 | text-align: center; 12 | } 13 | 14 | .intensity-title-image { 15 | -webkit-background-size: cover; 16 | -moz-background-size: cover; 17 | -o-background-size: cover; 18 | background-size: cover; 19 | width: 100%; 20 | height: 105vh; 21 | } 22 | 23 | .intensity-website-title { 24 | position: absolute; 25 | top: 45%; 26 | left: 50%; 27 | transform: translate(-50%, -50%); 28 | font-size: 4em; 29 | } 30 | 31 | /* Question page */ 32 | .question-title { 33 | font-size: 2em; 34 | text-align: center; 35 | } 36 | 37 | 38 | /* Form */ 39 | .card-body { 40 | background: #1a1a1f; 41 | font-size:1rem; 42 | height: 850px; 43 | } 44 | 45 | .box-label { 46 | font-size: 1rem; 47 | } 48 | 49 | .box-input { 50 | margin-left: 1rem; 51 | background: #1a1a1f; 52 | color: #E3E3E7; 53 | border-color: #E3E3E7; 54 | border-radius: 0.25rem; 55 | font-size: 1rem; 56 | width: 150px; 57 | height: 30px; 58 | } 59 | 60 | .green { 61 | color: #8EB93B; 62 | } 63 | 64 | .space { 65 | padding: 0.5rem; 66 | } 67 | 68 | .or { 69 | color: #007fff; 70 | margin-left: 2rem; 71 | margin-right: 2rem; 72 | } 73 | 74 | .tooltip-title { 75 | margin-top: 1rem; 76 | font-size: 1.5rem; 77 | } 78 | 79 | .tooltip-desc { 80 | font-size: 1rem; 81 | } 82 | 83 | .blue { 84 | color: #007fff; 85 | } 86 | 87 | .grey { 88 | color: grey; 89 | } 90 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/Documentation.css: -------------------------------------------------------------------------------- 1 | /* The whole documentation page */ 2 | .documentation { 3 | background-color: #1a1a1f; 4 | color: #E3E3E7; 5 | margin-top: -12rem; 6 | } 7 | 8 | /* Content */ 9 | .category-title { 10 | margin-left: 18%; 11 | } 12 | 13 | .doc-card-section { 14 | display: flex; 15 | flex-wrap: wrap; 16 | justify-content: left; 17 | margin-left: 18%; 18 | margin-right: 18%; 19 | } 20 | 21 | /* Cards */ 22 | .doc-card { 23 | position: relative; 24 | background-color: #8EB93B; 25 | height: 20rem; 26 | margin-top: 2rem; 27 | width: 20rem; 28 | float: left; 29 | margin-right: 0.5rem; 30 | color: #E3E3E7; 31 | padding: 0.5rem; 32 | } 33 | 34 | .doc-card-disabled { 35 | position: relative; 36 | background-color: grey; 37 | height: 20rem; 38 | margin-top: 2rem; 39 | width: 20rem; 40 | float: left; 41 | margin-right: 0.5rem; 42 | color: #E3E3E7; 43 | padding: 0.5rem; 44 | } 45 | 46 | .doc-card:hover { 47 | background-color: #007fff; 48 | } 49 | 50 | .doc-card-title { 51 | font-size: 2rem; 52 | margin-right: 50%; 53 | 54 | } 55 | 56 | .doc-card-desc { 57 | font-size: 1.25rem; 58 | margin-right: 50%; 59 | position: absolute; 60 | bottom: 0; 61 | left: 0.5rem; 62 | } -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/Documentation.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import './Documentation.css' 4 | 5 | const Documentation = () => { 6 | 7 | return( 8 |
    9 | 10 |
    11 |
    12 |
    13 | 14 |
    15 |

    Using the API

    16 | 17 |
    18 | 19 | 20 |
    21 |

    Data Retrieval

    22 |

    Walk through on pulling metric data from Azure Monitor

    23 |
    24 | 25 | 26 | 27 |
    28 |

    Query Formatting

    29 |

    Describes formatting requirements for input parameters

    30 |
    31 | 32 | 33 | 34 | 35 |
    36 |

    API Information

    37 |

    Detailed documents describing API use

    38 |
    39 | 40 | 41 | 42 |
    43 |

    Swagger

    44 |

    Update in progress

    45 |
    46 | 47 |
    48 | 49 | 50 |

    Project Information

    51 |
    52 | 53 |
    54 |

    Knowledge Base

    55 |

    Project Citations

    56 |
    57 | 58 |
    59 | {/*
  • Background Summary: Problem Space and Theory for Project Motivation
  • */} 60 | {/*
  • Case Study: Project Overview and Recommendations
  • */} 61 | 62 | 63 |

    Team Information and Progress

    64 |
    65 | 66 |
    67 |

    GitHub Repo

    68 |

    GreenAI-API team GitHub

    69 |
    70 |
    71 | 72 | 73 |
    74 |

    Decks

    75 |

    Slide decks from Vertical presentation

    76 |
    77 | 78 |
    79 | {/*
  • Miro: Relation diagram for API and UI
  • */} 80 | 81 |
    82 | 83 |
    84 |
    85 |
    86 | 87 |
    88 | ); 89 | } 90 | 91 | export default Documentation; -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/DocumentationContent.css: -------------------------------------------------------------------------------- 1 | .doc { 2 | background-color: #1a1a1f; 3 | color: #E3E3E7; 4 | margin-top: -12rem; 5 | } 6 | 7 | .doc-content { 8 | background-color: #8EB93B; 9 | width: 85%; 10 | margin-top: -12rem; 11 | } 12 | 13 | .doc-title { 14 | margin-left: -5rem; 15 | } 16 | 17 | .body { 18 | margin-left: 15rem; 19 | margin-right: 15rem; 20 | } 21 | 22 | .xs-extra-space { 23 | padding: 3rem; 24 | } -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/api_docs/ApiDocs.css: -------------------------------------------------------------------------------- 1 | .subBullet { 2 | margin-left: 2rem; 3 | } 4 | 5 | .mainInfo { 6 | margin-left: 2em; 7 | } 8 | 9 | .infoTitle { 10 | margin-top: 2em; 11 | } -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/api_docs/ApiDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './ApiDocs.css' 3 | 4 | const ApiDocs = () => { 5 | 6 | return( 7 |
    8 |
    9 |
    10 |
    11 |
    12 | 13 |
    14 |

    Accepted Input Formats for Timestamps

    15 | 16 |
    17 |

    Preconfigured as ISO format preferred

    18 |

    Easy input with the following constraints:

    19 |
      20 |
    • Possible value separators:
    • 21 |
        22 |
      • Spaces, Dashes, Backslashes
      • 23 |
      24 |
    25 | 26 |
    27 |
    28 | 29 |

    Date:

    30 |
  • If Month is written in english
  • 31 | 32 |
      33 |
    • month-day-year     ex: July 24 2020
    • 34 |
    • year-month-day     ex: 2020 July 24
    • 35 |
    • month-year-day     ex: July 2020 24
    • 36 |
    • day-year-month     ex: 24 2020 July
    • 37 |
    • year-day-month     ex: 2020 24 July
    • 38 |
    39 |
  • If month is numeric representation, day and month need to be connected with month preceding day
  • 40 |
      41 |
    • month-day-year     ex: 7/24/2020
    • 42 |
    • year-month-day     ex: 2020/7/24
    • 43 |
    44 | 45 |
    46 | 47 |

    Time:

    48 |
  • Accepts both 12 and 24-hour clocks formats
  • 49 | 50 |
      51 |
    • Default input is 24-hour clock
    • 52 |
    • 12-hour am/pm designations accepted
    • 53 |
    54 | 55 |
    56 | 57 |

    Precision Designation:

    58 |
    59 |
      60 |
    • Needs only 1 digit in hour position
    • 61 |
    • Must use colons to separate time precision levels
    • 62 |
    • Can specify time to only 2 digits of precision for each time position, down to seconds marker
    • 63 |
        64 |
      • Time precision format HH:MM:SS
      • 65 |
      • Ex: If 1 is input, it assumes 01:00:00
      • 66 |
      • Ex: If 1pm in input, it assumes 13:00:00
      • 67 |
      68 |
    69 | 70 |
    71 |
    72 | 73 |

    Time Zone:

    74 |
  • Input with a ISO numeric offset
  • 75 |
      76 |
    • Ex: Time input as: 13:00:00-0800
    • 77 |
    78 |
  • If not preconfigured ISO:
  • 79 |
      80 |
    • A space is needed between datetime and time zone
    • 81 |
    • Explicitly designate time zone via standard abbreviation
    • 82 |
        83 |
      • Ex: PST, CST, PDT, etc.
      • 84 |
      85 |
    • Time zone is an optional time input
    • 86 |
    • If none designated, default assumption is UTC
    • 87 |
    88 | 89 |

    If no given datetime stamp is given for an endpoint that requires one as a parameter, defaults to current datetime as input.

    90 |
    91 |
    92 | 93 |
    94 |
    95 |
    96 | 97 |
    98 |
    99 | ); 100 | } 101 | 102 | export default ApiDocs; -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/api_use/ApiUse.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/api_use/ApiUse.css -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/case_study/CaseStudy.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/case_study/CaseStudy.css -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/case_study/CaseStudy.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './CaseStudy.css' 3 | 4 | const CaseStudy = () => { 5 | 6 | return( 7 |
    8 |

    Case study is still being updated...

    9 |
    10 | ); 11 | } 12 | 13 | export default CaseStudy; -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/deck/Deck.css: -------------------------------------------------------------------------------- 1 | .slide-title { 2 | text-align: center; 3 | margin-bottom: 5rem; 4 | } -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/deck/Deck.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Deck.css' 3 | 4 | const Deck = () => { 5 | 6 | return( 7 |
    8 |
    9 |
    10 |
    11 |
    12 | 13 |

    Project Slide Decks

    14 | 15 |
    16 | 17 |

    Project Checkpoint Slide Deck

    18 |
    19 | 20 |
    21 | 22 |

    Slide deck for the halfway checkpoint of the project. Covers motivation for using marginal emissions as a metric and high-level architecture of the API. At this time, construction was beginning for load shifting features and calculating Azure emissions using WattTime grid records.

    23 | 24 |
    25 | 26 |
    27 |
    28 |
    29 | 30 |

    Project Conclusion Slide Deck

    31 |
    32 | 33 |
    34 | 35 |

    Slide deck for the end of the project. Brief recap of project space and use of marginal emission metrics, followed by an outline of the project tools and methods. Ends with an exposition of the features Carbon Intensity API offers, recommended use cases, and an outline of work to take the project forward. At this stage, the Carbon Intensity API can deliver and analyze WattTime data, provide emissions profiles for energy profiles, and offer load shifting suggestions across regions or time.

    36 |
    37 |
    38 |
    39 |
    40 |
    41 |
    42 | ); 43 | } 44 | 45 | export default Deck; -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/kb_cite/KbCite.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/kb_cite/KbCite.css -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/kb_summary/KbSummary.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/kb_summary/KbSummary.css -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/miro/Miro.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaylorPrewitt/carbon-awareAPI/23b69809fb4d34a37c40723150e01a6f3ee7b79d/Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/miro/Miro.css -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/miro/Miro.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Miro.css' 3 | 4 | const Miro = () => { 5 | 6 | return( 7 |
    8 |

    Design Diagram

    9 | 10 |
    11 | ); 12 | } 13 | 14 | export default Miro; -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/documentation/resources/monitor/Monitor.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: 'Segoe UI'; 4 | } 5 | 6 | .logo2 { 7 | height: 20px; 8 | vertical-align: middle; 9 | margin-bottom: 7px; 10 | } 11 | 12 | 13 | .red { color: #aa1c1c; } 14 | .yellow-background { background-color: rgb(247, 247, 165); }​ 15 | 16 | .card { 17 | justify-content: center; 18 | border: 2px solid #1a1a1f; 19 | border-radius: 20px; 20 | display:inline-block; 21 | margin-left: 3rem; 22 | margin-bottom: 1rem; 23 | } 24 | 25 | .markdown { 26 | margin-left: 2rem; 27 | margin-right: 2rem; 28 | } 29 | 30 | /* Python stuff */ 31 | @import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@300&display=swap'); 32 | 33 | .python { 34 | justify-content: center; 35 | border: 2px solid #1a1a1f; 36 | border-radius: 10px; 37 | display:inline-block; 38 | margin-left: 2rem; 39 | margin-bottom: 2rem; 40 | background-color: rgb(32, 32, 32); 41 | color: white; 42 | padding-left: 2.5rem; 43 | padding-right: 2.5rem; 44 | font-family: 'Fira Code', monospace; 45 | } 46 | 47 | .white { 48 | font-family: 'Fira Code', monospace; 49 | } 50 | 51 | .pink { 52 | color: pink; 53 | font-family: 'Fira Code', monospace; 54 | } 55 | 56 | .green-python { 57 | color: green; 58 | font-family: 'Fira Code', monospace; 59 | } 60 | 61 | .orange { 62 | color: orange; 63 | font-family: 'Fira Code', monospace; 64 | } 65 | 66 | .yellow { 67 | color: yellow; 68 | font-family: 'Fira Code', monospace; 69 | } 70 | 71 | .light-green { 72 | color: lightgreen; 73 | font-family: 'Fira Code', monospace; 74 | } 75 | 76 | .blue-python { 77 | color: rgb(35, 105, 235); 78 | font-family: 'Fira Code', monospace; 79 | } 80 | 81 | .l-blue { 82 | color: rgb(109, 216, 252); 83 | font-family: 'Fira Code', monospace; 84 | } 85 | 86 | .python p { 87 | margin-top:1rem; 88 | } -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/home/Home.css: -------------------------------------------------------------------------------- 1 | /* Main page image */ 2 | .main_image { 3 | width: 100%; 4 | z-index: 0; 5 | } 6 | 7 | /* The whole home page */ 8 | .home { 9 | background-color: #1a1a1f; 10 | color: #E3E3E7; 11 | margin-top: -10rem; 12 | } 13 | 14 | /* Home Title Section */ 15 | .title-container { 16 | position: relative; 17 | text-align: center; 18 | } 19 | 20 | .title-image { 21 | -webkit-background-size: cover; 22 | -moz-background-size: cover; 23 | -o-background-size: cover; 24 | background-size: cover; 25 | height: 105vh; 26 | } 27 | 28 | .microsoft-title { 29 | position: absolute; 30 | top: 36%; 31 | left: 50%; 32 | transform: translate(-50%, -50%); 33 | font-size: 2em; 34 | } 35 | 36 | .project-title { 37 | position: absolute; 38 | top: 45%; 39 | left: 50%; 40 | transform: translate(-50%, -50%); 41 | font-size: 3.5em; 42 | } 43 | 44 | .green { 45 | color: #8EB93B; 46 | } 47 | 48 | /* Problem Space Description */ 49 | .split-image { 50 | margin-top: 20rem; 51 | width: 100%; 52 | height: 350px; 53 | } 54 | 55 | 56 | .desc-title { 57 | font-size: 3rem; 58 | text-align: center; 59 | } 60 | 61 | .desc-sub { 62 | font-size: 1.25rem; 63 | width: 100%; 64 | margin-top: 1rem; 65 | } 66 | 67 | .desc-sub-title { 68 | font-size: 3rem; 69 | text-align: left; 70 | color: #007fff; 71 | } 72 | 73 | .desc { 74 | margin-right: -25rem; 75 | } 76 | 77 | /* Solution */ 78 | .solution-container { 79 | padding-bottom: 1rem; 80 | margin-right: 20rem; 81 | background-color: #E3E3E7; 82 | } 83 | 84 | .solution-img { 85 | -webkit-background-size: cover; 86 | -moz-background-size: cover; 87 | -o-background-size: cover; 88 | background-size: cover; 89 | width: 100%; 90 | } 91 | 92 | .solution-title { 93 | font-size: 3em; 94 | color: #1a1a1f; 95 | } 96 | 97 | .solution-desc-sub { 98 | font-size: 1.25rem; 99 | width: 60%; 100 | margin-top: 1.25rem; 101 | color: #1a1a1f; 102 | } 103 | 104 | 105 | .solution-desc { 106 | margin: 10rem; 107 | } 108 | 109 | 110 | /* Node Section */ 111 | .node-container { 112 | background-color: #007fff; 113 | } 114 | /* Main content */ 115 | .main_content { 116 | margin-left: 200px; 117 | margin-right: 200px; 118 | } 119 | 120 | /* Link container */ 121 | .link { 122 | display: inline-block; 123 | } 124 | 125 | .link-container { 126 | text-align: left; 127 | margin-left: -3rem; 128 | } 129 | 130 | 131 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/pages/shifting/Shifting.css: -------------------------------------------------------------------------------- 1 | 2 | .alert { 3 | padding: 20px; 4 | background-color: orange; 5 | color: white; 6 | width: 90%; 7 | 8 | } 9 | .center-display { 10 | justify-content: center; 11 | } 12 | 13 | .top { 14 | justify-content: center; 15 | 16 | } 17 | .icon-title { 18 | font-size: 1.25rem; 19 | margin-top: 1rem; 20 | } 21 | 22 | .icon-desc { 23 | font-size: 1.5rem; 24 | margin-top: 1rem; 25 | color: gray; 26 | } 27 | 28 | .detail { 29 | text-align: center; 30 | margin-top: 1rem; 31 | font-size: 1.25rem; 32 | } 33 | 34 | 35 | 36 | .search { 37 | justify-content: center; 38 | text-align: center; 39 | } 40 | 41 | .content { 42 | margin-top: 150px; 43 | } 44 | 45 | .btn-container { 46 | justify-content: center; 47 | text-align: center; 48 | } 49 | 50 | 51 | /* The whole shifting page */ 52 | .shifting { 53 | background-color: #1a1a1f; 54 | color: #E3E3E7; 55 | margin-top: -10rem; 56 | } 57 | 58 | /* Title Section */ 59 | .shifting-title-container { 60 | position: relative; 61 | text-align: center; 62 | } 63 | 64 | .shifting-title-image { 65 | -webkit-background-size: cover; 66 | -moz-background-size: cover; 67 | -o-background-size: cover; 68 | background-size: cover; 69 | width: 100%; 70 | height: 105vh; 71 | } 72 | 73 | .shifting-website-title { 74 | position: absolute; 75 | top: 45%; 76 | left: 50%; 77 | transform: translate(-50%, -50%); 78 | font-size: 4em; 79 | } 80 | 81 | /* Question page */ 82 | .question-title { 83 | font-size: 2em; 84 | text-align: center; 85 | } 86 | 87 | /* Form */ 88 | .card-body { 89 | background: #1a1a1f; 90 | font-size:1rem; 91 | height: 620px; 92 | } 93 | 94 | .box-label { 95 | font-size: 1rem; 96 | } 97 | 98 | .box-input { 99 | margin-left: 1rem; 100 | background: #1a1a1f; 101 | color: #E3E3E7; 102 | border-color: #E3E3E7; 103 | border-radius: 0.25rem; 104 | font-size: 1rem; 105 | width: 150px; 106 | height: 30px; 107 | } 108 | 109 | .green { 110 | color: #8EB93B; 111 | } 112 | 113 | .space { 114 | padding: 0.5rem; 115 | } 116 | 117 | .or { 118 | color: #007fff; 119 | margin-left: 2rem; 120 | margin-right: 2rem; 121 | } 122 | 123 | .tooltip-title { 124 | margin-top: 1rem; 125 | font-size: 1.5rem; 126 | } 127 | 128 | .tooltip-desc { 129 | font-size: 1rem; 130 | } 131 | 132 | .blue { 133 | color: #007fff; 134 | } 135 | 136 | /* loading screen */ 137 | .loading { 138 | background-color: #1a1a1f; 139 | color: #E3E3E7; 140 | margin-top: -12rem; 141 | height: 105vh; 142 | } 143 | 144 | .extra-space { 145 | padding: 8rem; 146 | } 147 | 148 | .loading-title{ 149 | text-align: center; 150 | font-size: 3em; 151 | color: #007fff; 152 | margin-top: 2em; 153 | } 154 | 155 | .loading-desc{ 156 | text-align: center; 157 | font-size: 1.5em; 158 | margin-top: 1em; 159 | } 160 | 161 | /* error page */ 162 | .error { 163 | background-color: #1a1a1f; 164 | color: #E3E3E7; 165 | margin-top: -12rem; 166 | height: 105vh; 167 | } 168 | 169 | .error-title{ 170 | text-align: center; 171 | font-size: 3em; 172 | color: #007fff; 173 | margin-top: 2em; 174 | } 175 | 176 | .error-desc{ 177 | text-align: center; 178 | font-size: 1.5em; 179 | margin-top: 1em; 180 | } 181 | 182 | .error-img{ 183 | height: 200px; 184 | display: block; 185 | margin-left: auto; 186 | margin-right: auto; 187 | align-items: center; 188 | } 189 | 190 | 191 | /* Result page */ 192 | .result { 193 | background-color: #8EB93B; 194 | color: #E3E3E7; 195 | margin-top: -12rem; 196 | } 197 | 198 | .title { 199 | color: #E3E3E7; 200 | } 201 | 202 | .sm-extra-space { 203 | padding: 4rem; 204 | } 205 | 206 | .icon-azure { 207 | padding-left: 1em; 208 | padding-right: 1em; 209 | height: 125px; 210 | width: 140px; 211 | vertical-align: middle; 212 | margin-bottom: 18px; 213 | } 214 | 215 | .icon-azure:hover { 216 | transform: scale(1.05); 217 | } 218 | 219 | .icon { 220 | padding-left: 1em; 221 | padding-right: 1em; 222 | height: 125px; 223 | vertical-align: middle; 224 | margin-bottom: 18px; 225 | } 226 | 227 | .icon:hover { 228 | transform: scale(1.05); 229 | } 230 | 231 | .result-card { 232 | background-color: #E3E3E7; 233 | text-align: center; 234 | border-radius: 2rem; 235 | margin:3rem; 236 | padding: 2rem; 237 | width: 80%; 238 | } 239 | 240 | .detail { 241 | font-size:1.25rem; 242 | } 243 | 244 | .accept-button { 245 | margin-top: 2rem; 246 | } 247 | 248 | .alert { 249 | width: 100%; 250 | font-size: 1rem; 251 | } 252 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /Carbon_Aware_Core_UI/React_Interface /src/utils/fade-in-out.js: -------------------------------------------------------------------------------- 1 | const fade_in_out = () => { 2 | const contentEles = document.getElementsByClassName("fade-in") 3 | console.log(contentEles) 4 | 5 | const appearOptions = { 6 | threshold: 1, 7 | rootMargin: "-15% 0px 0px 0px" 8 | } 9 | 10 | const appearOnScroll = new IntersectionObserver(entries => { 11 | entries.forEach(entry => { 12 | if (entry.isIntersecting) { 13 | entry.target.classList.add("appear") 14 | } else { 15 | entry.target.classList.remove("appear") 16 | } 17 | }) 18 | }, appearOptions) 19 | 20 | Array.from(contentEles).forEach((ele) => { 21 | appearOnScroll.observe(ele) 22 | }) 23 | } 24 | 25 | export default fade_in_out -------------------------------------------------------------------------------- /Documentation/Appendices.md: -------------------------------------------------------------------------------- 1 | # Appendices 2 | 3 |
    4 | 5 | ## Sections 6 | 7 |
      8 |
    1. Appendix 1: Retrieving Energy Metrics
    2. 9 |
    3. Appendix 2: Supporting Work
    4. 10 |
    5. Appendix 3: Carbon Wholesale Market
    6. 11 |
    7. Appendix 4: CAISO Supply and Demand Curves for October 20, 2021
    8. 12 |
    9. Appendix 5: CAISO Emission Curve for October 20, 2021
    10. 13 |
    11. Appendix 6: Azure data centers supported by WattTime balancing authorities
    12. 14 |
    15 | 16 |
    17 | 18 | 19 | 20 | ## Appendix 1: Retrieving Energy Metrics 21 | Example of retrieving energy metrics with [Python and Azure Monitor](https://github.com/TaylorPrewitt/carbon-awareAPI/tree/main/Retrieve_Energy_Metrics/AzureMonitorQuery). 22 | 23 |
    24 | 25 | 26 | 27 | ## Appendix 2: Supporting Work 28 | 29 | This project is an expression of the [Green Software Fountation](https://greensoftware.foundation/)’s Software Carbon Intensity (SCI) [Specification](https://github.com/Green-Software-Foundation/software_carbon_intensity/blob/dev/Software_Carbon_Intensity/Software_Carbon_Intensity_Specification.md) 30 | 31 |
    32 | 33 | 34 | 35 | ## Appendix 3: Carbon Wholesale Market 36 | 37 | ![image](https://user-images.githubusercontent.com/80305894/140421850-3a241723-3a66-44e0-acc0-bc5147969be2.png) 38 | 39 |
    40 | 41 | 42 | 43 | ## Appendix 4: CAISO Supply and Demand Curves for October 20, 2021 44 | 45 | ![image](https://user-images.githubusercontent.com/80305894/140421869-ce9ae463-24c1-409c-8149-c32470e79ada.png) 46 | 47 |
    48 | 49 | 50 | 51 | ## Appendix 5: CAISO Emission Curve for October 20, 2021 52 | 53 | ![image](https://user-images.githubusercontent.com/80305894/140421886-a6fa16c6-bbd3-460c-9076-4b8b8a84afa7.png) 54 | 55 |
    56 | 57 | 58 | 59 | ## Appendix 6: Azure data centers supported by WattTime balancing authorities 60 | 61 | | **US Based** | **Outside US** | 62 | | :------------- | :---------- | 63 | | East US | Australia Central | 64 | | East US 2 | Australia Central 2 | 65 | | Central US | Australia East | 66 | | North Central US | Australia Southeast | 67 | | South Central US | Canada Central | 68 | | West Central US | Canada East | 69 | | West US | France Central | 70 | | West US 2 | France South | 71 | | West US 3 | Germany Central | 72 | | | Germany North | 73 | | | North Europe | 74 | | | Norway East | 75 | | | Norway West | 76 | | | UK South | 77 | | | West Europe | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /Documentation/Case Studies/README.md: -------------------------------------------------------------------------------- 1 | # Case Study Timeline 2 | 3 | ### Carbon Optimized Demand Shifting at Scale 4 | September 2021 5 | 6 | ### Carbon Segmented Cloud Computes 7 | October 2021 8 | -------------------------------------------------------------------------------- /Documentation/References.md: -------------------------------------------------------------------------------- 1 | # References 2 | 3 | DiStefano, K., Richardson, H., Atelier Ten, & WattTime. (2019). The Future of Carbon Neutral Design. Atelier Ten. Retrieved from https://www.atelierten.com/app/uploads/2019/07/Carbon-methodology-paper-190724.pdf 4 | 5 | Schwartz, R., Dodge, J., Smith, N., & Etzioni, O. (2019). Green AI. Retrieved March 28, 2021, Retrieved from https://arxiv.org/pdf/1907.10597.pdf 6 | 7 | Smith, B. (2020). Microsoft Will Be Carbon Negative by 2030 [Web log post]. Retrieved April 01, 2021, Retrieved from https://aka.ms/MSFTcarbonfactsheet 8 | 9 | Listgarten, S. (2019). When to use Marginal Emissions (and when not to). Retrieved March 29, 2021, Retrieved from https://www.paloaltoonline.com/blogs/p/2019/09/29/marginal-emissions-what-they-are-and-when-to-use-them. 10 | 11 | Azure monitor REST API metric definitions. REST API (Azure Monitor) | Microsoft Docs. (2021). Retrieved June 2021, from https://docs.microsoft.com/en-us/rest/api/monitor/metric-definitions/list. 12 | 13 | California ISO. (2021). Retrieved from http://www.caiso.com/TodaysOutlook/Pages/index.html. 14 | 15 | The Climate Pledge. (2021). Retrieved April 2021, from https://www.theclimatepledge.com/. 16 | 17 | Mahesh, N. (2021, June 16). Azure network round-trip latency statistics. Microsoft Docs. Retrieved October 13, 2021, from https://docs.microsoft.com/en-us/azure/networking/azure-network-latency. 18 | 19 | Market for electricity. PJM Learning Center - Market for Electricity. (2021). Retrieved from https://learn.pjm.com/electricity-basics/market-for-electricity.aspx . 20 | 21 | Pricing calculator: Microsoft Azure. Pricing Calculator | Microsoft Azure. (2021). Retrieved October 13, 2021, from https://azure.microsoft.com/en-in/pricing/calculator/. 22 | 23 | Strubell, E., Ganesh, A., & McCallum, A. (2019, June 5). Energy and policy considerations for Deep Learning in NLP. arXiv.org. Retrieved from https://arxiv.org/abs/1906.02243. 24 | 25 | Environmental Protection Agency. (2021, July 21). EPA. Retrieved from https://www.epa.gov/energy/greenhouse-gas-equivalencies-calculator. 26 | 27 | Alarcon, N. (2020, July 7). OpenAI presents GPT-3, a 175 billion parameters language model. NVIDIA Developer Blog. Retrieved from https://developer.nvidia.com/blog/openai-presents-gpt-3-a-175-billion-parameters-language-model. 28 | 29 | Dodge, J., Prewitt, T., & Buchanan, W. (2021). personal. 30 | 31 | Walsh, N. (2020, January 16). Microsoft Sustainability Calculator helps enterprises analyze the carbon emissions of their IT infrastructure. Azure Blog and Updates. Retrieved from https://azure.microsoft.com/en-us/blog/microsoft-sustainability-calculator-helps-enterprises-analyze-the-carbon-emissions-of-their-it-infrastructure/. 32 | 33 | Microsoft. (2021). Microsoft Emissions Impact Dashboard. Retrieved from https://www.microsoft.com/en-us/sustainability/emissions-impact-dashboard?activetab=pivot_2%3Aprimaryr12. 34 | -------------------------------------------------------------------------------- /Documentation/Validation/README.md: -------------------------------------------------------------------------------- 1 | # Tool Validation 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Carbon Aware API 3 | *Draft, Project In Progress* 4 | 5 | ## Navigation 6 |
      7 |
    1. Overview
    2. 8 |
    3. Case Studies
    4. 9 |
    5. API Architecture
    6. 10 |
    7. Methodology
    8. 11 |
    9. Sample User Interface
    10. 12 |
    13 | 14 | 15 | ## Terminology 16 | | Term | Definition | 17 | | :------------- | :---------- | 18 | | **Carbon Intensity** | Carbon emitted per energy unit. | 19 | | **Grid-Based Carbon Intensity** | All entities who operate on a shared electrical grid, share a common *carbon intensity*. | 20 | | **Marginal Carbon Intensity** | The *carbon intensity* of the marginal power plant that supplies power when additional load added to the grid.| 21 | | **Carbon Aware** | Adjusted behavior in response to the *carbon intensity* of consumption.| 22 | | **Carbon Delta** | The difference in emissions between *carbon aware* and unaware actions. | 23 | | **Carbon Counterfactual** | The *carbon delta* had the *carbon aware* action been different.| 24 | | **Demand Shifting** | Selectively changing the time/location of a compute's execution, to a time/location where the energy demands are met by cleaner energy production, resulting in a lower *grid-based carbon intensity*.| 25 | | **Operational Emissions** | Emissions explained by the energy consumption and *grid-based carbon intensity* measurement during times of operation.| 26 | | **Embodied Emissions** | Carbon emissions resultant of creating the hardware, structural systems, maintanence, etc. (e.g. constructing a GPU or datacenter).| 27 | 28 | 29 | Other definitions and methods for the Carbon Awareness found at: [Green Software Foundation](https://github.com/Green-Software-Foundation) 30 | 31 |

    32 | 33 | 34 | ![Banner](https://user-images.githubusercontent.com/80305894/132620015-b0a5007a-d605-43ca-a260-8b3bc5206b32.png) 35 |

    36 | 37 | 38 | ## Overview 39 | 40 | To enable organizations to make smart decisions about their environmental impact and carbon footprint, we have created the Carbon Aware API to minimize the operational emissions of computational workflows. A few key features of the API are: 41 | 42 | * Utilizes marginal carbon emission measurements from WattTime to map carbon intensity rates to data centers. 43 | * Generates a retrospective carbon emission analysis 44 | * Provides forecasted demand shifting suggestions 45 | * Supplies regional carbon intensity information over different scopes 46 | * Hosts a green region picker for workspace configuration. 47 | 48 | **Marginal Carbon Emissions:** This grid-responsive metric with finer granularity than average emissions, allows for seasonality/diurnal trends captured in demand shifting (source). 49 | 50 | **Retrospective Analysis:** Time series evaluation to assess the carbon emissions for a given energy profile. Also provides counterfactual analysis to expose the potential emissions of if the run had been shifted. 51 | 52 | **Demand Shifting Scheduler**: Recommends data center and/or time which would yield a less carbon intensive run. 53 | 54 | * Temporal: Identifies the window of minimum carbon intensity for a specified run duration within a chosen region from a 24-hour forecast. 55 | * Geographic: Finds the region with the current lowest average carbon intensity for an immediate run of a specified duration. Can filters available regions by available SKU and migration laws for workspaces with protected data. 56 | 57 | **Regional Carbon Intensity:** Provides the carbon intensity for each data center supported by a WattTime-tracked balancing authority. The possible scopes are historic intensities (time series for prior 24-hours, week, and month), real-time marginal intensity, and forecast (mean intensity for upcoming user-defined window). 58 | 59 | **Green Region Picker:** Recommends the a data center to host a workspace based on expressed needs such as carbon efficiency, price, and latency. 60 |
    61 | 62 | For more information, please see the full tool description: [Carbon Aware API Details](https://github.com/TaylorPrewitt/carbon-awareAPI/tree/main/Documentation/Overview) 63 | 64 | 65 | 66 | 67 |
    68 | 69 | 70 | 71 | ## Case Studies 72 | 73 | Carbon intensity data for case studies provided by: [WattTime](https://www.watttime.org/) 74 | 75 | 76 | 77 | ### Carbon Optimized Demand Shifting at Scale 78 | September 2021 79 | 80 | **Details:** *Geographically and temporally shifting compute instances at scale would reduce carbon by X%* 81 | 82 | **Results:** *Organizations can reduce their operational emissions by 48% by geographically shifting and 12% by temporally shifting ML computes.* 83 | 84 | For more information and detailed results, please see the full case study: [Carbon Optimized Demand Shifting at Scale](https://github.com/TaylorPrewitt/carbon-awareAPI/tree/main/Documentation/Case%20Studies/Organizational_Shifting) 85 | 86 |
    87 | 88 | ### Carbon Segmented Cloud Computes 89 | October 2021 90 | 91 | **Details:** *Execute and progress cloud computes greater than 24 hours in duration during periods of low emission to reduce the carbon footprint by Y%* 92 | 93 | **Results:** *48-hour ML runs saw a mean of 0.5% change using standard temporal shifting, but controlling progression based on regional carbon intesity thresholds reduced operational emissions by 10%* 94 | 95 | For more information and detailed results, please see the full case study: [Carbon Segmented Cloud Computes](https://github.com/TaylorPrewitt/carbon-awareAPI/tree/main/Documentation/Case%20Studies/Carbon_trigger) 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Retrieve_Energy_Metrics/AzureMonitorQuery/AzureMonitorFileDownload.md: -------------------------------------------------------------------------------- 1 | # File Download Instructions 2 | 3 | ## Accessing Azure Monitor UI 4 | 1. Navigate to: https://azure.microsoft.com/en-us/ 5 | 2. Login to your Portal 6 | 3. In the search bar at the top center, search "Monitor" 7 | 4. In the top left under the 'Overview' title, search "Metrics" in the search bar 8 | 1. If this menu is not available, click the >> icon under “Monitor|Overview” 9 | 5. Select Metrics 10 | 11 | 12 | ## Define Resource Scope 13 | 1. Click the checkbox next to the subscription which contains the workspace which hosted the compute 14 | 1. If this subscription is not visible, select it in the subscription dropdown and then select for the scope 15 | 2. Select the resource type 'Machine Learning' in the 'Resource Type' drop down menu. 16 | 3. Select the workspace that executed the compute in the 'Machine Learning' drop down menu to specify the exact resource used. 17 | 1. Selecting this will auto populate the Location 18 | 4. Click apply 19 | 20 | 21 | ## Set Evaluation Metric 22 | 1. 'Scope' and 'Metric Namespace' will auto populate 23 | 2. Select "GpuEnergyJoules" in the 'Metric' drop down. 24 | 3. 'Aggregation' should then default to 'Sum', but if not, select this. 25 | 26 | 27 | ## Define Granularity 28 | 1. In the top right click the Time icon 29 | 2. Select "5 minutes" for 'Time granularity' in the dropdown 30 | 3. Define the start and end times, round to the nearest 5 min times which fully encapsulate the compute. 31 | 1. *Note, this will be all runs from workspace during this time window* 32 | 4. Click apply 33 | 34 | 35 | ## Filtering Metric Output (optional) 36 | 1. Click 'Add filter' 37 | 2. Select a 'Property' to filter on, such as "RunId" 38 | 3. Using this and selecting a specific run(s) under 'Values' can limit the energy profile to specific instances 39 | 40 | 41 | ## Downloading Data 42 | 1. Click the 'Share' button at the top right of the plot​ 43 | 2. Click 'Click Download to Excel' 44 | 45 | -------------------------------------------------------------------------------- /Retrieve_Energy_Metrics/AzureMonitorQuery/README.md: -------------------------------------------------------------------------------- 1 | # Azure Monitor 2 | 3 | To download an energy profile as a .xlsx file for a single workspace through the Azure Monitor UI, please refer to [File Download Instructions](https://github.com/TaylorPrewitt/carbon-awareAPI/blob/main/Retrieve_Energy_Metrics/AzureMonitorQuery/AzureMonitorFileDownload.md). 4 | 5 |
    6 | To query and retrieve energy consumption metrics via Azure Monitor for multiple resources and workspaces at once, please follow the below steps:
    7 |
      8 |
    1. Install Required Modules
    2. 9 |
    3. Login to the Azure SDK
    4. 10 |
    5. Change Working Directory
    6. 11 |
    7. Open query.py and Define Parameters
    8. 12 |
    9. Submit the Query
    10. 13 |
    11. Open unpack.py and Define Parameters
    12. 14 |
    13. Run the Script
    14. 15 |
    16 |
    17 | 18 | 19 | 20 | ## Install Required Modules 21 | These modules are not included as part of the python standard library and are needed to execute the script to retrieve energy metrics: 22 | 1. [az](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) 23 | 2. [requests](https://docs.python-requests.org/en/latest) 24 | 3. [pandas](https://pandas.pydata.org/pandas-docs/stable/index.html) 25 | 26 | To install them, run the following in the command line. 27 | `pip install -r requirements.txt` 28 |

    29 | 30 | 31 | 32 | ## Login to the Azure SDK 33 | Run `az login` in the terminal to login and use Azure CLI. 34 | 35 | If not currently logged in, this should open a browser page to login into Azure. If not logged in and no browser page opens, navigate to https://aka.ms/devicelogin. For additional support, see https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli 36 |

    37 | 38 | 39 | 40 | ## Change Working Directory 41 | For organization of the returned files, it is recommended to run query.py within the folder AzureMonitorQuery.
    42 | i.e. `cd \AzureMonitorQuery` 43 |
    44 | 45 | 46 | 47 | ## Open query.py and Define Parameters 48 | This will query multiple resource groups and workspaces for a single subscription.

    49 | Within the [query.py](https://github.com/TaylorPrewitt/carbon-awareAPI/blob/main/Retrieve_Energy_Metrics/AzureMonitorQuery/query.py), enter the following parameters in the spaces provided: 50 | 1. Subscription Name 51 | 2. Subscription ID 52 | 1. 32-digit identifier 53 | 3. Timespan 54 | 1. Start and end timestamps for the query period in UTC ISO format. 55 | * e.g. YYYY-mm-ddTHH:MM:SS.000Z 56 | 2. Query range is limited to 30-days of run history 57 | 4. Resource Group(s) 58 | 1. List of the resource group(s) which you would like to pull data for. 59 | 5. Workspace(s) 60 | 1. Names of all workspaces listed across all resource groups of the query. 61 |

    62 | 63 | 64 | 65 | ## Submit the Query 66 | With an active az login and the 5 query parameters defined, the query is ready to submit by running the script. The query will save files within the working directory with the naming convention of: energy_profile_{sub_name}_{resourceGroup}_{workspace}.json 67 | 68 | Each of these is JSON file which contains data for a given workspace with energy metrics split on 'runid' and 'deviceid'. 69 |

    70 | 71 | 72 | 73 | ## Open unpack.py and Define Parameters 74 | This will unpack JSON files from all workspaces queried for a given resource group and subscription.

    75 | Within the unpack.py, enter the following parameters in the spaces provided: 76 | 1. Subscription Name 77 | 2. Resource Group 78 | 3. Workspace(s) 79 | 1. Listed names of all workspaces queried within a specific Resource Group. 80 |

    81 | 82 | 83 | ## Run the Script 84 | Once the 3 parameters have been defined, [unpack.py](https://github.com/TaylorPrewitt/carbon-awareAPI/blob/main/Retrieve_Energy_Metrics/AzureMonitorQuery/unpack.py) is ready to run. This will save the following as files with the given types: 85 | 1. all_run_data.csv 86 | 1. All data in single index format, ordered and tagged by runid. 87 | 2. metadata.json 88 | 1. Metadata for the queries. This maps runid to the region where the workspace is located and the deviceid's which performed the run. 89 | 3. multi_index.h5 90 | 1. All data in a multi index format where each value is the Joules on energy consumed per 5 minute interval. 91 | 2. Each value has an index of timstamp, runid, total 92 | 93 | -------------------------------------------------------------------------------- /Retrieve_Energy_Metrics/AzureMonitorQuery/query.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | import subprocess 4 | import az 5 | # install the above packages if not already done, will throw an error if not in device path 6 | 7 | 8 | 9 | # Steps to Query Data: 10 | 11 | # FIRST: ensure your device has the az cli enabled for account 12 | # run command: "az login" in the terminal. this should open a browser page 13 | # https://aka.ms/devicelogin if no browser page is opened, this is the link 14 | # reference: https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli 15 | 16 | 17 | # SECOND: change working directory to /AzureMonitorQuery (folder that contains this script) 18 | 19 | 20 | # THIRD: fill in the following parameters: 21 | # subscription name/ID, start time, end time, resource groups, workspaces 22 | 23 | 24 | # subscription name and ID for the ML resource 25 | sub_name = '' 26 | sub_id = '########-####-####-####-############' 27 | 28 | # enter timespan to be searched (up to 30 day history) 29 | # times in UTC ISO = yyyy-mm-ddTHH:MM:SS.000Z 30 | # e.g. 2021-09-23T19:30:00.000Z 31 | starttime = '####-##-##T##:##:##.000Z' 32 | endtime = '####-##-##T##:##:##.000Z' 33 | 34 | # list of the available resource groups, or the resource group(s) which you would like to pull data for 35 | # include all names of resource groups from the input subscription 36 | # e.g. resourceGroup_list = ['resourceGroup1', 'resourceGroup2', .....] 37 | resourceGroup_list = ['', ] 38 | 39 | # list of the available workspaces, or the workspace(s) which you would like to pull data for 40 | # include all names of workspaces from all resource groups input into one list 41 | # e.g. workspace_list = ['workspace_name1', 'workspace_name2', .....] 42 | workspace_list = ['',] 43 | 44 | 45 | 46 | # With active az login and the 5 parameters filled out, the script is ready to run 47 | 48 | 49 | def get_AML_token(sub_id): 50 | ''' 51 | Parameters 52 | ---------- 53 | sub_id : string 54 | the subscription ID for the AML resources/workspaces. 55 | 56 | Returns 57 | ------- 58 | AML_token['accessToken'] : string 59 | bearer token belonging to user for the input AML subscription. 60 | ''' 61 | AML_token = subprocess.check_output(f"az account get-access-token --subscription {sub_id}", shell=True) 62 | AML_token = json.loads((AML_token.decode("utf-8"))) 63 | return AML_token['accessToken'] 64 | 65 | 66 | def get_resource_energy_data(workspace, resourceGroup, token): 67 | ''' 68 | Parameters 69 | ---------- 70 | workspace : string 71 | workspace within the the resource group . 72 | resourceGroup : string 73 | resource group to be searched for data. 74 | token : string 75 | Subscription bearer token. 76 | 77 | Returns 78 | ------- 79 | AML_energy_data : dictionary 80 | std out of Az Mon query. Each workspace over window, split on RunId 81 | ''' 82 | # define uri and build url for query 83 | req_url_sub_id = f"https://management.azure.com//subscriptions/{sub_id}/" 84 | req_url_resourceGroup = f"resourceGroups/{resourceGroup}/" 85 | req_url_workspace = f"providers/Microsoft.MachineLearningServices/workspaces/{workspace}/" 86 | req_url_metrics = "providers/microsoft.insights/metrics?api-version=2018-01-01&metricnames=GpuEnergyJoules&" 87 | req_url_timespan = f"interval=PT5M×pan={timespan}&" 88 | req_url_aggregation = "aggregation=total&" 89 | req_url_filter = "$filter=RunId eq '*' and DeviceId eq '*'" 90 | # assemble pieces into request url 91 | req_url = (req_url_sub_id + req_url_resourceGroup + req_url_workspace + 92 | req_url_metrics + req_url_timespan + req_url_aggregation + req_url_filter) 93 | # make request to Azure Monitor 94 | AML_headers = {'Authorization': 'Bearer {}'.format(token)} 95 | AML_energy_data = requests.get(req_url, headers=AML_headers) 96 | AML_energy_data = json.loads(AML_energy_data.text) 97 | 98 | 99 | return AML_energy_data 100 | 101 | 102 | # creating formatted time window from start and end times 103 | time_divider = '/' 104 | timespan = starttime + time_divider + endtime 105 | 106 | # calling bearer token for user of the subscription 107 | token = get_AML_token(sub_id) 108 | 109 | # initializing counter to id number of files 110 | file_count = 0 111 | # getting Az Mon GpuEnergyJoules data/metadata and saving to json if valid 112 | for resourceGroup in resourceGroup_list: 113 | for workspace in workspace_list: 114 | data = get_resource_energy_data(workspace, resourceGroup, token) 115 | if len(data) > 2: # bad response has length of 1 116 | if len(data['value'][0]['timeseries']) != 0: # if a valid resource-workspace, make sure data exists in time window 117 | with open(f"energy_profile_{sub_name}_{resourceGroup}_{workspace}.json", 'w') as fp: 118 | json.dump(data, fp) 119 | print('===========================') 120 | print(f"Energy data found during time window for workspace: {workspace}") 121 | print(f"Saving the file as energy_profile_{sub_name}_{resourceGroup}_{workspace}.json") 122 | print('') 123 | file_count += 1 124 | else: # if time series is an empty list due to no activity in the time window, disregard workspace 125 | print(f"No energy data found during time window for workspace: _{sub_name}_{resourceGroup}_{workspace}") 126 | print('') 127 | 128 | 129 | print(f"Number of files saved = {file_count}") 130 | print("Files saved in working directory folder as energy_profile_{sub_name}_{resourceGroup}_{workspace}.json") 131 | print('') 132 | 133 | 134 | -------------------------------------------------------------------------------- /Retrieve_Energy_Metrics/AzureMonitorQuery/requirements.txt: -------------------------------------------------------------------------------- 1 | az==0.1.0.dev1 2 | pandas==1.2.4 3 | requests==2.25.1 4 | -------------------------------------------------------------------------------- /Retrieve_Energy_Metrics/AzureMonitorQuery/unpack.py: -------------------------------------------------------------------------------- 1 | import json 2 | import pandas as pd 3 | 4 | 5 | # enter the details used in query.py 6 | # subscription name and the resource group desired for this unpack 7 | # this unpacks all workspaces from 1 resource group 8 | sub_name = '' 9 | resourceGroup = '' 10 | 11 | # list of workspaces to identify all files 12 | # this should be the same list submitted in query.py 13 | workspace_list = ['',] 14 | 15 | 16 | def get_data(workspace_name, resourceGroup): 17 | ''' 18 | Parameters 19 | ---------- 20 | workspace_name : string 21 | name of the workspace that hosted the run. 22 | resourceGroup : string 23 | name of the resource group that houses the run's workspace. 24 | 25 | Returns 26 | ------- 27 | df : DataFrame 28 | dataframe of a run's energy profile, grouped and summed over devices. 29 | 30 | ''' 31 | 32 | # load data in as dictionary 33 | dictionary = json.load(open(f"energy_profile_{sub_name}_{resourceGroup}_{workspace_name}.json")) 34 | 35 | # break data up and grab only needed components 36 | data_list = [] 37 | for n in range(len(dictionary['value'][0]['timeseries'])): 38 | for i in range(len(dictionary['value'][0]['timeseries'][n]['data'])): 39 | timestamp = dictionary['value'][0]['timeseries'][n]['data'][i]['timeStamp'] 40 | total = dictionary['value'][0]['timeseries'][n]['data'][i]['total'] 41 | runid = dictionary['value'][0]['timeseries'][n]['metadatavalues'][1]['value'] 42 | data_list.append({'timestamp':timestamp, 'total':total, 'runid':runid}) 43 | 44 | # format into dataframe summed over devices 45 | df = pd.DataFrame(data_list) 46 | df = df.groupby(['timestamp','runid'], as_index=False).sum() 47 | df['workspace'] = workspace_name 48 | df = df.sort_values(['runid', 'timestamp'], ascending=True) 49 | 50 | return df 51 | 52 | 53 | 54 | def make_key_data(workspace_list, resourceGroup): 55 | ''' 56 | Parameters 57 | ---------- 58 | workspace_list : list 59 | all workspaces submited in query.py to return Az Monitor data.. 60 | 61 | Returns 62 | ------- 63 | metadata_list : list 64 | list to be used as key for data dataframes. 65 | maps runid to metadata (resource region and workspace name) 66 | 67 | ''' 68 | 69 | metadata_list = [] 70 | for workspace_name in workspace_list: 71 | dictionary = json.load(open(f"energy_profile_{sub_name}_{resourceGroup}_{workspace_name}.json")) 72 | region = dictionary['resourceregion'] 73 | run_id_list = [] 74 | 75 | for i in range(len(dictionary['value'][0]['timeseries'])): 76 | runid = dictionary['value'][0]['timeseries'][i]['metadatavalues'][1]['value'] 77 | if runid not in run_id_list: 78 | run_id_list.append(runid) 79 | 80 | for run in run_id_list: 81 | metadata_list.append({'runid':run, 'metadata':{'region':region, 'workspace':workspace_name}}) 82 | 83 | return metadata_list 84 | 85 | 86 | 87 | def make_two_dataframes(workspace_list, resourceGroup): 88 | ''' 89 | makes a dataframe of for all data. split on runsid and tagged with workspace 90 | sorts to group run time spans together 91 | 92 | Parameters 93 | ---------- 94 | workspace_list : list 95 | all workspaces submited in query.py to return Az Monitor data. 96 | 97 | Returns 98 | ------- 99 | all_run_dataframe : DataFrame 100 | single tabluated dataframe of all runs. 101 | runs listed consecutively 102 | each time interval is tagged with its runid and workspace 103 | multi_index_dataframe : Multi Index DataFrame 104 | timestamps in UTC ISO as row index. 105 | ['total', 'runid'] as column index. 106 | each column is an energy profile for the labeled run over the time span 107 | each value is the Joules consumed per 5 minute interval. 108 | 109 | ''' 110 | all_run_dataframe = pd.DataFrame() 111 | for workspace in workspace_list: 112 | df = get_data(workspace, resourceGroup) 113 | all_run_dataframe = all_run_dataframe.append(df) 114 | multi_index_dataframe = all_run_dataframe.set_index(['timestamp', 'runid']).unstack(['runid']) 115 | multi_index_dataframe = multi_index_dataframe.drop('workspace', axis = 1) 116 | 117 | return all_run_dataframe, multi_index_dataframe 118 | 119 | 120 | 121 | # execute function to make metadata key for the unpacked data 122 | metadata_list = make_key_data(workspace_list, resourceGroup) 123 | 124 | 125 | 126 | # build dataframes from unpacked data. one multi-index the other is single level 127 | all_run_dataframe, multi_index_dataframe = make_two_dataframes(workspace_list, resourceGroup) 128 | 129 | 130 | # storing unique runid's 131 | runid_name_index = all_run_dataframe.groupby('runid').sum() 132 | runid_name_index = runid_name_index.reset_index() 133 | runid_name_index = runid_name_index.drop('total', axis=1) 134 | runid_name_index.to_csv('runid_name_index.csv') 135 | 136 | # storing metadata list to json file 137 | with open("metadata.json", 'w') as fp: 138 | json.dump(metadata_list, fp) 139 | 140 | # storing dataframes to files 141 | all_run_dataframe.to_csv('all_run_data.csv') 142 | multi_index_dataframe.to_hdf('multi_index.h5', 'runid') 143 | -------------------------------------------------------------------------------- /Retrieve_Energy_Metrics/README.md: -------------------------------------------------------------------------------- 1 | # Retrieving Energy Metrics 2 | 3 | ## Azure Monitor 4 | --------------------------------------------------------------------------------