From b0863960b87772113eeb396b61c1ce344608a790 Mon Sep 17 00:00:00 2001 From: Robin TROESCH <38283096+unitrium@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:38:04 +0100 Subject: [PATCH 1/6] refactor(ElectricityMaps): unify ElectricityMaps and ElectricityMapsFree --- .../architecture/c-sharp-client-library.md | 3 +- casdk-docs/docs/architecture/data-sources.md | 3 +- casdk-docs/docs/overview/enablement.md | 34 +-- casdk-docs/docs/quickstart.md | 16 +- .../tutorial-basics/carbon-aware-webapi.md | 28 +-- .../docs/tutorial-basics/containerization.md | 10 - .../tutorial-extras/carbon-aware-library.md | 24 --- .../docs/tutorial-extras/configuration.md | 66 +----- .../docs/tutorial-extras/containerization.md | 10 - casdk-docs/docs/tutorial-extras/packaging.md | 15 +- .../selecting-a-data-source.md | 32 ++- samples/casdk-demo/README.md | 13 +- .../CarbonAware.CLI.IntegrationTests.csproj | 2 - .../Emissions/EmissionsCommandTests.cs | 8 +- .../EmissionsForecastsCommandTests.cs | 7 +- .../Commands/Location/LocationCommandTests.cs | 1 - .../IntegrationTestingBase.cs | 13 +- ...taSources.ElectricityMapsFree.Mocks.csproj | 21 -- .../ElectricityMapsFreeDataSourceMocker.cs | 79 ------- ...are.DataSources.ElectricityMapsFree.csproj | 30 --- .../src/Client/ElectricityMapsFreeClient.cs | 195 ------------------ .../ElectricityMapsFreeClientException.cs | 11 - .../ElectricityMapsFreeClientHttpException.cs | 46 ----- .../src/Client/IElectricityMapsFreeClient.cs | 22 -- .../ElectricityMapsFreeClientConfiguration.cs | 27 --- .../ServiceCollectionExtensions.cs | 50 ----- .../Constants/AuthenticationHeaderTypes.cs | 6 - .../src/Constants/Paths.cs | 6 - .../src/Constants/QueryStrings.cs | 11 - .../src/ElectricityMapsFreeDataSource.cs | 115 ----------- .../src/Model/GridEmissionDataPoint.cs | 45 ---- .../src/Model/LoginResult.cs | 16 -- ...taSources.ElectricityMapsFree.Tests.csproj | 24 --- .../Client/ElectricityMapsFreeClientTests.cs | 169 --------------- .../test/Client/TestData.cs | 77 ------- ...tricityMapsFreeClientConfigurationTests.cs | 37 ---- .../ElectricityMapsFreeDataSourceTests.cs | 124 ----------- .../test/Usings.cs | 1 - ...arbonAware.DataSources.Registration.csproj | 2 - .../Configuration/DataSourceType.cs | 1 - .../ServiceCollectionExtensions.cs | 12 +- .../CarbonAwareControllerTests.cs | 9 +- .../LocationsControllerTests.cs | 3 +- src/CarbonAware/src/CarbonAware.csproj | 3 - src/CarbonAwareSDK.sln | 6 - 45 files changed, 53 insertions(+), 1380 deletions(-) delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/mock/CarbonAware.DataSources.ElectricityMapsFree.Mocks.csproj delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/mock/ElectricityMapsFreeDataSourceMocker.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/CarbonAware.DataSources.ElectricityMapsFree.csproj delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClient.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientException.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientHttpException.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/IElectricityMapsFreeClient.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Configuration/ElectricityMapsFreeClientConfiguration.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Configuration/ServiceCollectionExtensions.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/AuthenticationHeaderTypes.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/Paths.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/QueryStrings.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/ElectricityMapsFreeDataSource.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Model/GridEmissionDataPoint.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Model/LoginResult.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/CarbonAware.DataSources.ElectricityMapsFree.Tests.csproj delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Client/ElectricityMapsFreeClientTests.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Client/TestData.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Configuration/ElectricityMapsFreeClientConfigurationTests.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/ElectricityMapsFreeDataSourceTests.cs delete mode 100644 src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Usings.cs diff --git a/casdk-docs/docs/architecture/c-sharp-client-library.md b/casdk-docs/docs/architecture/c-sharp-client-library.md index 2b47fe4ee..b5479a215 100644 --- a/casdk-docs/docs/architecture/c-sharp-client-library.md +++ b/casdk-docs/docs/architecture/c-sharp-client-library.md @@ -48,8 +48,7 @@ The following namespaces are included: There are two main classes that represents the data fetched from the data sources (i.e `Static Json`, [WattTime](https://www.watttime.org), -[ElectricityMaps](https://www.electricitymaps.com), and -[ElectricityMapsFree](https://www.co2signal.com/)): +[ElectricityMaps](https://www.electricitymaps.com)): - `EmissionsData` - `EmissionsForecast` diff --git a/casdk-docs/docs/architecture/data-sources.md b/casdk-docs/docs/architecture/data-sources.md index c31f68b0c..df535c5e4 100644 --- a/casdk-docs/docs/architecture/data-sources.md +++ b/casdk-docs/docs/architecture/data-sources.md @@ -7,8 +7,7 @@ sidebar_position: 3 Data sources allow developers easily integrate different data providers into the carbon aware SDK ([WattTime](https://www.wattime.org), -[ElectricityMaps](https://www.electricitymaps.com/), -[ElectricityMapsFree](https://www.co2signal.com/) etc) to be made available to +[ElectricityMaps](https://www.electricitymaps.com/), etc) to be made available to all higher-level user-interfaces (WebAPI, CLI, etc), while avoiding the details of how to interact with any specific provider. diff --git a/casdk-docs/docs/overview/enablement.md b/casdk-docs/docs/overview/enablement.md index 01b296791..8489c421a 100644 --- a/casdk-docs/docs/overview/enablement.md +++ b/casdk-docs/docs/overview/enablement.md @@ -13,7 +13,7 @@ sidebar_position: 3 * SDK * Use cases -2. [How to Use Carbon Aware SDK](#2-how-to-use-carbon-aware-sdk) +2. [How to Use Carbon Aware SDK](#2-how-to-use-carbon-aware-sdk) 2.1 [Pre-requisites](#21-pre-requisites) * Data sources @@ -23,13 +23,13 @@ sidebar_position: 3 * Setup * Usage - 2.3 [WebAPI](#23-webapi) + 2.3 [WebAPI](#23-webapi) * Setup * Deploying with container * Deploying with Kubernetes * Usage * Calling WebAPI using CLI - * Calling WebAPI using client libraries + * Calling WebAPI using client libraries 2.4 [Configurations](#24-configurations) @@ -43,16 +43,16 @@ you different data than the WebAPI for the same query). We provide a number of different endpoints to provide the most flexibility to integrate to your environment: -* CLI +* CLI You can run the application using the [CLI](/src/CarbonAware.CLI) and refer - to more documentation [here](../tutorial-basics/carbon-aware-cli.md). + to more documentation [here](../tutorial-basics/carbon-aware-cli.md). -* WebAPI +* WebAPI You can build a container containing the [WebAPI](/src/CarbonAware.WebApi) and connect via REST requests and refer to more documentation [here](../tutorial-basics/carbon-aware-webapi.md). -* SDK +* SDK You can reference the [Carbon Aware C# Library](/src/GSF.CarbonAware) in your projects and make use of its functionalities and features. @@ -75,7 +75,6 @@ We support various data sources of carbon aware data: * [WattTime](https://www.watttime.org/) * [ElectricityMaps](https://www.electricitymaps.com/) -* [ElectricityMapsFree](https://www.co2signal.com/) * JSON file There are a few constraints to select data sources to some functions of @@ -91,7 +90,7 @@ providers into the carbon aware SDK. * Alternatively: * Docker * VSCode and its [Remote Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) -* WebAPI +* WebAPI * Docker * VSCode and its [Remote Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) @@ -127,20 +126,13 @@ VSCode Remote Containers (Dev Container). To run locally: or ```bash + export DataSources__EmissionsDataSource="ElectricityMaps" export DataSources__ForecastDataSource="ElectricityMaps" export DataSources__Configurations__ElectricityMaps__Type="ElectricityMaps" export DataSources__Configurations__ElectricityMaps__APITokenHeader="auth-token" export DataSources__Configurations__ElectricityMaps__APIToken="" ``` - or - - ```bash - export DataSources__EmissionsDataSource="ElectricityMapsFree" - export DataSources__Configurations__ElectricityMapsFree__Type="ElectricityMapsFree" - export DataSources__Configurations__ElectricityMapsFree__token="" - ``` - 4. Run the CLI using `dotnet run` The CLI will ask you to at minimum provide a `--location (-l)` parameter. @@ -269,19 +261,13 @@ First we need to set up the GitHub repository or ```bash + export DataSources__EmissionsDataSource="ElectricityMaps" export DataSources__ForecastDataSource="ElectricityMaps" export DataSources__Configurations__ElectricityMaps__Type="ElectricityMaps" export DataSources__Configurations__ElectricityMaps__APITokenHeader="auth-token" export DataSources__Configurations__ElectricityMaps__APIToken="" ``` - or - - ```bash - export DataSources__EmissionsDataSource="ElectricityMapsFree" - export DataSources__Configurations__ElectricityMapsFree__Type="ElectricityMapsFree" - export DataSources__Configurations__ElectricityMapsFree__token="" - ``` 6. In the VSCode Terminal: 7. Change directory to: `cd src/CarbonAware.WebApi/src` diff --git a/casdk-docs/docs/quickstart.md b/casdk-docs/docs/quickstart.md index a500520f5..29b8f788f 100644 --- a/casdk-docs/docs/quickstart.md +++ b/casdk-docs/docs/quickstart.md @@ -55,19 +55,13 @@ VSCode Remote Containers (Dev Container). To run locally: or ```bash + export DataSources__EmissionsDataSource="ElectricityMaps" export DataSources__ForecastDataSource="ElectricityMaps" export DataSources__Configurations__ElectricityMaps__Type="ElectricityMaps" export DataSources__Configurations__ElectricityMaps__APITokenHeader="auth-token" export DataSources__Configurations__ElectricityMaps__APIToken="" ``` - or - - ```bash - export DataSources__EmissionsDataSource="ElectricityMapsFree" - export DataSources__Configurations__ElectricityMapsFree__Type="ElectricityMapsFree" - export DataSources__Configurations__ElectricityMapsFree__token="" - ``` 1. Run the CLI using `dotnet run` @@ -213,19 +207,13 @@ First we need to set up the GitHub repository or ```bash + export DataSources__EmissionsDataSource="ElectricityMaps" export DataSources__ForecastDataSource="ElectricityMaps" export DataSources__Configurations__ElectricityMaps__Type="ElectricityMaps" export DataSources__Configurations__ElectricityMaps__APITokenHeader="auth-token" export DataSources__Configurations__ElectricityMaps__APIToken="" ``` - or - - ```bash - export DataSources__EmissionsDataSource="ElectricityMapsFree" - export DataSources__Configurations__ElectricityMapsFree__Type="ElectricityMapsFree" - export DataSources__Configurations__ElectricityMapsFree__token="" - ``` 6. In the VSCode Terminal: 7. Change directory to: `cd src/CarbonAware.WebApi/src` diff --git a/casdk-docs/docs/tutorial-basics/carbon-aware-webapi.md b/casdk-docs/docs/tutorial-basics/carbon-aware-webapi.md index 70a5947c7..8985d5a20 100644 --- a/casdk-docs/docs/tutorial-basics/carbon-aware-webapi.md +++ b/casdk-docs/docs/tutorial-basics/carbon-aware-webapi.md @@ -36,9 +36,6 @@ client generation - [ElectricityMaps](#electricitymaps) - [Locations](#electricitymaps-locations) - [Exception Handling](#electricitymaps-exception-handling) - - [ElectricityMapsFree](#electricitymapsfree) - - [Locations](#locations) - - [Exception Handling](#exception-handling) ## Endpoints @@ -491,9 +488,9 @@ specification dotnet build --configuration Release --no-restore dotnet tool run swagger tofile --output ./wwwroot/api/v1/swagger.yaml --yaml bin/Release/net8.0/CarbonAware.WebApi.dll v1 ``` -1. The `CarbonAware.WebApi/src/wwwroot/api/v1/swagger.yaml` file contains the supported +1. The `CarbonAware.WebApi/src/wwwroot/api/v1/swagger.yaml` file contains the supported OpenApi specification. -1. Use for instance [swagger editor](https://editor.swagger.io) to see and try +1. Use for instance [swagger editor](https://editor.swagger.io) to see and try the endpoint routes. ## Data Sources @@ -550,24 +547,3 @@ Data Source will forward the response code and message back to the caller. Refer to the [ElectricityMapsHttpClientException](../src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMaps/src/Client/ElectricityMapsClientHttpException.cs) class for documentation on expected error codes. - -### ElectricityMapsFree - -#### Locations - -Each ElectricityMapsFree emissions data point is associated with a particular -named country code. While the ElectricityMapsFree endpoint supports calling with -lat/long geoposition as well, the result will always be a corresponding country -code. -They provide a -[route on their parent API (ElectricityMaps)](https://static.electricitymaps.com/api/docs/index.html#zones) -which can be queried to list all the country codes you have access to given your -token. - -#### Exception Handling - -If ElectricityMapsFree responds with a 4XX or 5XX status code the -ElectricityMapsFree Data Source will forward the response code and message back -to the caller. Refer to the -[ElectricityMapsFreeHttpClientException](../src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientHttpException.cs) -class for documentation on expected error codes. diff --git a/casdk-docs/docs/tutorial-basics/containerization.md b/casdk-docs/docs/tutorial-basics/containerization.md index 8f8211e05..921c399a3 100644 --- a/casdk-docs/docs/tutorial-basics/containerization.md +++ b/casdk-docs/docs/tutorial-basics/containerization.md @@ -49,16 +49,6 @@ carbon_aware v1 6293e2528bf2 About an hour ago 230MB > carbon_aware:v1 ``` - or the [ElectricityMapsFree](https://www.co2signal.com/) provider - - ```sh - docker run --rm -p 8000:8080 \ - > -e DataSources__EmissionsDataSource="ElectricityMapsFree" \ - > -e DataSources__Configurations__ElectricityMapsFree__Type="ElectricityMapsFree" \ - > -e DataSources__Configurations__ElectricityMapsFree__token="" \ - > carbon_aware:v1 - ``` - 1. Verify that the WebApi is responding to requests using an HTTP client tool (e.g. `postman`, `curl`) diff --git a/casdk-docs/docs/tutorial-extras/carbon-aware-library.md b/casdk-docs/docs/tutorial-extras/carbon-aware-library.md index 61da4155d..c5c594226 100644 --- a/casdk-docs/docs/tutorial-extras/carbon-aware-library.md +++ b/casdk-docs/docs/tutorial-extras/carbon-aware-library.md @@ -30,9 +30,6 @@ same configuration - [ElectricityMaps](#electricitymaps) - [Locations](#locations) - [Exception Handling](#exception-handling) - - [ElectricityMapsFree](#electricitymapsfree) - - [Locations](#locations) - - [Exception Handling](#exception-handling) ## EmissionsHandler Functions @@ -469,24 +466,3 @@ Data Source will forward the response code and message back to the caller. Refer to the [ElectricityMapsHttpClientException](../src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMaps/src/Client/ElectricityMapsClientHttpException.cs) class for documentation on expected error codes. - -### ElectricityMapsFree - -#### Locations - -Each ElectricityMapsFree emissions data point is associated with a particular -named country code. While the ElectricityMapsFree endpoint supports calling with -lat/long geoposition as well, the result will always be a corresponding country -code. -They provide a -[route on their parent API (ElectricityMaps)](https://static.electricitymaps.com/api/docs/index.html#zones) -which can be queried to list all the country codes you have access to given your -token. - -#### Exception Handling - -If ElectricityMapsFree responds with a 4XX or 5XX status code the -ElectricityMapsFree Data Source will forward the response code and message back -to the caller. Refer to the -[ElectricityMapsFreeHttpClientException](../src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientHttpException.cs) -class for documentation on expected error codes. diff --git a/casdk-docs/docs/tutorial-extras/configuration.md b/casdk-docs/docs/tutorial-extras/configuration.md index 416dce2ed..cf2bd3431 100644 --- a/casdk-docs/docs/tutorial-extras/configuration.md +++ b/casdk-docs/docs/tutorial-extras/configuration.md @@ -16,9 +16,6 @@ - [BaseUrl](#baseurl) - [Emission Factor Type](#emission-factor-type) - [Disable Estimations](#disable-estimations) - - [ElectricityMapsFree Configuration](#electricitymapsfree-configuration) - - [API Token](#api-token) - - [BaseUrl](#baseurl) - [Cache](#cache) - [CarbonAwareVars](#carbonawarevars) - [Tracing and Monitoring Configuration](#tracing-and-monitoring-configuration) @@ -30,7 +27,6 @@ - [Configuration for Emissions data Using WattTime](#configuration-for-emissions-data-using-watttime) - [Configuration for Forecast data Using ElectricityMaps](#configuration-for-forecast-data-using-electricitymaps) - [Configuration for Emissions data using ElectricityMaps and Forecast data using WattTime](#configuration-for-emissions-data-using-electricitymaps-and-forecast-data-using-watttime) - - [Configuration for Emissions data using ElectricityMapsFree and Forecast data using WattTime](#configuration-for-emissions-data-using-electricitymapsfree-and-forecast-data-using-watttime) - [Configuration For Emissions data Using JSON](#configuration-for-emissions-data-using-json) - [Configuration Using WattTime and Defined Location Source Files](#configuration-using-watttime-and-defined-location-source-files) @@ -296,44 +292,6 @@ See the [ElectricityMaps API Documentation](https://static.electricitymaps.com/api/docs/index.html#estimations) for more details. -### ElectricityMapsFree Configuration - -If using the ElectricityMapsFree data source, ElectricityMapsFree configuration -is required. - -**With an account token:** - -> **NOTE** The ElectricityMapsFree API does not currently support access to -> historical forecasts. This means that functionality such as the CLI -> `emissions-forecasts` > `--requested-at` flag and the API `/forecasts/batch` > -> `requestedAt` input will respond with a `NotImplemented` error. -> -> The ElectricityMapsFree API also does not currently support access to -> historical emissions data. It only supports getting the single latest -> emissions data point for the given location. -> -> If either of these restrictions are an issue, a data source that has support -> for historical forecasts, such as [WattTime](#watttime-configuration) or -> historical emissions, such as -> [ElectricityMaps](#electricitymaps-configuration) may be preferable. - -```json -{ - "token": "", - "baseUrl": "https://api.co2signal.com/v1/" -} -``` - -#### API Token - -The ElectricityMapsFree token you receive with your account. - -#### BaseUrl - -The url to use when connecting to ElectricityMapsFree. Defaults to -"https://api.co2signal.com/v1/" but can be overridden in the config if needed -(such as to enable integration testing scenarios). - ## Cache Frequent access to data sources could cause problems such as performance trouble @@ -434,7 +392,7 @@ The scraping endpoint is `/metrics` like this: http://localhost/metrics ``` -By default, the exposed data are latest ones within last 24 hours. If you would like to change the period +By default, the exposed data are latest ones within last 24 hours. If you would like to change the period in some reasones, you can configure the value like this: ```json @@ -613,28 +571,6 @@ DataSources__Configurations__WattTime__Password="wattTimePassword" } ``` -## Configuration for Emissions data using ElectricityMapsFree and Forecast data using WattTime - -```json - "DataSources": { - "EmissionsDataSource": "ElectricityMapsFree", - "ForecastDataSource": "WattTime", - "Configurations": { - "WattTime": { - "Type": "WattTime", - "Username": "username", - "Password": "password", - "BaseURL": "https://api2.watttime.org/v2/", - }, - "ElectricityMapsFree": { - "Type": "ElectricityMapsFree", - "token": "token", - "BaseURL": "https://api.co2signal.com/v1/" - } - } - } -``` - ### Configuration For Emissions data Using JSON ```json diff --git a/casdk-docs/docs/tutorial-extras/containerization.md b/casdk-docs/docs/tutorial-extras/containerization.md index 713a534d8..d8b3a6c40 100644 --- a/casdk-docs/docs/tutorial-extras/containerization.md +++ b/casdk-docs/docs/tutorial-extras/containerization.md @@ -49,16 +49,6 @@ carbon_aware v1 6293e2528bf2 About an hour ago 230MB > carbon_aware:v1 ``` - or the [ElectricityMapsFree](https://www.co2signal.com/) provider - - ```sh - docker run --rm -p 8000:80 \ - > -e DataSources__EmissionsDataSource="ElectricityMapsFree" \ - > -e DataSources__Configurations__ElectricityMapsFree__Type="ElectricityMapsFree" \ - > -e DataSources__Configurations__ElectricityMapsFree__token="" \ - > carbon_aware:v1 - ``` - 1. Verify that the WebApi is responding to requests using an HTTP client tool (e.g. `postman`, `curl`) diff --git a/casdk-docs/docs/tutorial-extras/packaging.md b/casdk-docs/docs/tutorial-extras/packaging.md index 7aef80801..78ab91dbd 100644 --- a/casdk-docs/docs/tutorial-extras/packaging.md +++ b/casdk-docs/docs/tutorial-extras/packaging.md @@ -10,7 +10,6 @@ showing how the package can be consumed. - [Included Scripts](#included-scripts) - [Running the packaging scripts](#running-the-packaging-scripts) - [SDK Configuration](#sdk-configuration) - - [ElectricityMapsFree](#electricitymapsfree) - [ElectricityMaps](#electricitymaps) - [WattTime](#watttime) - [Json](#json) @@ -24,7 +23,6 @@ The current package include 8 projects from the SDK: 1. "GSF.CarbonAware" 2. "CarbonAware" -3. "CarbonAware.DataSources.ElectricityMapsFree" 4. "CarbonAware.DataSources.ElectricityMaps" 5. "CarbonAware.DataSources.Json" 6. "CarbonAware.DataSources.Registration" @@ -67,25 +65,16 @@ Alternatively you can run in your local environment using the ## SDK Configuration -The configuration needed to connect to WattTime, ElectricityMaps, ElectricityMapsFree, or Json data sources can be managed using environment variables or appsettings. +The configuration needed to connect to WattTime, ElectricityMaps, or Json data sources can be managed using environment variables or appsettings. More information on data source configuration can be found [here](configuration.md#datasources) -### ElectricityMapsFree - -Below are the environment variables needed to set up the -**ElectricityMapsFree** data source. - -```bash -export DataSources__EmissionsDataSource=ElectricityMapsFree -export DataSources__Configurations__ElectricityMapsFree__Type=ElectricityMapsFree -export DataSources__Configurations__ElectricityMapsFree__token=[ElectricityMapsFree APIToken]` -``` ### ElectricityMaps Below are the environment variables needed to set up the **ElectricityMaps** data source. ```bash +export DataSources__EmissionsDataSource=ElectricityMaps export DataSources__ForecastDataSource=ElectricityMaps export DataSources__Configurations__ElectricityMaps__Type=ElectricityMaps export DataSources__Configurations__ElectricityMaps__APITokenHeader=[ElectricityMaps APITokenHeader] diff --git a/casdk-docs/docs/tutorial-extras/selecting-a-data-source.md b/casdk-docs/docs/tutorial-extras/selecting-a-data-source.md index 5d25823a0..6b8394dd4 100644 --- a/casdk-docs/docs/tutorial-extras/selecting-a-data-source.md +++ b/casdk-docs/docs/tutorial-extras/selecting-a-data-source.md @@ -5,7 +5,7 @@ sidebar_position: 1 # Selecting a Data Source The Carbon Aware SDK includes access to various data sources of carbon aware -data, including WattTime, ElectricityMaps, ElectricityMapsFree, and a custom +data, including WattTime, ElectricityMaps, and a custom JSON source. These matrices are an attempt to track what features of the Carbon Aware SDK are enabled for which data sources. @@ -14,7 +14,6 @@ Aware SDK are enabled for which data sources. - [Type of Data Sources and Configuration](#type-of-data-sources-and-configuration) - [Data Source Methods Available](#data-source-methods-available) - [Location Coverage](#location-coverage) -- [Restriction: ElectricityMaps Free Trial User](#restrictions-electricitymaps-free-trial-user) ## Type of Data Sources and Configuration @@ -22,24 +21,24 @@ In the CarbonAware SDK configuration, you can set what data source to use as the `EmissionsDataSource` and the `ForecastDataSource`. There are also certain configuration fields that must be set in order to access the raw data. -| Type | WattTime | ElectricityMaps | ElectricityMapsFree | JSON | -|-------------------------------|-----------|------------------------------------------------------------------------------------|---------------------|----------| -| Is Emissions DataSource | ✅ | ✅ | ✅ | ✅ | -| Is Forecast DataSource | ✅ | ✅ | ❌ | ❌ | -| Makes HTTP(s) call | ✅ | ✅ | ✅ | ❌ | -| Can Use Custom Data | ❌ | ❌ | ❌ | ✅ | -| Supports Trial + Full Account | ✅ | ✅ (\*[see restriction below](#restrictions-electricitymaps-free-trial-user)) | N/A | N/A | +| Type | WattTime | ElectricityMaps | JSON | +|-------------------------------|-----------|------------------------------------------------------------------------------------|----------| +| Is Emissions DataSource | ✅ | ✅ | ✅ | +| Is Forecast DataSource | ✅ | ✅ | ❌ | +| Makes HTTP(s) call | ✅ | ✅ | ❌ | +| Can Use Custom Data | ❌ | ❌ | ✅ | +| Supports Trial + Full Account | ✅ | ✅ (\*[see restriction below](#restrictions-electricitymaps-free-trial-user)) | N/A | ## Data Source Methods Available Not all data sources support all the routes provided in the interfaces (`IEmissionsDataSource`/`IForecastDataSource`). -| Methods | WattTime | ElectricityMaps | ElectricityMapsFree | JSON | CLI Usage | Web Api Usage | SDK Usage | -| ----------------------- | :------: | :-------------: | :-----------------: | :------: | :--------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------: | -| GetCarbonIntensityAsync | ✅ | ✅ | ✅ | ✅ | `emissions` | `emissions/bylocation` or `emissions/bylocations` or `emissions/bylocations/best` or `emissions/average`‑`carbon`‑`intensity` or `emissions/average`‑`carbon`‑`intensity/batch` | `GetEmissionsDataAsync(...)` or `GetBestEmissionsDataAsync(...)` or `GetAverageCarbonIntensityDataAsync(...)` | -| GetCurrentForecastAsync | ✅ | ✅ | ❌ | ❌ | `emissions`‑`forecasts` | `forecasts/current` | `GetCurrentForecastAsync(...)` | -| GetForecastByDateAsync | ✅ | ❌ | ❌ | ❌ | `emissions`‑`forecasts` ‑‑`requested`‑`at` | `forecasts/batch` with `requestedAt` field | `GetForecastByDateAsync(...)` | +| Methods | WattTime | ElectricityMaps | JSON | CLI Usage | Web Api Usage | SDK Usage | +| ----------------------- | :------: | :-------------: | :------: | :--------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------: | +| GetCarbonIntensityAsync | ✅ | ✅ | ✅ | `emissions` | `emissions/bylocation` or `emissions/bylocations` or `emissions/bylocations/best` or `emissions/average`‑`carbon`‑`intensity` or `emissions/average`‑`carbon`‑`intensity/batch` | `GetEmissionsDataAsync(...)` or `GetBestEmissionsDataAsync(...)` or `GetAverageCarbonIntensityDataAsync(...)` | +| GetCurrentForecastAsync | ✅ | ✅ | ❌ | `emissions`‑`forecasts` | `forecasts/current` | `GetCurrentForecastAsync(...)` | +| GetForecastByDateAsync | ✅ | ❌ | ❌ | `emissions`‑`forecasts` ‑‑`requested`‑`at` | `forecasts/batch` with `requestedAt` field | `GetForecastByDateAsync(...)` | ## Location Coverage @@ -53,9 +52,8 @@ location config. relevant zone. - For `ElectricityMaps`, see their [live map app](https://app.electricitymaps.com/map) - to find the relevant zone and see current data coming in. -- For `ElectricityMapsFree`, see the Electricity Maps - [zone list](https://api.electricitymap.org/v3/zones) to find the relevant + to find the relevant zone and see current data coming in or their + [zone list](https://api.electricitymap.org/v3/zones) endpoint to find the relevant zones. ## Restrictions: free trial of ElectricityMaps diff --git a/samples/casdk-demo/README.md b/samples/casdk-demo/README.md index 168cd5abd..87d41ba96 100644 --- a/samples/casdk-demo/README.md +++ b/samples/casdk-demo/README.md @@ -22,8 +22,8 @@ NGINX is a reverse proxy to both Carbon Aware SDK and Swagger UI. To avoid CORS See [nginx-rp.conf](nginx-rp.conf) -/ -> Carbon Aware SDK -/swagger.yaml -> OpenAPI document provided by Carbon Aware SDK +/ -> Carbon Aware SDK +/swagger.yaml -> OpenAPI document provided by Carbon Aware SDK /swagger-ui/ -> Swagger UI for Carbon Aware SDK ## How to run @@ -53,12 +53,13 @@ See [nginx-rp.conf](nginx-rp.conf) ## Example -Run demonstration with ElectricityMapsFree datasource +Run demonstration with ElectricityMaps datasource ``` -export CASDK_DataSources__EmissionsDataSource=ElectricityMapsFree -export CASDK_DataSources__Configurations__ElectricityMapsFree__Type=ElectricityMapsFree -export CASDK_DataSources__Configurations__ElectricityMapsFree__token=YOUR_SECRET_TOKEN +export CASDK_DataSources__EmissionsDataSource=ElectricityMaps +export CASDK_DataSources__ForecastDataSource=ElectricityMaps +export CASDK_DataSources__Configurations__ElectricityMaps__Type=ElectricityMaps +export CASDK_DataSources__Configurations__ElectricityMaps__token=YOUR_SECRET_TOKEN ./demo.sh start ``` diff --git a/src/CarbonAware.CLI/test/integrationTests/CarbonAware.CLI.IntegrationTests.csproj b/src/CarbonAware.CLI/test/integrationTests/CarbonAware.CLI.IntegrationTests.csproj index a79c9cdf0..8c68ddd6d 100644 --- a/src/CarbonAware.CLI/test/integrationTests/CarbonAware.CLI.IntegrationTests.csproj +++ b/src/CarbonAware.CLI/test/integrationTests/CarbonAware.CLI.IntegrationTests.csproj @@ -21,8 +21,6 @@ Include="..\..\..\CarbonAware.DataSources\CarbonAware.DataSources.WattTime\mock\CarbonAware.DataSources.WattTime.Mocks.csproj" /> - \ No newline at end of file diff --git a/src/CarbonAware.CLI/test/integrationTests/Commands/Emissions/EmissionsCommandTests.cs b/src/CarbonAware.CLI/test/integrationTests/Commands/Emissions/EmissionsCommandTests.cs index 21473e37b..63eb86a63 100644 --- a/src/CarbonAware.CLI/test/integrationTests/Commands/Emissions/EmissionsCommandTests.cs +++ b/src/CarbonAware.CLI/test/integrationTests/Commands/Emissions/EmissionsCommandTests.cs @@ -6,12 +6,11 @@ namespace CarbonAware.CLI.IntegrationTests.Commands.Emissions; /// -/// Tests that the CLI handles and packages various responses from handlers +/// Tests that the CLI handles and packages various responses from handlers /// and data sources properly, including empty responses and exceptions. /// [TestFixture(DataSourceType.JSON)] [TestFixture(DataSourceType.WattTime)] -[TestFixture(DataSourceType.ElectricityMapsFree)] internal class EmissionsCommandTests : IntegrationTestingBase { public EmissionsCommandTests(DataSourceType dataSource) : base(dataSource) { } @@ -98,7 +97,7 @@ public async Task Emissions_InvalidStartAndEnd_ReturnsExpectedError() string expectedError = "Invalid parameters Start: Start must be before End "; // Act var exitCode = await InvokeCliAsync($"emissions -l {location} -s 2022-09-01T02:05:00Z -e 2022-09-01T01:00:00Z"); - // Whitespace characters regex + // Whitespace characters regex var regex = @"\s+"; var output = Regex.Replace(_console.Error.ToString()!, regex, " "); @@ -134,7 +133,6 @@ public async Task Emissions_BestOption_ReturnsExpectedData() [Test] public async Task Emissions_AverageOption_ReturnsExpectedData() { - IgnoreTestForDataSource($"data source does not implement the '-a' switch", DataSourceType.ElectricityMapsFree); // Arrange var start = DateTimeOffset.Parse("2022-09-01T00:00:00Z"); @@ -171,7 +169,7 @@ public async Task Average_Best_ReturnsExpectedError() // Assert Assert.AreEqual(1, exitCode); var expectedError = "Options --average and --best cannot be used together Option '-s' expects a single argument but 2 were provided. "; - // Whitespace characters regex + // Whitespace characters regex var regex = @"\s+"; var output = Regex.Replace(_console.Error.ToString()!, regex, " "); diff --git a/src/CarbonAware.CLI/test/integrationTests/Commands/EmissionsForecasts/EmissionsForecastsCommandTests.cs b/src/CarbonAware.CLI/test/integrationTests/Commands/EmissionsForecasts/EmissionsForecastsCommandTests.cs index 5daf173c8..855d6f24c 100644 --- a/src/CarbonAware.CLI/test/integrationTests/Commands/EmissionsForecasts/EmissionsForecastsCommandTests.cs +++ b/src/CarbonAware.CLI/test/integrationTests/Commands/EmissionsForecasts/EmissionsForecastsCommandTests.cs @@ -5,12 +5,11 @@ namespace CarbonAware.CLI.IntegrationTests.Commands.EmissionsForecasts; /// -/// Tests that the CLI handles and packages various responses from handlers +/// Tests that the CLI handles and packages various responses from handlers /// and data sources properly, including empty responses and exceptions. /// [TestFixture(DataSourceType.WattTime)] [TestFixture(DataSourceType.ElectricityMaps)] -//[TestFixture(DataSourceType.ElectricityMapsFree)] // Left out because these tests are not relevant for this data source internal class EmissionsForecastsCommandTests : IntegrationTestingBase { public EmissionsForecastsCommandTests(DataSourceType dataSource) : base(dataSource) { } @@ -73,14 +72,14 @@ public async Task EmissionsForecasts_StartAndEndOptions_ReturnsExpectedData() var end = start.AddHours(5); var dataStartAt = start.ToString("yyyy-MM-ddTHH:mm:ssZ"); var dataEndAt = end.ToString("yyyy-MM-ddTHH:mm:ssZ"); - + _dataSourceMocker.SetupForecastMock(); // Act var exitCode = await InvokeCliAsync($"emissions-forecasts -l {location} -s {dataStartAt} -e {dataEndAt}"); // Assert Assert.AreEqual(0, exitCode, _console.Error.ToString()); - + var jsonResults = JsonNode.Parse(_console.Out.ToString()!)!.AsArray()!; var firstResult = jsonResults.First()!.AsObject(); Assert.AreEqual(1, jsonResults.Count); diff --git a/src/CarbonAware.CLI/test/integrationTests/Commands/Location/LocationCommandTests.cs b/src/CarbonAware.CLI/test/integrationTests/Commands/Location/LocationCommandTests.cs index ff422376a..a2b625fbb 100644 --- a/src/CarbonAware.CLI/test/integrationTests/Commands/Location/LocationCommandTests.cs +++ b/src/CarbonAware.CLI/test/integrationTests/Commands/Location/LocationCommandTests.cs @@ -10,7 +10,6 @@ namespace CarbonAware.CLI.IntegrationTests.Commands.Location; [TestFixture(DataSourceType.JSON)] [TestFixture(DataSourceType.WattTime)] [TestFixture(DataSourceType.ElectricityMaps)] -[TestFixture(DataSourceType.ElectricityMapsFree)] class LocationCommandTests : IntegrationTestingBase { public LocationCommandTests(DataSourceType dataSource) : base(dataSource) { } diff --git a/src/CarbonAware.CLI/test/integrationTests/IntegrationTestingBase.cs b/src/CarbonAware.CLI/test/integrationTests/IntegrationTestingBase.cs index 1ab6b9d40..4818c7f0d 100644 --- a/src/CarbonAware.CLI/test/integrationTests/IntegrationTestingBase.cs +++ b/src/CarbonAware.CLI/test/integrationTests/IntegrationTestingBase.cs @@ -1,7 +1,6 @@ using CarbonAware.DataSources.Configuration; using CarbonAware.Interfaces; using CarbonAware.DataSources.ElectricityMaps.Mocks; -using CarbonAware.DataSources.ElectricityMapsFree.Mocks; using CarbonAware.DataSources.Json.Mocks; using CarbonAware.DataSources.WattTime.Mocks; using NUnit.Framework; @@ -81,7 +80,7 @@ protected async Task InvokeCliAsync(string arguments) var standardError = new StreamWriter(Console.OpenStandardError()); standardOutput.AutoFlush = true; standardError.AutoFlush = true; - + Console.SetOut(standardOutput); Console.SetError(standardError); @@ -115,6 +114,7 @@ public void Setup() } case DataSourceType.ElectricityMaps: { + Environment.SetEnvironmentVariable("DataSources__EmissionsDataSource", "ElectricityMaps"); Environment.SetEnvironmentVariable("DataSources__ForecastDataSource", "ElectricityMaps"); Environment.SetEnvironmentVariable("DataSources__Configurations__ElectricityMaps__Type", "ElectricityMaps"); Environment.SetEnvironmentVariable("DataSources__Configurations__ElectricityMaps__APITokenHeader", "token"); @@ -123,15 +123,6 @@ public void Setup() _dataSourceMocker = new ElectricityMapsDataSourceMocker(); break; } - case DataSourceType.ElectricityMapsFree: - { - Environment.SetEnvironmentVariable("DataSources__EmissionsDataSource", "ElectricityMapsFree"); - Environment.SetEnvironmentVariable("DataSources__Configurations__ElectricityMapsFree__Type", "ElectricityMapsFree"); - Environment.SetEnvironmentVariable("DataSources__Configurations__ElectricityMapsFree__token", "token"); - - _dataSourceMocker = new ElectricityMapsFreeDataSourceMocker(); - break; - } case DataSourceType.None: { throw new NotSupportedException($"DataSourceType {_dataSource.ToString()} not supported"); diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/mock/CarbonAware.DataSources.ElectricityMapsFree.Mocks.csproj b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/mock/CarbonAware.DataSources.ElectricityMapsFree.Mocks.csproj deleted file mode 100644 index a8878c6ae..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/mock/CarbonAware.DataSources.ElectricityMapsFree.Mocks.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - - - - diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/mock/ElectricityMapsFreeDataSourceMocker.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/mock/ElectricityMapsFreeDataSourceMocker.cs deleted file mode 100644 index 7ddf800b1..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/mock/ElectricityMapsFreeDataSourceMocker.cs +++ /dev/null @@ -1,79 +0,0 @@ -using CarbonAware.Interfaces; -using CarbonAware.DataSources.ElectricityMapsFree.Model; -using CarbonAware.DataSources.ElectricityMapsFree.Constants; -using System.Net; -using System.Net.Mime; -using System.Text.Json; -using WireMock.RequestBuilders; -using WireMock.ResponseBuilders; -using WireMock.Server; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Mocks; - -internal class ElectricityMapsFreeDataSourceMocker : IDataSourceMocker -{ - private readonly WireMockServer _server; - private static readonly JsonSerializerOptions _options = new JsonSerializerOptions(JsonSerializerDefaults.Web); - - - public ElectricityMapsFreeDataSourceMocker() - { - _server = WireMockServer.Start(); - Environment.SetEnvironmentVariable("DataSources__Configurations__ElectricityMapsFree__BaseURL", _server.Url!); - Initialize(); - } - - public void SetupDataMock(DateTimeOffset start, DateTimeOffset end, string location) - { - var data = new GridEmissionDataPoint - { - Disclaimer = string.Empty, - Status = "ok", - CountryCodeAbbreviation = location, - Data = new Data() { - Datetime = start, - CarbonIntensity = 100, - FossilFuelPercentage = 12.03F - }, - Units = new Units() - { - CarbonIntensity = "gCO2eq/kWh" - } - }; - - SetupResponseGivenGetRequest(Paths.Latest, data); - } - - public void SetupForecastMock() - { - throw new NotImplementedException(); - } - - public void SetupHistoricalBatchForecastMock() - { - throw new NotImplementedException(); - } - - public void Initialize() - { - // No initialization needed - return; - } - - public void Reset() => _server.Reset(); - - public void Dispose() => _server.Dispose(); - - private void SetupResponseGivenGetRequest(string path, object body) - { - var jsonBody = JsonSerializer.Serialize(body, _options); - _server - .Given(Request.Create().WithPath("/" + path).UsingGet()) - .RespondWith( - Response.Create() - .WithStatusCode(HttpStatusCode.OK) - .WithHeader("Content-Type", MediaTypeNames.Application.Json) - .WithBody(jsonBody) - ); - } -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/CarbonAware.DataSources.ElectricityMapsFree.csproj b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/CarbonAware.DataSources.ElectricityMapsFree.csproj deleted file mode 100644 index 310a6ed47..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/CarbonAware.DataSources.ElectricityMapsFree.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - net8.0 - enable - enable - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClient.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClient.cs deleted file mode 100644 index 0176b6be0..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClient.cs +++ /dev/null @@ -1,195 +0,0 @@ -using CarbonAware.DataSources.ElectricityMapsFree.Configuration; -using CarbonAware.DataSources.ElectricityMapsFree.Constants; -using CarbonAware.DataSources.ElectricityMapsFree.Model; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System.Diagnostics; -using System.Net.Http.Headers; -using System.Net.Mime; -using System.Net; -using System.Text.Json; -using System.Web; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Client; - -internal class ElectricityMapsFreeClient : IElectricityMapsFreeClient -{ - private static readonly JsonSerializerOptions options = new JsonSerializerOptions(JsonSerializerDefaults.Web); - - private static readonly HttpStatusCode[] RetriableStatusCodes = new HttpStatusCode[] - { - HttpStatusCode.Unauthorized, - HttpStatusCode.Forbidden - }; - - private readonly HttpClient client; - - private IOptionsMonitor ConfigurationMonitor { get; } - - private ElectricityMapsFreeClientConfiguration Configuration => this.ConfigurationMonitor.CurrentValue; - - private static readonly ActivitySource Activity = new ActivitySource(nameof(ElectricityMapsFreeClient)); - - private ILogger Log { get; } - - public ElectricityMapsFreeClient(IHttpClientFactory factory, IOptionsMonitor configurationMonitor, ILogger log) - { - this.client = factory.CreateClient(IElectricityMapsFreeClient.NamedClient); - this.ConfigurationMonitor = configurationMonitor; - this.Log = log; - Configuration.Validate(); - this.client.BaseAddress = new Uri(this.Configuration.BaseUrl); - this.client.DefaultRequestHeaders.Accept.Clear(); - this.client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); - } - - /// - public async Task GetCurrentEmissionsAsync(string countryCodeAbbreviation) - { - Log.LogInformation("Requesting latest carbon intensity from zone {countryCode}", countryCodeAbbreviation); - - var parameters = new Dictionary() - { - { QueryStrings.countryCodeAbbreviation, countryCodeAbbreviation } - }; - - var tags = new Dictionary() - { - { QueryStrings.countryCodeAbbreviation, countryCodeAbbreviation } - }; - - var result = await this.MakeRequestAsync(Paths.Latest, parameters, tags); - var emissionData = JsonSerializer.Deserialize(result, options) ?? throw new ElectricityMapsFreeClientException($"Error getting latest carbon intensity for countryCode {countryCodeAbbreviation}"); - if (emissionData == null || emissionData.Data.CarbonIntensity == null || emissionData.Data.Datetime == null) - { - Log.LogError("Region {countryCode} is not known", countryCodeAbbreviation); - throw new ElectricityMapsFreeClientException($"Region {countryCodeAbbreviation} is not known"); - } - return emissionData; - } - - /// - public async Task GetCurrentEmissionsAsync(string latitude, string longitude) - { - Log.LogDebug("Requesting latest carbon intensity using latitude {latitude} longitude {longitude}", - latitude, longitude); - - var parameters = new Dictionary() - { - { QueryStrings.Latitude, latitude }, - { QueryStrings.Longitude, longitude } - }; - - var result = await this.MakeRequestAsync(Paths.Latest, parameters); - - var emissionData = JsonSerializer.Deserialize(result, options) ?? throw new ElectricityMapsFreeClientException($"Error getting forecast for latitude {latitude} longitude {longitude}"); - return emissionData; - } - - private async Task GetAsyncWithAuthRetry(string uriPath) - { - this.EnsureToken(); - - var response = await this.client.GetAsync(uriPath); - - if (RetriableStatusCodes.Contains(response.StatusCode)) - { - Log.LogDebug("Failed to get url {url} with status code {statusCode}. Attempting to log in again.", uriPath, response.StatusCode); - this.UpdateAuthToken(); - response = await this.client.GetAsync(uriPath); - } - - if (!response.IsSuccessStatusCode) - { - Log.LogError("Error getting data from electricityMapsFree. StatusCode: {statusCode}. Response: {response}", response.StatusCode, response); - throw new ElectricityMapsFreeClientHttpException($"Error getting data from electricityMapsFree: {response.StatusCode}", response); - } - return response; - } - - private async Task GetAsyncStringWithAuthRetry(string uriPath) - { - var response = await this.GetAsyncWithAuthRetry(uriPath); - var data = await response.Content.ReadAsStringAsync(); - return data ?? string.Empty; - } - - private async Task GetAsyncStreamWithAuthRetry(string uriPath) - { - var response = await this.GetAsyncWithAuthRetry(uriPath); - return await response.Content.ReadAsStreamAsync(); - } - - private void EnsureToken() - { - if (!this.client.DefaultRequestHeaders.Contains("auth-token")) - { - this.UpdateAuthToken(); - } - } - - private void UpdateAuthToken() - { - using (var activity = Activity.StartActivity()) - { - Log.LogInformation("Attempting to log using token {token}", this.Configuration.Token); - this.SetAuthTokenAuthenticationHeader(this.Configuration.Token!); - } - } - - internal void SetAuthTokenAuthenticationHeader(string token) - { - this.client.DefaultRequestHeaders.Add("auth-token", token); - } - - private async Task MakeRequestAsync(string path, Dictionary parameters, Dictionary? tags = null) - { - using (var activity = Activity.StartActivity()) - { - var url = BuildUrlWithQueryString(path, parameters); - - Log.LogInformation("Requesting data using url {url}", url); - - if (tags != null) - { - foreach (var kvp in tags) - { - activity?.AddTag(kvp.Key, kvp.Value); - } - } - - var result = await this.GetAsyncStringWithAuthRetry(url); - - Log.LogDebug("For query {url}, received data {result}", url, result); - - return result; - } - } - - private string BuildUrlWithQueryString(string url, IDictionary queryStringParams) - { - if (Log.IsEnabled(LogLevel.Debug)) - { - Log.LogDebug("Attempting to build a url using url {url} and query string parameters {parameters}", url, string.Join(";", queryStringParams.Select(k => $"\"{k.Key}\":\"{k.Value}\""))); - } - - // this will get a specialized namevalue collection for formatting query strings. - var query = HttpUtility.ParseQueryString(string.Empty); - - foreach (var kvp in queryStringParams) - { - query[kvp.Key] = kvp.Value; - } - - var result = $"{url}?{query}"; - - if (Log.IsEnabled(LogLevel.Debug)) - { - Log.LogDebug("Built url {result} from url {url} and query string parameters {parameters}", result, url, string.Join(";", queryStringParams.Select(k => $"\"{k.Key}\":\"{k.Value}\""))); - } - - return result; - } -} - - diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientException.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientException.cs deleted file mode 100644 index 3d765e64b..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientException.cs +++ /dev/null @@ -1,11 +0,0 @@ -using CarbonAware.Interfaces; -using System; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Client; - -internal class ElectricityMapsFreeClientException : Exception -{ - public ElectricityMapsFreeClientException(string message) : base(message) - { - } -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientHttpException.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientHttpException.cs deleted file mode 100644 index 892ac34e1..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/ElectricityMapsFreeClientHttpException.cs +++ /dev/null @@ -1,46 +0,0 @@ -using CarbonAware.Interfaces; -using System; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Client; - -internal class ElectricityMapsFreeClientHttpException : Exception, IHttpResponseException -{ - /// - /// Creates a new instance of the class. - /// - /// The error message supplied. - /// The response object generating this exception. - public ElectricityMapsFreeClientHttpException(string message, HttpResponseMessage response) : base(message) - { - this.Response = response; - this.Status = (int)response.StatusCode; - this.Title = nameof(ElectricityMapsFreeClientHttpException); - this.Detail = message; - } - - /// - /// Gets the status code for the exception. See remarks for the status codes that can be returned. - /// - /// - /// 400: Returned when missing arguments (no country code passed or lat/lon don't map to a known country code) - /// 401: Returned when trying to access a path or location that isn't authorized for the token. - /// - public int? Status { get; } - - /// - /// A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence - /// of the problem, except for purposes of localization(e.g., using proactive content negotiation; - /// see[RFC7231], Section 3.4). - /// - public string? Title { get; } - - /// - /// A human-readable explanation specific to this occurrence of the problem. - /// - public string? Detail { get; } - - /// - /// Gets the response returned from the Electricity Maps Free call. - /// - public HttpResponseMessage? Response { get; } -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/IElectricityMapsFreeClient.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/IElectricityMapsFreeClient.cs deleted file mode 100644 index c8f0c6838..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Client/IElectricityMapsFreeClient.cs +++ /dev/null @@ -1,22 +0,0 @@ -using CarbonAware.DataSources.ElectricityMapsFree.Model; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Client; - -/// -/// An interface for interacting with the Electricity Maps Free API, also called CO2 Signal. -/// -internal interface IElectricityMapsFreeClient -{ - public const string NamedClient = "ElectricityMapsFreeClient"; - - /// - /// Async method to get the latest emission data for a given country code - /// - public Task GetCurrentEmissionsAsync(string countryCodeAbbreviation); - - /// - /// Async method to get the latest emission data for a given latitude and longitude - /// - public Task GetCurrentEmissionsAsync(string latitude, string longitude); - -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Configuration/ElectricityMapsFreeClientConfiguration.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Configuration/ElectricityMapsFreeClientConfiguration.cs deleted file mode 100644 index e31b2e2fa..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Configuration/ElectricityMapsFreeClientConfiguration.cs +++ /dev/null @@ -1,27 +0,0 @@ -using CarbonAware.Exceptions; -using CarbonAware.DataSources.ElectricityMapsFree.Constants; -using CarbonAware.DataSources.ElectricityMapsFree.Model; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Configuration; - -public class ElectricityMapsFreeClientConfiguration -{ - public const string Key = "ElectricityMapsFreeClient"; - - public string? Token { get; set; } - - public string BaseUrl { get; set; } = "https://api.co2signal.com/v1/"; - - public void Validate() - { - if (string.IsNullOrWhiteSpace(this.Token)) - { - throw new ConfigurationException($"{Key}:{nameof(this.Token)} is required for electricityMaps free."); - } - - if (!Uri.IsWellFormedUriString(this.BaseUrl, UriKind.Absolute)) - { - throw new ConfigurationException($"{Key}:{nameof(this.BaseUrl)} is not a valid absolute url."); - } - } -} \ No newline at end of file diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Configuration/ServiceCollectionExtensions.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Configuration/ServiceCollectionExtensions.cs deleted file mode 100644 index 8156b2b87..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Configuration/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,50 +0,0 @@ -using CarbonAware.Configuration; -using CarbonAware.DataSources.ElectricityMapsFree.Client; -using CarbonAware.Exceptions; -using CarbonAware.Interfaces; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using System.Net; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Configuration; - -internal static class ServiceCollectionExtensions -{ - public static IServiceCollection AddElectricityMapsFreeEmissionsDataSource(this IServiceCollection services, DataSourcesConfiguration dataSourcesConfig) - { - AddElectricityMapsFreeClient(services, dataSourcesConfig.EmissionsConfigurationSection()); - services.TryAddSingleton(); - return services; - } - - - private static void AddElectricityMapsFreeClient(IServiceCollection services, IConfigurationSection configSection) - { - services.Configure(c => - { - configSection.Bind(c); - }); - - var httpClientBuilder = services.AddHttpClient(IElectricityMapsFreeClient.NamedClient); - - var Proxy = configSection.GetSection("Proxy").Get(); - if (Proxy?.UseProxy == true) - { - if (String.IsNullOrEmpty(Proxy.Url)) - { - throw new ConfigurationException("Proxy Url is not configured."); - } - httpClientBuilder.ConfigurePrimaryHttpMessageHandler(() => - new HttpClientHandler() { - Proxy = new WebProxy { - Address = new Uri(Proxy.Url), - Credentials = new NetworkCredential(Proxy.Username, Proxy.Password), - BypassProxyOnLocal = true - } - } - ); - } - services.TryAddSingleton(); - } -} \ No newline at end of file diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/AuthenticationHeaderTypes.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/AuthenticationHeaderTypes.cs deleted file mode 100644 index 24d723ecf..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/AuthenticationHeaderTypes.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace CarbonAware.DataSources.ElectricityMapsFree.Constants; - -internal class AuthenticationHeaderTypes -{ - public const string AuthToken = "auth-token"; -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/Paths.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/Paths.cs deleted file mode 100644 index 738b0306d..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/Paths.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace CarbonAware.DataSources.ElectricityMapsFree.Constants; - -internal class Paths -{ - public const string Latest = "latest"; -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/QueryStrings.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/QueryStrings.cs deleted file mode 100644 index a7775ca64..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Constants/QueryStrings.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace CarbonAware.DataSources.ElectricityMapsFree.Constants; - -internal class QueryStrings -{ - public const string countryCodeAbbreviation = "countryCode"; - public const string StartTime = "starttime"; - public const string EndTime = "endtime"; - public const string Latitude = "lat"; - public const string Longitude = "lon"; - public const string Username = "username"; -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/ElectricityMapsFreeDataSource.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/ElectricityMapsFreeDataSource.cs deleted file mode 100644 index d4268e352..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/ElectricityMapsFreeDataSource.cs +++ /dev/null @@ -1,115 +0,0 @@ -using CarbonAware.DataSources.ElectricityMapsFree.Client; -using CarbonAware.DataSources.ElectricityMapsFree.Model; -using CarbonAware.Interfaces; -using CarbonAware.Model; -using Microsoft.Extensions.Logging; -using System.Diagnostics; - -namespace CarbonAware.DataSources.ElectricityMapsFree; -/// -/// Represents an Electricity Maps Free data source. -/// -internal class ElectricityMapsFreeDataSource : IEmissionsDataSource -{ - public string _name => "ElectricityMapsFreeDataSource"; - - public string _description => throw new NotImplementedException(); - - public string _author => throw new NotImplementedException(); - - public string _version => throw new NotImplementedException(); - - private ILogger _logger { get; } - - private IElectricityMapsFreeClient _electricityMapsFreeClient { get; } - - private static readonly ActivitySource Activity = new ActivitySource(nameof(ElectricityMapsFreeDataSource)); - - private ILocationSource _locationSource { get; } - - /// - /// Creates a new instance of the class. - /// - /// The logger for the datasource - /// The ElectricityMapsFree Client - /// The location source to be used to convert a location name to geocoordinates. - public ElectricityMapsFreeDataSource(ILogger logger, IElectricityMapsFreeClient client, ILocationSource locationSource) - { - this._logger = logger; - this._electricityMapsFreeClient = client; - this._locationSource = locationSource; - } - - - /// - public async Task> GetCarbonIntensityAsync(IEnumerable locations, DateTimeOffset periodStartTime, DateTimeOffset periodEndTime) - { - List EmissionsDataList = new List(); - - foreach (var location in locations) - { - var emissionsDataForLocation = await GetCarbonIntensityAsync(location, periodStartTime, periodEndTime); - EmissionsDataList.AddRange(emissionsDataForLocation); - } - - return EmissionsDataList; - } - - /// - public async Task> GetCarbonIntensityAsync(Location location, DateTimeOffset periodStartTime, DateTimeOffset periodEndTime) - { - this._logger.LogInformation($"Getting current carbon intensity emissions for location {location}"); - - Location? geolocation = null; - bool coordinatesAvailable; - try - { - geolocation = await this._locationSource.ToGeopositionLocationAsync(location); - - coordinatesAvailable = geolocation.Latitude != null && geolocation.Longitude != null; - } - catch (Exception) - { - coordinatesAvailable = false; - } - - GridEmissionDataPoint gridEmissionData; - if (coordinatesAvailable && geolocation != null) - { - string latitude = geolocation.LatitudeAsCultureInvariantString(); - string longitude = geolocation.LongitudeAsCultureInvariantString(); - gridEmissionData = await this._electricityMapsFreeClient.GetCurrentEmissionsAsync(latitude, longitude); - } - else - { - gridEmissionData = await this._electricityMapsFreeClient.GetCurrentEmissionsAsync(location.Name ?? ""); - } - - List EmissionsDataList = new List(); - var emissionDateTime = gridEmissionData.Data.Datetime; - - // periodStartTime should be less than current date time because this method should not handle forecast data. - var shouldReturn = periodStartTime <= DateTimeOffset.UtcNow; - if (shouldReturn && emissionDateTime != null && periodStartTime < periodEndTime) - { - // periodEndTime would be set periodStartTime in EmissionHandler if it is not specified. - // So we can assume we should return the most recent data if they equal. - // If not, we should return the data after checking it is within specified time range. - shouldReturn = periodStartTime <= emissionDateTime && emissionDateTime < periodEndTime; - } - - if (shouldReturn) - { - var emissionData = new EmissionsData() - { - Location = location.Name ?? "", - Time = emissionDateTime ?? new DateTimeOffset(), - Rating = gridEmissionData.Data.CarbonIntensity ?? 0.0, - Duration = new TimeSpan(0, 0, 0) - }; - EmissionsDataList.Add(emissionData); - } - - return EmissionsDataList; - } -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Model/GridEmissionDataPoint.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Model/GridEmissionDataPoint.cs deleted file mode 100644 index 9528c9335..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Model/GridEmissionDataPoint.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Text.Json.Serialization; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Model; - -/// -/// An object describing the emissions for a given countryCode -/// -[Serializable] -internal record GridEmissionDataPoint -{ - - [JsonPropertyName("_disclaimer")] - public string Disclaimer { get; set; } = string.Empty; - - [JsonPropertyName("status")] - public string Status { get; set; } = string.Empty; - - [JsonPropertyName("countryCode")] - public string CountryCodeAbbreviation { get; set; } = string.Empty; - - [JsonPropertyName("data")] - public Data Data { get; set; } = new Data(); - - [JsonPropertyName("units")] - public Units Units { get; set; } = new Units(); - -} - -internal record Data -{ - [JsonPropertyName("datetime")] - public DateTimeOffset? Datetime { get; set; } - - [JsonPropertyName("carbonIntensity")] - public float? CarbonIntensity { get; set; } - - [JsonPropertyName("fossilFuelPercentage")] - public float? FossilFuelPercentage { get; set; } -} - -internal record Units -{ - [JsonPropertyName("carbonIntensity")] - public string CarbonIntensity { get; set; } = string.Empty; -} diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Model/LoginResult.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Model/LoginResult.cs deleted file mode 100644 index 57da79521..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/src/Model/LoginResult.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Model; - -/// -/// Serializable object describing the electricityMap login response object. -/// -[Serializable] -internal record LoginResult -{ - /// - /// The Bearer Token used to authenticate future requests. - /// - [JsonPropertyName("Token")] - public string Token { get; set; } = string.Empty; -} \ No newline at end of file diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/CarbonAware.DataSources.ElectricityMapsFree.Tests.csproj b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/CarbonAware.DataSources.ElectricityMapsFree.Tests.csproj deleted file mode 100644 index 0375049af..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/CarbonAware.DataSources.ElectricityMapsFree.Tests.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - net8.0 - enable - - false - - - - - - - - - - - - - - - - - diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Client/ElectricityMapsFreeClientTests.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Client/ElectricityMapsFreeClientTests.cs deleted file mode 100644 index 43df28d2e..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Client/ElectricityMapsFreeClientTests.cs +++ /dev/null @@ -1,169 +0,0 @@ -using CarbonAware.DataSources.ElectricityMapsFree.Client; -using CarbonAware.DataSources.ElectricityMapsFree.Configuration; -using CarbonAware.DataSources.ElectricityMapsFree.Constants; -using CarbonAware.Exceptions; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Moq; -using Moq.Protected; -using Moq.Contrib.HttpClient; -using System.Net.Http; -using System.Threading.Tasks; -using System.Threading; -using System; -using System.Text.Json; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Tests; - -[TestFixture] -public class ElectricityMapsFreeClientTests -{ - private readonly string TestLatitude = "37.783"; - private readonly string TestLongitude = "-122.417"; - private readonly string TestCountryCode = "US-CAL-CISO"; - - private Mock Handler { get; set; } - - private IHttpClientFactory HttpClientFactory { get; set; } - - private ElectricityMapsFreeClientConfiguration Configuration { get; set; } - - private Mock> Options { get; set; } - - private Mock> Log { get; set; } - - public ElectricityMapsFreeClientTests() - { - this.Configuration = new ElectricityMapsFreeClientConfiguration() { }; - - this.Options = new Mock>(); - this.Log = new Mock>(); - - this.Options.Setup(o => o.CurrentValue).Returns(() => this.Configuration); - - this.Handler = new Mock(); - this.HttpClientFactory = Handler.CreateClientFactory(); - Mock.Get(this.HttpClientFactory).Setup(x => x.CreateClient(IElectricityMapsFreeClient.NamedClient)) - .Returns(() => - { - var client = Handler.CreateClient(); - return client; - }); - } - - [TestCase("ww.ca.u", "mytoken", TestName = "ClientInstantiation_FailsForInvalidConfig: url")] - [TestCase("https://example.com/", "", TestName = "ClientInstantiation_FailsForInvalidConfig: Token")] - public void ClientInstantiation_FailsForInvalidConfig(string baseUrl, string token) - { - // Arrange - this.Configuration = new ElectricityMapsFreeClientConfiguration() - { - Token = token, - BaseUrl = baseUrl, - }; - - // Act & Assert - Assert.Throws(() => new ElectricityMapsFreeClient(this.HttpClientFactory, this.Options.Object, this.Log.Object)); - } - - [Test] - public void AllPublicMethods_DoNotSwallowBadProxyExceptions() - { - // Arrange - var mockHttpClientFactory = Mock.Of(); - var mockHandler = new Mock(); - this.Configuration = GetValidConfiguration(); - - // A bad proxy will throw HttpRequestException when used so we mock that here. - mockHandler.Protected() - .Setup>( - "SendAsync", - ItExpr.IsAny(), - ItExpr.IsAny() - ) - .ThrowsAsync(new HttpRequestException()); - - Mock.Get(mockHttpClientFactory) - .Setup(h => h.CreateClient(It.IsAny())) - .Returns(new HttpClient(mockHandler.Object)); - - var client = new ElectricityMapsFreeClient(mockHttpClientFactory, this.Options.Object, this.Log.Object); - - // Act & Assert - Assert.ThrowsAsync(async () => await client.GetCurrentEmissionsAsync(TestCountryCode)); - Assert.ThrowsAsync(async () => await client.GetCurrentEmissionsAsync(TestLatitude, TestLongitude)); - } - - [Test] - public void GetCurrentEmissionsAsync_ThrowJsonException_WhenBadJsonIsReturned() - { - // Arrange - this.Configuration = GetValidConfiguration(); - AddHandler_RequestResponse(r => - { - return r.RequestUri!.ToString().Contains(Paths.Latest) && r.Method == HttpMethod.Get; - }, System.Net.HttpStatusCode.OK, "This is bad json"); - - var client = new ElectricityMapsFreeClient(this.HttpClientFactory, this.Options.Object, this.Log.Object); - - // Act & Assert - Assert.ThrowsAsync(async () => await client.GetCurrentEmissionsAsync(TestLatitude, TestLongitude)); - } - - [Test] - public async Task GetCurrentEmissionsAsync_DeserializesExpectedResponse() - { - // Arrange - this.Configuration = GetValidConfiguration(); - AddHandler_RequestResponse(r => - { - return r.RequestUri!.ToString().Contains(Paths.Latest) && r.Method == HttpMethod.Get; - }, System.Net.HttpStatusCode.OK, TestData.GetLatestCarbonIntensityDataJsonString()); - - var client = new ElectricityMapsFreeClient(this.HttpClientFactory, this.Options.Object, this.Log.Object); - - // Act - var latestData = await client.GetCurrentEmissionsAsync(TestLatitude, TestLongitude); - - // Assert - Assert.That(latestData, Is.Not.Null); - var dataPoint = latestData.Data; - Assert.That(latestData.CountryCodeAbbreviation, Is.EqualTo(TestCountryCode)); - Assert.Multiple(() => - { - Assert.That(dataPoint.Datetime, Is.EqualTo(new DateTimeOffset(2099, 1, 1, 0, 0, 0, TimeSpan.Zero))); - Assert.That(dataPoint.CarbonIntensity, Is.EqualTo(999)); - }); - } - - /** - * Helper to add client handler for request predicate and corresponding status code and response content - */ - private void AddHandler_RequestResponse(Predicate requestPredicate, System.Net.HttpStatusCode statusCode, string? responseContent = null) - { - if (responseContent != null) - { - this.Handler - .SetupRequest(requestPredicate) - .ReturnsResponse(statusCode, new StringContent(responseContent)); - } - else - { - this.Handler - .SetupRequest(requestPredicate) - .ReturnsResponse(statusCode); - } - } - - /** - * Provide valid values for token and baseurl - */ - static private ElectricityMapsFreeClientConfiguration GetValidConfiguration() - { - return new ElectricityMapsFreeClientConfiguration() - { - Token = "mytoken", - BaseUrl = "https://example.com/", - }; - } -} \ No newline at end of file diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Client/TestData.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Client/TestData.cs deleted file mode 100644 index 2199e8948..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Client/TestData.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Text.Json.Nodes; -using System; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Tests; - -public static class TestData -{ - private static readonly string disclaimer = "This data is the exclusive property of Electricity Maps and/or related parties. " - + "If you're in doubt about your rights to use this data, please contact api@co2signal.com"; - private static readonly string TestZoneId1 = "US-CAL-CISO"; - private static readonly string TestZoneName1 = "California Independent System Operator"; - - public static string GetZonesAllowedJsonString() - { - var json = new JsonObject - { - [TestZoneId1] = new JsonObject - { - ["zoneName"] = TestZoneName1, - ["access"] = new JsonArray - { - "carbon-intensity/history", - "carbon-intensity/forecast", - } - } - }; - - return json.ToString(); - } - - public static string GetNoPathsSupportedJsonString() - { - var json = new JsonObject - { - [TestZoneId1] = new JsonObject - { - ["zoneName"] = TestZoneName1, - ["access"] = new JsonArray - { - } - } - }; - - return json.ToString(); - } - - public static string GetNoZonesSupportedJsonString() - { - var json = new JsonObject - { - }; - - return json.ToString(); - } - - public static string GetLatestCarbonIntensityDataJsonString() - { - var json = new JsonObject - { - ["_disclaimer"] = disclaimer, - ["status"] = "ok", - ["countryCode"] = TestZoneId1, - ["data"] = new JsonObject - { - ["datetime"] = new DateTimeOffset(2099, 1, 1, 0, 0, 0, TimeSpan.Zero), - ["carbonIntensity"] = 999, - ["fossilFuelPercentage"] = 53.33 - }, - ["units"] = new JsonObject - { - ["carbonIntensity"] = "gCO2eq/kWh" - } - }; - - return json.ToString(); - } -} \ No newline at end of file diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Configuration/ElectricityMapsFreeClientConfigurationTests.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Configuration/ElectricityMapsFreeClientConfigurationTests.cs deleted file mode 100644 index 707b10982..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Configuration/ElectricityMapsFreeClientConfigurationTests.cs +++ /dev/null @@ -1,37 +0,0 @@ -using CarbonAware.DataSources.ElectricityMapsFree.Configuration; -using CarbonAware.Exceptions; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Tests; - -[TestFixture] -public class ElectricityMapsFreeClientConfigurationTests -{ - [TestCase("faketoken", "http://example.com", TestName = "Validate does not throw: token; url")] - public void Validate_DoesNotThrow(string? tokenValue, string? url) - { - // Arrange - var config = new ElectricityMapsFreeClientConfiguration(); - if (tokenValue != null) - config.Token = tokenValue; - if (url != null) - config.BaseUrl = url; - - // Act & Assert - Assert.DoesNotThrow(() => config.Validate()); - } - - [TestCase("faketoken", "not a url", TestName = "Validate throws: value; bad url")] - [TestCase(null, "http://example.com", TestName = "Validate throws: no value; url")] - public void Validate_Throws(string? tokenValue, string? url) - { - // Arrange - var config = new ElectricityMapsFreeClientConfiguration(); - if (tokenValue != null) - config.Token = tokenValue; - if (url != null) - config.BaseUrl = url; - - // Act & Assert - Assert.Throws(() => config.Validate()); - } -} \ No newline at end of file diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/ElectricityMapsFreeDataSourceTests.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/ElectricityMapsFreeDataSourceTests.cs deleted file mode 100644 index 21203ef35..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/ElectricityMapsFreeDataSourceTests.cs +++ /dev/null @@ -1,124 +0,0 @@ -using CarbonAware.DataSources.ElectricityMapsFree.Client; -using CarbonAware.DataSources.ElectricityMapsFree.Model; -using CarbonAware.Exceptions; -using CarbonAware.Interfaces; -using CarbonAware.Model; -using Microsoft.Extensions.Logging; -using System.Threading.Tasks; -using Moq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Globalization; - -namespace CarbonAware.DataSources.ElectricityMapsFree.Tests; - -[TestFixture] -public class ElectricityMapsFreeDataSourceTests -{ - private Mock> _logger { get; set; } - - private Mock _ElectricityMapsFreeClient { get; set; } - - private Mock _locationSource { get; set; } - private ElectricityMapsFreeDataSource _dataSource { get; set; } - - private static Location _defaultLocation = new Location() { Name = "eastus", Latitude = 34.123m, Longitude = 123.456m }; - - private static string _defaultLatitude => Convert.ToString(_defaultLocation.Latitude, CultureInfo.InvariantCulture) ?? ""; - private static string _defaultLongitude => Convert.ToString(_defaultLocation.Longitude, CultureInfo.InvariantCulture) ?? ""; - - public ElectricityMapsFreeDataSourceTests() - { - _logger = new Mock>(); - _ElectricityMapsFreeClient = new Mock(); - _locationSource = new Mock(); - _dataSource = new ElectricityMapsFreeDataSource(_logger.Object, _ElectricityMapsFreeClient.Object, _locationSource.Object); - } - - [TestCase(false, TestName = "GetCarbonIntensity_ReturnsResultsWhenRecordsFound without emission date time")] - [TestCase(true, TestName = "GetCarbonIntensity_ReturnsResultsWhenRecordsFound with emission date time")] - public async Task GetCarbonIntensity_ReturnsResultsWhenRecordsFound(bool withEmissionDateTime) - { - var startDate = DateTimeOffset.UtcNow.AddHours(-10); - var endDate = startDate.AddHours(1); - var expectedCarbonIntensity = 100; - - _locationSource.Setup(l => l.ToGeopositionLocationAsync(_defaultLocation)).Returns(Task.FromResult(_defaultLocation)); - - GridEmissionDataPoint emissionData = new() - { - Data = new Data() - { - Datetime = withEmissionDateTime ? startDate.AddMinutes(30) : null, - CarbonIntensity = expectedCarbonIntensity, - } - }; - - this._ElectricityMapsFreeClient.Setup(c => c.GetCurrentEmissionsAsync( - _defaultLatitude, - _defaultLongitude) - ).ReturnsAsync(emissionData); - - var result = await this._dataSource.GetCarbonIntensityAsync(new List() { _defaultLocation }, startDate, endDate); - - Assert.IsNotNull(result); - Assert.That(result.Count(), Is.EqualTo(1)); - - var first = result.First(); - Assert.IsNotNull(first); - Assert.That(first.Rating, Is.EqualTo(expectedCarbonIntensity)); - Assert.That(first.Location, Is.EqualTo(_defaultLocation.Name)); - - this._locationSource.Verify(l => l.ToGeopositionLocationAsync(_defaultLocation)); - } - - [TestCase(false, TestName = "GetCarbonIntensity_UseRegionNameWhenCoordinatesNotAvailable without emission date time")] - [TestCase(true, TestName = "GetCarbonIntensity_UseRegionNameWhenCoordinatesNotAvailable with emission date time")] - public async Task GetCarbonIntensity_UseRegionNameWhenCoordinatesNotAvailable(bool withEmissionDateTime) - { - var startDate = new DateTimeOffset(2022, 4, 18, 12, 32, 42, TimeSpan.FromHours(-6)); - var endDate = startDate.AddMinutes(1); - var expectedCarbonIntensity = 100; - - this._locationSource.Setup(l => l.ToGeopositionLocationAsync(_defaultLocation)).Throws(); - - GridEmissionDataPoint emissionData = new() - { - Data = new Data() - { - Datetime = withEmissionDateTime ? startDate.AddSeconds(30) : null, - CarbonIntensity = expectedCarbonIntensity, - } - }; - - this._ElectricityMapsFreeClient.Setup(c => c.GetCurrentEmissionsAsync(_defaultLocation.Name ?? "")).ReturnsAsync(emissionData); - - var result = await this._dataSource.GetCarbonIntensityAsync(new List() { _defaultLocation }, startDate, endDate); - - Assert.IsNotNull(result); - Assert.That(result.Count(), Is.EqualTo(1)); - - var first = result.First(); - Assert.IsNotNull(first); - Assert.That(first.Rating, Is.EqualTo(expectedCarbonIntensity)); - Assert.That(first.Location, Is.EqualTo(_defaultLocation.Name)); - - this._locationSource.Verify(l => l.ToGeopositionLocationAsync(_defaultLocation)); - this._ElectricityMapsFreeClient.Verify(l => l.GetCurrentEmissionsAsync(_defaultLocation.Name ?? "")); - } - - [Test] - public void GetCarbonIntensity_ThrowsWhenClientDoesNotKnowRegionName() - { - var startDate = new DateTimeOffset(2022, 4, 18, 12, 32, 42, TimeSpan.FromHours(-6)); - var endDate = startDate.AddMinutes(1); - - Location nonExistingLocation = new Location() { Name = "WrongLocationName", Latitude = 34.123m, Longitude = 123.456m }; - this._locationSource.Setup(l => l.ToGeopositionLocationAsync(nonExistingLocation)).Throws(); - - this._ElectricityMapsFreeClient.Setup(c => c.GetCurrentEmissionsAsync(nonExistingLocation.Name)).Throws(new ElectricityMapsFreeClientHttpException("Error", new System.Net.Http.HttpResponseMessage())); - - Assert.ThrowsAsync(async () => await this._dataSource.GetCarbonIntensityAsync(new List() { nonExistingLocation }, startDate, endDate)); - } -} \ No newline at end of file diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Usings.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Usings.cs deleted file mode 100644 index cefced496..000000000 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.ElectricityMapsFree/test/Usings.cs +++ /dev/null @@ -1 +0,0 @@ -global using NUnit.Framework; \ No newline at end of file diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.Registration/CarbonAware.DataSources.Registration.csproj b/src/CarbonAware.DataSources/CarbonAware.DataSources.Registration/CarbonAware.DataSources.Registration.csproj index 40ecc3ffe..87822d170 100644 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.Registration/CarbonAware.DataSources.Registration.csproj +++ b/src/CarbonAware.DataSources/CarbonAware.DataSources.Registration/CarbonAware.DataSources.Registration.csproj @@ -9,8 +9,6 @@ - (); @@ -67,10 +61,6 @@ public static IServiceCollection AddDataSourceService(this IServiceCollection se services.AddElectricityMapsForecastDataSource(dataSources); break; } - case DataSourceType.ElectricityMapsFree: - { - throw new ArgumentException("ElectricityMapsFree data source is not supported for forecast data"); - } case DataSourceType.None: { services.TryAddSingleton(); @@ -82,7 +72,7 @@ public static IServiceCollection AddDataSourceService(this IServiceCollection se { throw new ConfigurationException("No data sources are configured"); } - + return services; } diff --git a/src/CarbonAware.WebApi/test/integrationTests/CarbonAwareControllerTests.cs b/src/CarbonAware.WebApi/test/integrationTests/CarbonAwareControllerTests.cs index fc19dde48..41879e990 100644 --- a/src/CarbonAware.WebApi/test/integrationTests/CarbonAwareControllerTests.cs +++ b/src/CarbonAware.WebApi/test/integrationTests/CarbonAwareControllerTests.cs @@ -9,13 +9,12 @@ namespace CarbonAware.WepApi.IntegrationTests; /// -/// Tests that the Web API controller handles and packages various responses from a plugin properly +/// Tests that the Web API controller handles and packages various responses from a plugin properly /// including empty responses and exceptions. /// [TestFixture(DataSourceType.JSON)] [TestFixture(DataSourceType.WattTime)] [TestFixture(DataSourceType.ElectricityMaps)] -[TestFixture(DataSourceType.ElectricityMapsFree)] class CarbonAwareControllerTests : IntegrationTestingBase { private readonly string healthURI = "/health"; @@ -181,7 +180,6 @@ public async Task BestLocations_EmptyLocationQueryString_ReturnsBadRequest(strin [Test] public async Task EmissionsForecastsCurrent_SupportedDataSources_ReturnsOk() { - IgnoreTestForDataSource($"data source does not implement '{currentForecastURI}'", DataSourceType.JSON, DataSourceType.ElectricityMapsFree); _dataSourceMocker?.SetupForecastMock(); @@ -275,7 +273,7 @@ public async Task EmissionsForecastsBatch_MissingRequiredParams_ReturnsBadReques [TestCase("2021-09-01T08:30:00Z", "2021-09-01T08:30:00Z", "2021-09-02T08:30:00Z", "westus", 3, TestName = "EmissionsForecastsBatch expects OK for multiple elements")] public async Task EmissionsForecastsBatch_SupportedDataSources_ReturnsOk(string reqAt, string start, string end, string location, int nelems) { - IgnoreTestForDataSource($"data source does not implement '{batchForecastURI}'", DataSourceType.JSON, DataSourceType.ElectricityMaps, DataSourceType.ElectricityMapsFree); + IgnoreTestForDataSource($"data source does not implement '{batchForecastURI}'", DataSourceType.JSON, DataSourceType.ElectricityMaps); var expectedRequestedAt = DateTimeOffset.Parse(reqAt); var expectedDataStartAt = DateTimeOffset.Parse(start); @@ -315,7 +313,6 @@ public async Task EmissionsForecastsBatch_SupportedDataSources_ReturnsOk(string [TestCase("2021-12-25T00:00:00+06:00", "2021-12-26T00:00:00+06:00", "westus", nameof(EmissionsMarginalCarbonIntensity_ReturnsOk) + "1", TestName = "EmissionsMarginalCarbonIntensity expects OK date only, no time")] public async Task EmissionsMarginalCarbonIntensity_ReturnsOk(string start, string end, string location, string expectedResultName) { - IgnoreTestForDataSource($"data source does not implement '{averageCarbonIntensityURI}'", DataSourceType.ElectricityMapsFree); var startDate = DateTimeOffset.Parse(start); var endDate = DateTimeOffset.Parse(end); @@ -381,8 +378,6 @@ public async Task EmissionsMarginalCarbonIntensityBatch_MissingRequiredParams_Re [TestCase("2021-12-25T00:00:00+06:00", "2021-12-26T00:00:00+06:00", "westus", 3, nameof(EmissionsMarginalCarbonIntensityBatch_SupportedDataSources_ReturnsOk) + "1", TestName = "EmissionsMarginalCarbonIntensityBatch expects OK for multiple element batch")] public async Task EmissionsMarginalCarbonIntensityBatch_SupportedDataSources_ReturnsOk(string start, string end, string location, int nelems, string expectedResultName) { - IgnoreTestForDataSource($"data source does not implement '{batchAverageCarbonIntensityURI}'", DataSourceType.ElectricityMapsFree); - var startDate = DateTimeOffset.Parse(start); var endDate = DateTimeOffset.Parse(end); _dataSourceMocker?.SetupDataMock(startDate, endDate, location); diff --git a/src/CarbonAware.WebApi/test/integrationTests/LocationsControllerTests.cs b/src/CarbonAware.WebApi/test/integrationTests/LocationsControllerTests.cs index 1a1fd79c1..db289f4cb 100644 --- a/src/CarbonAware.WebApi/test/integrationTests/LocationsControllerTests.cs +++ b/src/CarbonAware.WebApi/test/integrationTests/LocationsControllerTests.cs @@ -7,12 +7,11 @@ namespace CarbonAware.WepApi.IntegrationTests; /// -/// Tests that the Web API controller handles locations instances +/// Tests that the Web API controller handles locations instances /// [TestFixture(DataSourceType.JSON)] [TestFixture(DataSourceType.WattTime)] [TestFixture(DataSourceType.ElectricityMaps)] -[TestFixture(DataSourceType.ElectricityMapsFree)] class LocationsControllerTests : IntegrationTestingBase { private readonly string locationsURI = "/locations"; diff --git a/src/CarbonAware/src/CarbonAware.csproj b/src/CarbonAware/src/CarbonAware.csproj index d04ce3a78..72bfe5ee3 100644 --- a/src/CarbonAware/src/CarbonAware.csproj +++ b/src/CarbonAware/src/CarbonAware.csproj @@ -28,9 +28,6 @@ - - - diff --git a/src/CarbonAwareSDK.sln b/src/CarbonAwareSDK.sln index 82672374a..3dce0b261 100644 --- a/src/CarbonAwareSDK.sln +++ b/src/CarbonAwareSDK.sln @@ -51,12 +51,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarbonAware.DataSources.Ele EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarbonAware.DataSources.ElectricityMaps.Mocks", "CarbonAware.DataSources\CarbonAware.DataSources.ElectricityMaps\mock\CarbonAware.DataSources.ElectricityMaps.Mocks.csproj", "{40155CED-4F39-485D-9AF8-4D267E236146}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarbonAware.DataSources.ElectricityMapsFree", "CarbonAware.DataSources\CarbonAware.DataSources.ElectricityMapsFree\src\CarbonAware.DataSources.ElectricityMapsFree.csproj", "{F08A1A30-EE88-4A32-9586-DC4E6410B9E2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CarbonAware.DataSources.ElectricityMapsFree.Tests", "CarbonAware.DataSources\CarbonAware.DataSources.ElectricityMapsFree\test\CarbonAware.DataSources.ElectricityMapsFree.Tests.csproj", "{52100C22-4F79-4498-B413-B93C68A599C2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CarbonAware.DataSources.ElectricityMapsFree.Mocks", "CarbonAware.DataSources\CarbonAware.DataSources.ElectricityMapsFree\mock\CarbonAware.DataSources.ElectricityMapsFree.Mocks.csproj", "{A7B0EF32-5AF3-4E56-AE88-627CC99BE635}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU From e3ba7d16027e4557928928eb31a50a03780ea605 Mon Sep 17 00:00:00 2001 From: Robin TROESCH <38283096+unitrium@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:40:34 +0100 Subject: [PATCH 2/6] remove free trial mention --- .../selecting-a-data-source.md | 37 +------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/casdk-docs/docs/tutorial-extras/selecting-a-data-source.md b/casdk-docs/docs/tutorial-extras/selecting-a-data-source.md index 6b8394dd4..8316045a4 100644 --- a/casdk-docs/docs/tutorial-extras/selecting-a-data-source.md +++ b/casdk-docs/docs/tutorial-extras/selecting-a-data-source.md @@ -27,7 +27,7 @@ configuration fields that must be set in order to access the raw data. | Is Forecast DataSource | ✅ | ✅ | ❌ | | Makes HTTP(s) call | ✅ | ✅ | ❌ | | Can Use Custom Data | ❌ | ❌ | ✅ | -| Supports Trial + Full Account | ✅ | ✅ (\*[see restriction below](#restrictions-electricitymaps-free-trial-user)) | N/A | +| Supports Trial + Full Account | ✅ | ✅ | N/A | ## Data Source Methods Available @@ -56,38 +56,3 @@ location config. [zone list](https://api.electricitymap.org/v3/zones) endpoint to find the relevant zones. -## Restrictions: free trial of ElectricityMaps - -ElectricityMaps allows new users to create a free trial for 1 month access to -the API. Free trial users have restricted access to the API and a slightly -different configuration for the SDK (see -[configuration.md](../tutorial-extras/configuration.md#electricitymaps-configuration). You can -request a free trial on the -[ElectricityMaps API Portal](https://api-portal.electricitymaps.com/). - -### Restricted Zone Access - -Free trial users only have access ~100 zones in the ElectricityMaps API. -ElectricityMaps maintains a -[frequently updated list](https://docs.google.com/document/d/e/2PACX-1vTdYp8E5E3fNogL54ICf_UxfA_rZ_RPO4WKWI4ZANPSX25jCbvHtAxc-VrJt9HymeRHFcSGWXjhVHS0/pub) -of available free trial zones that include the key, name, and country of each -zone. If you need access to other zones not included on the list, you will need -a full access product key. - -### Restricted Endpoint Access - -Free trial users only have access to seven endpoints in the ElectricityMaps API. -Of those seven, only two are currently supported as part of Carbon Aware SDK: - -1. `GET /carbon-intensity/forecast` -2. `GET /carbon-intensity/history` - -> Note: The Carbon Aware SDK is not restricting implementations to only support -> free trial users of ElectricityMaps. There may be implementations in the -> future that use endpoints that a free trial user may not be able to access and -> therefore cannot use that functionality of the SDK. - -### Restricted Call Access - -Free trial users are capped at 1,000 calls for the month of the free trial. Any -calls beyond the 1,000th call will be rejected. From ced86c745aea14a8cb92452751050b42eb97f624 Mon Sep 17 00:00:00 2001 From: Robin TROESCH <38283096+unitrium@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:49:24 +0100 Subject: [PATCH 3/6] DCO Remediation Commit for Robin TROESCH <38283096+unitrium@users.noreply.github.com> I, Robin TROESCH <38283096+unitrium@users.noreply.github.com>, hereby add my Signed-off-by to this commit: b0863960b87772113eeb396b61c1ce344608a790 I, Robin TROESCH <38283096+unitrium@users.noreply.github.com>, hereby add my Signed-off-by to this commit: e3ba7d16027e4557928928eb31a50a03780ea605 Signed-off-by: Robin TROESCH <38283096+unitrium@users.noreply.github.com> From ea4101297c43604da200cf3211ce9b6cbec82925 Mon Sep 17 00:00:00 2001 From: Robin TROESCH <38283096+unitrium@users.noreply.github.com> Date: Tue, 18 Mar 2025 10:42:21 +0100 Subject: [PATCH 4/6] fix(carbon-aware-web-api): fix integration test with json src --- .../test/integrationTests/CarbonAwareControllerTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CarbonAware.WebApi/test/integrationTests/CarbonAwareControllerTests.cs b/src/CarbonAware.WebApi/test/integrationTests/CarbonAwareControllerTests.cs index 41879e990..fb1c149f9 100644 --- a/src/CarbonAware.WebApi/test/integrationTests/CarbonAwareControllerTests.cs +++ b/src/CarbonAware.WebApi/test/integrationTests/CarbonAwareControllerTests.cs @@ -180,6 +180,7 @@ public async Task BestLocations_EmptyLocationQueryString_ReturnsBadRequest(strin [Test] public async Task EmissionsForecastsCurrent_SupportedDataSources_ReturnsOk() { + IgnoreTestForDataSource($"data source does not implement '{currentForecastURI}'", DataSourceType.JSON); _dataSourceMocker?.SetupForecastMock(); From 1c3a86a47e16dd47bae85cd02368d82138add284 Mon Sep 17 00:00:00 2001 From: Robin TROESCH <38283096+unitrium@users.noreply.github.com> Date: Tue, 18 Mar 2025 10:48:02 +0100 Subject: [PATCH 5/6] DCO Remediation Commit for Robin TROESCH <38283096+unitrium@users.noreply.github.com> I, Robin TROESCH <38283096+unitrium@users.noreply.github.com>, hereby add my Signed-off-by to this commit: ea4101297c43604da200cf3211ce9b6cbec82925 Signed-off-by: Robin TROESCH <38283096+unitrium@users.noreply.github.com> From 726e86afa494d9a5b56119cd231d2667717917a9 Mon Sep 17 00:00:00 2001 From: lav-julien <112700080+lav-julien@users.noreply.github.com> Date: Mon, 14 Apr 2025 11:01:39 +0200 Subject: [PATCH 6/6] add API TokenHeader and APIToken config --- samples/casdk-demo/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/casdk-demo/README.md b/samples/casdk-demo/README.md index 87d41ba96..4b221de69 100644 --- a/samples/casdk-demo/README.md +++ b/samples/casdk-demo/README.md @@ -59,7 +59,8 @@ Run demonstration with ElectricityMaps datasource export CASDK_DataSources__EmissionsDataSource=ElectricityMaps export CASDK_DataSources__ForecastDataSource=ElectricityMaps export CASDK_DataSources__Configurations__ElectricityMaps__Type=ElectricityMaps -export CASDK_DataSources__Configurations__ElectricityMaps__token=YOUR_SECRET_TOKEN +export CASDK_DataSources__Configurations__ElectricityMaps__APITokenHeader = "auth-token" +export CASDK_DataSources__Configurations__ElectricityMaps__APIToken=YOUR_SECRET_TOKEN ./demo.sh start ```