1 """Definition of Picnic sensors."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
7 from datetime
import datetime
8 from typing
import Any, Literal, cast
13 SensorEntityDescription,
28 SENSOR_CART_ITEMS_COUNT,
29 SENSOR_CART_TOTAL_PRICE,
30 SENSOR_LAST_ORDER_DELIVERY_TIME,
31 SENSOR_LAST_ORDER_MAX_ORDER_TIME,
32 SENSOR_LAST_ORDER_SLOT_END,
33 SENSOR_LAST_ORDER_SLOT_START,
34 SENSOR_LAST_ORDER_STATUS,
35 SENSOR_LAST_ORDER_TOTAL_PRICE,
36 SENSOR_NEXT_DELIVERY_ETA_END,
37 SENSOR_NEXT_DELIVERY_ETA_START,
38 SENSOR_NEXT_DELIVERY_SLOT_END,
39 SENSOR_NEXT_DELIVERY_SLOT_START,
40 SENSOR_SELECTED_SLOT_END,
41 SENSOR_SELECTED_SLOT_MAX_ORDER_TIME,
42 SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE,
43 SENSOR_SELECTED_SLOT_START,
45 from .coordinator
import PicnicUpdateCoordinator
48 @dataclass(frozen=True, kw_only=True)
50 """Describes Picnic sensor entity."""
53 "cart_data",
"slot_data",
"next_delivery_data",
"last_order_data"
55 value_fn: Callable[[Any], StateType | datetime]
57 entity_registry_enabled_default: bool =
False
60 SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = (
62 key=SENSOR_CART_ITEMS_COUNT,
63 translation_key=SENSOR_CART_ITEMS_COUNT,
64 data_type=
"cart_data",
65 value_fn=
lambda cart: cart.get(
"total_count", 0),
68 key=SENSOR_CART_TOTAL_PRICE,
69 translation_key=SENSOR_CART_TOTAL_PRICE,
70 native_unit_of_measurement=CURRENCY_EURO,
71 entity_registry_enabled_default=
True,
72 data_type=
"cart_data",
73 value_fn=
lambda cart: cart.get(
"total_price", 0) / 100,
76 key=SENSOR_SELECTED_SLOT_START,
77 translation_key=SENSOR_SELECTED_SLOT_START,
78 device_class=SensorDeviceClass.TIMESTAMP,
79 entity_registry_enabled_default=
True,
80 data_type=
"slot_data",
81 value_fn=
lambda slot: dt_util.parse_datetime(
str(slot.get(
"window_start"))),
84 key=SENSOR_SELECTED_SLOT_END,
85 translation_key=SENSOR_SELECTED_SLOT_END,
86 device_class=SensorDeviceClass.TIMESTAMP,
87 entity_registry_enabled_default=
True,
88 data_type=
"slot_data",
89 value_fn=
lambda slot: dt_util.parse_datetime(
str(slot.get(
"window_end"))),
92 key=SENSOR_SELECTED_SLOT_MAX_ORDER_TIME,
93 translation_key=SENSOR_SELECTED_SLOT_MAX_ORDER_TIME,
94 device_class=SensorDeviceClass.TIMESTAMP,
95 entity_registry_enabled_default=
True,
96 data_type=
"slot_data",
97 value_fn=
lambda slot: dt_util.parse_datetime(
str(slot.get(
"cut_off_time"))),
100 key=SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE,
101 translation_key=SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE,
102 native_unit_of_measurement=CURRENCY_EURO,
103 entity_registry_enabled_default=
True,
104 data_type=
"slot_data",
105 value_fn=
lambda slot: (
106 slot[
"minimum_order_value"] / 100
107 if slot.get(
"minimum_order_value")
112 key=SENSOR_LAST_ORDER_SLOT_START,
113 translation_key=SENSOR_LAST_ORDER_SLOT_START,
114 device_class=SensorDeviceClass.TIMESTAMP,
115 data_type=
"last_order_data",
116 value_fn=
lambda last_order: dt_util.parse_datetime(
117 str(last_order.get(
"slot", {}).
get(
"window_start"))
121 key=SENSOR_LAST_ORDER_SLOT_END,
122 translation_key=SENSOR_LAST_ORDER_SLOT_END,
123 device_class=SensorDeviceClass.TIMESTAMP,
124 data_type=
"last_order_data",
125 value_fn=
lambda last_order: dt_util.parse_datetime(
126 str(last_order.get(
"slot", {}).
get(
"window_end"))
130 key=SENSOR_LAST_ORDER_STATUS,
131 translation_key=SENSOR_LAST_ORDER_STATUS,
132 data_type=
"last_order_data",
133 value_fn=
lambda last_order: last_order.get(
"status"),
136 key=SENSOR_LAST_ORDER_MAX_ORDER_TIME,
137 translation_key=SENSOR_LAST_ORDER_MAX_ORDER_TIME,
138 device_class=SensorDeviceClass.TIMESTAMP,
139 entity_registry_enabled_default=
True,
140 data_type=
"last_order_data",
141 value_fn=
lambda last_order: dt_util.parse_datetime(
142 str(last_order.get(
"slot", {}).
get(
"cut_off_time"))
146 key=SENSOR_LAST_ORDER_DELIVERY_TIME,
147 translation_key=SENSOR_LAST_ORDER_DELIVERY_TIME,
148 device_class=SensorDeviceClass.TIMESTAMP,
149 entity_registry_enabled_default=
True,
150 data_type=
"last_order_data",
151 value_fn=
lambda last_order: dt_util.parse_datetime(
152 str(last_order.get(
"delivery_time", {}).
get(
"start"))
156 key=SENSOR_LAST_ORDER_TOTAL_PRICE,
157 translation_key=SENSOR_LAST_ORDER_TOTAL_PRICE,
158 native_unit_of_measurement=CURRENCY_EURO,
159 data_type=
"last_order_data",
160 value_fn=
lambda last_order: last_order.get(
"total_price", 0) / 100,
163 key=SENSOR_NEXT_DELIVERY_ETA_START,
164 translation_key=SENSOR_NEXT_DELIVERY_ETA_START,
165 device_class=SensorDeviceClass.TIMESTAMP,
166 entity_registry_enabled_default=
True,
167 data_type=
"next_delivery_data",
168 value_fn=
lambda next_delivery: dt_util.parse_datetime(
169 str(next_delivery.get(
"eta", {}).
get(
"start"))
173 key=SENSOR_NEXT_DELIVERY_ETA_END,
174 translation_key=SENSOR_NEXT_DELIVERY_ETA_END,
175 device_class=SensorDeviceClass.TIMESTAMP,
176 entity_registry_enabled_default=
True,
177 data_type=
"next_delivery_data",
178 value_fn=
lambda next_delivery: dt_util.parse_datetime(
179 str(next_delivery.get(
"eta", {}).
get(
"end"))
183 key=SENSOR_NEXT_DELIVERY_SLOT_START,
184 translation_key=SENSOR_NEXT_DELIVERY_SLOT_START,
185 device_class=SensorDeviceClass.TIMESTAMP,
186 data_type=
"next_delivery_data",
187 value_fn=
lambda next_delivery: dt_util.parse_datetime(
188 str(next_delivery.get(
"slot", {}).
get(
"window_start"))
192 key=SENSOR_NEXT_DELIVERY_SLOT_END,
193 translation_key=SENSOR_NEXT_DELIVERY_SLOT_END,
194 device_class=SensorDeviceClass.TIMESTAMP,
195 data_type=
"next_delivery_data",
196 value_fn=
lambda next_delivery: dt_util.parse_datetime(
197 str(next_delivery.get(
"slot", {}).
get(
"window_end"))
205 config_entry: ConfigEntry,
206 async_add_entities: AddEntitiesCallback,
208 """Set up Picnic sensor entries."""
209 picnic_coordinator = hass.data[DOMAIN][config_entry.entry_id][CONF_COORDINATOR]
213 PicnicSensor(picnic_coordinator, config_entry, description)
214 for description
in SENSOR_TYPES
219 """The CoordinatorEntity subclass representing Picnic sensors."""
221 _attr_has_entity_name =
True
222 _attr_attribution = ATTRIBUTION
223 entity_description: PicnicSensorEntityDescription
227 coordinator: PicnicUpdateCoordinator,
228 config_entry: ConfigEntry,
229 description: PicnicSensorEntityDescription,
231 """Init a Picnic sensor."""
237 entry_type=DeviceEntryType.SERVICE,
238 identifiers={(DOMAIN, cast(str, config_entry.unique_id))},
239 manufacturer=
"Picnic",
240 model=config_entry.unique_id,
245 """Return the value reported by the sensor."""
248 if self.coordinator.data
is not None
StateType|datetime native_value(self)
None __init__(self, PicnicUpdateCoordinator coordinator, ConfigEntry config_entry, PicnicSensorEntityDescription description)
web.Response get(self, web.Request request, str config_key)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)