17track sensor

I have the same problem, you still have it?

yep, still.

Hello guys,
I am sharing my code here. Idea is mine, but it was written by ChatGPT. Now, the integration is finally usable.

  1. Get attributes of each package based on package status - seventeentrack.get_packages. Change each “in_transit” for /not_found/delivered/undelivered/ready_to_be_picked_up/returned/expired. This will create few sensors. I am not using returned/expired because there is limit 100 API calls per day and each template is one call.
  - trigger:
      - platform: time_pattern
        hours: /1
      - platform: homeassistant
        event: start
    conditions:
      - condition: time       
        after: "05:59:00"
        before: "23:59:00"
    action:
      - action: seventeentrack.get_packages
        data:
          config_entry_id: XXXXXXXXXXX        #add your code
          package_state:
            - in_transit
        response_variable: in_transit
    sensor:
      - name: 17Track v preprave
        unique_id: 17track_v_preprave
        icon: mdi:truck-delivery-outline
        state: "{{ now().isoformat() }}"
#######changed attributes#######
        attributes:
          packages: "{{ in_transit['packages'] }}"

This code merge attributes of all (in my case) 5 sensors, which you created above into one sensor.

#######changed whole code#######
template:
  - sensor:
      - name: "17Track všetky balíky" #all packages
        unique_id: 17track_vsetky_baliky
        state: >
          {% set sensors = [
            'sensor.17track_v_preprave',   #in_transit
            'sensor.17track_dorucene',  #delivered
            'sensor.17track_nedorucene',   #undelivered
            'sensor.17track_nenajdene',   #not_found
            'sensor.17track_pripravene_na_vyzdvihnutie'   #ready_to_be_picked_up. Change names or if you have add also returned/expired
          ] %}
          {% set ns = namespace(all_packages=[]) %}
          {% for s in sensors %}
            {% set pkgs = state_attr(s, 'packages') | default([]) %}
            {% if pkgs is iterable %}
              {% set ns.all_packages = ns.all_packages + pkgs %}
            {% endif %}
          {% endfor %}
          {% if ns.all_packages | length > 0 %}
            {{ now().isoformat() }}
          {% else %}
            unavailable
          {% endif %}
        attributes:
          packages: >
            {% set sensors = [
              'sensor.17track_v_preprave',  #in_transit
              'sensor.17track_dorucene',  #delivered
              'sensor.17track_nedorucene',   #undelivered
              'sensor.17track_nenajdene',   #not_found
              'sensor.17track_pripravene_na_vyzdvihnutie'   #ready_to_be_picked_up. Change names or if you have add also returned/expired
            ] %}
            {% set ns = namespace(all_packages=[]) %}
            {% for s in sensors %}
              {% set pkgs = state_attr(s, 'packages') | default([]) %}
              {% if pkgs is iterable %}
                {% set ns.all_packages = ns.all_packages + pkgs %}
              {% endif %}
            {% endfor %}
            {% set filtered = ns.all_packages
              | selectattr('timestamp', 'defined')
              | rejectattr('timestamp', 'none')
              | list %}
            {{ filtered | sort(attribute='timestamp', reverse=true) }}

Create input_select (in my case input_select.17track_vsetky_baliky for all packages). Add one empty option, because it wont work.

Automation:
This automation fills input select with package names.

alias: Aktualizácia balíkov
triggers:
  - trigger: state
    entity_id: sensor.17track_vsetky_baliky     #all packages
  - event: start
    trigger: homeassistant
actions:
  - variables:
      baliky: "{{ state_attr('sensor.17track_vsetky_baliky', 'packages') }}"
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ baliky is iterable and baliky | length > 0 }}"
        sequence:
          - target:
              entity_id: input_select.17track_vsetky_baliky
            data:
              options: |
                {{ baliky | map(attribute='friendly_name') | list }}
            action: input_select.set_options
      - conditions:
          - condition: template
            value_template: "{{ baliky is not iterable or baliky | length == 0 }}"
        sequence:
          - target:
              entity_id: input_select.17track_vsetky_baliky
            data:
              options:
                - Žiadne balíky      #option if there are any packages
            action: input_select.set_options
mode: single

Scripts:
Scripts for archiving:

