Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

54 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Parcel Tracker

Home Assistant Parcel Tracking

Tests codecov License: Apache 2.0 HACS

Custom Home Assistant integration for household parcel tracking via Ship24 universal tracking API.

Features

  • Track parcels across 1500+ carriers (DHL, DPD, Hermes, GLS, UPS, FedEx, Amazon, etc.) with a single API key
  • Automatic carrier detection from tracking URLs
  • Periodic status polling with configurable interval
  • Deep links to carrier delivery preference pages (Abstellgenehmigung, etc.)
  • Status change events for automations (door opener, notifications)
  • Auto-cleanup of delivered parcels

Setup

  1. Get a free Ship24 API key (10 shipments/month) at https://dashboard.ship24.com
  2. Install as custom component in Home Assistant
  3. Add integration via UI β†’ enter Ship24 API key

Services

parcel_tracker.add

Register a new parcel for tracking.

# From tracking URL (carrier auto-detected)
action: parcel_tracker.add
data:
  tracking_url: "https://www.dhl.de/de/privatkunden/dhl-sendungsverfolgung.html?piececode=1234567890123456"
  description: "New keyboard"

# From tracking number
action: parcel_tracker.add
data:
  tracking_number: "1234567890123456"
  carrier: "DHL"

parcel_tracker.remove

action: parcel_tracker.remove
data:
  tracking_number: "1234567890123456"

Events

parcel_tracker.parcel_added

Fired when a new parcel is registered. Includes the carrier's preference URL for delivery options.

parcel_tracker.status_changed

Fired on every status transition.

event_data:
  tracking_number: "1234567890123456"
  carrier: "DHL"
  old_status: "in_transit"
  new_status: "out_for_delivery"
  eta: "2026-05-08"
  preference_url: "https://www.dhl.de/..."
  tracking_url: "https://www.dhl.de/..."

Dashboard

The integration creates one sensor entity per tracked parcel. You can view them via Settings β†’ Devices & Services β†’ Parcel Tracker or build a Lovelace dashboard card:

Auto-entities card (shows all active parcels)

Requires auto-entities from HACS:

type: custom:auto-entities
card:
  type: entities
  title: πŸ“¦ Parcels
  show_header_toggle: false
filter:
  include:
    - entity_id: sensor.parcel_*
      options:
        type: custom:template-entity-row
        state: "{{ state_attr(config.entity, 'carrier') }}: {{ states(config.entity) | replace('_', ' ') | title }}"
        secondary: >
          {{ state_attr(config.entity, 'tracking_number')[:12] }}…
          {% if state_attr(config.entity, 'eta') %} Β· ETA {{ state_attr(config.entity, 'eta') }}{% endif %}
        tap_action: |
          {
            "action": "url",
            "url_path": "{{ state_attr(config.entity, 'tracking_url') }}"
          }
sort:
  method: state
  reverse: true
show_empty: false
Simple entities card (no extra dependencies)

Manually list your parcel sensors (they appear/disappear as parcels are added/removed):

type: entities
title: πŸ“¦ Parcels
entities:
  - type: custom:template-entity-row
    entity: sensor.parcel_dhl_3456
    state: "{{ state_attr('sensor.parcel_dhl_3456', 'carrier') }}: {{ states('sensor.parcel_dhl_3456') | replace('_', ' ') | title }}"
    secondary: "ETA: {{ state_attr('sensor.parcel_dhl_3456', 'eta') }}"
    tap_action: |
      {
        "action": "url",
        "url_path": "{{ state_attr(config.entity, 'tracking_url') }}"
      }

Or use the built-in entity filter card for a zero-config list:

type: entity-filter
entities:
  - sensor.parcel_dhl_3456
  - sensor.parcel_dpd_7890
state_filter:
  - registered
  - in_transit
  - out_for_delivery

Example Automations

Notify to set delivery preferences (Abstellgenehmigung)

When a new parcel is registered, send a notification with a direct link to set your drop-off preference on the carrier's website:

automation:
  - alias: "Notify to set delivery drop-off"
    triggers:
      - trigger: event
        event_type: parcel_tracker.parcel_added
    conditions:
      - condition: template
        value_template: "{{ trigger.event.data.preference_url != '' }}"
    actions:
      - action: notify.mobile_app_your_phone
        data:
          title: "πŸ“¦ New parcel registered"
          message: >
            {{ trigger.event.data.carrier }} parcel added.
            Set your Abstellgenehmigung now!
          data:
            url: "{{ trigger.event.data.preference_url }}"
            actions:
              - action: URI
                title: "Set drop-off location"
                uri: "{{ trigger.event.data.preference_url }}"
