diff --git a/docs/documents/egl-api-doc.pdf b/docs/documents/egl-api-doc.pdf new file mode 100644 index 0000000000000000000000000000000000000000..71c2ba0601454ae3b75e7ff3b9a5fa1b56496a4e Binary files /dev/null and b/docs/documents/egl-api-doc.pdf differ diff --git a/docs/ecolyo/functionalities/challenge.md b/docs/ecolyo/functionalities/challenge.md index ddc2e65f6961327141fed52928aafcd3998d8097..76200b21f6d600297c056ee08ea0635501d81fa0 100644 --- a/docs/ecolyo/functionalities/challenge.md +++ b/docs/ecolyo/functionalities/challenge.md @@ -29,21 +29,110 @@ Then, he generate two randoms answers following the right answer. ## Duel -### On launch +### On launch In order to find a valid reference period we search for a period which is defined by the duel duration. We check the most recent period first if it's complete and then we go farther and farther in the time if the ones before got missing values. We also define a threshold for a maximum old period (6 months for the moment determined in the code ==> hardcoding). If the thresold is reached and no valid period was found, we alert the user that he can't launch the duel and have to wait before he can retry this process. -### On going +### On going - Every time the user go into the duel mode, we are checking if the duel is finished. - if (actualDate - startDate) > duelDuration, the duel is done. +Every time the user go into the duel mode, we are checking if the duel is finished. +if (actualDate - startDate) > duelDuration, the duel is done. -### On finish +### On finish - Once the state of the duel is set to DONE, we save the user result and determine if he wins (userComsumption < threshold of the reference period) or if he loses. Then the user sees his earned badge. +Once the state of the duel is set to DONE, we save the user result and determine if he wins (userComsumption < threshold of the reference period) or if he loses. Then the user sees his earned badge. +## Challenge data managment +We handle data storage according to the following process : +The folder /db contains all the JSON entities that are directly stored in the couchDB during the initialization process that is executed in the splash screen. They are stored under their related doctype. + +## Initialization and Updating + +During the initialization process, we store a hash for each dataEntity that is likely to be changed or updated. The hash is stored in the userProfile. + +```json +[ + { + "ecogestureHash": "", + "challengeHash": "", + "duelHash": "", + "isFirstConnection": true, + "haveSeenFavoriteModal": false, + "haveSeenOldFluidModal": false, + "haveSeenLastReport": true, + "sendReportNotification": false, + "monthlyReportDate": "0000-01-01T00:00:00.000Z" + } +] +``` + +This way, once the initialization is launched, we compare the hash we have in the current userProfile with the one generated from the entity located in /db folder, and if they are different we update the couchDB with the new data. + +### dataEntity vs userData + +In the project, you'll see two versions for the same data. The dataEntity (quizEntity, challengeEntity, ...) is the data stored in the db folder and in the couchDB. These data are only edited in the couchDB when we update a challenge/quiz/duel or add a new one. + +The userData (userChallenge, userQuiz...) is created from the entity and extended with user's data, such as his progress, his consumption data, goals, fails etc. + +Using this 2 structures allows us to keep user's datas when we'll update the application, by editing just the entities. + +## Challenges + +We can find the file challengeEntity.json in the /db folder. This file contains an array of challenges, and each of them includes relationships to duels, quiz, missions and actions. + +### Relationships + +Relationships is a functionality made by cozy, they are built with the name of the relation, containing a "data" object, itself containing the id of the related item and its doctype "\_type". Using this allows us to reduce the size of the stored items and increase readability. + +You can see more on [cozy documentation](https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.apps.suggestions/#relationships). + +```json +"relationships": { + "quiz": { + "data": { "_id": "QUIZ001", "_type": "com.grandlyon.ecolyo.quiz" } + }, + "duel": { + "data": { "_id": "DUEL001", "_type": "com.grandlyon.ecolyo.duel" } + } + } +``` + +### UserData creation + +Once a user launch a challenge in the Ecolyo app, we create a userChallenge and store it in the couchDB under the doctype '**com.grandlyon.ecolyo.userchallenge'.** During this process, the objects related to the challenge (quiz, duel, mission, action) will be be converted to an user version which contains informations about the user progress, the fluids connected and so on. So we have now a userChallenge that contains a userQuiz, a userDuel, etc. instead of relations. + +To illustrate this, let's show the conversion of quizEntity to userQuiz : + +```jsx +DuelEntity { + id: string + title: string + description: string + duration: Duration +} +``` + +Becomes : + +```jsx +UserQuiz { + id: string + title: string + description: string + duration: Duration + threshold: number + state: UserDuelState + startDate: string | null + fluidTypes: FluidType[] + userConsumption: number +} +``` + +### Data managment schema + + diff --git a/docs/ecolyo/konnectors/egl.md b/docs/ecolyo/konnectors/egl.md index 2f4f692dba5c6228a0130fccce621b4c7e2d7452..449222c70dbab7b1fcc1adbaca66ea81246357a1 100644 --- a/docs/ecolyo/konnectors/egl.md +++ b/docs/ecolyo/konnectors/egl.md @@ -1,2 +1,130 @@ !!! info "" - :construction: Section under Construction :construction: \ No newline at end of file +:construction: Section under Construction :construction: + +## EGL Konnector + +This konnector fetches consumptions measures from EGL API. +The EGL API allows us to get a user's consumption data gathered by it's connected water meter "Téléo". +You can clone the project [here](https://forge.grandlyon.com/web-et-numerique/llle_project/egl-konnector). + +You should also check Cozy's official documentations for konnectors : +[https://docs.cozy.io/en/tutorials/konnector/getting-started/](https://docs.cozy.io/en/tutorials/konnector/getting-started/) + +API Url for Development : [https://agence-rec.eaudugrandlyon.com](https://agence-rec.eaudugrandlyon.com/) + +API Url for Production : [https://agence.eaudugrandlyon.com/ws](https://agence.eaudugrandlyon.com/ws) + +## Authentication + +In order to authenticate to the EGL API we have to request the following route + +Method : **POST** + +Authentication Route : **/connect.asp** + +```json +"headers": +{ + { + "AuthKey": <your-auth-key>, + "Content-Type": "application/x-www-form-urlencoded" + } +} +``` + +```json +"body": +{ + "mode": "formdata" + { + "login": <your-login>, + "pass": <your-password> + } +} +``` + +Once you've sent this request the API should answer with a code 100 if everything is ok and provides you a valid **_token_** and **_num_abt_** that you will use later in order to get data. + +```json +{ + "codeRetour": 100, + "libelleRetour": "Connecté", + "resultatRetour": { + "num_abt": 1895683, + "token": "897555754A703055397897456568776E32704C3953514F5R" + } +} +``` + +## Fetch Data + +In order to get data from the EGL API we have to request the following route : + +Method : **POST** + +Authentication Route : **/getAllAgregatsByAbonnement.aspx** + +```json +"body": +{ + "mode": "formdata" + { + "login": <your-login>, + "pass": <your-password> + } +} +``` + +```json + +"body": +{ + "mode": "formdata" + { + "token": "897555754A703055397897456568776E32704C3953514F5R", + "num_abt": 1895683, + "date_debut": MM/JJ/YYYY, + "date_fin": MM/JJ/YYYY + } +} +``` + +The dates must be valid dates otherwise you'll get an error + +There answer will provides you an array of data day by day with the value got by the water meter 'ValeurIndex' at this moment. + +```json +{ + "codeRetour": 100, + "libelleRetour": "L'opération a réussi", + "resultatRetour": [ + { + "DateReleve": "2020-07-01T00:00:00+02:00", + "TypeAgregat": "R", + "ValeurIndex": 562362 + }, + { + "DateReleve": "2020-07-02T00:00:00+02:00", + "TypeAgregat": "R", + "ValeurIndex": 562432 + } + ] +} +``` + +You'll have to subtract a day value with the previous's to get a consumption for a given day. + +### TypeAgregats + +- "R", means the real value +- "A", means an anomaly +- "D", means a water meter changing +- "V" +- "X" +- "T", means pending data + +If you're looking for more information about the API, checkout the [complete API documentation](/documents/egl-api-doc.pdf) + +### Usage + +TODO : add explanation of how we manage data in the konnector diff --git a/docs/ecolyo/konnectors/enedis.md b/docs/ecolyo/konnectors/enedis.md index 2f4f692dba5c6228a0130fccce621b4c7e2d7452..ebc8cf40641e90d50b9abf53571d14151e590ac7 100644 --- a/docs/ecolyo/konnectors/enedis.md +++ b/docs/ecolyo/konnectors/enedis.md @@ -1,2 +1,39 @@ !!! info "" - :construction: Section under Construction :construction: \ No newline at end of file +:construction: Section under Construction :construction: + +This konnector fetches consumptions measures from Enedis API. This is an Oauth Konnector, meaning the authentification performed to access all data is made following an Oauth2 protocol. +You can clone the project [here](https://forge.grandlyon.com/web-et-numerique/llle_project/enedis-konnector). + +You should also check Cozy's official documentations for konnectors : +[https://docs.cozy.io/en/tutorials/konnector/getting-started/](https://docs.cozy.io/en/tutorials/konnector/getting-started/) +[https://docs.cozy.io/en/tutorials/konnector/oauth/](https://docs.cozy.io/en/tutorials/konnector/oauth/) + +## Enedis Konnector + +The Oauth protocol does not take place in the konnector code, therefore it is also important to take a look at the [proxy](../proxy/description.md) to fully understand all the interactions that will be told below. + +All the actions performed by the stack are targetted from pre-registered paramaters, here is the list of all parameters needed by the stack to perform the Oauth protocol and allow the konnector to fetch data. +On its first launch, following the Oauth Client Connect authentification. + +- The cozy stack calls the **authentification_endpoint** and start the oauth protocol, see [proxy doc](../proxy/description.md). +- The account has now an access_token and an id_token from the oauth call + +!!! info "" +id*token is only given when requesting the token endpoint in \_authorization_code* grant_type. +This token holds several meta datas, including the pce_id (id of user's meter) that will be needed further to fetch user's datas. + +- Konnector starts, fails to find a pce_id in database on first launch therefore decodes the id_token to store the pce_id in db (see [addData](https://docs.cozy.io/en/cozy-konnector-libs/api/#adddata_1)). +- Konnector restarts, this time knowing a pce_id, it fails to fetch datas because the access_token from oauth call has a reduced scope (only scoping for meta data requests). +- Konnector launches a refresh call, the proxy knows to answer it with a _client_credentials_ grant_type call to grdf /access_token. +- Konnector restarts with everyting needed in database to fetch datas and store them in couchdb. + +- Further jobs will not need to change scope again and will only ask for refresh tokens. + +## Enedis API + +API Url for Production : [https://gw.prd.api.enedis.fr](https://gw.prd.api.enedis.fr) + +Enpoints : + +- /v4/metering_data/consumption_load_curve +- /v4/metering_data/daily_consumption diff --git a/docs/ecolyo/project_architecture/doctypes.md b/docs/ecolyo/project_architecture/doctypes.md index d2ea0063095640d6d15adfd6e99aba8b592a7a2e..8cc7700a73c8234175010eab5fb4ae9e0d0eb470 100644 --- a/docs/ecolyo/project_architecture/doctypes.md +++ b/docs/ecolyo/project_architecture/doctypes.md @@ -1,34 +1,38 @@ ## Timeseries doctypes ### Description + Each fluid has its own doctype wildcard and one doctype per time step. Each available time step for a fluid depends of the available data from the energy provider. Here are the different time step: -* minute -* hour -* day -* month -* year + +- minute +- hour +- day +- month +- year ### Doctype Here are the available doctypes: -Fluid type | Doctype wildcard | Doctypes ----------- | -----------------|--------- -electricity fluid / enedis | **`com.grandlyon.enedis.*`** | **`com.grandlyon.enedis.minute`**<br>**`com.grandlyon.enedis.hour`**<br>**`com.grandlyon.enedis.day`**<br>**`com.grandlyon.enedis.month`**<br>**`com.grandlyon.enedis.year`** -gaz fluid / grdf | **`com.grandlyon.grdf.*`** | **`com.grandlyon.grdf.hour`**<br>**`com.grandlyon.grdf.day`**<br>**`com.grandlyon.grdf.month`**<br>**`com.grandlyon.grdf.year`** -water fluid / eau du grand lyon | **`com.grandlyon.egl.*`** | **`com.grandlyon.egl.day`**<br>**`com.grandlyon.egl.month`**<br>**`com.grandlyon.egl.year`** +| Fluid type | Doctype wildcard | Doctypes | +| ------------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| electricity fluid / enedis | **`com.grandlyon.enedis.*`** | **`com.grandlyon.enedis.minute`**<br>**`com.grandlyon.enedis.hour`**<br>**`com.grandlyon.enedis.day`**<br>**`com.grandlyon.enedis.month`**<br>**`com.grandlyon.enedis.year`** | +| gaz fluid / grdf | **`com.grandlyon.grdf.*`** | **`com.grandlyon.grdf.hour`**<br>**`com.grandlyon.grdf.day`**<br>**`com.grandlyon.grdf.month`**<br>**`com.grandlyon.grdf.year`** | +| water fluid / eau du grand lyon | **`com.grandlyon.egl.*`** | **`com.grandlyon.egl.day`**<br>**`com.grandlyon.egl.month`**<br>**`com.grandlyon.egl.year`** | ### Structure -Field | Type | Description ------ | -----|------------ -load | number | load (in kWh or L) -minute | number | minute of the date<br>*set to 0 except for minute serie* -hour | number | hour of the date<br>*set to 0 except for minute and hour series* -day | number | day of the date<br>*set to 1 for month and year series* -month | number | month of the date<br>*set to 1 for year series* -year | number | year of the date + +| Field | Type | Description | +| ------ | ------ | ---------------------------------------------------------------- | +| load | number | load (in kWh or L) | +| minute | number | minute of the date<br>_set to 0 except for minute serie_ | +| hour | number | hour of the date<br>_set to 0 except for minute and hour series_ | +| day | number | day of the date<br>_set to 1 for month and year series_ | +| month | number | month of the date<br>_set to 1 for year series_ | +| year | number | year of the date | ### Example + ``` { "load": 770.18, @@ -43,52 +47,74 @@ year | number | year of the date ## User profile ### Description + This doctype is used to store all information about the user. ### Doctype -**`com.grandlyon.ecolyo.userprofile`** + +**`com.grandlyon.ecolyo.profile`** ### Structure -Field | Type | Description ------ | -----|------------ -level | number | challenge level of the user -challengeTypeHash | string | Hash used to verify the content of challenge type -ecogestureHash | string | Hash used to verify the content of ecogesture -haveSeenWelcomeModal | boolean | flag to inform is the user have seen the welcome modal + +| Field | Type | Description | +| ---------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| id | string | Profile id | +| ecogestureHash | string | Hash used to verify the content of ecogestures | +| challengeHash | string | Hash used to verify the content of challenges | +| duelHash | string | Hash used to verify the content of duels | +| quizHash | string | Hash used to verify the content of quiz | +| isFirstConnection | boolean | Boolean used to inform if the user connects for the first time | +| haveSeenFavoriteModal | boolean | Boolean used to inform if user has seen the favorite modal | +| haveSeenLastReport | boolean | Boolean used to inform if user has seen the last report | +| haveSeenOldFluidModal | Datetime or boolean | Used to inform if user has seen the modal display when his data are too old. Its value is false or a DateTime when he saw it | +| sendReportNotification | boolean | Boolean used to inform if user has seen the report notification | +| monthlyReportDate | DateTime | Date of the last monthly report | ### Example + ``` { - "challengeTypeHash": "c10bbfec554e735d58a5d7009c9964e4a6bc4c65", - "ecogestureHash": "71d475cead14a465d697de596ad21e9aebf3def2", - "haveSeenWelcomeModal": true, - "level": 2 + "id": "0e016e853592e18155e87b85ce00a33a", + "challengeHash": "4cbcafe514788757c377534f1a407e022c29e38c", + "duelHash": "48371ffabb2853b0503b882f11e1fa8e730bac76", + "ecogestureHash": "9798a0aaccb47cff906fc4931a2eff5f9371dd8b", + "haveSeenFavoriteModal": true, + "haveSeenLastReport": true, + "haveSeenOldFluidModal": false, + "isFirstConnection": false, + "monthlyReportDate": "2021-01-03T00:00:00.000+01:00", + "quizHash": "11372a56c03edef1d6656f8a76d5ec457174f2c1", + "sendReportNotification": false } ``` ## Ecogesture ### Description + This doctype is used to store ecogestures. ### Doctype + **`com.grandlyon.ecolyo.ecogesture`** ### Structure -Field | Type | Description ------ | -----|------------ -shortName | string | short name of the ecogesture -longName | string | long name of the ecogesture -shortDescription | string | short description of the ecogesture -longDescription | string | long description of the ecogesture -usage | string | usage of the ecogesture -fluidTypes | FluidType[] | Array of fluid type on which ecogesture can have an impact<br><br>*FluidType enum:*<br>- *ELECTRICITY = 0*<br>- *WATER = 1*<br>- *GAS = 2*<br>- *MULTIFLUID = 3* -nwh | number | negawattheure - impact of the ecogesture from 0 to 10 -pack | number | pack number of the ecogesture (1 pack contain 2 ecogestures) -iconName | string | icon name for ecogesture -unlocked | boolean| (Optional) state for unlocked ecogesture + +| Field | Type | Description | +| ---------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| shortName | string | short name of the ecogesture | +| longName | string | long name of the ecogesture | +| shortDescription | string | short description of the ecogesture | +| longDescription | string | long description of the ecogesture | +| usage | string | usage of the ecogesture | +| fluidTypes | FluidType[] | Array of fluid type on which ecogesture can have an impact<br><br>_FluidType enum:_<br>- _ELECTRICITY = 0_<br>- _WATER = 1_<br>- _GAS = 2_<br>- _MULTIFLUID = 3_ | +| nwh | number | negawattheure - impact of the ecogesture from 0 to 10 | +| pack | number | pack number of the ecogesture (1 pack contain 2 ecogestures) | +| iconName | string | icon name for ecogesture | +| unlocked | boolean | (Optional) state for unlocked ecogesture | ### Example + ``` { "shortName": "Contrôle du nuage", @@ -104,110 +130,327 @@ unlocked | boolean| (Optional) state for unlocked ecogesture } ``` -## Challenge type +## Challenge ### Description -This doctype is used to store all available challenges. + +This doctype is used to store all challenges. ### Doctype -**`com.grandlyon.ecolyo.challengetype`** + +**`com.grandlyon.ecolyo.challenge`** ### Structure -Field | Type | Description ------ | -----|------------ -type | TypeChallenge | type of challenge<br><br>*TypeChallenge enum:*<br>- *CHALLENGE = 0*<br>- *ACHIEVEMENT = 1* -title | string | title of the challenge -description | string | description of the challenge -level | number | level needed to unlock the challenge -duration | Duration | duration. (Duration from luxon) -fluidTypes | FluidType[] | Array of fluid type associated to the challenge<br><br>*FluidType enum:*<br>- *ELECTRICITY = 0*<br>- *WATER = 1*<br>- *GAS = 2*<br>- *MULTIFLUID = 3* -relationships | any | relation to available ecogestures for the challenge<br><br>*"availableEcogestures": {*<br>*"data": Ecogesture[]*<br>*}* + +| Field | Type | Description | +| ------------- | ------ | ------------------------------------------------- | +| \_id | string | challenge id - respect the format _CHALLENGE000X_ | +| title | string | title of the challenge | +| description | string | description of the challenge | +| target | number | The number of stars required to unlock the duel | +| relationships | any | relation to quiz and duel | ### Example + ``` -{ - "type": 1, - "title": "Ecolyo Royal", - "description": "Connecter l'application Ecolyo à votre distributeur d'énergie", - "level": 1, - "duration": { - "days": 0 - }, - "fluidTypes": [ - 0, - 1, - 2 - ], + { + "_id": "CHALLENGE0001", + "title": "Nicolas Hublot", + "description": "foobar", + "target": 15, "relationships": { - "availableEcogestures": { - "data": [ - { - "_id": "0085", - "_type": "com.grandlyon.ecolyo.ecogesture" - }, - { - "_id": "0092", - "_type": "com.grandlyon.ecolyo.ecogesture" - } - ] - } + "quiz": { + "data": { "_id": "QUIZ001", "_type": "com.grandlyon.ecolyo.quiz" } + }, + "duel": { + "data": { "_id": "DUEL001", "_type": "com.grandlyon.ecolyo.duel" } + } } -} + } ``` ## User challenge ### Description + This doctype is used to store all additionnal information about a challenge started or ended by the user. ### Doctype + **`com.grandlyon.ecolyo.userchallenge`** ### Structure -Field | Type | Description ------ | -----|------------ -startingDate | string | starting date of the the challenge -endingDate | string | ending date of the challenge -state | ChallengeState | state of the challenge -maxEnergy | number | -currentEnergy | number | -badge | BadgeState | state of the badge<br><br>BadgeState enum<br>- *FAILED = 0*<br>- *SUCCESS = 1* -fluidTypes | FluidType[] | fluid types set when user launch the challenge<br><br>*FluidType enum:*<br>- *ELECTRICITY = 0*<br>- *WATER = 1*<br>- *GAS = 2*<br>- *MULTIFLUID = 3* -relationships | any | relation to the challenge type and selected ecogestures for the challenge<br><br>*"challengeType": {*<br>*"data": ChallengeType[]*<br>*}*<br><br>*"selectedEcogestures": {*<br>*"data": Ecogesture[]*<br>*}* + +| Field | Type | Description | +| ---------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| id | string | userChallenge id | +| title | string | userChallenge title | +| state | UserChallengeState | state of the challenge<br><br>UserChallengeState enum<br>- _LOCKED = 0_<br>- _UNLOCKED = 1_<br>- _ONGOING = 2_<br>- _DUEL = 3_<br>- _DONE = 4_ | +| target | number | Number of stars required to unlock the duel | +| progress | number | Number of stars earned by the user | +| quiz | UserQuiz | Complete Quiz object with progress | +| duel | UserDuelEntity | Complete Duel object with progress included | +| success | UserChallengeSuccess | Success state of the challenge<br><br>UserChallengeSuccess enum<br>- _ONGOING = 0_<br>- _LOST = 1_<br>- _WIN = 2_ | +| startDate | string null | starting date of the the challenge | +| endingDate | string null | ending date of the challenge | ### Example + ``` { - "state": 1 - "badge": 1, - "currentEnergy": -1, - "startingDate": "0001-01-01T00:00:00.000Z", - "endingDate": "2020-06-16T00:00:00.000+02:00", - "maxEnergy": -1, - "relationships": { - "challengeType": { - "data": { - "_id": "CHA00000001", - "_type": "com.grandlyon.ecolyo.challengetype" - } - }, - "selectedEcogestures": { - "data": [ - { - "_id": "0085", - "_type": "com.grandlyon.ecolyo.ecogesture" - }, - { - "_id": "0092", - "_type": "com.grandlyon.ecolyo.ecogesture" - } - ] - } + "_id": "eae3a79a05d677a739bdd2b46b009936", + "description": "foobar", + "duel": { + "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine", + "duration": { + "days": 7 + }, + "fluidTypes": [ + 0, + 1, + 2 + ], + "id": "DUEL001", + "startDate": null, + "state": 4, + "threshold": -1, + "title": "Nicolas Hublot", + "userConsumption": 0 + }, + "endingDate": null, + "id": "CHALLENGE0001", + "progress": 15, + "quiz": { + "customQuestion": { + "interval": 30, + "period": {}, + "questionLabel": "Quel jour ai-je le plus consommé la semaine dernière ?", + "result": 1, + "timeStep": 20, + "type": 0 }, + "id": "QUIZ001", + "questions": [ + { + "answers": [ + { + "answerLabel": "Vapeur d'eau", + "isTrue": false + }, + { + "answerLabel": "Fumée", + "isTrue": false + }, + { + "answerLabel": "Gouttelettes d'eau et cristaux de glace", + "isTrue": true + } + ], + "explanation": "Les nuages sont constitués de gouttelettes d'eau et parfois aussi de cristaux de glace", + "questionLabel": "De quoi les nuages sont-ils constitués ?", + "result": 1, + "source": "string" + }, + { + "answers": [ + { + "answerLabel": "86 km", + "isTrue": true + }, + { + "answerLabel": "78 km", + "isTrue": false + }, + { + "answerLabel": "56 km", + "isTrue": false + } + ], + "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône", + "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?", + "result": 1, + "source": "string" + }, + { + "answers": [ + { + "answerLabel": "Crémieux", + "isTrue": false + }, + { + "answerLabel": "Crépieux-Charmy", + "isTrue": true + }, + { + "answerLabel": "Charly", + "isTrue": false + } + ], + "explanation": "Crépieux-Charmy est le principal champ captant de la Métropole de Lyon", + "questionLabel": "Quelle est le nom du principal champ de captage d’eau potable de la Métropole ?", + "result": 1, + "source": "string" + }, + { + "answers": [ + { + "answerLabel": "Pompe à air", + "isTrue": false + }, + { + "answerLabel": "Pompe à cordes", + "isTrue": true + }, + { + "answerLabel": "Pompe de Cornouailles", + "isTrue": false + } + ], + "explanation": "Mise en fonctionnement en 1856, 3 pompes à vapeur dites de Cornouailles produisent quelque 20 000 m3 d'eau par jour. Ces pompes mesurent 20 m de haut et 13 m de large pour un poids de 200 tonnes. Leur balancier de 35 tonnes s'actionne toutes les 6 secondes, permettant ainsi l'envoi de 600 m3 d'eau par heure.", + "questionLabel": "Quelle type de pompes étaient utilisées à l'usine des eaux de Caluire jusqu'en 1910 ?", + "result": 1, + "source": "string" + } + ], + "result": 5, + "state": 2 + }, + "startDate": "2021-01-04T00:00:00.000Z", + "state": 3, + "success": 0, + "target": 15, + "title": "Nicolas Hublot" } ``` +## Quiz + +### Description + +This doctype is used to store all quiz. + +### Doctype + +**`com.grandlyon.ecolyo.quiz`** + +### Structure + +| Field | Type | Description | +| -------------- | -------------------- | ------------------------------------------- | +| \_id | string | quiz id - respect the format _QUIZ00X_ | +| questions | QuestionEntity[] | Array of questions entities | +| customQuestion | CustomQuestionEntity | Custom question based on user's consumption | + +### Example + +``` +{ + "_id": "QUIZ001", + "questions": [ + { + "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?", + "answers": [ + { "answerLabel": "86 km", "isTrue": true }, + { + "answerLabel": "78 km", + "isTrue": false + }, + { + "answerLabel": "56 km", + "isTrue": false + } + ], + "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône", + "source": "string" + }, + { + "questionLabel": "Quelle type de pompes étaient utilisées à l'usine des eaux de Caluire jusqu'en 1910 ?", + "answers": [ + { + "answerLabel": "Pompe à cordes", + "isTrue": true + }, + { + "answerLabel": "Pompe de Cornouailles", + "isTrue": false + }, + { + "answerLabel": "Pompe à air", + "isTrue": false + } + ], + "explanation": "Mise en fonctionnement en 1856, 3 pompes à vapeur dites de Cornouailles produisent quelque 20 000 m3 d'eau par jour. Ces pompes mesurent 20 m de haut et 13 m de large pour un poids de 200 tonnes. Leur balancier de 35 tonnes s'actionne toutes les 6 secondes, permettant ainsi l'envoi de 600 m3 d'eau par heure.", + "source": "string" + }, + { + "questionLabel": "Quelle est le nom du principal champ de captage d’eau potable de la Métropole ?", + "answers": [ + { "answerLabel": "Crémieux", "isTrue": false }, + { + "answerLabel": "Crépieux-Charmy", + "isTrue": true + }, + { + "answerLabel": "Charly", + "isTrue": false + } + ], + "explanation": "Crépieux-Charmy est le principal champ captant de la Métropole de Lyon", + "source": "string" + }, + { + "questionLabel": "De quoi les nuages sont-ils constitués ?", + "answers": [ + { "answerLabel": "Vapeur d'eau", "isTrue": false }, + { + "answerLabel": "Fumée", + "isTrue": false + }, + { + "answerLabel": "Gouttelettes d'eau et cristaux de glace", + "isTrue": true + } + ], + "explanation": "Les nuages sont constitués de gouttelettes d'eau et parfois aussi de cristaux de glace", + "source": "string" + } + ], + "customQuestion": { + "questionLabel": "Quel jour ai-je le plus consommé la semaine dernière ?", + "type": 0, + "timeStep": 20, + "interval": 30, + "period": {} + } + } +``` + +## Duel + +### Description +This doctype is used to store all duels. +### Doctype +**`com.grandlyon.ecolyo.duel`** +### Structure + +| Field | Type | Description | +| ----------- | -------- | -------------------------------------- | +| \_id | string | duel id - respect the format _DUEL00X_ | +| title | string | title of the duel | +| description | string | description of the duel | +| duration | Duration | Luxon Duration of the duel | + +### Example + +``` + { + "_id": "DUEL001", + "title": "Nicolas Hublot", + "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine", + "duration": { "days": 7 } + } +``` diff --git a/docs/img/challengeFlow.png b/docs/img/challengeFlow.png new file mode 100644 index 0000000000000000000000000000000000000000..d5ab6ec40a785d9cfe512abaacc373438b07f932 Binary files /dev/null and b/docs/img/challengeFlow.png differ