mirror of
https://github.com/home-assistant/core.git
synced 2025-07-11 15:27:08 +00:00
Move picnic sensor definitions (#91367)
* Move types and mixin to sensor * Move types and mixin to sensor
This commit is contained in:
parent
c40836b49f
commit
a272f8dfb2
@ -1,16 +1,6 @@
|
|||||||
"""Constants for the Picnic integration."""
|
"""Constants for the Picnic integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Any, Literal
|
|
||||||
|
|
||||||
from homeassistant.components.sensor import SensorDeviceClass, SensorEntityDescription
|
|
||||||
from homeassistant.const import CURRENCY_EURO
|
|
||||||
from homeassistant.helpers.typing import StateType
|
|
||||||
from homeassistant.util import dt as dt_util
|
|
||||||
|
|
||||||
DOMAIN = "picnic"
|
DOMAIN = "picnic"
|
||||||
|
|
||||||
CONF_API = "api"
|
CONF_API = "api"
|
||||||
@ -49,163 +39,3 @@ SENSOR_NEXT_DELIVERY_ETA_START = "next_delivery_eta_start"
|
|||||||
SENSOR_NEXT_DELIVERY_ETA_END = "next_delivery_eta_end"
|
SENSOR_NEXT_DELIVERY_ETA_END = "next_delivery_eta_end"
|
||||||
SENSOR_NEXT_DELIVERY_SLOT_START = "next_delivery_slot_start"
|
SENSOR_NEXT_DELIVERY_SLOT_START = "next_delivery_slot_start"
|
||||||
SENSOR_NEXT_DELIVERY_SLOT_END = "next_delivery_slot_end"
|
SENSOR_NEXT_DELIVERY_SLOT_END = "next_delivery_slot_end"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class PicnicRequiredKeysMixin:
|
|
||||||
"""Mixin for required keys."""
|
|
||||||
|
|
||||||
data_type: Literal[
|
|
||||||
"cart_data", "slot_data", "next_delivery_data", "last_order_data"
|
|
||||||
]
|
|
||||||
value_fn: Callable[[Any], StateType | datetime]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class PicnicSensorEntityDescription(SensorEntityDescription, PicnicRequiredKeysMixin):
|
|
||||||
"""Describes Picnic sensor entity."""
|
|
||||||
|
|
||||||
entity_registry_enabled_default: bool = False
|
|
||||||
|
|
||||||
|
|
||||||
SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = (
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_CART_ITEMS_COUNT,
|
|
||||||
icon="mdi:format-list-numbered",
|
|
||||||
data_type="cart_data",
|
|
||||||
value_fn=lambda cart: cart.get("total_count", 0),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_CART_TOTAL_PRICE,
|
|
||||||
native_unit_of_measurement=CURRENCY_EURO,
|
|
||||||
icon="mdi:currency-eur",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="cart_data",
|
|
||||||
value_fn=lambda cart: cart.get("total_price", 0) / 100,
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_SELECTED_SLOT_START,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:calendar-start",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="slot_data",
|
|
||||||
value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("window_start"))),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_SELECTED_SLOT_END,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:calendar-end",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="slot_data",
|
|
||||||
value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("window_end"))),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_SELECTED_SLOT_MAX_ORDER_TIME,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:clock-alert-outline",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="slot_data",
|
|
||||||
value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("cut_off_time"))),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE,
|
|
||||||
native_unit_of_measurement=CURRENCY_EURO,
|
|
||||||
icon="mdi:currency-eur",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="slot_data",
|
|
||||||
value_fn=lambda slot: (
|
|
||||||
slot["minimum_order_value"] / 100
|
|
||||||
if slot.get("minimum_order_value")
|
|
||||||
else None
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_LAST_ORDER_SLOT_START,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:calendar-start",
|
|
||||||
data_type="last_order_data",
|
|
||||||
value_fn=lambda last_order: dt_util.parse_datetime(
|
|
||||||
str(last_order.get("slot", {}).get("window_start"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_LAST_ORDER_SLOT_END,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:calendar-end",
|
|
||||||
data_type="last_order_data",
|
|
||||||
value_fn=lambda last_order: dt_util.parse_datetime(
|
|
||||||
str(last_order.get("slot", {}).get("window_end"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_LAST_ORDER_STATUS,
|
|
||||||
icon="mdi:list-status",
|
|
||||||
data_type="last_order_data",
|
|
||||||
value_fn=lambda last_order: last_order.get("status"),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_LAST_ORDER_MAX_ORDER_TIME,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:clock-alert-outline",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="last_order_data",
|
|
||||||
value_fn=lambda last_order: dt_util.parse_datetime(
|
|
||||||
str(last_order.get("slot", {}).get("cut_off_time"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_LAST_ORDER_DELIVERY_TIME,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:timeline-clock",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="last_order_data",
|
|
||||||
value_fn=lambda last_order: dt_util.parse_datetime(
|
|
||||||
str(last_order.get("delivery_time", {}).get("start"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_LAST_ORDER_TOTAL_PRICE,
|
|
||||||
native_unit_of_measurement=CURRENCY_EURO,
|
|
||||||
icon="mdi:cash-marker",
|
|
||||||
data_type="last_order_data",
|
|
||||||
value_fn=lambda last_order: last_order.get("total_price", 0) / 100,
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_NEXT_DELIVERY_ETA_START,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:clock-start",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="next_delivery_data",
|
|
||||||
value_fn=lambda next_delivery: dt_util.parse_datetime(
|
|
||||||
str(next_delivery.get("eta", {}).get("start"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_NEXT_DELIVERY_ETA_END,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:clock-end",
|
|
||||||
entity_registry_enabled_default=True,
|
|
||||||
data_type="next_delivery_data",
|
|
||||||
value_fn=lambda next_delivery: dt_util.parse_datetime(
|
|
||||||
str(next_delivery.get("eta", {}).get("end"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_NEXT_DELIVERY_SLOT_START,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:calendar-start",
|
|
||||||
data_type="next_delivery_data",
|
|
||||||
value_fn=lambda next_delivery: dt_util.parse_datetime(
|
|
||||||
str(next_delivery.get("slot", {}).get("window_start"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PicnicSensorEntityDescription(
|
|
||||||
key=SENSOR_NEXT_DELIVERY_SLOT_END,
|
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
|
||||||
icon="mdi:calendar-end",
|
|
||||||
data_type="next_delivery_data",
|
|
||||||
value_fn=lambda next_delivery: dt_util.parse_datetime(
|
|
||||||
str(next_delivery.get("slot", {}).get("window_end"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
"""Definition of Picnic sensors."""
|
"""Definition of Picnic sensors."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, cast
|
from typing import Any, Literal, cast
|
||||||
|
|
||||||
from homeassistant.components.sensor import SensorEntity
|
from homeassistant.components.sensor import (
|
||||||
|
SensorDeviceClass,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CURRENCY_EURO
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.device_registry import DeviceEntryType
|
from homeassistant.helpers.device_registry import DeviceEntryType
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
@ -15,14 +22,189 @@ from homeassistant.helpers.update_coordinator import (
|
|||||||
CoordinatorEntity,
|
CoordinatorEntity,
|
||||||
DataUpdateCoordinator,
|
DataUpdateCoordinator,
|
||||||
)
|
)
|
||||||
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ADDRESS,
|
ADDRESS,
|
||||||
ATTRIBUTION,
|
ATTRIBUTION,
|
||||||
CONF_COORDINATOR,
|
CONF_COORDINATOR,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SENSOR_TYPES,
|
SENSOR_CART_ITEMS_COUNT,
|
||||||
PicnicSensorEntityDescription,
|
SENSOR_CART_TOTAL_PRICE,
|
||||||
|
SENSOR_LAST_ORDER_DELIVERY_TIME,
|
||||||
|
SENSOR_LAST_ORDER_MAX_ORDER_TIME,
|
||||||
|
SENSOR_LAST_ORDER_SLOT_END,
|
||||||
|
SENSOR_LAST_ORDER_SLOT_START,
|
||||||
|
SENSOR_LAST_ORDER_STATUS,
|
||||||
|
SENSOR_LAST_ORDER_TOTAL_PRICE,
|
||||||
|
SENSOR_NEXT_DELIVERY_ETA_END,
|
||||||
|
SENSOR_NEXT_DELIVERY_ETA_START,
|
||||||
|
SENSOR_NEXT_DELIVERY_SLOT_END,
|
||||||
|
SENSOR_NEXT_DELIVERY_SLOT_START,
|
||||||
|
SENSOR_SELECTED_SLOT_END,
|
||||||
|
SENSOR_SELECTED_SLOT_MAX_ORDER_TIME,
|
||||||
|
SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE,
|
||||||
|
SENSOR_SELECTED_SLOT_START,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PicnicRequiredKeysMixin:
|
||||||
|
"""Mixin for required keys."""
|
||||||
|
|
||||||
|
data_type: Literal[
|
||||||
|
"cart_data", "slot_data", "next_delivery_data", "last_order_data"
|
||||||
|
]
|
||||||
|
value_fn: Callable[[Any], StateType | datetime]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PicnicSensorEntityDescription(SensorEntityDescription, PicnicRequiredKeysMixin):
|
||||||
|
"""Describes Picnic sensor entity."""
|
||||||
|
|
||||||
|
entity_registry_enabled_default: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = (
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_CART_ITEMS_COUNT,
|
||||||
|
icon="mdi:format-list-numbered",
|
||||||
|
data_type="cart_data",
|
||||||
|
value_fn=lambda cart: cart.get("total_count", 0),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_CART_TOTAL_PRICE,
|
||||||
|
native_unit_of_measurement=CURRENCY_EURO,
|
||||||
|
icon="mdi:currency-eur",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="cart_data",
|
||||||
|
value_fn=lambda cart: cart.get("total_price", 0) / 100,
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_SELECTED_SLOT_START,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:calendar-start",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="slot_data",
|
||||||
|
value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("window_start"))),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_SELECTED_SLOT_END,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:calendar-end",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="slot_data",
|
||||||
|
value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("window_end"))),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_SELECTED_SLOT_MAX_ORDER_TIME,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:clock-alert-outline",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="slot_data",
|
||||||
|
value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("cut_off_time"))),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE,
|
||||||
|
native_unit_of_measurement=CURRENCY_EURO,
|
||||||
|
icon="mdi:currency-eur",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="slot_data",
|
||||||
|
value_fn=lambda slot: (
|
||||||
|
slot["minimum_order_value"] / 100
|
||||||
|
if slot.get("minimum_order_value")
|
||||||
|
else None
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_LAST_ORDER_SLOT_START,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:calendar-start",
|
||||||
|
data_type="last_order_data",
|
||||||
|
value_fn=lambda last_order: dt_util.parse_datetime(
|
||||||
|
str(last_order.get("slot", {}).get("window_start"))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_LAST_ORDER_SLOT_END,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:calendar-end",
|
||||||
|
data_type="last_order_data",
|
||||||
|
value_fn=lambda last_order: dt_util.parse_datetime(
|
||||||
|
str(last_order.get("slot", {}).get("window_end"))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_LAST_ORDER_STATUS,
|
||||||
|
icon="mdi:list-status",
|
||||||
|
data_type="last_order_data",
|
||||||
|
value_fn=lambda last_order: last_order.get("status"),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_LAST_ORDER_MAX_ORDER_TIME,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:clock-alert-outline",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="last_order_data",
|
||||||
|
value_fn=lambda last_order: dt_util.parse_datetime(
|
||||||
|
str(last_order.get("slot", {}).get("cut_off_time"))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_LAST_ORDER_DELIVERY_TIME,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:timeline-clock",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="last_order_data",
|
||||||
|
value_fn=lambda last_order: dt_util.parse_datetime(
|
||||||
|
str(last_order.get("delivery_time", {}).get("start"))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_LAST_ORDER_TOTAL_PRICE,
|
||||||
|
native_unit_of_measurement=CURRENCY_EURO,
|
||||||
|
icon="mdi:cash-marker",
|
||||||
|
data_type="last_order_data",
|
||||||
|
value_fn=lambda last_order: last_order.get("total_price", 0) / 100,
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_NEXT_DELIVERY_ETA_START,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:clock-start",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="next_delivery_data",
|
||||||
|
value_fn=lambda next_delivery: dt_util.parse_datetime(
|
||||||
|
str(next_delivery.get("eta", {}).get("start"))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_NEXT_DELIVERY_ETA_END,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:clock-end",
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
data_type="next_delivery_data",
|
||||||
|
value_fn=lambda next_delivery: dt_util.parse_datetime(
|
||||||
|
str(next_delivery.get("eta", {}).get("end"))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_NEXT_DELIVERY_SLOT_START,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:calendar-start",
|
||||||
|
data_type="next_delivery_data",
|
||||||
|
value_fn=lambda next_delivery: dt_util.parse_datetime(
|
||||||
|
str(next_delivery.get("slot", {}).get("window_start"))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PicnicSensorEntityDescription(
|
||||||
|
key=SENSOR_NEXT_DELIVERY_SLOT_END,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
icon="mdi:calendar-end",
|
||||||
|
data_type="next_delivery_data",
|
||||||
|
value_fn=lambda next_delivery: dt_util.parse_datetime(
|
||||||
|
str(next_delivery.get("slot", {}).get("window_end"))
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ import requests
|
|||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components.picnic import const
|
from homeassistant.components.picnic import const
|
||||||
from homeassistant.components.picnic.const import CONF_COUNTRY_CODE, SENSOR_TYPES
|
from homeassistant.components.picnic.const import CONF_COUNTRY_CODE
|
||||||
|
from homeassistant.components.picnic.sensor import SENSOR_TYPES
|
||||||
from homeassistant.components.sensor import SensorDeviceClass
|
from homeassistant.components.sensor import SensorDeviceClass
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_ACCESS_TOKEN,
|
CONF_ACCESS_TOKEN,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user