Skip to content
Snippets Groups Projects
Commit 1ca126af authored by git-directory-deploy's avatar git-directory-deploy
Browse files

consent for load curve data and manual execution

parent d0050485
No related branches found
No related tags found
1 merge request!2Dev
{
"endOfLine": "auto",
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}
......@@ -4,7 +4,7 @@ const {
addData,
hydrateAndFilter,
errors,
cozyClient
cozyClient,
} = require('cozy-konnector-libs')
const getAccountId = require('./helpers/getAccountId')
......@@ -17,13 +17,18 @@ moment.locale('fr') // set the language
moment.tz.setDefault('Europe/Paris') // set the timezone
/*** Connector Constants ***/
const startDailyDate = moment().subtract(32, 'month')
const manualExecution = process.env.COZY_JOB_MANUAL_EXECUTION
const startDailyDate = manualExecution
? moment().subtract(12, 'month')
: moment().subtract(32, 'month')
const startDailyDateString = startDailyDate.format('YYYY-MM-DD')
const startLoadDate = moment().subtract(7, 'day')
const startLoadDateString = startLoadDate.format('YYYY-MM-DD')
const endDate = moment()
const endDateString = endDate.format('YYYY-MM-DD')
const baseUrl = 'https://gw.prd.api.enedis.fr'
const dailyDataURL = `${baseUrl}/v4/metering_data/daily_consumption`
const loadCurveURL = `${baseUrl}/v4/metering_data/consumption_load_curve`
/**
* The start function is run by the BaseKonnector instance only when it got all the account
......@@ -32,17 +37,18 @@ const baseUrl = 'https://gw.prd.api.enedis.fr'
* cozyParameters are static parameters, independents from the account. Most often, it can be a
* secret api key.
* @param {Object} fields
* @param {string} fields.access_token - a google access token
* @param {string} fields.refresh_token - a google refresh token
* @param {string} fields.access_token - access token
* @param {string} fields.refresh_token - refresh token
* @param {Object} cozyParameters - cozy parameters
* @param {boolean} doRetry - whether we should use the refresh token or not
*/
async function start(fields, cozyParameters, doRetry = true) {
log('info', 'Starting the enedis konnector')
log('info', `Manual execution: ${manualExecution}`)
const accountId = getAccountId()
let usage_point_id = ''
try {
const { access_token } = fields
let usage_point_id = ''
if (
this._account &&
this._account.oauth_callback_results &&
......@@ -52,6 +58,9 @@ async function start(fields, cozyParameters, doRetry = true) {
','
)
usage_point_id = usage_points_id[0]
} else if (fields.usage_point_id) {
// In case of refresh token, we retrieve the usage point id from the fields
usage_point_id = fields.usage_point_id
} else {
log('error', 'no usage_point_id found')
throw errors.USER_ACTION_NEEDED_OAUTH_OUTDATED
......@@ -67,7 +76,6 @@ async function start(fields, cozyParameters, doRetry = true) {
)
log('info', 'Agregate enedis daily data for month and year')
await agregateMonthAndYearData(processedDailyData)
log('info', 'Process enedis load data')
await startLoadDataProcess(access_token, usage_point_id)
} catch (err) {
......@@ -87,10 +95,10 @@ async function start(fields, cozyParameters, doRetry = true) {
log('info', `Error during refresh ${err.message}`)
throw errors.USER_ACTION_NEEDED_OAUTH_OUTDATED
}
log('info', 'refresh response')
log('info', JSON.stringify(body))
fields.access_token = body.attributes.oauth.access_token
fields.usage_point_id = usage_point_id
return start(fields, cozyParameters, false)
}
log('error', `Error during authentication: ${err.message}`)
......@@ -98,7 +106,7 @@ async function start(fields, cozyParameters, doRetry = true) {
} else {
log('error', 'caught an unexpected error')
log('error', err.message)
throw errors.VENDOR_DOWN
throw err
}
}
}
......@@ -111,8 +119,8 @@ async function getDailyData(token, usagePointID) {
const dataRequest = {
method: 'GET',
uri:
baseUrl +
'/v4/metering_data/daily_consumption?start=' +
dailyDataURL +
'?start=' +
startDailyDateString +
'&end=' +
endDateString +
......@@ -120,8 +128,8 @@ async function getDailyData(token, usagePointID) {
usagePointID,
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + token
}
Authorization: 'Bearer ' + token,
},
}
const response = await rp(dataRequest)
return response
......@@ -133,33 +141,88 @@ async function getDailyData(token, usagePointID) {
* If yes only call once the api
*/
async function startLoadDataProcess(token, usagePointID) {
log('info', 'Check history')
const isHistory = await isHistoryLoaded('com.grandlyon.enedis.minute')
if (isHistory) {
log('info', 'launch process without history')
await launchLoadDataProcess(
token,
usagePointID,
startLoadDateString,
endDateString
)
} else {
log('info', 'launch process with history')
for (var i = 0; i < 4; i++) {
const increamentedStartDate = moment(startLoadDate)
const incrementedEndDate = moment(endDate)
const increamentedStartDateString = increamentedStartDate
.subtract(7 * i, 'day')
.format('YYYY-MM-DD')
const incrementedEndDateString = incrementedEndDate
.subtract(7 * i, 'day')
.format('YYYY-MM-DD')
log('info', 'Check consent for user')
const isConsent = await checkConsentForLoadCurve(
token,
usagePointID,
startLoadDateString,
endDateString
)
if (isConsent) {
log('info', 'Check history')
const isHistory = await isHistoryLoaded('com.grandlyon.enedis.minute')
log('info', `isHistory: ${isHistory}`)
if (isHistory || manualExecution) {
log('info', 'launch process without history')
await launchLoadDataProcess(
token,
usagePointID,
increamentedStartDateString,
incrementedEndDateString
startLoadDateString,
endDateString
)
} else {
log('info', 'launch process with history')
for (var i = 0; i < 4; i++) {
const increamentedStartDate = moment(startLoadDate)
const incrementedEndDate = moment(endDate)
const increamentedStartDateString = increamentedStartDate
.subtract(7 * i, 'day')
.format('YYYY-MM-DD')
const incrementedEndDateString = incrementedEndDate
.subtract(7 * i, 'day')
.format('YYYY-MM-DD')
await launchLoadDataProcess(
token,
usagePointID,
increamentedStartDateString,
incrementedEndDateString
)
}
}
}
}
/**
* Request API and check return code
* Return true or false
*/
async function checkConsentForLoadCurve(
token,
usagePointID,
_startDate,
_endDate
) {
const dataRequest = {
method: 'GET',
uri:
loadCurveURL +
'?start=' +
_startDate +
'&end=' +
_endDate +
'&usage_point_id=' +
usagePointID,
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + token,
},
}
try {
await rp(dataRequest)
log('info', 'Consent found for load curve')
return true
} catch (err) {
if (
(err.statusCode === 400 || err.code === 400) &&
err.message.search('ADAM-ERR0075') > 0
) {
log('info', 'No consent for load curve')
return false
} else if (err.statusCode === 403 || err.code === 403) {
log('info', 'No consent for load curve')
return false
} else {
throw err
}
}
}
......@@ -202,8 +265,8 @@ async function getLoadData(token, usagePointID, _startDate, _endDate) {
const dataRequest = {
method: 'GET',
uri:
baseUrl +
'/v4/metering_data/consumption_load_curve?start=' +
loadCurveURL +
'?start=' +
_startDate +
'&end=' +
_endDate +
......@@ -211,22 +274,11 @@ async function getLoadData(token, usagePointID, _startDate, _endDate) {
usagePointID,
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + token
}
}
try {
const response = await rp(dataRequest)
return response
} catch (err) {
if (err.statusCode === 404 || err.code === 404) {
log('warning', 'caught an 404 error')
log('warning', err.message)
log('warning', err)
return null
} else {
throw err
}
Authorization: 'Bearer ' + token,
},
}
const response = await rp(dataRequest)
return response
}
/**
......@@ -241,7 +293,7 @@ async function processData(data, doctype, filterKeys) {
const formatedData = await formateData(intervalData, doctype)
// Remove data for existing days into the DB
const filteredData = await hydrateAndFilter(formatedData, doctype, {
keys: filterKeys
keys: filterKeys,
})
// Store new day data
await storeData(filteredData, doctype, filterKeys)
......@@ -271,7 +323,7 @@ async function agregateMonthAndYearData(data) {
)
await storeData(agregatedMonthData, 'com.grandlyon.enedis.month', [
'year',
'month'
'month',
])
// Agregation for Year data
const agregatedYearData = await buildAgregatedData(
......@@ -311,7 +363,7 @@ async function agregateHourlyData(data) {
'year',
'month',
'day',
'hour'
'hour',
])
}
}
......@@ -322,7 +374,7 @@ async function agregateHourlyData(data) {
async function storeData(data, doctype, filterKeys) {
log('debug', doctype, 'Store into')
const filteredDocuments = await hydrateAndFilter(data, doctype, {
keys: filterKeys
keys: filterKeys,
})
return await addData(filteredDocuments, doctype)
}
......@@ -349,7 +401,7 @@ async function formateData(data, doctype) {
month: parseInt(date.format('M')),
day: parseInt(date.format('D')),
hour: parseInt(date.format('H')),
minute: parseInt(date.format('m'))
minute: parseInt(date.format('m')),
}
}
})
......@@ -402,7 +454,7 @@ async function buildDataFromKey(doctype, key, value) {
month: parseInt(month),
day: parseInt(day),
hour: parseInt(hour),
minute: 0
minute: 0,
}
}
......
......@@ -12,9 +12,9 @@ const readManifest = () =>
const svgo = new SvgoInstance({
plugins: [
{
inlineStyles: { onlyMatchedOnce: false }
}
]
inlineStyles: { onlyMatchedOnce: false },
},
],
})
let iconName
......@@ -33,7 +33,7 @@ module.exports = {
mode: 'none',
output: {
path: path.join(__dirname, 'build'),
filename: 'index.js'
filename: 'index.js',
},
plugins: [
new CopyPlugin([
......@@ -42,19 +42,19 @@ module.exports = {
{ from: 'README.md' },
{ from: 'assets', transform: optimizeSVGIcon },
{ from: '.travis.yml' },
{ from: 'LICENSE' }
{ from: 'LICENSE' },
]),
new webpack.DefinePlugin({
__WEBPACK_PROVIDED_MANIFEST__: JSON.stringify(readManifest())
})
__WEBPACK_PROVIDED_MANIFEST__: JSON.stringify(readManifest()),
}),
],
module: {
// to ignore the warnings like :
// WARNING in ../libs/node_modules/bindings/bindings.js 76:22-40
// Critical dependency: the request of a dependency is an expression
// Since we cannot change this dependency. I think it won't hide more important messages
exprContextCritical: false
}
exprContextCritical: false,
},
}
function optimizeSVGIcon(buffer, path) {
......
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