Add "timestamp" attribute to seventeentrack ()

* bump py17track to 3.0.1

* Make aiohttp ClientSession optional

as introduced in py17track v3.0.0 (https://github.com/bachya/py17track/releases/tag/3.0.0)

* Update manifest.json

* add new attribute timestamp

introduced in 3.1.0

* Update requirements.txt

* Update requirements_all.txt

* Update requirements.txt

* Update requirements_test_all.txt

* Update sensor.py

* Update sensor.py

* Update manifest.json

* provide timezone configuration

user config to pre-define timezone of package status timestamps

* Update requirements_all.txt

* Update requirements_test_all.txt

* linting

* use hass.config.time_zone

* Update sensor.py

* Update test_sensor.py

* Update test_sensor.py

* black

* Update manifest.json

* adjust changes to session param

* added test against latest dev branch

* make isort happy

* make black happy

* make flake8 happy

* make black happy

* bump to 3.2.1

* 3.2.1

* Update typing 15
pull/48119/head
Andreas Brett 2021-03-19 12:34:06 +01:00 committed by GitHub
parent 4ee4d674d8
commit 993261e7f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 139 additions and 20 deletions
homeassistant/components/seventeentrack
tests/components/seventeentrack

View File

@ -2,6 +2,6 @@
"domain": "seventeentrack",
"name": "17TRACK",
"documentation": "https://www.home-assistant.io/integrations/seventeentrack",
"requirements": ["py17track==2.2.2"],
"requirements": ["py17track==3.2.1"],
"codeowners": ["@bachya"]
}

View File

