Skip to content

Commit 108922c

Browse files
committed
Add get_earliest_order utility function and update sensors to use it for delivery time calculations.
1 parent f127f7a commit 108922c

3 files changed

Lines changed: 84 additions & 17 deletions

File tree

custom_components/rohlikcz/binary_sensor.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
ICON_CALENDAR_REMOVE
1515
from .entity import BaseEntity
1616
from .hub import RohlikAccount
17+
from .utils import get_earliest_order
1718

1819
async def async_setup_entry(
1920
hass: HomeAssistant,
@@ -166,8 +167,8 @@ def is_on(self) -> bool | None:
166167
@property
167168
def extra_state_attributes(self) -> dict | None:
168169
next_orders = self._rohlik_account.data.get('next_order', [])
169-
if next_orders and len(next_orders) > 0:
170-
order = next_orders[0] # Get the first next order
170+
order = get_earliest_order(next_orders)
171+
if order:
171172
return {
172173
"order_data": order
173174
}

custom_components/rohlikcz/sensor.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
ICON_NEXT_ORDER_TILL, ICON_INFO, ICON_DELIVERY_TIME, ICON_MONTHLY_SPENT
2020
from .entity import BaseEntity
2121
from .hub import RohlikAccount
22-
from .utils import extract_delivery_datetime, calculate_current_month_orders_total
22+
from .utils import extract_delivery_datetime, calculate_current_month_orders_total, get_earliest_order
2323

2424
SCAN_INTERVAL = timedelta(seconds=600)
2525

@@ -598,13 +598,22 @@ class NextOrderSince(BaseEntity, SensorEntity):
598598

599599
@property
600600
def native_value(self) -> datetime | None:
601-
"""Returns remaining orders without limit."""
602-
if len(self._rohlik_account.data['next_order']) > 0:
603-
slot_start = datetime.strptime(self._rohlik_account.data["next_order"][0].get("deliverySlot", {}).get("since", None),
604-
"%Y-%m-%dT%H:%M:%S.%f%z")
605-
return slot_start
606-
else:
607-
return None
601+
"""Returns start of delivery window for the earliest order."""
602+
earliest_order = get_earliest_order(self._rohlik_account.data.get('next_order', []))
603+
if earliest_order:
604+
try:
605+
slot_start = datetime.strptime(earliest_order.get("deliverySlot", {}).get("since", None),
606+
"%Y-%m-%dT%H:%M:%S.%f%z")
607+
return slot_start
608+
except (ValueError, TypeError):
609+
# Try without microseconds if the format doesn't match
610+
try:
611+
slot_start = datetime.strptime(earliest_order.get("deliverySlot", {}).get("since", None),
612+
"%Y-%m-%dT%H:%M:%S%z")
613+
return slot_start
614+
except (ValueError, TypeError):
615+
return None
616+
return None
608617

609618
@property
610619
def icon(self) -> str:
@@ -625,13 +634,22 @@ class NextOrderTill(BaseEntity, SensorEntity):
625634

626635
@property
627636
def native_value(self) -> datetime | None:
628-
"""Returns remaining orders without limit."""
629-
if len(self._rohlik_account.data['next_order']) > 0:
630-
slot_start = datetime.strptime(self._rohlik_account.data["next_order"][0].get("deliverySlot", {}).get("till", None),
637+
"""Returns end of delivery window for the earliest order."""
638+
earliest_order = get_earliest_order(self._rohlik_account.data.get('next_order', []))
639+
if earliest_order:
640+
try:
641+
slot_end = datetime.strptime(earliest_order.get("deliverySlot", {}).get("till", None),
631642
"%Y-%m-%dT%H:%M:%S.%f%z")
632-
return slot_start
633-
else:
634-
return None
643+
return slot_end
644+
except (ValueError, TypeError):
645+
# Try without microseconds if the format doesn't match
646+
try:
647+
slot_end = datetime.strptime(earliest_order.get("deliverySlot", {}).get("till", None),
648+
"%Y-%m-%dT%H:%M:%S%z")
649+
return slot_end
650+
except (ValueError, TypeError):
651+
return None
652+
return None
635653

636654
@property
637655
def icon(self) -> str:

custom_components/rohlikcz/utils.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,52 @@ def extract_delivery_datetime(text: str) -> datetime | None:
159159
pass
160160

161161
# No valid time information found
162-
return None
162+
return None
163+
164+
165+
def get_earliest_order(orders: list) -> dict | None:
166+
"""
167+
Find the order with the earliest delivery time from a list of orders.
168+
169+
Args:
170+
orders (list): List of order dictionaries, each containing a 'deliverySlot' with 'since' field
171+
172+
Returns:
173+
dict: The order with the earliest delivery time, or None if no valid order found
174+
"""
175+
if not orders or len(orders) == 0:
176+
return None
177+
178+
earliest_order = None
179+
earliest_time = None
180+
181+
for order in orders:
182+
try:
183+
# Extract delivery slot and since time
184+
delivery_slot = order.get("deliverySlot", {})
185+
since_str = delivery_slot.get("since", None)
186+
187+
if since_str is None:
188+
continue
189+
190+
# Parse the datetime string (format: "%Y-%m-%dT%H:%M:%S.%f%z")
191+
try:
192+
delivery_time = datetime.strptime(since_str, "%Y-%m-%dT%H:%M:%S.%f%z")
193+
except ValueError:
194+
# Try without microseconds if the format doesn't match
195+
try:
196+
delivery_time = datetime.strptime(since_str, "%Y-%m-%dT%H:%M:%S%z")
197+
except ValueError:
198+
# Skip orders with invalid date format
199+
continue
200+
201+
# Check if this is the earliest order so far
202+
if earliest_time is None or delivery_time < earliest_time:
203+
earliest_time = delivery_time
204+
earliest_order = order
205+
206+
except (KeyError, TypeError, AttributeError):
207+
# Skip orders with missing or invalid structure
208+
continue
209+
210+
return earliest_order

0 commit comments

Comments
 (0)