将PRONOTE整合到您的家庭助理中

Pronote 的 是Index Education公司的出色应用,为大多数学校提供设备。

如果你不知道,走你的路,你不需要把它集成到你的家庭自动化中。

 

小心,这个Retex已经过时了,确实自2023年6月起。 整合 整合 (谢谢你来了。 德尔菲基) 注意下面描述的一切。 我HA中的某些链接或文件可能不再匹配此文本的其余部分。 当然,我建议使用集成。

以下是最新的Retex: 我正在研究Pronote的HA卡。

 

这种整合基于Dathosim脚本(非常感谢!!)
https://github.com/dathosim/Pronote2Homeassistant

我修改了几行代码,以适应我的使用或适应新的HA标准(平台: 模板/传感器 : 成为模板:/传感器(例如)

安装 PronotePy 库

它是一个开源的python库: Pronotepy 的

要安装此库,请在命令行上运行:

PIP 安装 Pronotepy

或使用最新版本(不推荐):

https://github.com/bain3/pronotepy/archive/refs/heads/master.zip。

不时地,你必须考虑投一小枪:

PIP install-upgrade pronotepy

安装 Dathosim python 脚本

转到 HA 的 /config 文件夹,并创建一个可以调用的新文件夹。 Python _ 脚本 这将包含您的自定义脚本。

在这个 /config/python_scripts 文件夹中,放置文件 Pronote.py 的 以及 配置 .ini 分布情况 Pronote2Homeassistant 的.

配置 Python 脚本

有必要编辑文件 配置 .ini 并添加具体信息。

特殊配置 Sigalou

我发现有问题与ENT中庭_sud。 出于某种原因,我不得不更改Python脚本。 我将把这个信息传递给达索西姆,看看会发生什么。 我在这里给出我的修改,它们可能是有用的。 我修改了第57行。

# 客户端 =(pronotepy.ParentClient if type _account == 'parent' else pronotepy.Client)(url, username, password, ent)client =(pronotepy.ParentClient if type _account =='parent' else pronotepy.Client)('https://0xx0xxxx.index-education.net/pronote/mobile.parent.html', username = 'xxxxx', password='yyyy', ent=atrium _sud)
  • 为了获得URL,我继续注释在闪烁QR码时查看提议的URL。
  • 对于xxxx,你必须输入用户名和yyyy的密码。

有了这个,剧本就完美了。 如果你比我幸运一点,一切都应该与你的凭据完成配置文件提供的脚本一起工作。

启动脚本

这是你必须交叉手指的地方,以确保一切顺利。

您必须连接到 SSH 命令行,转到以前使用以下之一创建的 phyton_scripts 文件夹:

CD /config/python_scripts

CD /usr/share/hassio/homeassistant/python_scripts/ (在Dathosim)

然后运行脚本:

python3 pronote.py

如果没有什么特别的事情发生,没有错误消息是没问题,脚本运行得很好。

当一切顺利时,一个文件 pronote_prenomenfant.json 在 /config/www 中创建

该文件将被HA查询以检索信息。

自动启动脚本

有经典的方法,可能是Linux纯粹主义者的首选,即添加一个crontab。 

* * * * * * * /usr/bin/python3 /usr/share/hassio/hassio/python_scripts/pronote.py > /tmp/pronote.log 2>&1

或取决于您的系统:

* * * * * * * * /config/python_scripts/pronote.py > /tmp/pronote.log 2>&1

这不是我选择的方法,我想用100。% Home Assistant,在我的学习阶段,我研究了如何启动cron以及如何启动Python脚本。

添加启动 shell 命令的自动化

哈称之为计时器模式

我在config.yaml文件中添加了一个_command.yaml shell文件 

在这个 _command.yaml shell 文件中,我添加:

update_pronote : python3 /config/python_scripts/pronote。

在自动化中,我添加了一个新的自动化,将启动脚本 update_pronote。 

触发器是每10分钟触发一次

操作是一个 shell 命令,启动 update_pronote

在YAML模式下,这给出了:

每10分钟,我就会生成一个文件/config/www/pronote_enfant.json。

恢复数据

然后,HA将启动REST查询以获取数据。

Dathosim给出了所有发射请求,他们正在:
https://github.com/dathosim/Pronote2Homeassistant/blob/main/configuration.yaml

当然有必要更换:

  • DEMO 的 以孩子的名字命名
  • 192.168.XX.XX HA的IP地址

我修改了一些语法或传感器(模板),查看我的文件。 模板.yaml

创建 Pronote 屏幕

最后一步是在地图上显示以pronote…开始的传感器,以制作一个漂亮的屏幕。

以下是Dathosim屏幕的代码: https://github.com/dathosim/Pronote2Homeassistant/blob/main/lovelace.yaml

以下是我的代码:

类型 : 水平堆栈列: 2 平方: 假卡片: 类型: 垂直堆栈卡: 类型: Markdown 内容: 《 | -
          <div>今天的时间表 </div>
          <table>
              <tbody>
                  {%在 state.sensor.pronote_edt_coralie_today.attributes.edt_today.edt_today%}
                  <tr style="background-color:#FF0000"><td>
                      {%- if state_attr('sensor.pronote_edt_coralie_today', 'edt_today')[loop.index-1]['cancellation'] == false -%}
                          <mark>
                          {State _attr('sensor.pronote_edt_coralie_today', 'edt_today')[loop.index-1]['hour']}}
                          </mark>
                      {%不然 - 否则 -%}
                          <span>
                          {State _attr('sensor.pronote_edt_coralie_today', 'edt_today')[loop.index-1]['hour']}}
                          </span>
                      {% Endif 的 %}</td>
                      <td>{State _attr('sensor.pronote_edt_coralie_today', 'edt_today')[loop.index-1]['_fin time]}</td>
                      <td>
                      {State _attr('sensor.pronote_edt_coralie_today', 'edt_today')[loop.index-1]['course']} {{state _attr('sensor.pronote_edt_coralie_today')} {loop.index-1]['course']} {State _attr('sensor.pronote_edt_coralie_today')} {loop.index-1]['course']} {State _attr('sensor.pronote_edt_coralie_today')% 如果没有 state_attr('sensor.pronote_edt_coralie_today', 'edt_today')[loop.index-1]['status'] == None %}<span>{State _attr('sensor.pronote_edt_coralie_today', 'edt_today')[loop.index-1]['status']}}</span>
                      {% Endif 的 %}</td>
                      <td>{State _attr('sensor.pronote_edt_coralie_today', 'edt_today')[loop.index-1]['room']}</td>
                  </tr>
                  {% 结束 于 %}
            </tbody>
          </table>
        Card_mod : 风格: .: | ha-card ha-markdown { padding:0px } ha-card ha-markdown.no-header { padding:0px } ha-markdown$: | div { background-color:rgb(100,100); 填充 : 12px 12px; 颜色:白色; font-weight:normal; font-size:1.2em; border-top-left-radius: 5px; Border-top-right-radius: 5px; } table{ border-collapse : 崩溃; 字体大小 : 0.9em; font-family : 机器人; 宽度 : 100%; 提纲: 0px 固体 #393c3d; margin-top:5px; } 注释 { text-align: 中心; 字体重量 : 大胆; 字体大小 : 1.2em; } TD {padding: 5px 10px 5px 10px 文本对齐: 左; 边界底部: 0px 固体 #1c2020; } TR { border-bottom: 0px 固体 #1c2020; } TR:nth-of-type(even){ background-color: RGB(54、54、54、0.3); } TR:last-of-type { border-bottom: 透明; }* 标记 { 背景: #009767; 颜色 : #222627; Border-radius: 5px; 填充 : 5px; } span {背景: #EC4B34; 颜色 : #222627; Border-radius: 5px; 填充 : 5px; } span {padding: 5px; } TR:nth-child(n+2)&gt; td:nth-child(2){ text-align: 左; 类型: Markdown 内容: &gt;-
          <div>时间使用: {State _attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[0]['date']}}</div>

          <table>
              <tbody>
                  {%在 state.sensor.pronote_edt_coralie_nextday.attributes.edt_next_next_next_nextday%}
                  <tr style="background-color:#FF0000"><td>
                      {%- if state_attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[loop.index-1]['cancellation'] == false -%}
                          <mark>
                          {State _attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[loop.index-1]['hour']}
                          </mark>
                      {%不然 - 否则 -%}
                          <span>
                          {State _attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[loop.index-1]['hour']}
                          </span>
                      {% Endif 的 %}</td>
                      <td>{State _attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[loop.index-1]['_fin time]}</td>
                      <td>
                      {State _attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[loop.index-1]['course']} {state _attr('sensor.pronote_edt_coralie_nex_nextday')}% 如果不是 state_attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[loop.index-1]['status'] == None %}<span>{State _attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[loop.index-1]['status']}</span>
                      {% Endif 的 %}</td>
                      <td>{State _attr('sensor.pronote_edt_coralie_nextday', 'edt_nextday')[loop.index-1]['room']}</td>
                  </tr>
                  {% 结束 于 %}
            </tbody>
          </table>
        Card_mod : 风格: .: | ha-card ha-markdown { padding:0px } ha-card ha-markdown.no-header { padding:0px } ha-markdown$: | div { background-color:rgb(100,100); 填充 : 12px 12px; 颜色:白色; font-weight:normal; font-size:1.2em; border-top-left-radius: 5px; Border-top-right-radius: 5px; } table{ border-collapse : 崩溃; 字体大小 : 0.9em; font-family : 机器人; 宽度 : 100%; 提纲: 0px 固体 #393c3d; margin-top:5px; } 注释 { text-align: 中心; 字体重量 : 大胆; 字体大小 : 1.2em; } TD {padding: 5px 10px 5px 10px 文本对齐: 左; 边界底部: 0px 固体 #1c2020; } TR { border-bottom: 0px 固体 #1c2020; } TR:nth-of-type(even){ background-color: RGB(54、54、54、0.3); } TR:last-of-type { border-bottom: 透明; }* 标记 { 背景: #009767; 颜色 : #222627; Border-radius: 5px; 填充 : 5px; } span {背景: #EC4B34; 颜色 : #222627; Border-radius: 5px; 填充 : 5px; } span {padding: 5px; } TR:nth-child(n+2)&gt; td:nth-child(2){ text-align: 左; 类型: Markdown 内容: 《 | -
      <div>职责 职责</div>
      <table>
          <tbody>
              {%在 state.sensor.pronote_devoir_coralie.attributes.devoir.devoir%}
              <tr>
                  <td>
                  {%- if state_attr('sensor.pronote_devoir_coralie', 'duty')[loop.index-1]['done'] == true -%}
                      <mark>
                      {State _attr('sensor.pronote_devoir _coralie', 'duty')[loop.index-1]['date']}
                      </mark>
                  {%不然 - 否则 -%}
                      <span>
                      {State _attr('sensor.pronote_devoir _coralie', 'duty')[loop.index-1]['date']}
                      </span>
                  {% Endif 的 %}</td>              
                  <td>{State _attr('sensor.pronote_devoir _coralie', 'duty')[loop.index-1]['title']}</td>
                  <td>{State _attr('sensor.pronote_devoir _coralie', 'duty')[loop.index-1]['description']}</td>
              </tr>
              {% 结束 于 %}
        </tbody>
      </table>
    Card_mod : 风格: .: | ha-card ha-markdown { padding:0px } ha-card ha-markdown.no-header { padding:0px } ha-markdown$: | h1 { font-weight: 正常; 字体大小 : 24px; div { background-color:rgb(100,100,100); 填充 : 12px 12px; 颜色:白色; font-weight:normal; font-size:1.2em; border-top-left-radius: 5px; Border-top-right-radius: 5px; } table{ border-collapse : 崩溃; 字体大小 : 0.9em; font-family : 机器人; 宽度 : 汽车; 提纲: 0px 固体 #393c3d; 保证金顶 : 10px; } 注释 { text-align: 中心; 字体重量 : 大胆; 字体大小 : 1.2em; } TD {padding: 5px 5px 5px 5px 文本对齐: 左; 边界底部: 0px 固体 #1c2020; } TR { border-bottom: 0px 固体 #1c2020; } TR:nth-of-type(even){ background-color: RGB(54、54、54、0.3); } TR:last-of-type { border-bottom: 透明; } Mark {背景: #009767; 颜色 : #222627; Border-radius: 5px; 填充 : 5px; } span {背景: #EC4B34; 颜色 : #222627; Border-radius: 5px; 填充 : 5px; } span {padding: 5px; } TR:nth-child(n+2)&gt; td:nth-child(2){ text-align: 左; 类型: Markdown 内容: 《 | -
      <div>评价</div>
      <table width='100%'>
        <tbody>
        {%用于 state.sensor.pronote_eval_coralie.attributes.evaluation 中的 attr%} {% 如果 loop.index < 40  %}
        <tr>
        <td width='10%'>{attr['date _courte']}</td>
        <td width='70%'>{attr['eval]}</td>
        <td width='20%'>
        {%f或 attr2 in attr.acquisitions%{\displaystyle }% 如果 attr2['acquisition _level'] == "A+" %{\displaystyle }% Elif attr2['acquisition _level'] = "A" %{\displaystyle }% Elif attr2['acquisition _level'] = "B+" %} ⚪ + {% Elif attr2['acquisition _level'] = "B" %} ⚪ {% Elif attr2['acquisition _level'] = "C+" %\r\n\n\n}% Elif attr2['acquisition _level'] = "C" %{\displaystyle }% Elif attr2['acquisition _level'] = "D+" %} ⚪ + {% Elif attr2['acquisition _level'] = "D" %} ⚪ {% Elif attr2['acquisition _level'] = "E" %{\displaystyle }% 其他 其它 %{ attr2['acquisition _level']} { attr2['acquisition _level']} {{ attr2['acquisition _level']} {{ attr2['acquisition _level']} {% Endif 的 %} {% 结束 于 %}
        </td>
        </tr>
        {% Endif 的 %} {% 结束 于 %}
      </tbody>
      </table>
    Card_mod : 风格: .: | ha-card ha-markdown { padding:0px } ha-card ha-markdown.no-header { padding:0px } ha-markdown$: | h1 { font-weight: 正常; 字体大小 : 24px; div { background-color:rgb(100,100,100); 填充 : 12px 12px; 颜色:白色; font-weight:normal; font-size:1.2em; border-top-left-radius: 5px; Border-top-right-radius: 5px; } table{ border-collapse : 崩溃; 字体大小 : 0.9em; font-family : 机器人; 宽度 : 汽车; 提纲: 0px 固体 #393c3d; 保证金顶 : 10px; } 注释 { text-align: 中心; 字体重量 : 大胆; 字体大小 : 1.2em; } TD {padding: 5px 5px 5px 5px 文本对齐: 左; 边界底部: 0px 固体 #1c2020; } TR { border-bottom: 0px 固体 #1c2020; } TR:nth-of-type(even){ background-color: RGB(54、54、54、0.3); } TR:last-of-type { border-bottom: 透明; } Mark {背景: #009767; 颜色 : #222627; Border-radius: 10px; 填充 : 5px; } span {背景: #EC4B34; 颜色 : #222627; Border-radius: 10px; 填充 : 5px; } span {padding: 5px; } TR:nth-child(n+2)&gt; td:nth-child(2){ text-align: 左; }

请注意:

我改变了点的颜色,因为通信对我女儿成立的标注的配置不好。 为了绿色,我放了一颗绿色的心。

奖金 奖励

添加更新地图

为了将更新从每10分钟减少到每4小时,我在上面的图像中添加了地图。

因此,我们有自上次更新以来的延迟,如果我们想要立即更新,我们按下它并开始执行。

卡片代码:

类型: custom:auto-entities 卡 : 类型 : 实体过滤 : 包括: Entent_id : Automation.mise _a _jour _pronote 选项: 次要_info : 最后触发

将更新限制为工作日

在将更新时间从10分钟切换到4小时后,我试图将此更新限制为工作日。

有一个集成创建了一个二进制_sensor,它为我们提供了这些信息: 工作 日 工作 日.

我没有进入它的安装,文档是拱形的简单。

我刚刚在自动化中添加了一个条件:

以下是完整的自动化代码:

化名 : 更新的注释说明: 触发器: 平台: Time_pattern 小时 : /4条件: 类型: is_on 条件 : 设备 _id : 64bbc75616d4864596e1fd861c865904 entity_id: binary_sensor.workday 域: binary_sensor 操作 : 服务: shell_command.update_pronote 数据: {} 模式: 单 人 单

编辑 编辑 : 一 个 新 教程 允许您仅在工作日和校外假期触发Pronote更新。

链接 Pronote 并触发 Alexa 闹钟

这将是下一步

但我会在周日安排这个 明天开课时间