[Article] Intégration Pronote : cours, devoirs, notes, etc

Peut-être que ça vaudrait le coup d’ouvrir un topic séparé ? On ne sait pas si c’est lié à Pronote. Il est vrai que je constate la même chose mais j’ai plein d’autres intégrations…

Peut-être que des personnes n’utilisant pas Pronote nous indiqueront constater la même chose ?

2 « J'aime »

Tout à fait d’accord.

J’avais une suspiscion car Pronote est un peu le dernier truc que j’ai ajouté et je n’avais jamais remarqué ça avant…

Bon si on est que trois, c’est peut être pas pronote…

Je vais profiter des vacances pour essayer de débrancher pronote pour voir…

Puis le cas échéant je créerait un autre topic…

Bonjour à tous,
Habituellement je cherche tout seul mais franchement ça fait des jours que je butte sur le même truc et j’ai beau avoir essayé je ne sais pas combien de manips, mais rien n’y fait. C’est pourquoi, après avoir essuyé les nombreux messages de ce feed, et avoir essayé autant de manips que possible je viens chercher un peu d’aide…
J’ai un accès parent pour voir les notes de ma fille.
J’ai lancé l’installation et l’update de pronote.py.
Après quoi, je modifie le fichier config.ini.
Je ne comprends pas trop pourquoi l’ENT n’est pas obligatoire. Néanmoins, j’ai fait un essai en mettant mon login et mot de passe, et j’ai un problème de client…
Après quoi, je renseigne ce qui me semble être le bon ENT mais là j’ai un message comme quoi ma fille n’est pas dedans. Alors que pour reprendre son identifiant, j’ai installé le HACS de DELPHIKI qui fonctionne via le QR code…

Si une âme charitable accepterais de me venir en aide SVP

On est 4 ! J’ai également ce soucis d’augmentation de mémoire

1 « J'aime »

Bon, j’ai finalement trouvé la solution pour me connecter j’ai récupéré quelques sensors mais pas tous. je continue d’investiguer :slight_smile:

T’es probablement dans le mauvais post… voir ici
Pronote dans HA - les notes, devoirs, absences et emploi du temps des enfants - Home Assistant - Tutoriels & Partages / Général - Home Assistant Communauté Francophone (hacf.fr)

1 « J'aime »

Bon, suite à la dernière mise à jour d’ HAOS, on peut super facilement consulter l’historique…

Et on y voit que l’augmentation de la RAM colle avec mon installation de pronote.

(première installation réussie de Pronote le 6 septembre puis pas mal de reset durant quelques jours suite au PB de mise à jour des capteurs de l’époque)

Je ne sais pas quel est le soucis, mais il se passe un truc quelque part qui fait que la RAM utilisée augmente doucement mais surement… si ce n’est pas l’intégration Pronote, c’est peut être dans les template et les cartes associées.

1 « J'aime »

J’ai publié une (micro-)màj, la version 0.13.6, qui permet de passer sous la dernière version de pronotepy (2.13.0)

Je suis en train de travailler sur une version qui permet de corriger les soucis du style « State attributes for sensor.pronote_xxx_timetable_period exceed maximum size of 16384 bytes »
J’ai une version qui fonctionne, mais c’est pas très clean pour le moment.
Dans tous les cas, ça aura pour effet de ne pas pouvoir déterminer le nombre exact de cours (et donc de jours) retourné par le sensor timetable_period, parce qu’en gros, j’ajoute des cours jusqu’à atteindre la limite à ne pas dépasser en terme de stockage.

3 « J'aime »

J’ai exactement le même soucis que toi.
Je tenterai de désactiver pronote le temps des vacances pour voir si c’est bien ça.

@delphiki est-ce que tu rencontres le soucis de ton côté également ?

J’ai des potes qui n’ont pas Pronote et qui ont le meme soucis…
Ca me soule serieusement de faire des restart tous les 2 jours juste pour ca …

Effectivement, je n’avais pas fait attention, mais j’ai la même chose au niveau conso mémoire, ça augmente progressivement. Je ne le ressens pas trop parce que j’ai mis 6 Go de RAM sur la VM, donc c’est assez large, mais le fait est que j’ai le même souci.
Je ne saurais pas dire si ça vient de l’intégration pour le coup, la dernière fois que j’ai eu un souci dans le genre, c’était à cause des add-on pour les assistants vocaux (que j’ai désactivés depuis).

EDIT : j’ai désactivé l’intégration pour voir cet aprem si ça change quelque chose.

