Using if to select parts of json?

The swedish weather service have a json with weather alerts where there are lots of alerts that looks like this:

{
    "alert": [
        {
            "identifier": "smhi-bpm-1564025849412",
            "sender": "[email protected]",
            "sent": "2019-07-25T05:55:21+02:00",
            "status": "Actual",
            "msgType": "Alert",
            "scope": "Public",
            "code": [
                "system_affiliation 5",
                "latest_update 2019-08-07T22:56:41+02:00",
                "system_version 30",
                "system_alert_category risk"
            ],
            "info": {
                "language": "sv-SE",
                "category": "Met",
                "event": "fire warning",
                "urgency": "Expected",
                "severity": "Severe",
                "certainty": "Possible",
                "eventCode": [
                    {
                        "valueName": "system_event_level",
                        "value": "Risk Forest fire"
                    },
                    {
                        "valueName": "system_event_sv-SE",
                        "value": "Brandvarning"
                    },
                    {
                        "valueName": "system_event_priority",
                        "value": 0
                    },
                    {
                        "valueName": "system_event_level_sv-SE",
                        "value": "Risk Skogsbrand"
                    },
                    {
                        "valueName": "system_event_level_color",
                        "value": "#ab56ac"
                    },
                    {
                        "valueName": "system_event_level_id",
                        "value": 4
                    }
                ],
                "effective": "2019-07-25T05:55:21+02:00",
                "onset": "2019-07-25T05:55:21+02:00",
                "expires": "2020-07-24T05:37:29+02:00",
                "senderName": "SMHI, Swedish Meteorological and Hydrological Institute",
                "headline": "Västerbottens län kustland",
                "description": "När: Torsdag\nVar: I hela området\nIntensitet: Risken för bränder i skog och mark är mycket stor eller extremt stor\nKommentar: -",
                "web": "http://www.smhi.se/vadret/vadret-i-sverige/Varningar",
                "parameter": [
                    {
                        "valueName": "system_position",
                        "value": 1
                    },
                    {
                        "valueName": "system_history",
                        "value": "{\"history\":[{\"date\":\"2019-07-: -\"}]}"
                    },
                    {
                        "valueName": "system_eng_headline",
                        "value": "Västerbottens län kustland"
                    },
                    {
                        "valueName": "system_eng_description",
                        "value": "When: Thursday\nWhere: In the whole area\nIntensity: The risk of fires in forest and land is very high or extremely high\nComment: -"
                    },
                    {
                        "valueName": "system_backward_information_reference",
                        "value": "smhi-bpm-1563938982343;1"
                    }
                ],
                "area": {
                    "areaDesc": "033"
                }
            }
        }, etc. a bunch more like the above.
        }
    ]
}

Can I somehow in the value template use a if value to only select the alerts where AreaDesc is one that I select… they have each area in a separate json for some reason!

I was thinking something like this?

{% if value("areaDesc", "033")  -%}
  json_attributes
  - eventCode
{%- else -%}
  No Warnings
{%- endif %}

The way their json is setup does not lend well for the rest sensor. You’ll need to create separate sensors for each event code.

Here is a template that will select the correct event. This template returns the severity.

      {% set areaDesc = '033' %}
      {% set alert = value_json['alert'] | selectattr('info.area.areaDesc','eq',areaDesc) | list | first %}
      {{ alert.info.severity }}

eventCode

      {% set areaDesc = '033' %}
      {% set alert = value_json['alert'] | selectattr('info.area.areaDesc','eq',areaDesc) | list | first %}
      {{ alert.info.eventCode }}

Wow thanks, had no idea you could do it that way!

Just tried it and the first one worked just fine but the last one throws me an error since they for some reason add a complete history and that exceeds 255 chars :frowning:

