节省电动汽车的Wallbox充电会话

我查看从Wallbox集成中检索到的数据

以下是对数据的一个小概述,将允许我从传感器.wallbox _charges中的最后一次充电会话中保存数据。

我已经在这个 Retex 上描述了所有 Wallbox 集成实体:

触发 器

所以我要用 传感器.wallbox_portal_status_description 作为记录最后一次充电会话的触发器。

因此,我将使用状态的更改从充电到其他东西来触发录制。

数据 数据

  • Wallbox Portal 添加 能源 (sensor.wallbox_portal_added_energy)将给我在最后一次充电时添加到汽车电池中的kWh数量。
  • Wallbox 门户 添加 范围 (sensor.wallbox_portal_added_range)将给我一个增加的km数量的估计,这可以通过最后一次加载来实现。
  • Wallbox 门户 能源 价格 (sensor.wallbox_portal_energy_price)将给我每千瓦时的价格,我将用它来计算负载的成本。

我添加了将存储负载数据的集成

我找到了整合 哈斯变量, 绝对棒极了 多亏了 安卡玛 市 以及 Snuffy2 的 这项工作和后续工作。

它允许你创建一个没有连接到任何东西(不是模板)的传感器。 该传感器即使在重新启动HA时也保持其值。 这正是我所需要的,而不使用外部数据备份模式(json,其他…数据库)。

新传感器称为: 传感器.wallbox _ 充电

我添加了一个传感器来检测负载的开始

事实上,集成并没有给我最后一次负载的时间和开始日期。 为了计算持续时间,我发现有这些信息很有趣。 所以我要创造它。

我依靠 sensor.wallbox _portal _added _range 实体,我会获取充电的开始时间/日期(因此它在过去 5 小时内的最低值)

在我的传感器.yaml文件中,我添加了这个实体:

平台: 统计名称: "Wallbox Portal Added Range Min" entity_id: Sensor.wallbox _portal _added _range state _characteristic: DateTime _value _min max_age: 小时 : 5  

这将为我创建实体: 传感器.wallbox _portal _added_range _min

我将使用这个实体来记录充电的开始并计算充电时间。

我添加了将保存数据的自动化。

这是相当复杂的,我想它是简单的,我会一步一步地解释它。

这里是完整的代码第一。

