Hello everyone!
My web design creativity is a little bit limp
So does anyone have a good looking card for 17Track sensor with package details?
Looking forward for your examples.
Hello everyone!
My web design creativity is a little bit limp
So does anyone have a good looking card for 17Track sensor with package details?
Looking forward for your examples.
Why not just use a simple monster card?
type: 'custom:monster-card'
card:
type: entities
title: 17track.net
show_header_toggle: false
filter:
include:
- entity_id: sensor.seventeentrack_package_*
Could be beautified, but for the moment it’s working and displaying any newly added packages from my 17track account
Will take a look.
This is what I have been using
type: markdown
content: |2-
{% if is_state('sensor.seventeentrack_packages_in_transit', '0') %}
**Nothing Is In Transit**
{% else %}
**In Transit**
{% for package in
states.sensor.seventeentrack_packages_in_transit.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if is_state('sensor.seventeentrack_packages_ready_to_be_picked_up', '0') %}
**Nothing Is Out For Delivery**
{% else %}
**Out For Delivery**
{% for package in
states.sensor.seventeentrack_packages_ready_to_be_picked_up.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if is_state('sensor.seventeentrack_packages_delivered', '0') %}
**Nothing Is Delivered**
{% else %}
**Delivered**
{% for package in
states.sensor.seventeentrack_packages_delivered.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
title: 17Track Packages
I added some icons.
type: markdown
content: |2-
{% if is_state('sensor.seventeentrack_packages_in_transit', '0') %}
<ha-icon icon="mdi:transit-connection-variant"></ha-icon> - **Nothing Is In Transit**
{% else %}
<ha-icon icon="mdi:transit-connection-variant"></ha-icon> - **In Transit**
{% for package in
states.sensor.seventeentrack_packages_in_transit.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if is_state('sensor.seventeentrack_packages_ready_to_be_picked_up', '0') %}
**<ha-icon icon="mdi:truck-delivery"></ha-icon> - Nothing Is Out For Delivery**
{% else %}
**<ha-icon icon="mdi:truck-delivery"></ha-icon> - Out For Delivery**
{% for package in
states.sensor.seventeentrack_packages_ready_to_be_picked_up.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if is_state('sensor.seventeentrack_packages_delivered', '0') %}
**<ha-icon icon="mdi:package-variant-closed-check"></ha-icon> - Nothing Is Delivered**
{% else %}
**<ha-icon icon="mdi:package-variant-closed-check"></ha-icon> - Delivered**
{% for package in
states.sensor.seventeentrack_packages_delivered.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
title: Deliveries
I added some code for not found
type: markdown
content: |2-
{% if is_state('sensor.seventeentrack_packages_in_transit', '0') %}
<ha-icon icon="mdi:transit-connection-variant"></ha-icon> - **Nothing Is In Transit**
{% else %}
<ha-icon icon="mdi:transit-connection-variant"></ha-icon> - **In Transit**
{% for package in
states.sensor.seventeentrack_packages_in_transit.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if is_state('sensor.seventeentrack_packages_ready_to_be_picked_up', '0') %}
**<ha-icon icon="mdi:truck-delivery"></ha-icon> - Nothing Is Out For Delivery**
{% else %}
**<ha-icon icon="mdi:truck-delivery"></ha-icon> - Out For Delivery**
{% for package in
states.sensor.seventeentrack_packages_ready_to_be_picked_up.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if is_state('sensor.seventeentrack_packages_delivered', '0') %}
**<ha-icon icon="mdi:package-variant-closed-check"></ha-icon> - Nothing Is Delivered**
{% else %}
**<ha-icon icon="mdi:package-variant-closed-check"></ha-icon> - Delivered**
{% for package in
states.sensor.seventeentrack_packages_delivered.attributes.packages %}
>- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if is_state('sensor.seventeentrack_packages_not_found', '0') %}
<ha-icon icon="mdi:alert"></ha-icon> - **Nothing Not Found**
{% else %}
<ha-icon icon="mdi:alert"></ha-icon> - **Not Found**
{% for package in
states.sensor.seventeentrack_packages_not_found.attributes.packages %}
>- **{{ package.tracking_number }}**
{% endfor %}
{% endif %}
title: Deliveries
I’ll continue this chain of forum-based version management with my iteration
{% macro package_display(package) %}
{% set detail_sensor_name = 'sensor.17track_package_' + package.tracking_number | lower %}
{% if not is_state(detail_sensor_name, 'unknown') %}
- **<a target="_blank" rel="noopener noreferrer" href="https://www.17track.net/?nums={{ state_attr(detail_sensor_name, 'tracking_number') }}">{{ state_attr(detail_sensor_name, 'friendly_name') }}</a>** ({{ relative_time(state_attr(detail_sensor_name, 'timestamp')) }} ago)
{{ state_attr(detail_sensor_name, 'origin_country') }} › {{ state_attr(detail_sensor_name, 'destination_country') }}
{{ state_attr(detail_sensor_name, 'location') }}: {{ state_attr(detail_sensor_name, 'info_text') }}
{% endif %}
{% endmacro %}
{% if not is_state('sensor.17track_packages_in_transit', '0') %}
<ha-icon icon="mdi:transit-connection-variant"></ha-icon> **In Transit**
{% for package in state_attr('sensor.17track_in_transit', 'packages') %}
{{ package_display(package) }}
{% endfor %}
{% endif %}
{% if not is_state('sensor.17track_ready_to_be_picked_up', '0') %}
<ha-icon icon="mdi:truck-delivery"></ha-icon> **Out For Delivery**
{% for package in state_attr('sensor.17track_ready_to_be_picked_up', 'packages') %}
{{ package_display(package) }}
{% endfor %}
{% endif %}
{% if not is_state('sensor.17track_delivered', '0') %}
<ha-icon icon="mdi:package-variant-closed-check"></ha-icon> **Delivered**
{% for package in state_attr('sensor.17track_delivered', 'packages') %}
{{ package_display(package) }}
{% endfor %}
{% endif %}
{% if not is_state('sensor.17track_not_found', '0') %}
<ha-icon icon="mdi:alert"></ha-icon> **Not Found**
{% for package in state_attr('sensor.17track_not_found', 'packages') %}
{{ package_display(package) }}
{% endfor %}
{% endif %}
Hi guys,
Any suggestions on how to achieve this, now that sensors are deprecated and we only have the seventeentrack.get_packages
action, that, as far as I can tell, can’t be called from within the template?
I have risen to the challenge and created an automation that fills helper variable with the content I want, which I can then use in a Markdown card.
So first, create a helper called input_text.parcels
here: Link to Helpers – My Home Assistant
I have given it the icon mdi:package-variant
and a maximum length of 50000
.
Then, create an automation that will fill this variable. This is the raw automation yaml:
alias: Parcel Check
description: ""
trigger: []
condition: []
action:
- action: seventeentrack.get_packages
metadata: {}
data:
config_entry_id: 0123456789
package_state:
- in_transit
response_variable: transit
- action: seventeentrack.get_packages
metadata: {}
data:
config_entry_id: 0123456789
package_state:
- not_found
response_variable: notfound
- action: seventeentrack.get_packages
metadata: {}
data:
config_entry_id: 0123456789
package_state:
- ready_to_be_picked_up
response_variable: outfordelivery
- action: seventeentrack.get_packages
metadata: {}
data:
config_entry_id: 0123456789
package_state:
- delivered
response_variable: delivered
- action: input_text.set_value
metadata: {}
data:
value: |
{% if transit.packages|length > 0 %}
<ha-icon icon="mdi:transit-connection-variant"></ha-icon> in transit
{% for package in transit.packages %}
- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if outfordelivery.packages|length > 0 %}
<ha-icon icon="mdi:truck-delivery"></ha-icon> out for delivery
{% for package in outfordelivery.packages %}
- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if notfound.packages|length > 0 %}
<ha-icon icon="mdi:alert"></ha-icon> not found
{% for package in notfound.packages %}
- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
{% if delivered.packages|length > 0 %}
<ha-icon icon="mdi:package-variant-closed-check"></ha-icon> delivered
{% for package in delivered.packages %}
- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{
package.info_text }}
{% endfor %}
{% endif %}
target:
entity_id: input_text.parcels
mode: single
Of course you need to select your correct config_entry_id from the dropdown.
Then create a simple card with this content:
type: markdown
content: '{{states(''input_text.parcels'')}}'
title: Parcels
For testing, run the automation manually. If you want to update states regularly, simply add a time_platform
trigger or other trigger of your choice.
I have not yet tested all states, but it seems to work fine.
Of course you can modify this to your liking, and add your enhanced version here
Yeah, and it promptly failed today after adding a third package to be tracked. Looks like input_text
helpers can only carry up to 255 characters, even though the UI doesn’t stop me from entering the 50000
I wanted
In order to limit myself to fewer characters, the action assigning the variable now looks like this:
action: input_text.set_value
metadata: {}
data:
value: |
{% if transit.packages|length > 0 %}
## 📤 in transit
{% for package in transit.packages %}
- **{{ package.friendly_name }}:** {{ package.info_text }}
{% endfor %}
{% endif %}
{% if outfordelivery.packages|length > 0 %}
## 🚚 out for delivery
{% for package in outfordelivery.packages %}
- **{{ package.friendly_name }}:** {{ package.info_text }}
{% endfor %}
{% endif %}
{% if notfound.packages|length > 0 %}
## ⚠️ not found
{% for package in notfound.packages %}
- **{{ package.friendly_name }}:** {{ package.info_text }}
{% endfor %}
{% endif %}
{% if delivered.packages|length > 0 %}
## 📦 delivered
{% for package in delivered.packages %}
- **{{ package.friendly_name }}:** {{ package.info_text }}
{% endfor %}
{% endif %}
target:
entity_id: input_text.parcels
This replaces the HA icons with unicode emojis, and removes the tracking number (I’m not interested in that anyway).
With my currently 3 packages I came up with about 215 characters (depending on friendly_name length and the info_text).
Yeah the 255 char limit is pretty bad. Apparently entity attributes can store 16kb, so maybe using something like GitHub - pmazz/ps_hassio_entities: Python script to handle state and attributes of existing sensors and entities it would be possible to store the markdown into an attribute on the helper variable instead?
So, I had a go at this, and it seems to be working fine. You need to enable python_scripts
in your configuration.yaml
as per Python Scripts - Home Assistant, then install GitHub - pmazz/ps_hassio_entities: Python script to handle state and attributes of existing sensors and entities and then I have the automation place the markdown into a markdown
attribute on each helper variable I created (as I initially created one helper variable per delivery category as an initial bodge around the 255 char limit), e.g.:
- action: python_script.hass_entities
metadata: {}
data:
action: set_state_attributes
entity_id: input_text.parcels_out_for_delivery
state: '{{ ''Updated at ''~ now().strftime(''%H:%M'')}}'
attributes:
- markdown: >-
{% if outfordelivery.packages|length > 0 %}
**<ha-icon icon="mdi:truck-delivery"></ha-icon> - Out for delivery**
{% for package in outfordelivery.packages %}
- **{{ package.friendly_name }} ({{ package.tracking_number }}):** {{ package.info_text }}
{% endfor %}
{% else %}
**<ha-icon icon="mdi:truck-delivery"></ha-icon> - Out for delivery**
{% endif %}
Then in the markdown card, I just include the markdown attributes from each helper, e.g.
{{states.input_text.parcels_delivered.attributes.markdown}}
{{states.input_text.parcels_out_for_delivery.attributes.markdown}}
{{states.input_text.parcels_in_transit.attributes.markdown}}
{{states.input_text.parcels_not_found.attributes.markdown}}
Regarding the error,
17Track package sensors are deprecated and will be removed.
Please update your automations and scripts to get data using the seventeentrack.get_packages
action
Which bit do i change i am using an entities card with a filter
seventeentrack.get_packages
Tia
Your code worked but I was confused by the above so for anyone else that does not understand this … After the YAML is put in for the automation go back to the Visual Editor view. Then for each item you need to set the integration you are using for the 17Track service.
Ended up going thru the amazing replies in here and putting together a tweaked version.
It uses the python_scripts
mentioned by @Lenbok here:
To use the automation you need to create 6 text helpers with the following names:
parcels_not_found
parcels_in_transit
parcels_out_for_delivery
parcels_delivered
parcels_undelivered
parcels_alert
Here is the full automation I ended up going with:
alias: 17Track
description: Automation to fetch package status from 17Track
triggers:
- trigger: time_pattern
minutes: /30
conditions: []
actions:
- action: seventeentrack.get_packages
data:
package_state:
- not_found
config_entry_id:
response_variable: notfound
- action: python_script.hass_entities
metadata: {}
data:
action: set_state_attributes
entity_id: input_text.parcels_not_found
state: "{{ 'Updated at '~ now().strftime('%H:%M')}}"
attributes:
- markdown: >
## <ha-icon icon="mdi:package-variant-remove"></ha-icon> - Not Found
({{notfound.packages|length}})
{% if notfound.packages|length > 0 %}
{% for package in notfound.packages %}
>- **{% if package.friendly_name|length > 0 %}{{
package.friendly_name }}{% else %}{{package.tracking_number}}{%
endif %}:** {{ package.info_text }}
{% endfor %}
{% else %}
-
{% endif %}
- action: seventeentrack.get_packages
data:
package_state:
- in_transit
config_entry_id:
response_variable: intransit
- action: python_script.hass_entities
metadata: {}
data:
action: set_state_attributes
entity_id: input_text.parcels_in_transit
state: "{{ 'Updated at '~ now().strftime('%H:%M')}}"
attributes:
- markdown: >
## <ha-icon icon="mdi:airplane-clock"></ha-icon> - In Transit
({{intransit.packages|length}})
{% if intransit.packages|length > 0 %}
{% for package in intransit.packages %}
>- **{% if package.friendly_name|length > 0 %}{{
package.friendly_name }}{% else %}{{package.tracking_number}}{%
endif %}:** {{ package.info_text }}
{% endfor %}
{% else %}
-
{% endif %}
- action: seventeentrack.get_packages
data:
config_entry_id:
package_state:
- ready_to_be_picked_up
response_variable: outfordelivery
- action: python_script.hass_entities
metadata: {}
data:
action: set_state_attributes
entity_id: input_text.parcels_out_for_delivery
state: "{{ 'Updated at '~ now().strftime('%H:%M')}}"
attributes:
- markdown: >
## <ha-icon icon="mdi:truck-delivery"></ha-icon> - Out for delivery
({{outfordelivery.packages|length}})
{% if outfordelivery.packages|length > 0 %}
{% for package in outfordelivery.packages %}
>- **{% if package.friendly_name|length > 0 %}{{
package.friendly_name }}{% else %}{{package.tracking_number}}{%
endif %}:** {{ package.info_text }}
{% endfor %}
{% else %}
-
{% endif %}
- action: seventeentrack.get_packages
data:
config_entry_id:
package_state:
- delivered
response_variable: delivered
- action: python_script.hass_entities
metadata: {}
data:
action: set_state_attributes
entity_id: input_text.parcels_delivered
state: "{{ 'Updated at '~ now().strftime('%H:%M')}}"
attributes:
- markdown: >
## <ha-icon icon="mdi:package-check"></ha-icon> - Delivered
({{delivered.packages|length}})
{% if delivered.packages|length > 0 %}
{% for package in delivered.packages %}
>- **{% if package.friendly_name|length > 0 %}{{
package.friendly_name }}{% else %}{{package.tracking_number}}{%
endif %}:** {{ package.info_text }}
{% endfor %}
{% else %}
-
{% endif %}
- action: seventeentrack.get_packages
data:
config_entry_id:
package_state:
- undelivered
response_variable: undelivered
- action: python_script.hass_entities
metadata: {}
data:
action: set_state_attributes
entity_id: input_text.parcels_undelivered
state: "{{ 'Updated at '~ now().strftime('%H:%M')}}"
attributes:
- markdown: >
## <ha-icon icon="mdi:archive-cancel"></ha-icon> - Undelivered
({{undelivered.packages|length}})
{% if undelivered.packages|length > 0 %}
{% for package in undelivered.packages %}
>- **{% if package.friendly_name|length > 0 %}{{
package.friendly_name }}{% else %}{{package.tracking_number}}{%
endif %}:** {{ package.info_text}}
{% endfor %}
{% else %}
-
{% endif %}
- action: seventeentrack.get_packages
data:
config_entry_id:
package_state:
- returned
response_variable: alert
- action: python_script.hass_entities
metadata: {}
data:
action: set_state_attributes
entity_id: input_text.parcels_alert
state: "{{ 'Updated at '~ now().strftime('%H:%M')}}"
attributes:
- markdown: >
## <ha-icon icon="mdi:archive-alert"></ha-icon> - Alert
({{alert.packages|length}})
{% if alert.packages|length > 0 %}
{% for package in alert.packages %}
>- **{% if package.friendly_name|length > 0 %}{{
package.friendly_name }}{% else %}{{package.tracking_number}}{%
endif %}:** {{ package.info_text}}
{% endfor %}
{% else %}
-
{% endif %}
mode: single
I set mine to update every 30 minutes, feel free to change that around so that it suits you.
After adding the code, you need to go into visual mode and select your 17Track integration here for every action (thanks to @felafel for pointing it out):
Once that is done, just add these six individually on your lovelace as markdown cards:
{{states.input_text.parcels_undelivered.attributes.markdown}}
{{states.input_text.parcels_alert.attributes.markdown}}
End result looks something like this:
Hope this helps someone!
Edit: added counters
Edit 2: added tracking number for packages without a note
Edit 3: added Undelivered and Alert statuses