Chez moi aussi pas de réelle inquiétude car ça augmente très progressivement (environ 0.3% par heure) donc entre le reset d’hier et ce midi on est passé de 25.5 à 29% de RAM occupée, rien de critique (4G de RAM sur le mini PC, par contre j’aurai mis mon Rpi 3 à genoux…).

J’en ai profité pour faire un gros tour de correction de la plupart des erreurs qui restaient (quelques erreurs dans les templates notamment ceux liés à Pronote) et la correction d’une vielle erreur qui trainait sur l’integration d’Alexa. Mais j’ai toujours le phénomène.

Est-ce un gros problème?

Tout dépend l’ordre de grandeur que tu parviens à avoir avec des journées types? Personnellement si ça fait déjà une semaine complète c’est bien…

Bon, effectivement, en désactivant l’intégration tout l’aprem, je n’ai pas la mémoire qui augmente autant qu’avant (toujours un peu, mais sensiblement moins), donc il doit y avoir un souci de fuite mémoire quelque part.
Je vais tester d’installer ma version de test avec les correctifs sur le sensor timetable_period pour voir si ça change quelque chose.

4 « J'aime »

Si ça peut t’aider, en plongeant dans l’historique, je vois que le phénomène a débuté le 13 septembre entre 9h et 10h chez moi.

Ce qui correspond à priori à l’installation de la version 0.5.1 avec le correctif pour la mise à jour des données.

J’avais installé la 0.6.0 quelques jours plus tard, visiblement sans changement.

2 « J'aime »

Tiens je viens de remarquer que tu as fait une faute de frappe dans le no de version sur HACS: la version c’est désormais la 1.13.6 !

On est donc passé en version 1 :champagne:

@delphiki
J’ai désactivé ce matin mes 3 comptes Pronote, je n’ai plus aucun probleme de Ram Core qui monte avec restart HA obligé après 2 jours… Ca vient bien de Pronote donc…

Ce soir toujours encéphalogramme plat de la ram avec PRONOTE désactivé

Arg ! oui ! il doit y avoir une petite fuite mémoire :scream:
Devinez quand j’ai installé l’intégration Pronote ? :stuck_out_tongue_winking_eye:


@delphiki : si tu peux faire quelque chose rapidement ?:pray:t2:

Bon en attendant la correction du bug de mémoire, j’ai repris tous le design que j’avais fait sur mon intégration d’origine (Pronote2HomeAssistant) et j’ai rappliqué tout ça au modèle qu’avait fourni @delphiki un peu plus haut (qui lui même s’était inspiré du mien il me semble :wink:)

Le design ça donne ça :

Voila le contenu complet du fichier /homeassistant/custom_templates/pronote.jinja :

{%- macro absences_markdown(firstname, sensor_id) -%}
{% set items = state_attr(sensor_id,'absences') %}
<div>{{ firstname }} - Absences</div>
<table>
        {%- for item in items -%}
        <tr>
            <td width="50%">
                Le {{as_timestamp(item.from) | int | timestamp_custom('%d %b à %Hh%M', true)}}
                <br>{{item.hours}} de cours manqué(s)</td>
            <td>
            {%- if item.reason == '' -%}
                Motif : inconnu<br/>
            {%- else -%}
                Motif : {{item.reason}}<br/>
            {% endif %}
            {%- if item.justified == false -%}
                <span>Absence non justifiée</span>
            {%- else -%}
                <mark>Absence justifiée</mark>
            {% endif %}</td>               
        </tr>
        {% endfor %}
</table>
{% endmacro %}

{%- macro homework_markdown(firstname, sensor_id) -%}
{% set days = ["Lun.", "Mar.", "Mer.", "Jeu.", "Ven.", "Sam.", "Dim."] %}
{% set items = state_attr(sensor_id,'homework') %}
<div>{{ firstname }} - Devoirs</div>
<table>
        {%- for item in items -%}
            <tr>
                <td>{{ days[item.date.strftime('%w')| int - 1] }} {{as_timestamp(item.date) | int | timestamp_custom('%d/%m', true)}}</td>
                <td><span></span></td>
                <td><b>{{ item.subject}}</b><br>{{ item.short_description }}</td>
                <td>{%- if item.done -%}<mark>fait</mark>{%- else -%}<span>non_fait</span>{%- endif -%}</td>
           </tr>
        {% endfor %}
</table>
{% endmacro %}