2019-08-08 16:31:28 ERROR (MainThread) [homeassistant.components.mqtt.sensor] Exception in message_received when handling msg on '/SMHI/warning/': '{"language":"sv-SE","category":"Met","event":"heavy rain","urgency":"Expected","severity":"Severe","certainty":"Possible","eventCode":[{"valueName":"system_event_level","value":"Risk Heavy rain"},{"valueName":"system_event_sv-SE","value":"Stora regnmängder"},{"valueName":"system_event_priority","value":0},{"valueName":"system_event_level_sv-SE","value":"Risk Stora regnmängder"},{"valueName":"system_event_level_color","value":"#75d5ff"},{"valueName":"system_event_level_id","value":0}],"effective":"2019-08-08T10:07:02+02:00","onset":"2019-08-08T10:07:02+02:00","expires":"2020-08-07T10:00:51+02:00","senderName":"SMHI, Swedish Meteorological and Hydrological Institute","headline":"Västernorrlands län","description":"När: Torsdag eftermiddag och kväll\nVar: Hela området men med stora lokala variationer\nIntensitet: Tidvis regn- och åskskurar som kan vara kraftiga och ge mycket regn på kort tid. Det kan komma upp till 35-50 mm regn\nKommentar: I samband med kraftiga skurar finns risk för mycket hårda vindbyar.","web":"http://www.smhi.se/vadret/vadret-i-sverige/Varningar","parameter":[{"valueName":"system_position","value":1},{"valueName":"system_eng_description","value":"When: Thursday afternoon and evening\nWhere: The whole area but with local variations\nIntensity: Occasional rain and thunderstorms that can be heavy and cause a lot of rain in a short time. There can be up to 35-50 mm of rain\nComment: In conjunction with heavy showers there is a risk of very hard winds."},{"valueName":"system_history","value":"{\"history\":[{\"date\":\"2019-08-08T10:07:02\",\"node\":\"description\",\"label\":\"Områdesbeskrivning (Sv)\",\"value\":\"När: Torsdag eftermiddag och kväll\\nVar: Hela området men med stora lokala variationer\\nIntensitet: Tidvis regn- och åskskurar som kan vara kraftiga och ge mycket regn på kort tid. Det kan komma upp till 35-50 mm regn\\nKommentar: I samband med kraftiga skurar finns risk för mycket hårda vindbyar.\"}]}"},{"valueName":"system_eng_headline","value":"Västernorrlands län"}],"area":{"areaDesc":"034"}}'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/mqtt/sensor.py", line 190, in message_received
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 267, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 363, in _async_write_ha_state
    self.entity_id, state, attr, self.force_update, self._context
  File "/usr/src/homeassistant/homeassistant/core.py", line 987, in async_set
    state = State(entity_id, new_state, attributes, last_changed, None, context)
  File "/usr/src/homeassistant/homeassistant/core.py", line 732, in __init__
    ).format(entity_id)
homeassistant.exceptions.InvalidStateError: Invalid state encountered for entity id: sensor.smhi_warning_2. State max length is 255 characters.

Can I somehow skip either system_history or the entire parametersectoion?

Well yeah, you can’t use the entire event code because it’s a large object. You have to get the individual attributes out from the eventCode

{{ alert.info.eventCode[0].valueName }}

yeah I figured that part out :smiley:
I made one like this to fetch the description

- platform: rest
  resource: https://opendata-download-warnings.smhi.se/api/version/2/alerts.json
  name: "SMHI Warning - description"
  value_template: >-
    {% set areaDesc = '034' %}
    {% set alert = value_json['alert'] | selectattr('info.area.areaDesc','eq',areaDesc) | list | first %}
    {{ alert.info.description }}

but even the description is more then it can handle since it’s 294 characters!

I read here (Need help storing URL for use in generic IP camera (over 255 chars)) the suggestion to use json_attributes since they can handle more then 255 chars

Right but then you can’t use the rest sensor based on how the json is built. You’d need to use something else.

Answering myself here just to write it down if someone else tries :smiley:

Made a sensor like this to try the attribute workaround:

- platform: rest
  resource: https://opendata-download-warnings.smhi.se/api/version/2/alerts.json
  name: "SMHI Warning - attributes"
  value_template: >-
    {% set areaDesc = '034' %}
    {% set alert = value_json['alert'] | selectattr('info.area.areaDesc','eq',areaDesc) | list | first %}
    {{ alert.info }}
  json_attributes:
    - urgency
    - severity
    - certainty
    - eventCode[1].value
    - description

But that still gives the 255 limit error:

homeassistant.exceptions.InvalidStateError: Invalid state encountered for entity id: sensor.smhi_warning_name. State max length is 255 characters.
2019-08-08 17:33:33 ERROR (SyncWorker_0) [homeassistant.components.scrape.sensor] Unable to extract data from HTML
2019-08-08 17:33:41 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 254, in async_update_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 363, in _async_write_ha_state
    self.entity_id, state, attr, self.force_update, self._context
  File "/usr/src/homeassistant/homeassistant/core.py", line 987, in async_set
    state = State(entity_id, new_state, attributes, last_changed, None, context)
  File "/usr/src/homeassistant/homeassistant/core.py", line 732, in __init__
    ).format(entity_id)

yeah it looks like that… guess I’ll have to learn to make a custom component! :laughing:
Thanks for all the help @petro