Skip to content
Snippets Groups Projects
Commit f86e9743 authored by Yoan VALLET's avatar Yoan VALLET
Browse files

add consumption load curve data

parent 2b8cec72
No related branches found
No related tags found
No related merge requests found
...@@ -13,40 +13,99 @@ moment.locale('fr') // set the language ...@@ -13,40 +13,99 @@ moment.locale('fr') // set the language
moment.tz.setDefault('Europe/Paris') // set the timezone moment.tz.setDefault('Europe/Paris') // set the timezone
/*** Connector Constants ***/ /*** Connector Constants ***/
const startDate = moment() const startDailyDate = moment()
.subtract(32, 'month') .subtract(32, 'month')
.format('YYYY-MM-DD') .format('YYYY-MM-DD')
const endDate = moment().format('YYYY-MM-DD') const startLoadDate = moment()
.subtract(8, 'day')
.format('YYYY-MM-DD')
const endDate = moment()
.subtract(1, 'day')
.format('YYYY-MM-DD')
const baseUrl = 'https://gw.hml.api.enedis.fr' const baseUrl = 'https://gw.hml.api.enedis.fr'
// The start function is run by the BaseKonnector instance only when it got all the account /**
// information (fields). When you run this connector yourself in "standalone" mode or "dev" mode, * The start function is run by the BaseKonnector instance only when it got all the account
// the account information come from ./konnector-dev-config.json file * information (fields). When you run this connector yourself in "standalone" mode or "dev" mode,
// cozyParameters are static parameters, independents from the account. Most often, it can be a * the account information come from ./konnector-dev-config.json file
// secret api key. * cozyParameters are static parameters, independents from the account. Most often, it can be a
* secret api key.
*/
async function start(fields) { async function start(fields) {
try { try {
const { access_token } = fields const { access_token } = fields
const usage_point_id = 22516914714270 const { info } = fields
log('info', 'Fetching enedis data') const usage_point_id = info.usage_point_id
const fetchedData = await getDailyData(access_token, usage_point_id)
log('info', 'Process data') log('info', 'Fetching enedis daily data')
await processData(fetchedData) const fetchedDailyData = await getDailyData(access_token, usage_point_id)
log('info', 'Saving data to Cozy') log('info', 'Process enedis daily data')
const processedDailyData = await processData(
fetchedDailyData,
'io.enedis.day',
['year', 'month', 'day']
)
log('info', 'Agregate enedis daily data for month and year')
await agregateMonthAndYearData(processedDailyData)
log('info', 'Fetching enedis load data')
const fetchedLoadData = await getLoadData(access_token, usage_point_id)
if (fetchedLoadData && fetchedLoadData.length > 0) {
log('info', 'Process enedis load data')
const processedLoadData = await processData(
fetchedLoadData,
'io.enedis.minute',
['year', 'month', 'day', 'hour', 'minute']
)
log('info', 'Agregate enedis load data for hour')
await agregateHourlyData(processedLoadData)
} else {
log('info', 'No consent or data for load curve')
}
} catch (err) { } catch (err) {
log('error', err.message) log('error', err.message)
} }
} }
// Retrieve data from the API /**
// Format: { value: "Wh", "date": "YYYY-MM-DD" } * Retrieve data from the API
* Format: { value: "Wh", "date": "YYYY-MM-DD" }
*/
async function getDailyData(token, usagePointID) { async function getDailyData(token, usagePointID) {
const dataRequest = { const dataRequest = {
method: 'GET', method: 'GET',
uri: uri:
baseUrl + baseUrl +
'/v4/metering_data/daily_consumption?start=' + '/v4/metering_data/daily_consumption?start=' +
startDate + startDailyDate +
'&end=' +
endDate +
'&usage_point_id=' +
usagePointID,
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + token
}
}
try {
const response = await rp(dataRequest)
return response
} catch (error) {
throw error
}
}
/**
* Retrieve data from the API
* Format: { value: "W", "date": "YYYY-MM-DD hh:mm:ss" }
*/
async function getLoadData(token, usagePointID) {
const dataRequest = {
method: 'GET',
uri:
baseUrl +
'/v4/metering_data/consumption_load_curve?start=' +
startLoadDate +
'&end=' + '&end=' +
endDate + endDate +
'&usage_point_id=' + '&usage_point_id=' +
...@@ -64,34 +123,87 @@ async function getDailyData(token, usagePointID) { ...@@ -64,34 +123,87 @@ async function getDailyData(token, usagePointID) {
} }
} }
async function processData(data) { /**
* Parse data
* Remove existing data from DB using hydrateAndFilter
* Store filtered data
* Return the list of filtered data
*/
async function processData(data, doctype, filterKeys) {
const parsedData = JSON.parse(data) const parsedData = JSON.parse(data)
const intervalData = parsedData.meter_reading.interval_reading const intervalData = parsedData.meter_reading.interval_reading
const formatedData = await formateData(intervalData) const formatedData = await formateData(intervalData)
// Remove data for existing days into the DB // Remove data for existing days into the DB
const filteredData = await hydrateAndFilter(formatedData, 'io.enedis.day', { const filteredData = await hydrateAndFilter(formatedData, doctype, {
keys: ['year', 'month', 'day'] keys: filterKeys
}) })
// Store new day data // Store new day data
await storeData(filteredData, 'io.enedis.day', ['year', 'month', 'day']) await storeData(filteredData, doctype, filterKeys)
return filteredData
}
/**
* Agregate data from daily data to monthly and yearly data
*/
async function agregateMonthAndYearData(data) {
// Sum year and month values into object with year or year-month as keys // Sum year and month values into object with year or year-month as keys
if (filteredData && filteredData.length > 0) { if (data && data.length > 0) {
let yearData = {}
let monthData = {} let monthData = {}
filteredData.forEach(element => { let yearData = {}
element.year in yearData data.forEach(element => {
? (yearData[element.year] += element.load)
: (yearData[element.year] = element.load)
element.year + '-' + element.month in monthData element.year + '-' + element.month in monthData
? (monthData[element.year + '-' + element.month] += element.load) ? (monthData[element.year + '-' + element.month] += element.load)
: (monthData[element.year + '-' + element.month] = element.load) : (monthData[element.year + '-' + element.month] = element.load)
element.year in yearData
? (yearData[element.year] += element.load)
: (yearData[element.year] = element.load)
}) })
// Agregation for Month data
const agregatedYearData = await agregateData('io.enedis.year', yearData) const agregatedMonthData = await buildAgregatedData(
monthData,
'io.enedis.month'
)
await storeData(agregatedMonthData, 'io.enedis.month', ['year', 'month'])
// Agregation for Year data
const agregatedYearData = await buildAgregatedData(
yearData,
'io.enedis.year'
)
await storeData(agregatedYearData, 'io.enedis.year', ['year']) await storeData(agregatedYearData, 'io.enedis.year', ['year'])
}
}
const agregatedMonthData = await agregateData('io.enedis.month', monthData) /**
await storeData(agregatedMonthData, 'io.enedis.month', ['year', 'month']) * Agregate data from load data (every 30 min) to Hourly data
*/
async function agregateHourlyData(data) {
// Sum year and month values into object with year or year-month as keys
if (data && data.length > 0) {
let hourData = {}
data.forEach(element => {
let key =
element.year +
'-' +
element.month +
'-' +
element.day +
'-' +
element.hour
key in hourData
? (hourData[key] += element.load)
: (hourData[key] = element.load)
})
// Agregation for Month data
const agregatedMonthData = await buildAgregatedData(
hourData,
'io.enedis.hour'
)
await storeData(agregatedMonthData, 'io.enedis.hour', [
'year',
'month',
'day',
'hour'
])
} }
} }
...@@ -112,9 +224,8 @@ async function storeData(data, doctype, filterKeys) { ...@@ -112,9 +224,8 @@ async function storeData(data, doctype, filterKeys) {
*/ */
async function formateData(data) { async function formateData(data) {
log('info', 'Formating data') log('info', 'Formating data')
log('debug', start, 'Start date')
return data.map(record => { return data.map(record => {
const date = moment(record.date, 'YYYY/MM/DD') const date = moment(record.date, 'YYYY/MM/DD h:mm:ss')
if (record.value != -2) { if (record.value != -2) {
return { return {
load: parseFloat(record.value / 1000), load: parseFloat(record.value / 1000),
...@@ -132,11 +243,11 @@ async function formateData(data) { ...@@ -132,11 +243,11 @@ async function formateData(data) {
* Retrieve and remove old data for a specific doctype * Retrieve and remove old data for a specific doctype
* Return an Array of agregated data * Return an Array of agregated data
*/ */
async function agregateData(doctype, data) { async function buildAgregatedData(data, doctype) {
let agregatedData = [] let agregatedData = []
for (let [key, value] of Object.entries(data)) { for (let [key, value] of Object.entries(data)) {
const data = await buildDataFromKey(doctype, key, value) const data = await buildDataFromKey(doctype, key, value)
const oldValue = await resetInProgressAggregatedData(doctype, data) const oldValue = await resetInProgressAggregatedData(data, doctype)
data.load += oldValue data.load += oldValue
agregatedData.push(data) agregatedData.push(data)
} }
...@@ -150,21 +261,31 @@ async function agregateData(doctype, data) { ...@@ -150,21 +261,31 @@ async function agregateData(doctype, data) {
* For month doctype: key = "YYYY-MM" * For month doctype: key = "YYYY-MM"
*/ */
async function buildDataFromKey(doctype, key, value) { async function buildDataFromKey(doctype, key, value) {
let year, month let year, month, day, hour
if (doctype === 'io.enedis.year') { if (doctype === 'io.enedis.year') {
year = key year = key
month = 1 month = 1
day = 0
hour = 0
} else if (doctype === 'io.enedis.month') {
const split = key.split('-')
year = split[0]
month = split[1]
day = 0
hour = 0
} else { } else {
const split = key.split('-') const split = key.split('-')
year = split[0] year = split[0]
month = split[1] month = split[1]
day = split[2]
hour = split[3]
} }
return { return {
load: Math.round(value * 1000) / 1000, load: Math.round(value * 1000) / 1000,
year: parseInt(year), year: parseInt(year),
month: parseInt(month), month: parseInt(month),
day: 0, day: parseInt(day),
hour: 0, hour: parseInt(hour),
minute: 0 minute: 0
} }
} }
...@@ -176,7 +297,7 @@ async function buildDataFromKey(doctype, key, value) { ...@@ -176,7 +297,7 @@ async function buildDataFromKey(doctype, key, value) {
* { load: 76.712, year: 2020, ... } need to be replace by * { load: 76.712, year: 2020, ... } need to be replace by
* { load: 82.212, year: 2020, ... } after enedis data reprocess * { load: 82.212, year: 2020, ... } after enedis data reprocess
*/ */
async function resetInProgressAggregatedData(doctype, data) { async function resetInProgressAggregatedData(data, doctype) {
// /!\ Warning: cannot use mongo queries because not supported for dev by cozy-konnectors-libs // /!\ Warning: cannot use mongo queries because not supported for dev by cozy-konnectors-libs
log('debug', doctype, 'Remove aggregated data for') log('debug', doctype, 'Remove aggregated data for')
const result = await cozyClient.data.findAll(doctype) const result = await cozyClient.data.findAll(doctype)
...@@ -188,11 +309,21 @@ async function resetInProgressAggregatedData(doctype, data) { ...@@ -188,11 +309,21 @@ async function resetInProgressAggregatedData(doctype, data) {
filtered = result.filter(function(el) { filtered = result.filter(function(el) {
return el.year == data.year return el.year == data.year
}) })
} else { } else if (doctype === 'io.enedis.month') {
// Monthly case // Monthly case
filtered = result.filter(function(el) { filtered = result.filter(function(el) {
return el.year == data.year && el.month == data.month return el.year == data.year && el.month == data.month
}) })
} else {
// Hourly case
filtered = result.filter(function(el) {
return (
el.year == data.year &&
el.month == data.month &&
el.day == data.day &&
el.hour == data.hour
)
})
} }
// Remove data // Remove data
let sum = 0.0 let sum = 0.0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment