-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
120 lines (94 loc) · 3.94 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const fs = require('fs');
require('dotenv').config()
const fetch = require('node-fetch');
const moment = require('moment-timezone');
const qs = require('qs');
const xml2js = require('xml2js');
const { flatten, groupBy, forIn, sortBy, uniqBy, uniq, range } = require('lodash');
const { ENTSOE_TOKEN } = process.env;
const FRANCE_DOMAIN = '10YFR-RTE------C';
const DATE_FORMAT = "YYYYMMDDHHmm"
const { chunkAndChainPromises, toCSV } = require('./helpers');
const historicYears = range(2005, 2019);
const DEFAULT_START_DATE = '2019-01-01';
moment.tz.setDefault('Europe/Paris');
async function fetchDayAheadAuctionData(startOfWeek) {
const params = {
securityToken: ENTSOE_TOKEN,
documentType: 'A44',
in_Domain: FRANCE_DOMAIN,
out_Domain: FRANCE_DOMAIN,
periodStart: moment(startOfWeek).tz('Europe/London').format(DATE_FORMAT),
periodEnd: moment(startOfWeek).tz('Europe/London').add(1, 'week').format(DATE_FORMAT),
}
console.log(moment(startOfWeek).toISOString());
const url = `https://transparency.entsoe.eu/api?${qs.stringify(params)}`;
const res = await fetch(url, {
headers: {
'Content-Type': 'application/json',
}
});
const xml = await res.text();
const data = await xml2js.parseStringPromise(xml);
const timeseries = data.Publication_MarketDocument.TimeSeries
const days = timeseries.map(t => t.Period[0].Point.map(p => p['price.amount'][0]));
const dataByHour = days.reduce((res, v, i) => {
return res.concat(v.map((price, j) => ({
startDate: moment(startOfWeek).add(i, 'days').add(j, 'hours').toISOString(),
endDate: moment(startOfWeek).add(i, 'days').add(j + 1, 'hours').toISOString(),
price_euros_mwh: price
})))
}, [])
return dataByHour;
}
function csvFormatter(data) {
const formattedData = data.map(item => {
return {
date: moment(item.startDate).tz('Europe/Paris').format('YYYY-MM-DD'),
start_hour: moment(item.startDate).tz('Europe/Paris').format('HH:mm'),
end_hour: moment(item.endDate).tz('Europe/Paris').format('HH:mm'),
price_euros_mwh: item.price_euros_mwh,
volume_mwh: item.volume_mwh,
}
});
return toCSV(formattedData, Object.keys(formattedData[0]));
}
async function main() {
const today = moment().startOf('day');
let startDate = moment(DEFAULT_START_DATE).startOf('day');
let years = [];
historicYears.map(year => {
const data = JSON.parse(fs.readFileSync(`./historicData/${year}.json`));
fs.writeFileSync(`./data/${year}.csv`, csvFormatter(data));
})
if (fs.existsSync('./data/years.json')) {
years = JSON.parse(fs.readFileSync('./data/years.json')).sort();
const lastYear = years[years.length - 1];
const currentYear = today.year();
const firstYear = lastYear === currentYear ? currentYear : lastYear + 1;
console.log('Cache found, first year :', firstYear);
startDate = moment().year(firstYear).startOf('year');
}
const weekCount = Math.ceil(today.diff(startDate, 'weeks', true));
const weeks = Array.from({ length: weekCount }).map((_, i) => {
return moment(startDate).add(i, 'week').format();
});
const weekData = await chunkAndChainPromises(weeks, date => fetchDayAheadAuctionData(date), 1);
const allData = uniqBy(flatten(weekData), 'startDate')
.filter(item => item.startDate < today.format());
const dataByYear = groupBy(allData, d => moment(d.startDate).year());
const finalYears = uniq(Object.keys(dataByYear).map(i => Number(i)).concat(years)).sort();
forIn(dataByYear, (values, year) => {
const sorted = sortBy(values, d => moment(d.startDate).unix());
console.log(`Write files for year ${year} (${sorted.length} items)`);
fs.writeFileSync(`./data/${year}.json`, JSON.stringify(sorted));
fs.writeFileSync(`./data/${year}.csv`, csvFormatter(sorted));
});
fs.writeFileSync('./data/years.json', JSON.stringify(finalYears));
}
// fetchDayAheadAuctionData(moment('2019-01-01'));
main()
.catch(error => {
console.error(error);
process.exit(1);
});