化名 : 保存加载会话描述 : 触发器: 平台: 国家实体_id: Sensor.wallbox_portal_status_description: 收费到: null别名: 当充电结束条件时: [] 行动: 化名: > - 初始化第一个conso,仅启动一次(通过禁用其他操作),然后禁用服务: variable.update _sensor 数据: 替换_attributes : 真实值: Init 属性 : 会话加载: null 目标: entity_id : 启用 Sensor.wallbox _charge : False - 服务: variable.update _sensor 数据: 替换_attributes : 真实值: >- { as_timestamp(states('sensor.wallbox _portal _added_range _min'))| int Ω timestamp _custom('')%d/%m/%Y 位 %H:%M:%s', true)} 属性: 会话加载: > {% 设置会话充电 = {'consumption': 2.14 『成本』: 0.43、『持续时间』: "00:27","开始": "19/09/2023 20:36","结束": "21:03","km": 17、"saved_at": 1695150359} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 23.29 『成本』: 4.66『持续时间』: "04:19","开始": "21/09/2023 21:06","结束": "01:25","km": 192 "saved_at": 1695323159} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 7.68『成本』: 1.54、『持续时间』: "01:23","开始": "22/09/2023 08:45","结束": "10:08","km": 63、"saved_at": 1695409559} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 23.8、『成本』: 4.76、『持续时间』: "04:26","开始": "23/09/2023 16:57","结束": "21:23","km": 第196章 "saved_at": 1695495959} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 23.64『成本』: 4.73、『持续时间』: "04:05","开始": "26/09/2023 20:59","结束": "01:04","km": 第195章 "saved_at": 1695755159} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 24.04『成本』: 4.81、『持续时间』: "05:17","开始": 2023年9月28日 21:21,"结束": "02:38","km": 第198章 "saved_at": 1695927959} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 17.3、『成本』: 3.46、『持续时间』: "03:51","开始": "30/09/2023 21:31","结束": 01:22,"km": 143 "saved_at": 1696100759} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 22.18 『成本』: 4.44、『持续时间』: "04:25","开始": "03/10/2023 20:43","结束": "01:08","km": 第183章 "saved_at": 1696359959} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 23.86『成本』: 4.77、『持续时间』: "05:26","开始": "05/10/2023 21:03","结束": "02:29","km": 第197章 "saved_at": 1696532759} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 23.43 『成本』: 4.69、『持续时间』: "05:07","开始": "07/10/2023 20:34","结束": "01:41","km": 第193章 "saved_at": 1696705559} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 23.32『成本』: 4.66『持续时间』: "04:40","开始": "2023年10月10日 20:57","结束": "04:40","km": 192 "saved_at": 1696964759} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 25.19 『成本』: 5.04『持续时间』: "04:39","开始": "12/10/2023 19:53","结束": "00:32","km": 第208章 "saved_at": 1697137559} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 8.61『成本』: 1.72、『持续时间』: "01:32","开始": "13/10/2023 21:05","结束": "22:37","km": 71、"saved_at": 1697223959} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 27.76『成本』: 5.55『持续时间』: "04:46","开始": "16/10/2023 02:11","结束": "06:57","km": 231 "saved_at": 1697474976} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 24.18 『成本』: 4.84、『持续时间』: "04:12","开始": "18/10/2023 02:11","结束": "06:23","km": 201 "saved_at": 1697657509} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 20.17『成本』: 4.03、『持续时间』: "03:38","开始": '19/10/2023 02:11', 'end': "05:50","km": 第168章 "saved_at": 1697688628} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 23.08『成本』: 4.62、『持续时间』: "04:13","开始": "21/10/2023 02:12","结束": "06:25","km": 192 "saved_at": 1697867735} %{ sessionload } { sessionload },{% 设置会话充电 = {'consumption': 12.19 『成本』: 2.44、『持续时间』: "03:21","开始": 2023年10月22日02:13,"结束": "05:34","km": 101、"saved_at": 1697946854} %}{ sessionload }} 目标: entity_id : 启用 Sensor.wallbox _charge : 假别名 : > - 初始化第一个 conso,仅启动一次(通过禁用其他操作),然后禁用 - 服务: variable.update _sensor 数据: 替换_attributes : 真实值: >- { as_timestamp(states('sensor.wallbox _portal _added_range _min'))| int Ω timestamp _custom('')%d/%m/%Y 位 %H:%M:%s', true)} 属性: 会话加载: >- {% 设置 diff_seconds = now().timestamp()- state.sensor.wallbox _portal _added _range _min.state | as_timestamp %} {% 设置小时 =(diff _seconds / 3600)| int %} {% 设置分钟 =((diff_seconds) % 3600)/ 60)| int %} {% 设置会话收费 = {'consumption': States('sensor.wallbox _portal _added _energy')| float θ round(2), 'cost': (States('sensor.wallbox _portal _energy _price')| float * state('sensor.wallbox _portal _added _energy')θ float round(2), 'duration': 》d:d' | 格式(小时,分钟),'开始': as_timestamp(states('sensor.wallbox_portal_added_range_min'))| int | timestamp_custom('')%d/%m/%Y 位 %H:%M', true, 'end': now().strftime(')%H:%)"km": State('sensor.wallbox _portal _added _range')| int, 'saved_at': now().timestamp()| int } %} {% 如果 state_attr('sensor.wallbox _charges', 'sessionscharge')不是没有 %{ state_attr('sensor.wallbox _charges', 'sessionscharge')}, { sessioncharge } { sessioncharge } { sessioncharge } {% 其他 其它 %} { sessionload }, { sessionload } { sessionload } { sessionload } {% Endif 的 %目标: entity_id : 启用 Sensor.wallbox _charge : 真实别名: 保存刚刚结束模式的加载会话 : 单 人 单

 

部分解释

  • 触发器: 这是当负载完成。
  • 行动1(默认禁用)只有在考虑禁用其他两个动作时才会被激活,它是在记录数据的实体后初始化为'null'。
  • 行动2(默认禁用)在考虑禁用其他两个动作时,应该只激活一次,这是为了初始化一些先前的数据。 事实上,自从购买汽车以来,我不想丢失充电数据,所以我把它存储在那里。 
  • 动作3(默认激活)是计算和记录负载数据的动作。

触发码的解释 

此触发器基于Home Assistant的『状态』平台。 它监视特定实体的状态,在这种情况下,'sensor.wallbox _portal _status _description'。 具体来说,它被配置为在该实体的状态发生变化时做出反应。 配置细节如下:

实体_id: 它指定了被监控状态的实体。 在这种情况下,它是 'sensor.wallbox _portal _status _description'。 可以通过提供列表形式的实体列表来监控多个实体。 然而,在这个例子中,只有一个实体被监控。

-"来自: 充电 : 这意味着触发器在"sensor.wallbox_portal_status _description"为"Charging"时做出反应。 这是触发自动化的一个条件。 触发器只有在前一个状态是『充电』时才会反应。

至: null : 这意味着当'sensor.wallbox_portal_status _description'的当前状态从"Charging"更改为任何其他状态时,触发器会做出反应,包括"null"。 这是触发自动化的新条件。 当状态从充电变为任何其他状态时,触发器会做出反应。

别名: 当负载结束时 : 这是触发器的别名,这个名字让你更容易识别它。 在这种情况下,它只是表明当负载结束时将触发自动化。

总之,每当'sensor.wallbox_portal_status_description'的状态从"充电"变为任何其他状态时,这种自动化就会被触发,这意味着它被设计成在电动汽车负载结束时做出反应。

行动1的解释 

此操作旨在使用 Home Assistant 的"variable.update _sensor _sensor"服务初始化名为"sensor.wallbox _charges"的传感器的首次消耗(充电)。 以下是对行动每个组成部分的详细解释:

'alias': 它只是行动的名称或描述,使其更容易理解。 在这种情况下,它表明此操作旨在初始化第一次消费,并且应该只执行一次。 它还建议在其执行后禁用进一步行动。

服务: variable.update_sensor : 此行指定用于执行操作的服务。 variable.update _sensor 服务用于更新或初始化实体的属性(在本例中,是 'sensor.wallbox _charges')。

『数据』: 本节包含要与服务一起发送的数据。 在这种情况下:
替换 _attributes : 是真的: 这表明现有实体的属性需要被新数据所取代。 如果"替换_attributes"设置为"true",则"sensor.wallbox _charges"的现有属性将被新数据替换。

- 值 : Init': 这表示要分配给'sensor.wallbox _charges'的'会话负载'属性的值。 在这种情况下,值"INIT"被分配。

属性: 会话加载: null : 此行指示'sensor.wallbox_charges'的'会话负载'属性必须初始化为'null'。

『目标』: 它指定目标实体,即更新属性的实体。 在这种情况下,目标实体是 sensor.wallbox _charges。

启用: 是真的: 这表明此操作已启用并可以执行。

总之,此操作用于初始化'sensor.wallbox_charges'实体的'会话负载'属性,其值为'null',使用variable.update _sensor服务。 它仅执行一次以执行此初始化,然后建议禁用此操作。 这对于在自动化或实体中开始使用特定的初始值可能是有用的。

行动2的解释

此操作旨在使用一系列预先存在的加载会话数据初始化名为"sensor.wallbox _charges"的实体的"会话"属性。 以下是对动作每个元素的详细解释:

服务: variable.update_sensor : 这是用于在 Home Assistant 中更新或初始化实体属性的服务。

『数据』: 本节包含要与服务一起发送的数据。 在这种情况下:
替换 _attributes : 是真的: 这表明传感器.wallbox _charges实体的现有属性将被新数据所取代。

『价值』: 此部分用于定义 sensor.wallbox _charges 实体的 sessionload 属性的值。 该值是使用 Jinja2 模型动态生成的。 它使用第一个充电会话的时间戳(即'sensor.wallbox _portal _added _range _min')来获取日期和时间,然后将其格式化为"day/month/year hour:minute:second"。 这意味着值『会话负载』将随着第一次充电会话的日期和时间初始化。

-『属性』: 这是定义每个充电会话的数据的地方。 每个加载会话都使用 Jinja2 模板以特定格式定义。 这些收费会话由逗号分开。

『目标』: 它指定目标实体,即更新属性的实体。 在这种情况下,目标实体是 sensor.wallbox _charges。

启用: 是真的: 这表明此操作已启用并可以执行。

此操作的目的是使用来自加载会话的模拟数据初始化 'sensor.wallbox _charges' 的'会话负载'属性。 这可以用于测试或从虚构的负载数据开始。 初始化后,建议禁用此操作,如别名所示,因为它不需要重复。

行动3:主要行动

此操作旨在更新"sensor.wallbox _charges"实体的"会话"属性,使用刚刚结束的加载会话中的数据。 以下是对动作每个元素的详细解释:

服务: variable.update_sensor : 这是用于在 Home Assistant 中更新或初始化实体属性的服务。

『数据』: 本节包含要与服务一起发送的数据。 在这种情况下:
替换 _attributes : 是真的: 这表明传感器.wallbox _charges实体的现有属性将被新数据所取代。

『价值』: 此部分用于定义 sensor.wallbox _charges 实体的 sessionload 属性的值。 该值是使用 Jinja2 模型动态生成的。 它包括:
使用timestamp_custom函数将'sensor.wallbox_portal_added_range_min'的时间戳转换为特定的日期和时间格式。

-『属性』: 这是定义加载会话数据的地方。 这些数据由各种实体计算,特别是'sensor.wallbox _portal _added _energy','sensor.wallbox _portal _energy _price','sensor.wallbox _portal _added _rangemin','sensor.wallbox _portal _added _range',以及当前时间戳(通过 'now()获取')。 数据应包括充电时段的消耗、成本、持续时间、起始、结束、公里数和时间戳。

持续时间是通过从当前时间戳(以秒表示)中减去充电会话的开始时间戳来计算的。 然后,这些秒被转换成小时和分钟。

在 节 中 {% 如果… %}",代码检查"sensor.wallbox _charges"实体的"会话负载"属性是否已经定义。 如果是这种情况,则应保留现有数据。 否则,将添加新的加载会话数据。

『目标』: 它指定目标实体,即更新属性的实体。 在这种情况下,目标实体是 sensor.wallbox _charges。

启用: 是真的: 这表明此操作已启用并可以执行。

此操作的目的是记录刚刚在"sensor.wallbox _charges"实体的"会话负载"属性中结束的每个加载会话的数据。 这跟踪执行的每个充电会话。

 

结果 , 结果

因此,在负载的每一端,都会向 sensor.wallbox _charges 实体添加一个新记录。

其内容如下:

 

添加显示所有充电会话的地图

<div>收费会议</div> 
上次更新 : { state_attr('sensor.sessions_de _charge','updated_at')} <br><br>
{% 设置项目 = state_attr('sensor.wallbox _charges', 'sessionscharge') %}
<table width='100%'>
<tbody>
{% for i in range(0, items | count, 1) %}
<tr>
<td>{{ items[i].start } 到 {{ item[i].fin } }({{{ item[i].duration }})</td>
<td>{{ items[i].consumption } kWh</td>
<td>+{{ items[i].km } 公里</td>
<td>{{ item[i].cost } 欧元</td>
</tr>

{% 结束 于 %}
</tbody>
</table>

添加按年、月、周显示摘要的地图

类型 : Markdown 内容: &gt;-
  <div><h1>收费会议</div>  {%- 设置默认_language = 'en' %最新更新: { state_attr('sensor.wallbox _charges','updated _at')} <br><br>


  {% 设置项目 = state_attr('sensor.wallbox _charges', 'sessionscharge') %} {% 设置 septjours = now()- timedelta(days=7) %} {% 设置 power_semaine = namespace(value=0) %} {% 设置 cout_semaine = namespace(value=0) %} {% 设置 unmois = now()- timedelta(days=30) %} {% 设置 power_months = namespace(value=0) %} {% 设置 cout_mois = namespace(value=0) %} {% 设置uneannee = now()- timedelta(days=365) %} {% 设置 power_annee = namespace(value=0) %} {% 设置 cout_annee = namespace(value=0) %} {% for i in range(0, items | count, 1) %} {% 如果 items[i].saved_at | int &gt;= as_timestamp(uneannee) %} {% 设置 power_annee.value = power_annee.value + items[i].consumption %} {% 设置 cout_annee.value = cout_annee.value + items[i]。 %} {% 如果 items[i].saved_at | int &gt;= as_timestamp(unmonth) %} {% 设置 power_mois.value = power_mois.value + items[i].consumption %} {% 设置 cout_mois.value = cout_mois.value + items[i]。 %} {% 如果 items[i].saved_at | int &gt;= as_timestamp(sevendays) %} {% 设置 power_semaine.value = power_semaine.value + items[i].consumption %} {% 设置 cout_semaine.value = cout_semaine.value + items[i]。 %} {% Endif 的 %} {% Endif 的 %} {% Endif 的 %} {% 结束 于 %}

  </ha-alert> <ha-alert alert-type="info" title="上个月: { { power _mois.value | int }} kWh - { { cost _mois.value θ float Round(2)}} 欧元"></ha-alert> <ha-alert alert-type="info" title="去年: {{ power_annee.value | int }} kWh - {{{ cout _annee.value θ float θ round(2)}} 欧元"></ha-alert>


  <br> 


  {% 设置项目 = state_attr('sensor.wallbox _charges', 'sessionscharge') %} {% 设置 septjours = now()- timedelta(days=7) %}

  <table width='100%'> <tbody>  {% for i in range(0, items | count, 1) %} {% 如果 items[i].saved_at | int &gt;= as_timestamp(sevendays) %} {% 设置 datetime _obj = strptime(items[i].start, '%d/%m/%Y 位 %H:%M')) %}

  <tr> <td><h5>{{{items[i].start } {{ items[i].fin } }({{{ items[i].duration }})</td> <td>{{ items[i].consumption } kWh</td> <td>+{{ items[i].km } 公里</td> <td>{{ item[i].cost } 欧元</td> </tr> {% Endif 的 %} {% 结束 于 %} </tbody> </table>
    <ha-alert alert-type="success" title="上周: { { power_semaine.value | int}} kWh - { cost_semaine.value θ round(2)} €">    
风格: .: | ha-card { margin: 0px 0px 0px 0px; Box-shadow : 无; }ha-markdown : $: | h5 { font-size: 15px! 重要 字体重量 : 正常!重要 填充 : 0px 0px 0px 8px! 边框左: 3px 固态 #429f46; }

 

奖金 : 将数据保存到CSV文件

为了将来使用(并且在出现故障时不会丢失数据),我决定在没有CSV文件的情况下保存每个加载会话。 在每次会议中,添加一条线。

这就是我如何意识到这一点。

我添加了一个传感器『文件』,对应于CSV文件。

我用一个文件 通知.yaml 在config.yaml文件夹中,该文件夹由命令在此文件中声明 通知: 包括notify.yaml

我用这个代码声明这个新传感器:

姓名: _de_charge _CSV 平台会话: 文件名 : /config/www/csv/sessions_de _charge.csv 时间戳: 假 的

因此,当我想写入文件时,我执行服务就足够了。 通知.sessions_de _charge_CSV

我添加一个动作

我在上面介绍的自动化中添加了一个动作,该操作将为加载会话的每个记录写一行。

服务: Notify.sessions_de _charge _CSV 数据: 数据: {} 留言: >- {% 设置 diff_seconds = now().timestamp()- state.sensor.wallbox _portal _added _range _min.state | as_timestamp %} {% 设置小时 =(diff _seconds / 3600)| int %} {% 设置分钟 =((diff_seconds) % 3600)/ 60)| int %} {% 设置会话收费 _string = " + state('sensor.wallbox _portal _added _energy')| round(2)θ replace('.', ',')。 " +(States('sensor.wallbox _portal _energy _price')| float * state('sensor.wallbox _portal _added _energy')θ float round(2))。 " + " 。d:d' | 格式(hours, minutes)θ字符串 + "; " + as_timestamp(states('sensor.wallbox_portal _added_range_min'))| int | timestamp_custom(')'"%d/%m/%Y', true)| string + "; " + as_timestamp(states('sensor.wallbox_portal _added_range_min'))| int | timestamp_custom(')'"%H:%m', true)| string + "; " + now().strftime(')"%H:%m')| string + "; " + States('sensor.wallbox _portal _added _range')| int θ string + "; " " + now().timestamp()| int θ 字符串 %} { sessioncharge _string } 启用: 真实别名: 在 _de_charge.CSV 会话文件中添加一行