1 """Define services for the Mealie integration."""
3 from dataclasses
import asdict
4 from datetime
import date
5 from typing
import cast
7 from aiomealie
import (
10 MealieValidationError,
13 import voluptuous
as vol
38 from .coordinator
import MealieConfigEntry
40 SERVICE_GET_MEALPLAN =
"get_mealplan"
41 SERVICE_GET_MEALPLAN_SCHEMA = vol.Schema(
43 vol.Required(ATTR_CONFIG_ENTRY_ID): str,
44 vol.Optional(ATTR_START_DATE): cv.date,
45 vol.Optional(ATTR_END_DATE): cv.date,
49 SERVICE_GET_RECIPE =
"get_recipe"
50 SERVICE_GET_RECIPE_SCHEMA = vol.Schema(
52 vol.Required(ATTR_CONFIG_ENTRY_ID): str,
53 vol.Required(ATTR_RECIPE_ID): str,
57 SERVICE_IMPORT_RECIPE =
"import_recipe"
58 SERVICE_IMPORT_RECIPE_SCHEMA = vol.Schema(
60 vol.Required(ATTR_CONFIG_ENTRY_ID): str,
61 vol.Required(ATTR_URL): str,
62 vol.Optional(ATTR_INCLUDE_TAGS): bool,
66 SERVICE_SET_RANDOM_MEALPLAN =
"set_random_mealplan"
67 SERVICE_SET_RANDOM_MEALPLAN_SCHEMA = vol.Schema(
69 vol.Required(ATTR_CONFIG_ENTRY_ID): str,
70 vol.Required(ATTR_DATE): cv.date,
71 vol.Required(ATTR_ENTRY_TYPE): vol.In([x.lower()
for x
in MealplanEntryType]),
75 SERVICE_SET_MEALPLAN =
"set_mealplan"
76 SERVICE_SET_MEALPLAN_SCHEMA = vol.Any(
79 vol.Required(ATTR_CONFIG_ENTRY_ID): str,
80 vol.Required(ATTR_DATE): cv.date,
81 vol.Required(ATTR_ENTRY_TYPE): vol.In(
82 [x.lower()
for x
in MealplanEntryType]
84 vol.Required(ATTR_RECIPE_ID): str,
89 vol.Required(ATTR_CONFIG_ENTRY_ID): str,
90 vol.Required(ATTR_DATE): cv.date,
91 vol.Required(ATTR_ENTRY_TYPE): vol.In(
92 [x.lower()
for x
in MealplanEntryType]
94 vol.Required(ATTR_NOTE_TITLE): str,
95 vol.Required(ATTR_NOTE_TEXT): str,
102 """Get the Mealie config entry."""
103 if not (entry := hass.config_entries.async_get_entry(config_entry_id)):
105 translation_domain=DOMAIN,
106 translation_key=
"integration_not_found",
107 translation_placeholders={
"target": DOMAIN},
109 if entry.state
is not ConfigEntryState.LOADED:
111 translation_domain=DOMAIN,
112 translation_key=
"not_loaded",
113 translation_placeholders={
"target": entry.title},
115 return cast(MealieConfigEntry, entry)
119 """Set up the services for the Mealie integration."""
121 async
def async_get_mealplan(call: ServiceCall) -> ServiceResponse:
122 """Get the mealplan for a specific range."""
124 start_date = call.data.get(ATTR_START_DATE, date.today())
125 end_date = call.data.get(ATTR_END_DATE, date.today())
126 if end_date < start_date:
128 translation_domain=DOMAIN,
129 translation_key=
"end_date_before_start_date",
131 client = cast(MealieConfigEntry, entry).runtime_data.client
133 mealplans = await client.get_mealplans(start_date, end_date)
134 except MealieConnectionError
as err:
136 translation_domain=DOMAIN,
137 translation_key=
"connection_error",
139 return {
"mealplan": [asdict(x)
for x
in mealplans.items]}
141 async
def async_get_recipe(call: ServiceCall) -> ServiceResponse:
144 recipe_id = call.data[ATTR_RECIPE_ID]
145 client = entry.runtime_data.client
147 recipe = await client.get_recipe(recipe_id)
148 except MealieConnectionError
as err:
150 translation_domain=DOMAIN,
151 translation_key=
"connection_error",
153 except MealieNotFoundError
as err:
155 translation_domain=DOMAIN,
156 translation_key=
"recipe_not_found",
157 translation_placeholders={
"recipe_id": recipe_id},
159 return {
"recipe": asdict(recipe)}
161 async
def async_import_recipe(call: ServiceCall) -> ServiceResponse:
162 """Import a recipe."""
164 url = call.data[ATTR_URL]
165 include_tags = call.data.get(ATTR_INCLUDE_TAGS,
False)
166 client = entry.runtime_data.client
168 recipe = await client.import_recipe(url, include_tags)
169 except MealieValidationError
as err:
171 translation_domain=DOMAIN,
172 translation_key=
"could_not_import_recipe",
174 except MealieConnectionError
as err:
176 translation_domain=DOMAIN,
177 translation_key=
"connection_error",
179 if call.return_response:
180 return {
"recipe": asdict(recipe)}
183 async
def async_set_random_mealplan(call: ServiceCall) -> ServiceResponse:
184 """Set a random mealplan."""
186 mealplan_date = call.data[ATTR_DATE]
187 entry_type = MealplanEntryType(call.data[ATTR_ENTRY_TYPE])
188 client = entry.runtime_data.client
190 mealplan = await client.random_mealplan(mealplan_date, entry_type)
191 except MealieConnectionError
as err:
193 translation_domain=DOMAIN,
194 translation_key=
"connection_error",
196 if call.return_response:
197 return {
"mealplan": asdict(mealplan)}
200 async
def async_set_mealplan(call: ServiceCall) -> ServiceResponse:
201 """Set a mealplan."""
203 mealplan_date = call.data[ATTR_DATE]
204 entry_type = MealplanEntryType(call.data[ATTR_ENTRY_TYPE])
205 client = entry.runtime_data.client
207 mealplan = await client.set_mealplan(
210 recipe_id=call.data.get(ATTR_RECIPE_ID),
211 note_title=call.data.get(ATTR_NOTE_TITLE),
212 note_text=call.data.get(ATTR_NOTE_TEXT),
214 except MealieConnectionError
as err:
216 translation_domain=DOMAIN,
217 translation_key=
"connection_error",
219 if call.return_response:
220 return {
"mealplan": asdict(mealplan)}
223 hass.services.async_register(
225 SERVICE_GET_MEALPLAN,
227 schema=SERVICE_GET_MEALPLAN_SCHEMA,
228 supports_response=SupportsResponse.ONLY,
230 hass.services.async_register(
234 schema=SERVICE_GET_RECIPE_SCHEMA,
235 supports_response=SupportsResponse.ONLY,
237 hass.services.async_register(
239 SERVICE_IMPORT_RECIPE,
241 schema=SERVICE_IMPORT_RECIPE_SCHEMA,
242 supports_response=SupportsResponse.OPTIONAL,
244 hass.services.async_register(
246 SERVICE_SET_RANDOM_MEALPLAN,
247 async_set_random_mealplan,
248 schema=SERVICE_SET_RANDOM_MEALPLAN_SCHEMA,
249 supports_response=SupportsResponse.OPTIONAL,
251 hass.services.async_register(
253 SERVICE_SET_MEALPLAN,
255 schema=SERVICE_SET_MEALPLAN_SCHEMA,
256 supports_response=SupportsResponse.OPTIONAL,
None setup_services(HomeAssistant hass)
MealieConfigEntry async_get_entry(HomeAssistant hass, str config_entry_id)