@ -24,6 +24,7 @@ _LOGGER = logging.getLogger(__name__)
ATTR_DESTINATION_COUNTRY = "destination_country"
ATTR_INFO_TEXT = "info_text"
ATTR_TIMESTAMP = "timestamp"
ATTR_ORIGIN_COUNTRY = "origin_country"
ATTR_PACKAGES = "packages"
ATTR_PACKAGE_TYPE = "package_type"
@ -65,9 +66,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Configure the platform and add the sensors."""
websession = aiohttp_client.async_get_clientsession(hass)
session = aiohttp_client.async_get_clientsession(hass)
client = SeventeenTrackClient(websession)
client = SeventeenTrackClient(session=session)
try:
login_result = await client.profile.login(
@ -89,6 +90,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
scan_interval,
config[CONF_SHOW_ARCHIVED],
config[CONF_SHOW_DELIVERED],
str(hass.config.time_zone),
)
await data.async_update()
@ -151,6 +153,7 @@ class SeventeenTrackSummarySensor(Entity):
{
ATTR_FRIENDLY_NAME: package.friendly_name,
ATTR_INFO_TEXT: package.info_text,
ATTR_TIMESTAMP: package.timestamp,
ATTR_STATUS: package.status,
ATTR_LOCATION: package.location,
ATTR_TRACKING_NUMBER: package.tracking_number,
@ -172,6 +175,7 @@ class SeventeenTrackPackageSensor(Entity):
ATTR_ATTRIBUTION: DEFAULT_ATTRIBUTION,
ATTR_DESTINATION_COUNTRY: package.destination_country,
ATTR_INFO_TEXT: package.info_text,
ATTR_TIMESTAMP: package.timestamp,
ATTR_LOCATION: package.location,
ATTR_ORIGIN_COUNTRY: package.origin_country,
ATTR_PACKAGE_TYPE: package.package_type,
@ -237,7 +241,11 @@ class SeventeenTrackPackageSensor(Entity):
return
self._attrs.update(
{ATTR_INFO_TEXT: package.info_text, ATTR_LOCATION: package.location}
{
ATTR_INFO_TEXT: package.info_text,
ATTR_TIMESTAMP: package.timestamp,
ATTR_LOCATION: package.location,
}
)
self._state = package.status
self._friendly_name = package.friendly_name
@ -277,7 +285,13 @@ class SeventeenTrackData:
"""Define a data handler for 17track.net."""
def __init__(
self, client, async_add_entities, scan_interval, show_archived, show_delivered
self,
client,
async_add_entities,
scan_interval,
show_archived,
show_delivered,
timezone,
):
"""Initialize."""
self._async_add_entities = async_add_entities
@ -287,6 +301,7 @@ class SeventeenTrackData:
self.account_id = client.profile.account_id
self.packages = {}
self.show_delivered = show_delivered
self.timezone = timezone
self.summary = {}
self.async_update = Throttle(self._scan_interval)(self._async_update)
@ -297,7 +312,7 @@ class SeventeenTrackData:
try:
packages = await self._client.profile.packages(
show_archived=self._show_archived
show_archived=self._show_archived, tz=self.timezone
)
_LOGGER.debug("New package data received: %s", packages)

View File

@ -1213,7 +1213,7 @@ py-schluter==0.1.7
py-zabbix==1.1.7
# homeassistant.components.seventeentrack
py17track==2.2.2
py17track==3.2.1
# homeassistant.components.hdmi_cec
pyCEC==0.5.1

View File

@ -629,7 +629,7 @@ py-melissa-climate==2.1.4
py-nightscout==1.2.2
# homeassistant.components.seventeentrack
py17track==2.2.2
py17track==3.2.1
# homeassistant.components.control4
pyControl4==0.0.6

View File

@ -71,7 +71,7 @@ NEW_SUMMARY_DATA = {
class ClientMock:
"""Mock the py17track client to inject the ProfileMock."""
def __init__(self, websession) -> None:
def __init__(self, session) -> None:
"""Mock the profile."""
self.profile = ProfileMock()
@ -101,7 +101,10 @@ class ProfileMock:
return self.__class__.login_result
async def packages(
self, package_state: int | str = "", show_archived: bool = False
self,
package_state: int | str = "",
show_archived: bool = False,
tz: str = "UTC",
) -> list:
"""Packages mock."""
return self.__class__.package_list[:]
@ -169,7 +172,14 @@ async def test_invalid_config(hass):
async def test_add_package(hass):
"""Ensure package is added correctly when user add a new package."""
package = Package(
"456", 206, "friendly name 1", "info text 1", "location 1", 206, 2
"456",
206,
"friendly name 1",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
)
ProfileMock.package_list = [package]
@ -178,7 +188,14 @@ async def test_add_package(hass):
assert len(hass.states.async_entity_ids()) == 1
package2 = Package(
"789", 206, "friendly name 2", "info text 2", "location 2", 206, 2
"789",
206,
"friendly name 2",
"info text 2",
"location 2",
"2020-08-10 14:25",
206,
2,
)
ProfileMock.package_list = [package, package2]
@ -191,10 +208,24 @@ async def test_add_package(hass):
async def test_remove_package(hass):
"""Ensure entity is not there anymore if package is not there."""
package1 = Package(
"456", 206, "friendly name 1", "info text 1", "location 1", 206, 2
"456",
206,
"friendly name 1",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
)
package2 = Package(
"789", 206, "friendly name 2", "info text 2", "location 2", 206, 2
"789",
206,
"friendly name 2",
"info text 2",
"location 2",
"2020-08-10 14:25",
206,
2,
)
ProfileMock.package_list = [package1, package2]
@ -217,7 +248,14 @@ async def test_remove_package(hass):
async def test_friendly_name_changed(hass):
"""Test friendly name change."""
package = Package(
"456", 206, "friendly name 1", "info text 1", "location 1", 206, 2
"456",
206,
"friendly name 1",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
)
ProfileMock.package_list = [package]
@ -227,7 +265,14 @@ async def test_friendly_name_changed(hass):
assert len(hass.states.async_entity_ids()) == 1
package = Package(
"456", 206, "friendly name 2", "info text 1", "location 1", 206, 2
"456",
206,
"friendly name 2",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
)
ProfileMock.package_list = [package]
@ -244,7 +289,15 @@ async def test_friendly_name_changed(hass):
async def test_delivered_not_shown(hass):
"""Ensure delivered packages are not shown."""
package = Package(
"456", 206, "friendly name 1", "info text 1", "location 1", 206, 2, 40
"456",
206,
"friendly name 1",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
40,
)
ProfileMock.package_list = [package]
@ -259,7 +312,15 @@ async def test_delivered_not_shown(hass):
async def test_delivered_shown(hass):
"""Ensure delivered packages are show when user choose to show them."""
package = Package(
"456", 206, "friendly name 1", "info text 1", "location 1", 206, 2, 40
"456",
206,
"friendly name 1",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
40,
)
ProfileMock.package_list = [package]
@ -274,7 +335,14 @@ async def test_delivered_shown(hass):
async def test_becomes_delivered_not_shown_notification(hass):
"""Ensure notification is triggered when package becomes delivered."""
package = Package(
"456", 206, "friendly name 1", "info text 1", "location 1", 206, 2
"456",
206,
"friendly name 1",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
)
ProfileMock.package_list = [package]
@ -284,7 +352,15 @@ async def test_becomes_delivered_not_shown_notification(hass):
assert len(hass.states.async_entity_ids()) == 1
package_delivered = Package(
"456", 206, "friendly name 1", "info text 1", "location 1", 206, 2, 40
"456",
206,
"friendly name 1",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
40,
)
ProfileMock.package_list = [package_delivered]
@ -310,3 +386,31 @@ async def test_summary_correctly_updated(hass):
assert len(hass.states.async_entity_ids()) == 7
for state in hass.states.async_all():
assert state.state == "1"
async def test_utc_timestamp(hass):
"""Ensure package timestamp is converted correctly from HA-defined time zone to UTC."""
package = Package(
"456",
206,
"friendly name 1",
"info text 1",
"location 1",
"2020-08-10 10:32",
206,
2,
tz="Asia/Jakarta",
)
ProfileMock.package_list = [package]
await _setup_seventeentrack(hass)
assert hass.states.get("sensor.seventeentrack_package_456") is not None
assert len(hass.states.async_entity_ids()) == 1
assert (
str(
hass.states.get("sensor.seventeentrack_package_456").attributes.get(
"timestamp"
)
)
== "2020-08-10 03:32:00+00:00"
)