merci @vingerha
J’ai corrigé aussi de mon coté (légèrement différemment) et j’ai mis à jour sur GitHub :
Et bien en fait ca serait possible en théorie mais il faudrait pouvoir mettre une 3eme balise différente pour le « modifié ».
Car vous aurez remarqué que je met un mark pour les cours standard et un span pour les cours annulés
Pourquoi car je ne peux pas ajouter un style à la balise pour faire :
<span class="normal">
ou <span class="annule">
Du coup, il faudrait trouver une 3eme balise html qui ne servent a rien pour gérer le modifié
@HollyFredD, Bravo ! c’est une super nouvelle ça !
pourrais-tu stp détailler en quelques point l’installation du script quand tu es sous HASS OS stp ?
Pour que je mette dans la doc pour tout ceux qui sont comme sur sur HASS OS
Merci d’avance
Voici le markdown du wiki que je me suis fait (il manque les étapes de créations des sensors, c’est du work in progress. Mais les étapes pour le script sont là)
Attention, j’ai vraiment pas mal bidouillé avant que ça ne « tombe en marche ». J’espère que sur une install « propre » ces étapes suffisent à rendre le script fonctionnel.
Je passe par un shell_command pour lancer le script, et j’execute de façon régulière (toutes les heures) ce shell_command via une time_based automation (non décris encore dans le doc)
Pronote
Configuration add-on SSH
Toute la configuration peut se faire en se connectant en SSH à HomeAssistant grâce à l’add-on suivant :
Dans l’onglet configuration, il faut penser à configurer le username
et password
Puis ajouter dans la section init_commands
la ligne suivante et bien penser à cliquer sur save
pip install pronepy
Cela aura pour effet d’installer le package pronotepy
au démarrage de HomeAssistant.
Pour vous connecter en SSH à votre HassOS via votre terminal préféré :
ssh identifiant_ssh_hassos@ip_hassos
Puis saisir votre mot de passe
Installation des scripts et librairie Python
Créer un répertoire /config/python_scripts
puis le sous-répertoire /config/python-scripts/local-packages
mkdir /config/python_scripts
mkdir /config/python_scripts/local-packages
Puis ajouter :
1/ Le script python pronote.py
via la commande dans le répertoire python-scripts
curl https://raw.githubusercontent.com/dathosim/Pronote2Homeassistant/main/pronote.py --outpout /config/python_scripts/pronote.py
2/ Les librairies nécessaires dans le répertoire local-packages
Il faut ensuite récupérer les packages pronotepy
qui est dans /usr/lib/pythonx.x/site-packages
(remplacer « x.x » par la version python installée chez vous, au moment de la rédaction de ce wiki j’ai la 3.10) et copier cette librairie dans le répertoire /config/python_scripts/local-packages
cp -R /usr/lib/python3.10/site-packages/pronotepy /config/python_scripts/local-packages/
Il faut maintenant, dans le script pronote.py
, récupéré plus tôt, préciser où se trouvent les « local-packages » (et donc pronotepy), pour cela il faut ajouter/modifier le code suivant tout en haut du fichier pronote.py
(si vous n’ajouter pas cela en haut du fichier, cela ne marchera pas)
Création des shell_commands pour automatiser l’exécution de script
Dans /config/devices/shell_commands.yaml
il faut ajouter :
pronote_update: python3 /config/python_scripts/pronote.py
pré-requis : il faut avoir la ligne suivante dans son configuration.yaml
shell_command: !include devices/shell_commands.yaml
Bonjour à tous,
Petit soucis et besoin d’aide du coup.
Pour se connecter, je passe par :
- https://cas.mon-ent-occitanie.fr/ ensuite
-
https://educonnect.education.gouv.fr/
je rentre les identifiants ELEVE (puisque j’ai que ça)
Et ensuite je suis redirigé vers :
https://0340034c.index-education.net/pronote/eleve…
Par conséquent, j’ai renseigné le fichier pronote.py :
prefix_url = « 0340034c »
type_compte = « eleve »
username=« user2mafille »
password=« password2mafille »
ent = None (pas compris cette variable)
Je un test avec le script seul mais ça ne parvient pas à se connecter j’ai l’impression.
root@hass:/usr/share/hassio/homeassistant/python_scripts# /usr/bin/python3 /usr/share/hassio/homeassistant/python_scripts/pronote.py
Erreur de connexion à Pronote (sans ENT) avec le compte élève - vérifier les paramètres
Traceback (most recent call last):
File "/usr/share/hassio/homeassistant/python_scripts/pronote.py", line 60, in <module>
if client.logged_in:
NameError: name 'client' is not defined
root@hass:/usr/share/hassio/homeassistant/python_scripts#
Merci
Bonsoir @noabeuh, (Benoît?)
En fait, tu te connecte via un cas (central authentification service) qui semble être celui de l’ent (espace numérique de travail) de l’occitannie
Du coup il faut que tu mettes la variable à 1
Mais aussi il faudrait vérifier que ce cas et cet ent est pris en charge par la lib pronotepy Que j’utilise dans cette intégration…
Bonjour @Dathosim, (Damien?)
Merci pour ton retour, Je crois que je ne suis pas le seul.
Je essayer de creuser.
Merci
@Dathosim : une idée ?
Sinon j’ai aussi ceci dans mes logs HA
Logger: homeassistant.helpers.template_entity
Source: helpers/template_entity.py:356
First occurred: 22:53:37 (8 occurrences)
Last logged: 22:53:37
TemplateError('UndefinedError: None has no element 2') while processing template 'Template("{{ state_attr('sensor.pronote_edt_lou_prochain_jour', 'edt_prochainjour')[2]['annulation'] }}")' for attribute '_state' in entity 'binary_sensor.pronote_edt_lou_prochain_jour_cours_2_annulation'
TemplateError('UndefinedError: None has no element 3') while processing template 'Template("{{ state_attr('sensor.pronote_edt_lou_prochain_jour', 'edt_prochainjour')[3]['annulation'] }}")' for attribute '_state' in entity 'binary_sensor.pronote_edt_lou_prochain_jour_cours_3_annulation'
TemplateError('UndefinedError: None has no element 4') while processing template 'Template("{{ state_attr('sensor.pronote_edt_lou_prochain_jour', 'edt_prochainjour')[4]['annulation'] }}")' for attribute '_state' in entity 'binary_sensor.pronote_edt_lou_prochain_jour_cours_4_annulation'
TemplateError('UndefinedError: None has no element 5') while processing template 'Template("{{ state_attr('sensor.pronote_edt_lou_prochain_jour', 'edt_prochainjour')[5]['annulation'] }}")' for attribute '_state' in entity 'binary_sensor.pronote_edt_lou_prochain_jour_cours_5_annulation'
TemplateError('UndefinedError: None has no element 6') while processing template 'Template("{{ state_attr('sensor.pronote_edt_lou_prochain_jour', 'edt_prochainjour')[6]['annulation'] }}")' for attribute '_state' in entity 'binary_sensor.pronote_edt_lou_prochain_jour_cours_6_annulation'
quelqu’un as une solution pour régler ce soucis ? il me semble avoir déjà vu des annuls et deplacement de cours donc ça doit fonctionner …
Hello, comment as tu rösolu ce point ? j’ai moi aussi une erreur comme tu avais si j’enlève les __ autour de file. Merci de ton aide ou de celui qui aura la réponse
J’ai commencé à travailler dessus.
J’ai créé un nouveau fichier json : pronote_last_notes_« +eleve_id+ ».json (vide au départ avec {})
Et modifié le fichier python comme ceci :
J’ai déplacé cette ligne tout en haut ou presque
location = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
Puis modifié la partie des notes
#Lecture notes déjà transmises (créer le fichier vide avec {} la première fois)
lastNotes = {}
with open(os.path.join(location, "../www/pronote_last_notes_"+eleve_id+".json")) as outfile:
lastNotes = json.load(outfile)
#Transformation des notes en Json
jsondata['note'] = []
jsondata['noteSensor'] = []
for grade in grades:
index_note += 1
if index_note == limit_note:
break
uniqid = ""
commentaire = ""
if grade.comment != '' :
commentaire = ' ('+grade.comment+')'
noteJson = {
'date': grade.date.strftime("%d/%m/%Y"),
'date_courte': grade.date.strftime("%d/%m"),
'cours': grade.subject.name+commentaire,
'note': grade.grade,
'sur': grade.out_of,
'note_sur': grade.grade+'\u00A0/\u00A0'+grade.out_of,
'coeff': grade.coefficient,
'moyenne_classe': grade.average,
'max': grade.max,
'min': grade.min,
'comment': grade.comment,
}
jsondata['note'].append(noteJson)
uniqid = grade.date.strftime("%d/%m/%Y")+grade.subject.name+commentaire+grade.grade
if uniqid not in lastNotes :
jsondata['noteSensor'].append(noteJson)
lastNotes[uniqid] = ""
Et à la fin :
with open(os.path.join(location, "../www/pronote_last_notes_"+eleve_id+".json"), "a") as outfile:
outfile.truncate(0)
json.dump(lastNotes, outfile, indent=4)
Et j’ai créé un nouveau sensor :
- platform: rest
name: pronote_sensor_note_camille
scan_interval: 10
json_attributes:
- noteSensor
value_template: |
{% if value_json.noteSensor.3 is defined %}
Camille a 4 nouvelles notes :
{{ value_json.noteSensor.0.cours }} : {{ value_json.noteSensor.0.note_sur }}, coefficient : {{ value_json.noteSensor.0.coeff }}, moyenne : {{ value_json.noteSensor.0.moyenne_classe }}, min : {{ value_json.noteSensor.0.min }}, max : {{ value_json.noteSensor.0.max }}
{{ value_json.noteSensor.1.cours }} : {{ value_json.noteSensor.1.note_sur }}, coefficient : {{ value_json.noteSensor.1.coeff }}, moyenne : {{ value_json.noteSensor.1.moyenne_classe }}, min : {{ value_json.noteSensor.1.min }}, max : {{ value_json.noteSensor.1.max }}
{{ value_json.noteSensor.2.cours }} : {{ value_json.noteSensor.2.note_sur }}, coefficient : {{ value_json.noteSensor.2.coeff }}, moyenne : {{ value_json.noteSensor.2.moyenne_classe }}, min : {{ value_json.noteSensor.2.min }}, max : {{ value_json.noteSensor.2.max }}
{{ value_json.noteSensor.3.cours }} : {{ value_json.noteSensor.3.note_sur }}, coefficient : {{ value_json.noteSensor.3.coeff }}, moyenne : {{ value_json.noteSensor.3.moyenne_classe }}, min : {{ value_json.noteSensor.3.min }}, max : {{ value_json.noteSensor.3.max }}
{% elif value_json.noteSensor.2 is defined %}
Camille a 3 nouvelles notes :
{{ value_json.noteSensor.0.cours }} : {{ value_json.noteSensor.0.note_sur }}, coefficient : {{ value_json.noteSensor.0.coeff }}, moyenne : {{ value_json.noteSensor.0.moyenne_classe }}, min : {{ value_json.noteSensor.0.min }}, max : {{ value_json.noteSensor.0.max }}
{{ value_json.noteSensor.1.cours }} : {{ value_json.noteSensor.1.note_sur }}, coefficient : {{ value_json.noteSensor.1.coeff }}, moyenne : {{ value_json.noteSensor.1.moyenne_classe }}, min : {{ value_json.noteSensor.1.min }}, max : {{ value_json.noteSensor.1.max }}
{{ value_json.noteSensor.2.cours }} : {{ value_json.noteSensor.2.note_sur }}, coefficient : {{ value_json.noteSensor.2.coeff }}, moyenne : {{ value_json.noteSensor.2.moyenne_classe }}, min : {{ value_json.noteSensor.2.min }}, max : {{ value_json.noteSensor.2.max }}
{% elif value_json.noteSensor.1 is defined %}
Camille a 2 nouvelles notes :
{{ value_json.noteSensor.0.cours }} : {{ value_json.noteSensor.0.note_sur }}, coefficient : {{ value_json.noteSensor.0.coeff }}, moyenne : {{ value_json.noteSensor.0.moyenne_classe }}, min : {{ value_json.noteSensor.0.min }}, max : {{ value_json.noteSensor.0.max }}
{{ value_json.noteSensor.1.cours }} : {{ value_json.noteSensor.1.note_sur }}, coefficient : {{ value_json.noteSensor.1.coeff }}, moyenne : {{ value_json.noteSensor.1.moyenne_classe }}, min : {{ value_json.noteSensor.1.min }}, max : {{ value_json.noteSensor.1.max }}
{% elif value_json.noteSensor.0 is defined %}
Camille a une nouvelle note :
{{ value_json.noteSensor.0.cours }} : {{ value_json.noteSensor.0.note_sur }}, coefficient : {{ value_json.noteSensor.0.coeff }}, moyenne : {{ value_json.noteSensor.0.moyenne_classe }}, min : {{ value_json.noteSensor.0.min }}, max : {{ value_json.noteSensor.0.max }}
{% else %}
None
{% endif %}
resource: 'pronote_camille.json'
Voilà comme ça je ne suis plus dérangé si le prof change une note d’un autre élève ce qui change la moyenne.
Et je suis prévenu s’il y a plusieurs notes à la fois ou si plusieurs notes dans la journée, je n’ai plus à chaque fois que la première.
Si vous voyez une solution pour avoir une meilleure écriture pour le sensor et gérer x notes, je prends
Pour nous qui utilisent « pronote » dans HomeAssistent, je voudrais bien vous attender sur le fait que le tout est possible que avec le top travail de la part des devs de pronotepy.
Sans leurs efforts il n’y avait pas une interface qui permets de gratuitement connecter avec des dizaines de CAS/ENT spécifiques.
Même si leur travail n’est pas fait pour gagner de l’argent…je pense qu’une petite geste sera bien apprécié.
@vingerha : tu as entièrement raison !
J’ai donc fait un geste ! (symbolique pour l’instant…)
Et ca me donne envie d’ouvrir la cagnotte pour mon intégration et reverser à pronotepy quand ça demande une correction/évolution de son côté
Salut.
j’aimerais que le sensor début de cours se mette à jours en cas d’annulation de cours.
est-ce possible ?
@jimsaye : la mise à jour du sensor « début de cours » en cas d’annulation est déjà prise en compte
(ou alors y’a un bug…)
@jimsaye : Désolé ! je viens de vérifier et j’avais fait une motification sur le script pour le gérer mais je ne l’avais jamais poussé la modification sur Github
Et pourtant j’avais poussé le Lovelace associé (encore plus grave)
Dans ton cas tu mets à jour le script avec celui que je viens de pousser et ça va marcher !
@Specnaz :
je viens de corriger le problème que tu as sur les 2 premiers sensor qui affichent « pas cours »
En fait, j’avais fait une évolution du script pour gérer (dans le script) l’heure de début qui tient compte des cours annulé (pour pas le faire dans le template - mais elle n’avait pas été poussé sur Github
Je viens de le faire
tu peux reprendre la dernière version du script pronote.py
voila le dernier commit
NB : le lovelace associé est déjà bon
Merci je vais regarder ça
Un grand merci à toi !
Dans le log j’ai encore celles là qui trainent :
Logger: homeassistant.helpers.template_entity
Source: helpers/template_entity.py:356
First occurred: 00:26:36 (12 occurrences)
Last logged: 00:26:36
Logger: homeassistant.helpers.template_entity
Source: helpers/template_entity.py:356
First occurred: 00:26:36 (12 occurrences)
Last logged: 00:26:36
TemplateError('UndefinedError: None has no element 4') while processing template 'Template("{{ state_attr('sensor.pronote_edt_lou_prochain_jour', 'edt_prochainjour')[4]['annulation'] }}")' for attribute '_state' in entity 'binary_sensor.pronote_edt_lou_prochain_jour_cours_4_annulation'
TemplateError('UndefinedError: None has no element 5') while processing template 'Template("{{ state_attr('sensor.pronote_edt_lou_prochain_jour', 'edt_prochainjour')[5]['annulation'] }}")' for attribute '_state' in entity 'binary_sensor.pronote_edt_lou_prochain_jour_cours_5_annulation'
TemplateError('UndefinedError: None has no element 6') while processing template 'Template("{{ state_attr('sensor.pronote_edt_lou_prochain_jour', 'edt_prochainjour')[6]['annulation'] }}")' for attribute '_state' in entity 'binary_sensor.pronote_edt_lou_prochain_jour_cours_6_annulation'
@Specnaz :
Ça en fait ça peut arriver et c’est normal
Pour la recherche des annulations, le system créé des sensors pour chaque heure de la journée de cours - mais si l’élève n’a que 3 heures de cours alors les derniers sensor son crée en erreur…
Il faudrait que je trouve un moyen plus clean…