{%- macro grades_markdown(firstname, sensor_id) -%}
{% set items = state_attr(sensor_id,'grades') %}
<div>{{ firstname }} - Notes</div>
<table>
        {%- for item in items -%}
            <tr>
                <td width="20%">{{as_timestamp(item.date) | int | timestamp_custom('%d/%m', true)}}</td>
                <td><span></span></td>
                <td><b>{{ item.subject}}</b><br>{{ item.comment }}</td>
                <td width="30%"><b>{{ item.grade_out_of }} </b>
                {%- if item.coefficient != '1' -%} <i>(Coeff. : {{ item.coefficient }})</i>{% endif %}
                <ul>
                <li>Moy. cl.: {{ item.class_average }}</li>
                <li>Min-max : {{ item.min }}-{{ item.max }}</li>
                </ul>
                </td>
           </tr>
        {% endfor %}
</table>
{% endmacro %}

{%- macro timetable_markdown(firstname, sensor_id) -%}
    {%- if as_timestamp(now())|int <= as_timestamp((state_attr(sensor_id, 'lessons')|last).end_at)|int + (3*3600) -%}
        {% set days = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"] %}
        {% set items = state_attr(sensor_id,'lessons') %}
        <div>
            {{ firstname }} - {{ days[items[0].start_at.strftime('%w')| int - 1] }} {{as_timestamp(items[0].start_at) | int | timestamp_custom('%d/%m', true)}}
            - Début à {{ as_timestamp(state_attr(sensor_id,'day_start_at'))| int | timestamp_custom('%-Hh%M', true) }}
        </div>
        <table>
            {%- for item in items -%}
                {%- set canceled = item.canceled == True -%}
                <tr>
                    <td>
                        {{ item.start_time }}<br />
                        {{ item.end_time }}
                    </td>
                    <td>
                        <span></span>
                    </td>
                    <td>
                        {%- if canceled -%}<del>{%- endif -%}
                        <b>{{ item.lesson }}</b>
                        {%- if canceled -%}</del>{%- endif -%}
                        <br />
                        Salle {{ item.classroom }}
                    </td>
                    <td>
                        {%- if canceled -%}
                            <mark>{{ item.status }}</mark>  
                        {%- elif item.status != None -%}
                            <span>{{ item.status }}</span>
                        {%- endif -%}
                    </td>
                </tr>
            {%- endfor -%}
        </table>
    {%- endif -%}
{% endmacro %}

{%- macro pronote_styles(sensor_id) -%}
    div {
        background-color:rgb(50, 50, 50);
        padding: 12px;
        color:white;
        font-weight:normal;
        font-size:1.2em;
        border-top-left-radius: 5px; 
        border-top-right-radius: 5px;
    }
    table{
        font-size: 0.9em;
        font-family: Roboto;
        width: 100%;
        outline: 0px solid #393c3d;
        margin-top:5px;
        border-collapse: collapse;
    }
    td {
        vertical-align: middle;
    }
    tr td:last-child span {
        background-color: #EC4B34;
        padding: 4px;
        border-radius: 4px;
        white-space: nowrap;
    }
    mark {
        background-color: #009767;
        padding: 4px;
        border-radius: 4px;
        white-space: nowrap;
        margin-top:3px
    }
    @media (prefers-color-scheme: dark) {
        tr:nth-child(even) {background-color: #242424;}
    }
    @media (prefers-color-scheme: light) {
        tr:nth-child(odd) {background-color: #e9e9e9;}
    }    
    tr td:nth-child(2) {
        width: 4px;
        padding: 5px 0;
    }

    {%- if sensor_id == "sensor.pronote_xxxxxxxxx_timetable_next_day" -%}
     
        tr td:nth-child(2) > span {
            display:inline-block;
            width: 4px;
            height: 3rem;
            border-radius:4px;
        }
    
        tr td:first-child {
            width: 13%;
            text-align:right;
        }
        {%- set items = state_attr(sensor_id, 'lessons') -%}
        {%- for i in range(0, items | count, 1) -%}
            {%- if items[i].canceled and not loop.last and items[i].start_at == items[i+1].start_at -%}
                tr:nth-child({{ loop.index }}) {
                    display:none;
                }
            {%- else -%}
                tr:nth-child({{ loop.index }}) td:nth-child(2) > span {
                    background-color: {{items[i].background_color}};
                }
                {% if as_timestamp(now()) > as_timestamp(items[i].end_at) %}
                    tr:nth-child({{ loop.index }}) {
                        opacity: 0.3;
                    }
                {% endif %}
            {%- endif -%}
        {%- endfor -%}
    {% endif %}
    
    {%- if sensor_id == "sensor.pronote_xxxxxxxxx_homework" -%}
        tr td:nth-child(2) > span {
            display:inline-block;
            width: 4px;
            height: 3rem;
            border-radius:4px;
        }
        
        tr td:first-child {
            width: 13%;
            text-align:center;
            white-space: nowrap;
        }

        {%- set items = state_attr(sensor_id, 'homework') -%}
        {%- for i in range(0, items | count, 1) -%}
            tr:nth-child({{ loop.index }}) td:nth-child(2) > span {
                background-color: {{items[i].background_color}};
            }

        {%- endfor -%}
    {% endif %}


    {%- if sensor_id == "sensor.pronote_xxxxxxxxxxx_grades" -%}
        tr td:nth-child(2) > span {
            display:inline-block;
            width: 4px;
            height: 3rem;
            border-radius:4px;
        }
        tr td:first-child {
            width: 15%;
            text-align:center;
            white-space: nowrap;
        }
        tr td:last-child {
            width: 30%;
            white-space: nowrap;
        }
        
        {%- set items = state_attr(sensor_id, 'grades') -%}
        {%- for i in range(0, items | count, 1) -%}
            {%- if items[i].grade >= items[i].class_average -%}
                tr:nth-child({{ loop.index }}) td:nth-child(2) > span {
                    background-color: #009767;
                }
            {%- else -%}    
                tr:nth-child({{ loop.index }}) td:nth-child(2) > span {
                    background-color: #EC4B34;
                }
            {%- endif -%}    
        {%- endfor -%}
    {% endif %}

    ul{
        padding: 0px 0px 0px 0px;
        margin: 0px;
        list-style-type:none;
    }
    li{
        padding: 0px 0px 0px 0px;
        font-style: italic;
        color: grey;
    }
    tr.canceled td {
        color: orange;
    }
    td {
        padding: 5px 10px 5px 10px;
        text-align: left;
        vertical-align: top;
    }
{%- endmacro -%}

Et voici le Lovelace de chaque bloc

L’emploi du temps du prochain jour :

type: markdown
content: >-
  {%- from 'pronote.jinja' import timetable_markdown -%} {{-
  timetable_markdown('Pronote',
  'sensor.pronote_simon_timetable_next_day') -}}
card_mod:
  style:
    .: |
      ha-card ha-markdown {
        padding:0px
      }
      ha-card ha-markdown.no-header {
        padding:0px
      }
    ha-markdown$: >
      {%- from 'pronote.jinja' import pronote_styles -%} {{-
      pronote_styles('sensor.pronote_simon_timetable_next_day') -}}

le bloc des devoirs :

type: markdown
content: >-
  {%- from 'pronote.jinja' import homework_markdown -%} 
  {{-homework_markdown('Pronote','sensor.pronote_simon_homework')-}}
card_mod:
  style:
    .: |
      ha-card ha-markdown {
        padding:0px
      }
      ha-card ha-markdown.no-header {
        padding:0px
      }
    ha-markdown$: >
      {%- from 'pronote.jinja' import pronote_styles -%} {{-
      pronote_styles('sensor.pronote_simon_homework') -}}

Les notes :

type: markdown
content: >-
  {%- from 'pronote.jinja' import grades_markdown -%} 
  {{-grades_markdown('Pronote','sensor.pronote_simon_grades')-}}
card_mod:
  style:
    .: |
      ha-card ha-markdown {
        padding:0px
      }
      ha-card ha-markdown.no-header {
        padding:0px
      }
    ha-markdown$: >
      {%- from 'pronote.jinja' import pronote_styles -%} {{-
      pronote_styles('sensor.pronote_simon_grades') -}}

Les absences :

type: markdown
content: >-
  {%- from 'pronote.jinja' import absences_markdown -%} 
  {{-absences_markdown('Pronote','sensor.pronote_simon_absences')-}}
card_mod:
  style:
    .: |
      ha-card ha-markdown {
        padding:0px
      }
      ha-card ha-markdown.no-header {
        padding:0px
      }
    ha-markdown$: >
      {%- from 'pronote.jinja' import pronote_styles -%} {{-
      pronote_styles('sensor.pronote_simon_absences') -}}

Voila ! j’espère que ça servira a ceux qui n’ont pas le design d @herveaurel et qui veulent qqchose de rapide

3 « J'aime »

Merci beaucoup; je vais tester cela.
Il y a besoin de creer ou installer qqchose de specifique pour la partie pronote.jinga? Hormis creer le rep custom_templates et pronote.jinga et coller ton code?

1 « J'aime »