Skip to content
Snippets Groups Projects
enedis-sge.md 14.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bastien DUMONT's avatar
    Bastien DUMONT committed
    # Enedis SGE Konnector
    
    This konnector fetches consumption measures from Enedis SGE SOAP API.
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    You should also check Cozy's official documentations for konnectors :
    
    https://docs.cozy.io/en/tutorials/konnector/getting-started
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    ## Enedis context
    
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    The API used by this konnector are the one used by all energy providers (edf, total...), this one is supposed to have a high availability. Contrary to enedis oauth konnector, this is a regular auth konnector.
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    ## Technical overview
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    ### Lib used
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    - xml2js: Lib allowing easy parsing to json
    - easy-soap-request: Lib making soap request
    
    ### WSO2
    
    
    For now enedis API are proxied by WSO2 api manager. You can find documentation and devportal [here](https://apis.grandlyon.fr/devportal).
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    ### Scaffolding
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    
    - core/types: contains jsdoc types
    - core/: requests wrapper with error handling logic
    - helpers/ : contains helpers for aggregation, env and parsing
    
    - requests/: contain all methods for : Parsing sge requests, Send/get backoffice data, interactions with cozy stack
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    - index.js: main file where default konnector methods are launch (start, ...)
    
    - onDeleteAccount.js: hold consent suppression when a user delete an account. Automatically launched on delete.
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    ### ts-check
    
    In order to have better comfort while coding, we have enable ts-checking with vs-code. The verification is based on js-doc, please take time to maintain the js-doc.
    
    
    :::info ts-check
    The ts-check is none blocking. It will only put information in vs-code ide.
    :::
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    In order to local test you have to copy the [konnector-dev-config.example.json](https://forge.grandlyon.com/web-et-numerique/factory/llle_project/enedis-sge-konnector/-/blob/dev/konnector-dev-config.example.json?ref_type=heads) to `konnector-dev-config.json` and replace values and corresponding secrets.
    
    :::warning user consent
    While running in dev mode, be sure to have user consent, either on production env or with enedis standard form.
    :::
    
    
    You can now run the following commands to run the konnector :
    
    ```sh
    
    yarn standalone # Run inside shell with no cozy env dependencies
    yarn standalone-no-data # Run inside shell without getting any data
    yarn dev # Run with your local cozy. For this one you need local stack to run
    yarn onDeleteAccount:standalone # Run onDeleteAccount script
    yarn onDeleteAccount # Run onDeleteAccount script with real cozy
    
    For standalone cmd you can find konnector results in `/data/importedData.json`
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    ### Konnector Methods
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    | Method | Description |
    | ------ | ------ |
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    | start | Main method of konnector. Handle global flow and init method with provided params |
    
    | gatherData | Wrapper for getting daily, half-hour and max power data |
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    | getData | Get daily data |
    | getMaxPowerData | Get daily Max Power data |
    | getHalfHourData | Get half-hour data |
    
    Rémi PAILHAREY's avatar
    Rémi PAILHAREY committed
    | getOffPeakHours | Get off-peak hours if activated in contract and store them in cozy.account  |
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    | processData | Given a doctype, parse and format data before storing and aggregating |
    
    | setStartDate | Save startDate with the right time range |
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    | storeData | Save data to user's cozy |
    | agregateMonthAndYearData | Sum daily data for months and years |
    
    | isFirstStart | Check if it's first start or an alternate start base on boId in cozy.account |
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    ## Dataflow
    
    ### Overview
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    Functional and technical flow chart:
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    [Lien du schema](https://whimsical.com/sge-tech-DxbYM8DdajRjTr6WZat1bV)
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    ### Authentication
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    Information required:
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    - Name
    - Surname
    - PointID (PDL)
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    - Full address
    
    - Postal Code
    - City
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    
    #### Test with user invoices
    
    To test user invoices, you will have to make a copy of `konnector-dev-config.example.json` to `konnector-dev-config.json` and fill out informations.
    
    Then, to test the authentication flow of the konnector without fetching any data, launch the script `yarn standalone-no-data`
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    ### Fetch Data
    
    In order to get data from the SGE API we have to request the following route :
    
    
    #### Get user contract startDate
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    Method : **POST**
    
    Data Route : **enedis_SGE_ConsultationDonneesTechniquesContractuelles/1.0**
    
    ```xml
    <soapenv:Body>
        <v2:consulterDonneesTechniquesContractuelles>
            <pointId>${pointId}</pointId>
            <loginUtilisateur>${userLogin}</loginUtilisateur>
            <autorisationClient>true</autorisationClient>
        </v2:consulterDonneesTechniquesContractuelles>
    </soapenv:Body>
    ```
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    #### Get daily data and Get Half-hour data
    
    
    Method : **POST**
    
    Data Route : **enedis_SGE_ConsultationMesuresDetaillees/1.0**
    
    ```xml
    <?xml version='1.0' encoding='utf-8'?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:v2="http://www.enedis.fr/sge/b2b/services/consultationmesuresdetaillees/v2.0"
         xmlns:v1="http://www.enedis.fr/sge/b2b/technique/v1.0">
         <soapenv:Header/>
         <soapenv:Body>
            <v2:consulterMesuresDetaillees>
               <demande>
                  <initiateurLogin>${appLogin}</initiateurLogin>
                  <pointId>${pointId}</pointId>
                  <mesuresTypeCode>${mesureType}</mesuresTypeCode>
                  <grandeurPhysique>${unit}</grandeurPhysique>
                  <soutirage>true</soutirage>
                  <injection>false</injection>
                  <dateDebut>${startDate}</dateDebut>
                  <dateFin>${endDate}</dateFin>
                  <mesuresCorrigees>false</mesuresCorrigees>
                  <accordClient>true</accordClient>
               </demande>
            </v2:consulterMesuresDetaillees>
         </soapenv:Body>
      </soapenv:Envelope>
    ```
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    
    
    #### Get Max Power data
    
    Method : **POST**
    
    Data Route : **enedis_SGE_ConsultationMesuresDetaillees/1.0**
    
    ```xml
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:v2="http://www.enedis.fr/sge/b2b/services/consultationmesuresdetaillees/v2.0"
         xmlns:v1="http://www.enedis.fr/sge/b2b/technique/v1.0">
          <soapenv:Header/>
          <soapenv:Body>
              <v2:consulterMesuresDetaillees>
                  <demande>
                      <initiateurLogin>${appLogin}</initiateurLogin>
                      <pointId>${pointId}</pointId>
                      <mesuresTypeCode>${mesureType}</mesuresTypeCode>
                      <grandeurPhysique>${unit}</grandeurPhysique>
                      <soutirage>true</soutirage>
                      <injection>false</injection>
                      <dateDebut>${startDate}</dateDebut>
                      <dateFin>${endDate}</dateFin>
                      <mesuresPas>P1D</mesuresPas>
                      <mesuresCorrigees>false</mesuresCorrigees>
                      <accordClient>true</accordClient>
                  </demande>
              </v2:consulterMesuresDetaillees>
          </soapenv:Body>
      </soapenv:Envelope>
    ```
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    
    
    #### Get contract information
    
    Method : **POST**
    
    Data Route : **enedis_SGE_enedis_SGE_ConsultationDonneesTechniquesContractuelles/1.0**
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    
    
    Rémi PAILHAREY's avatar
    Rémi PAILHAREY committed
    This route also gives off-peak hours, if the user chose a contract with off-peak hours
    
    
    ```xml
    <?xml version='1.0' encoding='utf-8'?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:v2="http://www.enedis.fr/sge/b2b/services/consulterdonneestechniquescontractuelles/v1.0"
         xmlns:v1="http://www.enedis.fr/sge/b2b/technique/v1.0">
         <soapenv:Header/>
         <soapenv:Body>
            <v2:consulterDonneesTechniquesContractuelles>
               <pointId>${pointId}</pointId>
               <loginUtilisateur>${appLogin}</loginUtilisateur>
               <autorisationClient>true</autorisationClient>
            </v2:consulterDonneesTechniquesContractuelles>
         </soapenv:Body>
      </soapenv:Envelope>
    ```
    
    
    Rémi PAILHAREY's avatar
    Rémi PAILHAREY committed
    Response :
    
    ```xml
    <point id="12345678912345">
      <donneesGenerales>
        <etatContractuel code="SERVC">
          <libelle>En service</libelle>
        </etatContractuel>
        <adresseInstallation>
          <numeroEtNomVoie>208 BIS RUE GARIBALDI</numeroEtNomVoie>
          <codePostal>69003</codePostal>
          <commune code="69383">
            <libelle>LYON 3</libelle>
          </commune>
        </adresseInstallation>
        <niveauOuvertureServices>2</niveauOuvertureServices>
      </donneesGenerales>
      <situationComptage>
        <dispositifComptage>
          <relais>
            <plageHeuresCreuses>HC (22H00-6H00)</plageHeuresCreuses>
          </relais>
        </dispositifComptage>
      </situationComptage>
    </point>
    ```
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    #### Get user PDL
    
    
    Method : **POST**
    
    Data Route : **enedis_SGE_RechercheServicesMesures/1.0**
    
    ```xml
    <?xml version='1.0' encoding='utf-8'?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:v2="http://www.enedis.fr/sge/b2b/services/rechercherpoint/v2.0"
         xmlns:v1="http://www.enedis.fr/sge/b2b/technique/v1.0">
         <soapenv:Header/>
         <soapenv:Body>
            <v2:rechercherPoint>
               <criteres>
                  <adresseInstallation>
                     <numeroEtNomVoie>${address}</numeroEtNomVoie>
                     <codePostal>${postalCode}</codePostal>
                     <codeInseeCommune>${inseeCode}</codeInseeCommune>
                  </adresseInstallation>
                  <nomClientFinalOuDenominationSociale>${name}</nomClientFinalOuDenominationSociale>
                  <rechercheHorsPerimetre>true</rechercheHorsPerimetre>
               </criteres>
               <loginUtilisateur>${appLogin}</loginUtilisateur>
            </v2:rechercherPoint>
         </soapenv:Body>
      </soapenv:Envelope>
    ```
    
    #### Get User services subscriptions
    
    Method : **POST**
    
    Data Route : **enedis_SGE_RechercheServicesMesures/1.0**
    
    ```xml
    <?xml version='1.0' encoding='utf-8'?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:v2="http://www.enedis.fr/sge/b2b/rechercherservicessouscritsmesures/v1.0"
         xmlns:v1="http://www.enedis.fr/sge/b2b/technique/v1.0">
          <soapenv:Header/>
          <soapenv:Body>
              <v2:rechercherServicesSouscritsMesures>
                <criteres>
                  <pointId>${pointId}</pointId>
                  <contratId>${contractId}</contratId>
                </criteres>
                <loginUtilisateur>${appLogin}</loginUtilisateur>
              </v2:rechercherServicesSouscritsMesures>
          </soapenv:Body>
      </soapenv:Envelope>
    ```
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    #### Start user contract
    
    
    Method : **POST**
    
    Data Route : **enedis_SGE_CommandeCollectePublicationMesures/1.0**
    
    ```xml
    <?xml version='1.0' encoding='utf-8'?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:v2="http://www.enedis.fr/sge/b2b/commandercollectepublicationmesures/v3.0"
         xmlns:v1="http://www.enedis.fr/sge/b2b/technique/v1.0">
          <soapenv:Header/>
          <soapenv:Body>
              <v2:commanderCollectePublicationMesures>
                  <demande>
                      <donneesGenerales>
                          <objetCode>AME</objetCode>
                          <pointId>${pointId}</pointId>
                          <initiateurLogin>${appLogin}</initiateurLogin>
                          <contratId>${contractId}</contratId>
                      </donneesGenerales>
                      <accesMesures>
                          <dateDebut>${startDate}</dateDebut>
                          <dateFin>${endDate}</dateFin>
                          <declarationAccordClient>
                              <accord>true</accord>
                              <personnePhysique>
                                  <nom>${name}</nom>
                              </personnePhysique>
                          </declarationAccordClient>
                          <mesuresTypeCode>CDC</mesuresTypeCode>
                          <soutirage>true</soutirage>
                          <injection>false</injection>
                          <mesuresPas>PT30M</mesuresPas>
                          <mesuresCorrigees>false</mesuresCorrigees>
                          <transmissionRecurrente>true</transmissionRecurrente>
                          <periodiciteTransmission>P1D</periodiciteTransmission>
                      </accesMesures>
                  </demande>
              </v2:commanderCollectePublicationMesures>
          </soapenv:Body>
      </soapenv:Envelope>
    ```
    
    #### Stop User contract
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    
    
    ```xml
    <?xml version='1.0' encoding='utf-8'?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:v2="http://www.enedis.fr/sge/b2b/commanderarretservicesouscritmesures/v1.0"
         xmlns:v1="http://www.enedis.fr/sge/b2b/technique/v1.0">
          <soapenv:Header/>
          <soapenv:Body>
              <v2:commanderArretServiceSouscritMesures>
                  <demande>
                      <donneesGenerales>
                          <objetCode>ASS</objetCode>
                          <pointId>${pointId}</pointId>
                          <initiateurLogin>${appLogin}</initiateurLogin>
                          <contratId>${contractId}</contratId>
                      </donneesGenerales>
                      <arretServiceSouscrit>
                      <serviceSouscritId>${serviceSouscritId}</serviceSouscritId>
                      </arretServiceSouscrit>
                  </demande>
              </v2:commanderArretServiceSouscritMesures>
          </soapenv:Body>
      </soapenv:Envelope>
    ```
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    The same endpoint is used to get the data. The soap body is the following:
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    Method : **POST**
    
    Data Route : **enedis_SGE_ConsultationDonneesTechniquesContractuelles/1.0**
    
    ```xml
    <soapenv:Body>
        <v2:consulterMesuresDetaillees>
            <demande>
                <initiateurLogin>${userLogin}</initiateurLogin>
                <pointId>${pointId}</pointId>
                <mesuresTypeCode>${mesureType}</mesuresTypeCode>
                <grandeurPhysique>${unit}</grandeurPhysique>
                <soutirage>true</soutirage>
                <injection>false</injection>
                <dateDebut>${startDt}</dateDebut>
                <dateFin>${endDt}</dateFin>
                <mesuresCorrigees>false</mesuresCorrigees>
                <accordClient>true</accordClient>
            </demande>
        </v2:consulterMesuresDetaillees>
    </soapenv:Body>
    ```
    
    
    ### Known Issues
    
    #### Contract deletion and creation on same day
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    If you stop a contract on a day, (for exemple 8/08/22), you cannot start a new contract for this date with [start contract route](./enedis-sge.md#user_contract_start). You have to wait for the next day. This might cause some production issues
    
    
    #### User data collect opposition
    
    
    Users can remove consent from enedis account on data collecting. This will return the following when checking contracts.
    
    
    ```xml
    <serviceSouscritMesures>
        <serviceSouscritId>74472322</serviceSouscritId>
        <pointId>19176410771132</pointId>
        <serviceSouscritType code="OPPENR"/>
        <serviceSouscritLibelle>Opposition à l'enregistrement de la courbe de charge</serviceSouscritLibelle>
        <injection>false</injection>
        <soutirage>true</soutirage>
        <etatCode>ACTIF</etatCode>
        <dateDebut>2022-06-24+02:00</dateDebut>
        <dateFin>2022-08-10+02:00</dateFin>
        <motifFinLibelle>Arrêt par le client</motifFinLibelle>
    </serviceSouscritMesures>
    ```
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    We cannot override that, the only solution is to tell the user to activate data collect on [enedis](https://mon-compte-particulier.enedis.fr/donnees/).