What does Settings > System > Logs > Show Raw logs (3dots) say?
See below
2025-12-14 13:06:00.465 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: No first item, sequence was empty. when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% if as_timestamp(now()) > as_timestamp(pakket.planned_from) %}
{% if as_timestamp(now()) < as_timestamp(pakket.planned_to) %}expecting
{% else %}overdue
{% endif %}
{% else %}notexpecting {% endif %}'
2025-12-14 13:06:00.465 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'list object' has no attribute 'planned_from' when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% if as_timestamp(now()) > as_timestamp(pakket.planned_from) %}
{% if as_timestamp(now()) < as_timestamp(pakket.planned_to) %}expecting
{% else %}overdue
{% endif %}
{% else %}notexpecting {% endif %}'
2025-12-14 13:06:00.465 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'list object' has no attribute 'planned_from' when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% if as_timestamp(now()) > as_timestamp(pakket.planned_from) %}
{% if as_timestamp(now()) < as_timestamp(pakket.planned_to) %}expecting
{% else %}overdue
{% endif %}
{% else %}notexpecting {% endif %}'
2025-12-14 13:06:00.465 ERROR (MainThread) [homeassistant.helpers.sensor] Error rendering attributes.expect_now template for sensor.postnl_packages_onderweg: ValueError: Template error: as_timestamp got invalid input '' when rendering template '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% if as_timestamp(now()) > as_timestamp(pakket.planned_from) %}
{% if as_timestamp(now()) < as_timestamp(pakket.planned_to) %}expecting
{% else %}overdue
{% endif %}
{% else %}notexpecting {% endif %}' but no default was specified
2025-12-14 13:06:00.466 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: No first item, sequence was empty. when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% set tijd_raw = pakket.planned_from if pakket.planned_from is defined else [] %} {% if tijd_raw %}
{{ as_timestamp(pakket.planned_from) | timestamp_custom('%H:%M') }} - {{ as_timestamp(pakket.planned_to) | timestamp_custom('%H:%M') }}
{% else %}Onbekend {% endif %}'
2025-12-14 13:06:00.466 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: No first item, sequence was empty. when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% set tijd_raw = pakket.planned_from if pakket.planned_from is defined else [] %} {% if tijd_raw %}
{{ as_timestamp(pakket.planned_from) | timestamp_custom('%d-%m-%Y %H:%M') }}
{% else %}Onbekend {% endif %}'
2025-12-14 13:06:00.466 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: No first item, sequence was empty. when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% set tijd_raw = pakket.expected_datetime if pakket.expected_datetime is defined else [] %} {% if tijd_raw %}
{{ as_timestamp(pakket.expected_datetime) | timestamp_custom('%d-%m-%Y %H:%M') }}
{% else %}Onbekend {% endif %}'
2025-12-14 13:06:00.466 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: No first item, sequence was empty. when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% set tijd_raw = pakket.planned_to if pakket.planned_to is defined else [] %} {% if tijd_raw %}
{{ as_timestamp(pakket.planned_to) | timestamp_custom('%d-%m-%Y %H:%M') }}
{% else %}Onbekend {% endif %}'
2025-12-16 14:32:00.079 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: No first item, sequence was empty. when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% if as_timestamp(now()) > as_timestamp(pakket.planned_from) %}
{% if as_timestamp(now()) < as_timestamp(pakket.planned_to) %}expecting
{% else %}overdue
{% endif %}
{% else %}notexpecting {% endif %}'
2025-12-16 14:32:00.079 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'list object' has no attribute 'planned_from' when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% if as_timestamp(now()) > as_timestamp(pakket.planned_from) %}
{% if as_timestamp(now()) < as_timestamp(pakket.planned_to) %}expecting
{% else %}overdue
{% endif %}
{% else %}notexpecting {% endif %}'
2025-12-16 14:32:00.079 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'list object' has no attribute 'planned_from' when rendering '{% set pakket = state_attr('sensor.postnl_delivery', 'enroute') | first or [] %} {% if as_timestamp(now()) > as_timestamp(pakket.planned_from) %}
{% if as_timestamp(now()) < as_timestamp(pakket.planned_to) %}expecting
{% else %}overdue
{% endif %}
{% else %}notexpecting {% endif %}'
I got similar logs.
I have requested some assistance from openAI, And I got it working now, There was also a malformed argument warning. But I have this working right now. The code also checks if there is any information filled in the object, before processing. If it’s empty, it’s not gonna use it, reducing faults.
type: custom:mod-card
style: |
ha-card {
border-radius: 20px !important;
background-color: rgba(10, 10, 10, 0.4) !important;
}
card:
type: vertical-stack
cards:
- type: heading
heading: Packages
heading_style: title
badges:
- type: entity
show_state: true
show_icon: true
entity: sensor.postnl_delivery
icon: phu:postnl
- type: entity
show_state: true
show_icon: true
entity: sensor.dhl_packages
icon: phu:dhl
card_mod:
style: |
ha-card {
margin-top: 10px !important;
margin-right: 10px !important;
margin-left: 20px !important;
}
- type: custom:auto-entities
card:
type: entities
show_header_toggle: false
card_mod:
style: |
ha-card {
background: none;
margin-top: -33px;
}
filter:
template: >
{% set dhl_packages = state_attr('sensor.dhl_raw_json_data','parcels') or [] %}
{% set postnl_enroute = state_attr('sensor.postnl_delivery','enroute') or [] %}
{% set postnl_delivered = state_attr('sensor.postnl_delivery','delivered') or [] %}
{% set enroute_list = namespace(items=[]) %}
{% set delivered_list = namespace(items=[]) %}
{# --- PROCESS DHL --- #}
{% for package in dhl_packages %}
{% set status_raw = package.status | lower %}
{% set barcode = package.barcode %}
{% set name = package.sender.name | default('Unknown sender') %}
{% set time_raw = package.receivingTimeIndication.start
if package.receivingTimeIndication is defined and package.receivingTimeIndication.start is defined else
package.receivingTimeIndication.moment
if package.receivingTimeIndication is defined and package.receivingTimeIndication.moment is defined else none %}
{% set time_end = package.receivingTimeIndication.end
if package.receivingTimeIndication is defined and package.receivingTimeIndication.end is defined else time_raw %}
{% set time_ts = time_raw | default(0) | as_timestamp %}
{% set time_str = 'Unknown' %}
{% if time_raw %}
{% set time_str = time_ts | timestamp_custom('%d-%m-%Y %H:%M') %}
{% if time_raw != time_end %}
{% set time_str = time_str ~ ' - ' ~ (time_end | as_timestamp | timestamp_custom('%H:%M')) %}
{% endif %}
{% endif %}
{% set clean_status = status_raw | replace('_',' ') | lower | capitalize %}
{% if 'prenotification' in clean_status %} {% set clean_status = 'Registered' %} {% endif %}
{% if 'shipment picked up' in clean_status %} {% set clean_status = 'Received by DHL' %} {% endif %}
{% if 'parcel sorted' in clean_status %} {% set clean_status = 'Sorted' %} {% endif %}
{% if 'in transit' in clean_status %} {% set clean_status = 'In transit' %} {% endif %}
{% if 'local depot' in clean_status %} {% set clean_status = 'At local depot' %} {% endif %}
{% if 'out for delivery' in clean_status %} {% set clean_status = 'Out for delivery' %} {% endif %}
{% if 'delivered' in clean_status or 'collected' in clean_status %}
{% set sub_label = 'Delivered' %}
{% set target_list = delivered_list.items %}
{% else %}
{% set sub_label = 'Expected' %}
{% set target_list = enroute_list.items %}
{% endif %}
{% set dhl_url = 'https://www.dhl.com/nl-en/home/tracking.html?tracking-id=' ~ barcode ~ '&submit=1' %}
{% set row = {
'type': 'custom:template-entity-row',
'entity': 'sensor.dhl_raw_json_data',
'name': name ~ ' - ' ~ barcode,
'state': clean_status,
'secondary': sub_label ~ ': ' ~ time_str,
'icon': 'phu:dhl',
'color': '#ffcc00',
'tap_action': {'action':'url','url_path': dhl_url},
'sort_time': time_ts
} %}
{% if sub_label == 'Delivered' %}
{% set delivered_list.items = delivered_list.items + [row] %}
{% else %}
{% set enroute_list.items = enroute_list.items + [row] %}
{% endif %}
{% endfor %}
{# --- PROCESS POSTNL ENROUTE --- #}
{% for package in postnl_enroute %}
{% set barcode = package.key %}
{% set name = package.name | default('Unknown sender') %}
{% set status_raw = package.status_message | default('') %}
{% set clean_status = 'Expected' %}
{% if 'nog niet door PostNL' in status_raw %} {% set clean_status = 'Registered' %} {% endif %}
{% if 'is ontvangen' in status_raw %} {% set clean_status = 'Received by PostNL' %} {% endif %}
{% if 'is gesorteerd' in status_raw %} {% set clean_status = 'Sorted' %} {% endif %}
{% if 'is onderweg' in status_raw %} {% set clean_status = 'Out for delivery' %} {% endif %}
{% if 'afgehaald' in status_raw or 'pakketautomaat' in status_raw %} {% set clean_status = 'Ready for pickup' %} {% endif %}
{% if 'betaald' in status_raw %} {% set clean_status = 'Clearance fees paid' %} {% endif %}
{% set time_raw = package.planned_from if package.planned_from is defined else none %}
{% set time_ts = time_raw | default(0) | as_timestamp %}
{% set time_str = 'Unknown' %}
{% if time_raw %} {% set time_str = time_ts | timestamp_custom('%d-%m-%Y %H:%M') %} {% endif %}
{% set postnl_url = package.url | default('https://www.postnl.nl/tracktrace') %}
{% set row = {
'type': 'custom:template-entity-row',
'entity': 'sensor.postnl_delivery',
'name': name ~ ' - ' ~ barcode,
'state': clean_status,
'secondary': 'Expected: ' ~ time_str,
'icon': 'phu:postnl',
'color': '#FB6200',
'tap_action': {'action':'url','url_path': postnl_url},
'sort_time': time_ts
} %}
{% set enroute_list.items = enroute_list.items + [row] %}
{% endfor %}
{# --- PROCESS POSTNL DELIVERED --- #}
{% for package in postnl_delivered %}
{% set time_raw = package.delivery_date if package.delivery_date is defined else none %}
{% set time_ts = time_raw | default(0) | as_timestamp %}
{% set days_diff = (now().timestamp() - time_ts)/86400 %}
{% if days_diff <= 3 %}
{% set barcode = package.key %}
{% set status_raw = package.status_message | default('') %}
{% set clean_status = 'Delivered' %}
{% set postnl_url = package.url | default('https://www.postnl.nl/tracktrace') %}
{% set time_str = time_ts | timestamp_custom('%d-%m-%Y %H:%M') %}
{% set row = {
'type': 'custom:template-entity-row',
'entity': 'sensor.postnl_delivery',
'name': barcode,
'state': clean_status,
'secondary': 'Delivered: ' ~ time_str,
'icon': 'phu:postnl',
'color': '#FB6200',
'tap_action': {'action':'url','url_path': postnl_url},
'sort_time': time_ts
} %}
{% set delivered_list.items = delivered_list.items + [row] %}
{% endif %}
{% endfor %}
{# --- SORT AND RENDER JSON --- #}
{% set enroute_sorted = enroute_list.items | sort(attribute='sort_time') %}
{% set delivered_sorted = delivered_list.items | sort(attribute='sort_time', reverse=true) %}
{% set final_list = [] %}
{% if enroute_sorted | count > 0 %}
{% set final_list = final_list + [{"type": "section", "label": "🚚 Enroute"}] %}
{% set final_list = final_list + enroute_sorted %}
{% endif %}
{% if delivered_sorted | count > 0 %}
{% set final_list = final_list + [{"type": "section", "label": "📦 Delivered"}] %}
{% set final_list = final_list + delivered_sorted %}
{% endif %}
{{ final_list | tojson }}
show_empty: true
Has anyone got the issue where their PostNL authentication has expired and they cannot get it to work? I click the “Send” button, which redirects my to PostNL login. I login, and then I get stuck on:
Did you add the browser app installed.
You need this to get this to work
Hi Jonathan.
Great guide. Question about DPD, GLS etc, is that the same approach as you did for DHL?
I’ve vibe coded a Lovelace card to track packages: Package Tracker Card. It currently supports both parcel-ha and ha-postnl. Created it for personal use, but it might come in handy for others too.
Wow nice one !
thanks for the contribution!!
Also very interested in the code for DPD, GLS etc. @Jonathanx597 ![]()