Notify parcel in transit
automation:
  - alias: "Notify parcel in transit"
    triggers:
      - trigger: event
        event_type: parcel_tracker.status_changed
        event_data:
          new_status: in_transit
    actions:
      - action: notify.mobile_app_your_phone
        data:
          title: "πŸ“¦ Parcel on the way!"
          message: "{{ trigger.event.data.carrier }} parcel is in transit (ETA: {{ trigger.event.data.eta }})"
          data:
            url: "{{ trigger.event.data.tracking_url }}"
Share tracking links from your phone

The integration registers a webhook automatically β€” no HA automation needed. Just point your phone's share shortcut at:

POST https://<ha-external-url>/api/webhook/parcel_tracker_register

JSON body:

{"url": "<tracking-url>", "device": "<phone-name>"}

Android step-by-step using HTTP Shortcuts (F-Droid / Play Store):

  1. Open the app β†’ tap + (bottom-right) β†’ Regular Shortcut
  2. Basic Request Settings
    • Name: Track Parcel
    • Method: POST
    • URL: https://<your-ha-url>/api/webhook/parcel_tracker_register
  3. Request Body / Payload
    • Tap Request Body β†’ select Custom Text
    • Content Type: application/json
    • In the body text field, enter:
      {"url": "{share_text}", "device": "my-pixel"}
      

      {share_text} is a built-in variable β€” the app replaces it automatically with whatever text is shared. Don't create a variable for it; just type it literally.

      Replace my-pixel with whatever name you want to identify this phone.

  4. Trigger from Share Sheet (Android 11+)
    • Go back to the shortcut's main settings screen
    • Tap Trigger & Execution Settings (⚑ icon)
    • Enable "Accept shared text from other apps"
    • You may need to restart HTTP Shortcuts (or reboot) for Android to register the new share target
  5. Save the shortcut (βœ“ top-right)

Usage (Android 11+): Share a tracking link β†’ pick HTTP Shortcuts β†’ select Track Parcel.

Alternative: older Android / home-screen shortcut (no share sheet)

If your device doesn't support the share-into feature (Android < 11), use a dialog variable instead:

  1. In HTTP Shortcuts, open Variables (drawer menu) β†’ + β†’ Text Input
    • Variable key: tracking_url
    • Title: Tracking URL
  2. Create the shortcut as above, but use this body:
    {"url": "{tracking_url}", "device": "my-phone"}
    
  3. Place the shortcut on your home screen (long-press shortcut β†’ "Place on home screen" / use the widget picker)
  4. To use: copy the tracking link β†’ tap the home-screen shortcut β†’ paste β†’ confirm

iOS β€” use the built-in Shortcuts app with a "Get Contents of URL" action (POST, same JSON body). Add the shortcut to your Share Sheet.

Open door for parcel delivery
alias: Open door for parcel delivery
triggers:
  - entity_id: binary_sensor.doorbell_bell_signal
    to: "on"
    trigger: state
conditions:
  - condition: template
    value_template: >
      {{ states.sensor
         | selectattr('entity_id', 'match', 'sensor.parcel_.*')
         | selectattr('state', 'in', ['in_transit', 'out_for_delivery'])
         | selectattr('attributes.eta', 'eq', now().strftime('%Y-%m-%d'))
         | list | count > 0 }}
actions:
  - action: switch.turn_on
    target:
      entity_id: switch.doorbell_door_opener

Entity Model

Each tracked parcel becomes a sensor entity:

  • State: registered | in_transit | out_for_delivery | delivered | failed_attempt | exception | unknown
  • Attributes: carrier, tracking_number, eta, registered_by, registered_at, last_api_update, tracking_url, preference_url, description

Configuration Options

Via UI (Settings β†’ Integrations β†’ Parcel Tracker β†’ Configure):

Option Default Description
Cleanup days 3 Days after delivery before auto-removal (1-30)
Scan interval 2h How often to poll Ship24 for updates (1-12h)

Supported Carriers

Carrier preference links
Carrier Preference Page
DHL Sendungsverfolgung β†’ Empfangsoptionen
DPD PaketankΓΌndigung
Hermes Sendungsinformation
GLS FlexDeliveryService
UPS My Choice
FedEx Delivery Manager
Amazon Order History
URL auto-detection patterns
Carrier URL Pattern
DHL dhl.de, nolp.dhl.de
DPD dpd.de, tracking.dpd
Hermes myhermes.de, hermesworld
GLS gls-group.com, gls-pakete
UPS ups.com
FedEx fedex.com
Amazon amazon.de/progress-tracker

Development

# Run tests
uv run pytest tests/ -v

# Lint
uv run ruff check . && uv run ruff format --check .

Dependencies

  • Home Assistant 2024.1+
  • Ship24 API key (free plan: https://dashboard.ship24.com)
  • HTTP Shortcuts app on Android phones (for share sheet integration)

About

A Home Assistant custom integration for tracking household parcels via Ship24 API

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages