From e71f8c444b42a2727b0d3bd8f84ca94c4fb64879 Mon Sep 17 00:00:00 2001 From: Manu <4445816+tr4nt0r@users.noreply.github.com> Date: Tue, 11 Feb 2025 11:41:11 +0100 Subject: [PATCH] Add user profile info to Habitica sensor and device URL (#137152) Add user profile attributes to Habitica sensor and device URL --- homeassistant/components/habitica/entity.py | 8 +++++++- homeassistant/components/habitica/sensor.py | 20 +++++++++++++++++++ .../components/habitica/strings.json | 16 ++++++++++++++- tests/components/habitica/fixtures/user.json | 17 +++++++++++++--- .../habitica/snapshots/test_sensor.ambr | 5 +++++ 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/habitica/entity.py b/homeassistant/components/habitica/entity.py index 932fec69f83..692ea5e5ac1 100644 --- a/homeassistant/components/habitica/entity.py +++ b/homeassistant/components/habitica/entity.py @@ -4,6 +4,8 @@ from __future__ import annotations from typing import TYPE_CHECKING +from yarl import URL + from homeassistant.const import CONF_NAME, CONF_URL from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.entity import EntityDescription @@ -36,6 +38,10 @@ class HabiticaBase(CoordinatorEntity[HabiticaDataUpdateCoordinator]): manufacturer=MANUFACTURER, model=NAME, name=coordinator.config_entry.data[CONF_NAME], - configuration_url=coordinator.config_entry.data[CONF_URL], + configuration_url=( + URL(coordinator.config_entry.data[CONF_URL]) + / "profile" + / coordinator.config_entry.unique_id + ), identifiers={(DOMAIN, coordinator.config_entry.unique_id)}, ) diff --git a/homeassistant/components/habitica/sensor.py b/homeassistant/components/habitica/sensor.py index e89bd0e7006..e715dd6d07b 100644 --- a/homeassistant/components/habitica/sensor.py +++ b/homeassistant/components/habitica/sensor.py @@ -35,6 +35,7 @@ from homeassistant.helpers.issue_registry import ( async_delete_issue, ) from homeassistant.helpers.typing import StateType +from homeassistant.util import dt as dt_util from .const import ASSETS_URL, DOMAIN from .coordinator import HabiticaConfigEntry, HabiticaDataUpdateCoordinator @@ -105,6 +106,20 @@ SENSOR_DESCRIPTIONS: tuple[HabiticaSensorEntityDescription, ...] = ( key=HabiticaSensorEntity.DISPLAY_NAME, translation_key=HabiticaSensorEntity.DISPLAY_NAME, value_fn=lambda user, _: user.profile.name, + attributes_fn=lambda user, _: { + "blurb": user.profile.blurb, + "joined": ( + dt_util.as_local(joined).date() + if (joined := user.auth.timestamps.created) + else None + ), + "last_login": ( + dt_util.as_local(last).date() + if (last := user.auth.timestamps.loggedin) + else None + ), + "total_logins": user.loginIncentives, + }, ), HabiticaSensorEntityDescription( key=HabiticaSensorEntity.HEALTH, @@ -393,6 +408,11 @@ class HabiticaSensor(HabiticaBase, SensorEntity): ): return SVG_CLASS[_class] + if self.entity_description.key is HabiticaSensorEntity.DISPLAY_NAME and ( + img_url := self.coordinator.data.user.profile.imageUrl + ): + return img_url + if entity_picture := self.entity_description.entity_picture: return ( entity_picture diff --git a/homeassistant/components/habitica/strings.json b/homeassistant/components/habitica/strings.json index 4d353cec40e..a5f64dca7c2 100644 --- a/homeassistant/components/habitica/strings.json +++ b/homeassistant/components/habitica/strings.json @@ -199,7 +199,21 @@ }, "sensor": { "display_name": { - "name": "Display name" + "name": "Display name", + "state_attributes": { + "blurb": { + "name": "About" + }, + "joined": { + "name": "Joined" + }, + "last_login": { + "name": "Last login" + }, + "total_logins": { + "name": "Total logins" + } + } }, "health": { "name": "Health", diff --git a/tests/components/habitica/fixtures/user.json b/tests/components/habitica/fixtures/user.json index 991f2db0ba8..58eca2837b6 100644 --- a/tests/components/habitica/fixtures/user.json +++ b/tests/components/habitica/fixtures/user.json @@ -2,8 +2,18 @@ "success": true, "data": { "api_user": "test-api-user", - "profile": { "name": "test-user" }, - "auth": { "local": { "username": "test-username" } }, + "profile": { + "name": "test-user", + "blurb": "My mind is a swirling miasma of scintillating thoughts and turgid ideas.", + "imageUrl": "https://pbs.twimg.com/profile_images/378800000771780608/a32e71fe6a64eba6773c20d289eddc8e.png" + }, + "auth": { + "local": { "username": "test-username" }, + "timestamps": { + "created": "2013-12-02T22:23:29.249Z", + "loggedin": "2025-02-02T03:14:33.864Z" + } + }, "stats": { "buffs": { "str": 26, @@ -162,6 +172,7 @@ "createdAt": "2025-02-08T22:06:08.894Z", "updatedAt": "2025-02-08T22:06:17.195Z" } - ] + ], + "loginIncentives": 241 } } diff --git a/tests/components/habitica/snapshots/test_sensor.ambr b/tests/components/habitica/snapshots/test_sensor.ambr index 110bde5e60d..881326f76d8 100644 --- a/tests/components/habitica/snapshots/test_sensor.ambr +++ b/tests/components/habitica/snapshots/test_sensor.ambr @@ -154,7 +154,12 @@ # name: test_sensors[sensor.test_user_display_name-state] StateSnapshot({ 'attributes': ReadOnlyDict({ + 'blurb': 'My mind is a swirling miasma of scintillating thoughts and turgid ideas.', + 'entity_picture': 'https://pbs.twimg.com/profile_images/378800000771780608/a32e71fe6a64eba6773c20d289eddc8e.png', 'friendly_name': 'test-user Display name', + 'joined': datetime.date(2013, 12, 2), + 'last_login': datetime.date(2025, 2, 1), + 'total_logins': 241, }), 'context': , 'entity_id': 'sensor.test_user_display_name',