Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
enedis-konnector
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
web-et-numerique
Factory
LLLE_Project
enedis-konnector
Commits
f86e9743
Commit
f86e9743
authored
4 years ago
by
Yoan VALLET
Browse files
Options
Downloads
Patches
Plain Diff
add consumption load curve data
parent
2b8cec72
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/index.js
+170
-39
170 additions, 39 deletions
src/index.js
with
170 additions
and
39 deletions
src/index.js
+
170
−
39
View file @
f86e9743
...
@@ -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
startDa
ilyDa
te
=
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
a
gregateData
(
doctype
,
data
)
{
async
function
buildA
gregate
d
Data
(
d
ata
,
d
octype
)
{
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
(
d
ata
,
d
octype
)
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
(
d
ata
,
d
octype
)
{
// /!\ 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
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment