@rfdez/pvpc-mcp-server
Version:
Fetch the Voluntary Price for the Small Consumer (PVPC) published daily by Red Eléctrica at 8:15 p.m. This includes the hourly electricity tariffs that will apply the following day for consumers billed under the 2.0 TD tariff.
101 lines (100 loc) • 3.58 kB
JavaScript
import QueryString from "qs";
import { PvpcError } from "./error.js";
export class PvpcApiClient {
key;
static GEOS = {
8741: "Península",
8742: "Canarias",
8743: "Baleares",
8744: "Ceuta",
8745: "Melilla",
};
static PVPC_BASE_URL = "https://api.esios.ree.es/indicators/1001";
headers;
constructor(key) {
this.key = key;
if (!key) {
this.key = process.env.ESIOS_API_KEY;
if (!this.key) {
throw new Error(`Missing API key. See https://api.esios.ree.es/doc/index.html.
Pass it to the constructor \`new PvpcApiClient("123")\`
or set the environment variable \`ESIOS_API_KEY\` with your API key.
`);
}
}
this.headers = new Headers({
Accept: "application/json; application/vnd.esios-api-v1+json",
"Content-Type": "application/json",
"x-api-key": this.key,
});
}
async fetchRequest(path, options = {}) {
let response;
try {
response = await fetch(`${PvpcApiClient.PVPC_BASE_URL}${path}`, options);
}
catch (error) {
console.error("Error fetching data:", error instanceof Error ? error.message : error);
throw new PvpcError("Unable to fetch data. The request could not be resolved.", "NetworkError");
}
if (!response.ok) {
try {
const error = (await response.json());
throw PvpcError.fromResponse(error);
}
catch (err) {
if (err instanceof SyntaxError) {
throw new PvpcError("Internal server error. We are unable to process your request right now, please try again later.", "ApplicationError");
}
if (err instanceof Error) {
throw new PvpcError(err.message, "ApplicationError");
}
throw new PvpcError(response.statusText, "ApplicationError");
}
}
const data = (await response.json());
return data;
}
async get(path, options = {}) {
const requestOptions = {
method: "GET",
headers: this.headers,
...options,
};
return this.fetchRequest(path, requestOptions);
}
async fetchPrices(params) {
const queryParams = {
locale: params.locale,
start_date: params.startDate,
end_date: params.endDate,
time_agg: params.timeAggregation,
time_trunc: params.timeTruncation,
geo_agg: params.geographicalAggregation,
geo_ids: params.geographicalIds,
geo_trunc: params.geographicalTruncation,
};
const stringQueryParams = QueryString.stringify(queryParams, {
arrayFormat: "brackets",
encode: false,
skipNulls: true,
});
const response = await this.get(`?${stringQueryParams}`);
const currencyCode = "EUR";
const currencySymbol = "€";
const magnitude = "€/MWh";
return response.indicator.values.map((v) => ({
price: {
amount: v.value,
currencyCode,
currencySymbol,
},
magnitude,
datetime: v.datetime,
datetimeUtc: v.datetime_utc,
geographicalId: v.geo_id,
geographicalName: v.geo_name,
updatedAt: response.indicator.values_updated_at,
}));
}
}