Add get_assets filtering: offset, on_this_day, city, state, country
All checks were successful
Validate / Hassfest (push) Successful in 3s
All checks were successful
Validate / Hassfest (push) Successful in 3s
- Add offset parameter for pagination support - Add on_this_day parameter for memories filtering (match month and day) - Add city, state, country parameters for geolocation filtering - Update README with new parameters and examples Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
76
README.md
76
README.md
@@ -143,6 +143,7 @@ target:
|
|||||||
entity_id: sensor.album_name_asset_limit
|
entity_id: sensor.album_name_asset_limit
|
||||||
data:
|
data:
|
||||||
limit: 10 # Maximum number of assets (1-100)
|
limit: 10 # Maximum number of assets (1-100)
|
||||||
|
offset: 0 # Number of assets to skip (for pagination)
|
||||||
favorite_only: false # true = favorites only, false = all assets
|
favorite_only: false # true = favorites only, false = all assets
|
||||||
filter_min_rating: 4 # Min rating (1-5)
|
filter_min_rating: 4 # Min rating (1-5)
|
||||||
order_by: "date" # Options: "date", "rating", "name", "random"
|
order_by: "date" # Options: "date", "rating", "name", "random"
|
||||||
@@ -150,11 +151,16 @@ data:
|
|||||||
asset_type: "all" # Options: "all", "photo", "video"
|
asset_type: "all" # Options: "all", "photo", "video"
|
||||||
min_date: "2024-01-01" # Optional: assets created on or after this date
|
min_date: "2024-01-01" # Optional: assets created on or after this date
|
||||||
max_date: "2024-12-31" # Optional: assets created on or before this date
|
max_date: "2024-12-31" # Optional: assets created on or before this date
|
||||||
|
on_this_day: "2024-02-14" # Optional: filter by month and day (memories)
|
||||||
|
city: "Paris" # Optional: filter by city name
|
||||||
|
state: "California" # Optional: filter by state/region
|
||||||
|
country: "France" # Optional: filter by country
|
||||||
```
|
```
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `limit` (optional, default: 10): Maximum number of assets to return (1-100)
|
- `limit` (optional, default: 10): Maximum number of assets to return (1-100)
|
||||||
|
- `offset` (optional, default: 0): Number of assets to skip before returning results. Use with `limit` for pagination (e.g., `offset: 0, limit: 10` for first page, `offset: 10, limit: 10` for second page)
|
||||||
- `favorite_only` (optional, default: false): Filter to show only favorite assets
|
- `favorite_only` (optional, default: false): Filter to show only favorite assets
|
||||||
- `filter_min_rating` (optional, default: 1): Minimum rating for assets (1-5 stars). Applied independently of `favorite_only`
|
- `filter_min_rating` (optional, default: 1): Minimum rating for assets (1-5 stars). Applied independently of `favorite_only`
|
||||||
- `order_by` (optional, default: "date"): Field to sort assets by
|
- `order_by` (optional, default: "date"): Field to sort assets by
|
||||||
@@ -171,6 +177,10 @@ data:
|
|||||||
- `"video"`: Return only videos
|
- `"video"`: Return only videos
|
||||||
- `min_date` (optional): Filter assets created on or after this date. Use ISO 8601 format (e.g., `"2024-01-01"` or `"2024-01-01T10:30:00"`)
|
- `min_date` (optional): Filter assets created on or after this date. Use ISO 8601 format (e.g., `"2024-01-01"` or `"2024-01-01T10:30:00"`)
|
||||||
- `max_date` (optional): Filter assets created on or before this date. Use ISO 8601 format (e.g., `"2024-12-31"` or `"2024-12-31T23:59:59"`)
|
- `max_date` (optional): Filter assets created on or before this date. Use ISO 8601 format (e.g., `"2024-12-31"` or `"2024-12-31T23:59:59"`)
|
||||||
|
- `on_this_day` (optional): Filter assets by matching month and day (memories/anniversary filter). Provide a date in ISO 8601 format (e.g., `"2024-02-14"`) to get all assets taken on February 14th of any year
|
||||||
|
- `city` (optional): Filter assets by city name (case-insensitive substring match). Based on reverse geocoded location from asset GPS data
|
||||||
|
- `state` (optional): Filter assets by state/region name (case-insensitive substring match). Based on reverse geocoded location from asset GPS data
|
||||||
|
- `country` (optional): Filter assets by country name (case-insensitive substring match). Based on reverse geocoded location from asset GPS data
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
@@ -254,6 +264,72 @@ data:
|
|||||||
order: "descending"
|
order: "descending"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Get "On This Day" memories (photos from today's date in previous years):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
service: immich_album_watcher.get_assets
|
||||||
|
target:
|
||||||
|
entity_id: sensor.album_name_asset_limit
|
||||||
|
data:
|
||||||
|
limit: 20
|
||||||
|
on_this_day: "{{ now().strftime('%Y-%m-%d') }}"
|
||||||
|
order_by: "date"
|
||||||
|
order: "ascending"
|
||||||
|
```
|
||||||
|
|
||||||
|
Paginate through all assets (first page):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
service: immich_album_watcher.get_assets
|
||||||
|
target:
|
||||||
|
entity_id: sensor.album_name_asset_limit
|
||||||
|
data:
|
||||||
|
limit: 10
|
||||||
|
offset: 0
|
||||||
|
order_by: "date"
|
||||||
|
order: "descending"
|
||||||
|
```
|
||||||
|
|
||||||
|
Paginate through all assets (second page):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
service: immich_album_watcher.get_assets
|
||||||
|
target:
|
||||||
|
entity_id: sensor.album_name_asset_limit
|
||||||
|
data:
|
||||||
|
limit: 10
|
||||||
|
offset: 10
|
||||||
|
order_by: "date"
|
||||||
|
order: "descending"
|
||||||
|
```
|
||||||
|
|
||||||
|
Get photos taken in a specific city:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
service: immich_album_watcher.get_assets
|
||||||
|
target:
|
||||||
|
entity_id: sensor.album_name_asset_limit
|
||||||
|
data:
|
||||||
|
limit: 50
|
||||||
|
city: "Paris"
|
||||||
|
asset_type: "photo"
|
||||||
|
order_by: "date"
|
||||||
|
order: "descending"
|
||||||
|
```
|
||||||
|
|
||||||
|
Get all assets from a specific country:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
service: immich_album_watcher.get_assets
|
||||||
|
target:
|
||||||
|
entity_id: sensor.album_name_asset_limit
|
||||||
|
data:
|
||||||
|
limit: 100
|
||||||
|
country: "Japan"
|
||||||
|
order_by: "date"
|
||||||
|
order: "ascending"
|
||||||
|
```
|
||||||
|
|
||||||
### Send Telegram Notification
|
### Send Telegram Notification
|
||||||
|
|
||||||
Send notifications to Telegram. Supports multiple formats:
|
Send notifications to Telegram. Supports multiple formats:
|
||||||
|
|||||||
@@ -435,6 +435,7 @@ class ImmichAlbumWatcherCoordinator(DataUpdateCoordinator[AlbumData | None]):
|
|||||||
async def async_get_assets(
|
async def async_get_assets(
|
||||||
self,
|
self,
|
||||||
limit: int = 10,
|
limit: int = 10,
|
||||||
|
offset: int = 0,
|
||||||
favorite_only: bool = False,
|
favorite_only: bool = False,
|
||||||
filter_min_rating: int = 1,
|
filter_min_rating: int = 1,
|
||||||
order_by: str = "date",
|
order_by: str = "date",
|
||||||
@@ -442,11 +443,16 @@ class ImmichAlbumWatcherCoordinator(DataUpdateCoordinator[AlbumData | None]):
|
|||||||
asset_type: str = "all",
|
asset_type: str = "all",
|
||||||
min_date: str | None = None,
|
min_date: str | None = None,
|
||||||
max_date: str | None = None,
|
max_date: str | None = None,
|
||||||
|
on_this_day: str | None = None,
|
||||||
|
city: str | None = None,
|
||||||
|
state: str | None = None,
|
||||||
|
country: str | None = None,
|
||||||
) -> list[dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
"""Get assets from the album with optional filtering and ordering.
|
"""Get assets from the album with optional filtering and ordering.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
limit: Maximum number of assets to return (1-100)
|
limit: Maximum number of assets to return (1-100)
|
||||||
|
offset: Number of assets to skip before returning results (for pagination)
|
||||||
favorite_only: Filter to show only favorite assets
|
favorite_only: Filter to show only favorite assets
|
||||||
filter_min_rating: Minimum rating for assets (1-5)
|
filter_min_rating: Minimum rating for assets (1-5)
|
||||||
order_by: Field to sort by - 'date', 'rating', or 'name'
|
order_by: Field to sort by - 'date', 'rating', or 'name'
|
||||||
@@ -454,6 +460,10 @@ class ImmichAlbumWatcherCoordinator(DataUpdateCoordinator[AlbumData | None]):
|
|||||||
asset_type: Asset type filter - 'all', 'photo', or 'video'
|
asset_type: Asset type filter - 'all', 'photo', or 'video'
|
||||||
min_date: Filter assets created on or after this date (ISO 8601 format)
|
min_date: Filter assets created on or after this date (ISO 8601 format)
|
||||||
max_date: Filter assets created on or before this date (ISO 8601 format)
|
max_date: Filter assets created on or before this date (ISO 8601 format)
|
||||||
|
on_this_day: Filter assets by matching month and day (ISO 8601 format)
|
||||||
|
city: Filter assets by city (case-insensitive substring match)
|
||||||
|
state: Filter assets by state/region (case-insensitive substring match)
|
||||||
|
country: Filter assets by country (case-insensitive substring match)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of asset data dictionaries
|
List of asset data dictionaries
|
||||||
@@ -484,6 +494,39 @@ class ImmichAlbumWatcherCoordinator(DataUpdateCoordinator[AlbumData | None]):
|
|||||||
if max_date:
|
if max_date:
|
||||||
assets = [a for a in assets if a.created_at <= max_date]
|
assets = [a for a in assets if a.created_at <= max_date]
|
||||||
|
|
||||||
|
# Apply "on this day" filtering (match month and day)
|
||||||
|
if on_this_day:
|
||||||
|
try:
|
||||||
|
# Parse the reference date (supports ISO 8601 format)
|
||||||
|
ref_date = datetime.fromisoformat(on_this_day.replace("Z", "+00:00"))
|
||||||
|
ref_month = ref_date.month
|
||||||
|
ref_day = ref_date.day
|
||||||
|
|
||||||
|
def matches_day(asset: AssetInfo) -> bool:
|
||||||
|
"""Check if asset's date matches the reference month and day."""
|
||||||
|
try:
|
||||||
|
asset_date = datetime.fromisoformat(
|
||||||
|
asset.created_at.replace("Z", "+00:00")
|
||||||
|
)
|
||||||
|
return asset_date.month == ref_month and asset_date.day == ref_day
|
||||||
|
except (ValueError, AttributeError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
assets = [a for a in assets if matches_day(a)]
|
||||||
|
except ValueError:
|
||||||
|
_LOGGER.warning("Invalid on_this_day date format: %s", on_this_day)
|
||||||
|
|
||||||
|
# Apply geolocation filtering (case-insensitive substring match)
|
||||||
|
if city:
|
||||||
|
city_lower = city.lower()
|
||||||
|
assets = [a for a in assets if a.city and city_lower in a.city.lower()]
|
||||||
|
if state:
|
||||||
|
state_lower = state.lower()
|
||||||
|
assets = [a for a in assets if a.state and state_lower in a.state.lower()]
|
||||||
|
if country:
|
||||||
|
country_lower = country.lower()
|
||||||
|
assets = [a for a in assets if a.country and country_lower in a.country.lower()]
|
||||||
|
|
||||||
# Apply ordering
|
# Apply ordering
|
||||||
if order_by == "random":
|
if order_by == "random":
|
||||||
import random
|
import random
|
||||||
@@ -508,8 +551,8 @@ class ImmichAlbumWatcherCoordinator(DataUpdateCoordinator[AlbumData | None]):
|
|||||||
reverse=(order == "descending")
|
reverse=(order == "descending")
|
||||||
)
|
)
|
||||||
|
|
||||||
# Limit results
|
# Apply offset and limit for pagination
|
||||||
assets = assets[:limit]
|
assets = assets[offset : offset + limit]
|
||||||
|
|
||||||
# Build result with all available asset data (matching event data)
|
# Build result with all available asset data (matching event data)
|
||||||
result = []
|
result = []
|
||||||
|
|||||||
@@ -8,5 +8,5 @@
|
|||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"issue_tracker": "https://github.com/DolgolyovAlexei/haos-hacs-immich-album-watcher/issues",
|
"issue_tracker": "https://github.com/DolgolyovAlexei/haos-hacs-immich-album-watcher/issues",
|
||||||
"requirements": [],
|
"requirements": [],
|
||||||
"version": "2.6.0"
|
"version": "2.7.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ async def async_setup_entry(
|
|||||||
vol.Optional("limit", default=10): vol.All(
|
vol.Optional("limit", default=10): vol.All(
|
||||||
vol.Coerce(int), vol.Range(min=1, max=100)
|
vol.Coerce(int), vol.Range(min=1, max=100)
|
||||||
),
|
),
|
||||||
|
vol.Optional("offset", default=0): vol.All(
|
||||||
|
vol.Coerce(int), vol.Range(min=0)
|
||||||
|
),
|
||||||
vol.Optional("favorite_only", default=False): bool,
|
vol.Optional("favorite_only", default=False): bool,
|
||||||
vol.Optional("filter_min_rating", default=1): vol.All(
|
vol.Optional("filter_min_rating", default=1): vol.All(
|
||||||
vol.Coerce(int), vol.Range(min=1, max=5)
|
vol.Coerce(int), vol.Range(min=1, max=5)
|
||||||
@@ -111,6 +114,10 @@ async def async_setup_entry(
|
|||||||
vol.Optional("asset_type", default="all"): vol.In(["all", "photo", "video"]),
|
vol.Optional("asset_type", default="all"): vol.In(["all", "photo", "video"]),
|
||||||
vol.Optional("min_date"): str,
|
vol.Optional("min_date"): str,
|
||||||
vol.Optional("max_date"): str,
|
vol.Optional("max_date"): str,
|
||||||
|
vol.Optional("on_this_day"): str,
|
||||||
|
vol.Optional("city"): str,
|
||||||
|
vol.Optional("state"): str,
|
||||||
|
vol.Optional("country"): str,
|
||||||
},
|
},
|
||||||
"async_get_assets",
|
"async_get_assets",
|
||||||
supports_response=SupportsResponse.ONLY,
|
supports_response=SupportsResponse.ONLY,
|
||||||
@@ -196,6 +203,7 @@ class ImmichAlbumBaseSensor(CoordinatorEntity[ImmichAlbumWatcherCoordinator], Se
|
|||||||
async def async_get_assets(
|
async def async_get_assets(
|
||||||
self,
|
self,
|
||||||
limit: int = 10,
|
limit: int = 10,
|
||||||
|
offset: int = 0,
|
||||||
favorite_only: bool = False,
|
favorite_only: bool = False,
|
||||||
filter_min_rating: int = 1,
|
filter_min_rating: int = 1,
|
||||||
order_by: str = "date",
|
order_by: str = "date",
|
||||||
@@ -203,10 +211,15 @@ class ImmichAlbumBaseSensor(CoordinatorEntity[ImmichAlbumWatcherCoordinator], Se
|
|||||||
asset_type: str = "all",
|
asset_type: str = "all",
|
||||||
min_date: str | None = None,
|
min_date: str | None = None,
|
||||||
max_date: str | None = None,
|
max_date: str | None = None,
|
||||||
|
on_this_day: str | None = None,
|
||||||
|
city: str | None = None,
|
||||||
|
state: str | None = None,
|
||||||
|
country: str | None = None,
|
||||||
) -> ServiceResponse:
|
) -> ServiceResponse:
|
||||||
"""Get assets for this album with optional filtering and ordering."""
|
"""Get assets for this album with optional filtering and ordering."""
|
||||||
assets = await self.coordinator.async_get_assets(
|
assets = await self.coordinator.async_get_assets(
|
||||||
limit=limit,
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
favorite_only=favorite_only,
|
favorite_only=favorite_only,
|
||||||
filter_min_rating=filter_min_rating,
|
filter_min_rating=filter_min_rating,
|
||||||
order_by=order_by,
|
order_by=order_by,
|
||||||
@@ -214,6 +227,10 @@ class ImmichAlbumBaseSensor(CoordinatorEntity[ImmichAlbumWatcherCoordinator], Se
|
|||||||
asset_type=asset_type,
|
asset_type=asset_type,
|
||||||
min_date=min_date,
|
min_date=min_date,
|
||||||
max_date=max_date,
|
max_date=max_date,
|
||||||
|
on_this_day=on_this_day,
|
||||||
|
city=city,
|
||||||
|
state=state,
|
||||||
|
country=country,
|
||||||
)
|
)
|
||||||
return {"assets": assets}
|
return {"assets": assets}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,15 @@ get_assets:
|
|||||||
min: 1
|
min: 1
|
||||||
max: 100
|
max: 100
|
||||||
mode: slider
|
mode: slider
|
||||||
|
offset:
|
||||||
|
name: Offset
|
||||||
|
description: Number of assets to skip before returning results (for pagination). Use with limit to fetch assets in pages.
|
||||||
|
required: false
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
mode: box
|
||||||
favorite_only:
|
favorite_only:
|
||||||
name: Favorite Only
|
name: Favorite Only
|
||||||
description: Filter to show only favorite assets.
|
description: Filter to show only favorite assets.
|
||||||
@@ -95,6 +104,30 @@ get_assets:
|
|||||||
required: false
|
required: false
|
||||||
selector:
|
selector:
|
||||||
text:
|
text:
|
||||||
|
on_this_day:
|
||||||
|
name: On This Day
|
||||||
|
description: Filter assets by matching month and day (memories/anniversary filter). Provide a date in ISO 8601 format (e.g., 2024-02-14) to get all assets taken on February 14th of any year.
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
city:
|
||||||
|
name: City
|
||||||
|
description: Filter assets by city name (case-insensitive substring match). Based on reverse geocoded location from asset GPS data.
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
state:
|
||||||
|
name: State
|
||||||
|
description: Filter assets by state/region name (case-insensitive substring match). Based on reverse geocoded location from asset GPS data.
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
country:
|
||||||
|
name: Country
|
||||||
|
description: Filter assets by country name (case-insensitive substring match). Based on reverse geocoded location from asset GPS data.
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
send_telegram_notification:
|
send_telegram_notification:
|
||||||
name: Send Telegram Notification
|
name: Send Telegram Notification
|
||||||
|
|||||||
@@ -143,6 +143,10 @@
|
|||||||
"name": "Limit",
|
"name": "Limit",
|
||||||
"description": "Maximum number of assets to return (1-100)."
|
"description": "Maximum number of assets to return (1-100)."
|
||||||
},
|
},
|
||||||
|
"offset": {
|
||||||
|
"name": "Offset",
|
||||||
|
"description": "Number of assets to skip (for pagination)."
|
||||||
|
},
|
||||||
"favorite_only": {
|
"favorite_only": {
|
||||||
"name": "Favorite Only",
|
"name": "Favorite Only",
|
||||||
"description": "Filter to show only favorite assets."
|
"description": "Filter to show only favorite assets."
|
||||||
@@ -170,6 +174,22 @@
|
|||||||
"max_date": {
|
"max_date": {
|
||||||
"name": "Maximum Date",
|
"name": "Maximum Date",
|
||||||
"description": "Filter assets created on or before this date (ISO 8601 format)."
|
"description": "Filter assets created on or before this date (ISO 8601 format)."
|
||||||
|
},
|
||||||
|
"on_this_day": {
|
||||||
|
"name": "On This Day",
|
||||||
|
"description": "Filter assets by matching month and day (memories/anniversary filter)."
|
||||||
|
},
|
||||||
|
"city": {
|
||||||
|
"name": "City",
|
||||||
|
"description": "Filter assets by city name (case-insensitive)."
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"name": "State",
|
||||||
|
"description": "Filter assets by state/region name (case-insensitive)."
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"name": "Country",
|
||||||
|
"description": "Filter assets by country name (case-insensitive)."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -143,6 +143,10 @@
|
|||||||
"name": "Лимит",
|
"name": "Лимит",
|
||||||
"description": "Максимальное количество возвращаемых файлов (1-100)."
|
"description": "Максимальное количество возвращаемых файлов (1-100)."
|
||||||
},
|
},
|
||||||
|
"offset": {
|
||||||
|
"name": "Смещение",
|
||||||
|
"description": "Количество файлов для пропуска (для пагинации)."
|
||||||
|
},
|
||||||
"favorite_only": {
|
"favorite_only": {
|
||||||
"name": "Только избранные",
|
"name": "Только избранные",
|
||||||
"description": "Фильтр для отображения только избранных файлов."
|
"description": "Фильтр для отображения только избранных файлов."
|
||||||
@@ -170,6 +174,22 @@
|
|||||||
"max_date": {
|
"max_date": {
|
||||||
"name": "Максимальная дата",
|
"name": "Максимальная дата",
|
||||||
"description": "Фильтровать файлы, созданные в эту дату или до (формат ISO 8601)."
|
"description": "Фильтровать файлы, созданные в эту дату или до (формат ISO 8601)."
|
||||||
|
},
|
||||||
|
"on_this_day": {
|
||||||
|
"name": "В этот день",
|
||||||
|
"description": "Фильтр по совпадению месяца и дня (воспоминания/годовщины)."
|
||||||
|
},
|
||||||
|
"city": {
|
||||||
|
"name": "Город",
|
||||||
|
"description": "Фильтр по названию города (без учёта регистра)."
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"name": "Регион",
|
||||||
|
"description": "Фильтр по названию региона/области (без учёта регистра)."
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"name": "Страна",
|
||||||
|
"description": "Фильтр по названию страны (без учёта регистра)."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user