Jinja2嵌套for循环,用于解析多个字典key:value对

时间:2018-12-03 17:50:19

标签: jinja2

我在这里的第一篇文章很抱歉,如果还不清楚的话。是的,我确实在这个论坛和其他论坛上进行了搜索,可以找到一个解决方案(谢谢),但是我敢肯定这不是最好的方法。

Victron太阳能电池充电器和控制器将大量数据馈入云(Victron远程管理),我可以使用它们的API进行访问。
JSON形式的响应是一系列记录,我认为它们类似于字典,每个记录都有一组特定的key:value对,在VRM输出中称为记录。

以下示例(116条记录中只有2条记录):

{
        "idSite": 10986,
        "timestamp": 1543599455,
        "Device": "Battery Monitor",
        "instance": 258,
        "idDataAttribute": 47,
        "description": "Battery voltage",
        "formatWithUnit": "%.2F V",
        "dbusServiceType": "battery",
        "dbusPath": "/Dc/0/Voltage",
        "code": "V",
        "formattedValue": "24.01 V",
        "id": 44
    },
    {
        "idSite": 10986,
        "timestamp": 1543599455,
        "Device": "Battery Monitor",
        "instance": 258,
        "idDataAttribute": 49,
        "description": "Current",
        "formatWithUnit": "%.2F A",
        "dbusServiceType": "battery",
        "dbusPath": "/Dc/0/Current",
        "code": "I",
        "formattedValue": "-2.40 A",
        "id": 45

我想提取“电池电压”和其他参数以在Home Assistant前端和电源自动化中报告。

我首先使用基于记录ID定位值的Jinja2模板。例如,在此示例中,在记录44中找到了电池电压。
问题是Victron会不时更改这些记录的数量或顺序,而我的“硬编码”模板返回的则是乱码。

因此,我研究了如何在for循环和if测试序列中将所需的度量作为参数传递,并且找到了一种满足我需要的方法。

{%- set object = "formattedValue" -%}
{%- set vrm_records =  states.sensor.vrm_data.attributes.records -%}

{%- for device in ["Gateway", "258", "256", "Inverter"] -%}
  {%- for target in ["Local ip address", "Remote ip address", "Battery voltage", "Current", "Consumed Amphours", "State of charge", "Time to go", "Maximum voltage", "Discharged Energy", "Charged Energy", "Battery current", "Battery watts", "Load state", "Charger on/off", "Charge state", "PV voltage", "PV current", "PV power", "Yield today", "Maximum charge power today", "Yield yesterday", "Maximum charge power yesterday", "Error code", "Output voltage", "Inverter on/off/eco", "Inverter state", "Low battery voltage alarm"] -%}
    {%- for record in vrm_records -%}
      {%- for key, value in record.items() -%}
        {%- if value|string() == target|string() -%}
          {%- for key, value in record.items() -%}
            {%- if value|string() == device|string() -%}
              {%- for key , value in record.items() -%}
                {%- if key|string() == object|string() -%}
                {{ target }} is {{ value }}
                {% endif -%}
              {%- endfor -%}
            {%- endif -%}
          {%- endfor -%}
        {%- endif -%}
      {%- endfor -%}
    {%- endfor -%}
  {%- endfor -%}
{%- endfor -%}

我要检索的值具有键“ formattedValue”,因此我将其声明为对象。
set vrm_records行检索所有我认为像字典的116条记录。
每个记录都链接到VRM设置中的设备,例如256(电池监视器)或258(太阳能充电器),因此我使用此列表在第一个for循环中过滤该设备。
第二个for循环包含我要为其检索值的目标键的列表。
遵循很长的if和for语句序列,该方法有效!

但是我敢肯定,到目前为止,这并不是一种优雅的方法。

任何帮助表示赞赏。
谢谢。

0 个答案:

没有答案