archivacia_baliku:
  alias: Archivácia balíku   #archive
  mode: single
  sequence:
  - variables:
      vybrany_balik: "{{ states('input_select.17track_vsetky_baliky') }}"    
      baliky: "{{ state_attr('sensor.17track_vsetky_baliky', 'packages') }}"    #all packages
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ baliky is iterable }}"
        sequence:
          - variables:
              target_package: >
                {{ baliky | selectattr('friendly_name', 'equalto', vybrany_balik) | list | first }}
          - action: seventeentrack.archive_package
            data:
              package_tracking_number: "{{ target_package.tracking_number }}"
              config_entry_id: XXXXXXXXXXX             #add your code
#######added#######
          - delay: 00:00:02
          - action: automation.trigger
            entity_id: automation.aktualizacia_balikov_do_dashboardu #update values in dashboard

Script for Adding package into 17track:

pridanie_baliku:
  alias: Pridanie balíku
  mode: single
  sequence:
  - action: seventeentrack.add_package
    data:
      package_tracking_number: '{{ states(''input_text.sledovacie_cislo_balika'')
        }}'
      package_friendly_name: '{{ states(''input_text.nazov_balika'') }}'
      config_entry_id: XXXXXXXXXXX             #add your code
  - delay: 00:00:03
  - action: input_text.set_value
    data:
      entity_id:
      - input_text.sledovacie_cislo_balika    #tracking number
      - input_text.nazov_balika    #package name
      value: ''
#######added#######
  - delay: 00:00:02
  - action: automation.trigger
    entity_id: automation.aktualizacia_balikov_do_dashboardu #update values in dashboard

and you need two input_texts with tracking number and package name.

Dashboard:
Here you select your package:

type: entities
entities:
  - entity: input_select.17track_vsetky_baliky  #all packages

and button for archiving:

type: custom:button-card
name: archivovať     #archive
styles:
  card:
    - "--mdc-ripple-color": green
    - "--mdc-ripple-press-opacity": 0.5
tap_action:
  action: call-service
  service: script.archivacia_baliku     #script for archiving package

You need integration button-card from HACS.

Details about package, which you wanto to add in 17track. You need two input_texts.

type: entities
entities:
  - entity: input_text.sledovacie_cislo_balika   #tracking number
  - entity: input_text.nazov_balika     #package name
title: Pridávanie balíka 

Button for adding package

type: custom:button-card
name: Pridať
styles:
  card:
    - "--mdc-ripple-color": green
    - "--mdc-ripple-press-opacity": 0.5
tap_action:
  action: call-service
  service: script.pridanie_baliku    #script for adding package

Card with all packages

type: markdown
content: >-
  <table width="100%" >
    <tr>
      <th colspan=2> Package</th>
      <th> Info </th>
      <th> Updated </th>
    </tr>
    <tr>
    <tr>
  {% for item in state_attr('sensor.17track_vsetky_baliky', 'packages') %}        #all packages
    {% if item.tracking_number %}
  <tr>
    <td width="15%" align="center"> {{item.friendly_name}} </td>
    <td width="5%" align="center">
      {% if item.status == "In Transit" %} <ha-icon icon="mdi:truck-delivery-outline"></ha-icon>
      {% elif item.status == "Delivered" %} <ha-icon icon="mdi:package-variant-closed-check"></ha-icon>
      {% elif item.status == "Undelivered" %} <ha-icon icon="mdi:truck-remove"></ha-icon>
      {% elif item.status == "Not found" %} <ha-icon icon="mdi:package-variant-closed-remove"></ha-icon>
      {% elif item.status == "Ready To Be Picked Up" %} <ha-icon icon="mdi:hand-back-left"></ha-icon> 
      {% endif %} </td>
    <td width="65%" align="left"> <font size="1"> {{item.tracking_number}}, {{item.info_text}}</td>
    <td width="15%" align="center"> {{ as_timestamp(item.timestamp) | timestamp_custom("%d.%h %H:%M") }}</td> 
  </tr>
    {% endif %} 
  {% endfor %}

Community helps me a lot, so I hope someone will use it. There should be something easier, but I am not that good. This worked for me.

PS: there would be cool, if we have also service delete_package. It is in API.

Edit december 2025: few updates, because it was not working for few weeks. Do not know what changed, but now it is working again.

1 Like