456 files
This commit is contained in:
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -2,96 +2,32 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.input_number import (
|
||||
CONF_INITIAL,
|
||||
CONF_MAX,
|
||||
CONF_MIN,
|
||||
CONF_STEP,
|
||||
DOMAIN,
|
||||
MODE_BOX,
|
||||
MODE_SLIDER,
|
||||
NumberStorageCollection,
|
||||
_cv_input_number,
|
||||
STORAGE_FIELDS,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_MODE,
|
||||
CONF_NAME,
|
||||
CONF_UNIT_OF_MEASUREMENT,
|
||||
)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
||||
|
||||
from ....services import AbstractSpookAdminService
|
||||
from ....helper_collections import AbstractSpookCreateHelperService
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from homeassistant.core import ServiceCall
|
||||
|
||||
CONF_INPUT_NUMBER_ID = "input_number_id"
|
||||
|
||||
CREATE_FIELDS = {
|
||||
vol.Required(CONF_NAME): vol.All(str, vol.Length(min=1)),
|
||||
vol.Optional(CONF_INPUT_NUMBER_ID): cv.slug,
|
||||
# Core requires a minimum and a maximum. This action never has: it started
|
||||
# out with 0 and 100, and calls written against that keep working.
|
||||
_FIELDS = {
|
||||
**{
|
||||
marker: validator
|
||||
for marker, validator in STORAGE_FIELDS.items()
|
||||
if marker not in (CONF_MIN, CONF_MAX)
|
||||
},
|
||||
vol.Optional(CONF_MIN, default=0): vol.Coerce(float),
|
||||
vol.Optional(CONF_MAX, default=100): vol.Coerce(float),
|
||||
vol.Optional(CONF_INITIAL): vol.Coerce(float),
|
||||
vol.Optional(CONF_STEP, default=1): vol.All(vol.Coerce(float), vol.Range(min=1e-9)),
|
||||
vol.Optional(CONF_ICON): cv.icon,
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
|
||||
vol.Optional(CONF_MODE, default=MODE_SLIDER): vol.In([MODE_SLIDER, MODE_BOX]),
|
||||
}
|
||||
|
||||
|
||||
class SpookService(AbstractSpookAdminService):
|
||||
class SpookService(AbstractSpookCreateHelperService):
|
||||
"""Input number service to create a new helper on the fly."""
|
||||
|
||||
domain = DOMAIN
|
||||
service = "create"
|
||||
schema = vol.All(vol.Schema(CREATE_FIELDS), _cv_input_number)
|
||||
|
||||
async def async_handle_service(self, call: ServiceCall) -> None:
|
||||
"""Handle the service call."""
|
||||
input_number_id = call.data.get(CONF_INPUT_NUMBER_ID)
|
||||
data = {k: v for k, v in call.data.items() if k != CONF_INPUT_NUMBER_ID}
|
||||
|
||||
collection: NumberStorageCollection
|
||||
if DOMAIN in self.hass.data:
|
||||
collection = self.hass.data[DOMAIN]
|
||||
else:
|
||||
# Major hack to get around edge cases. 👻
|
||||
collection = self.hass.data["websocket_api"]["input_number/list"][
|
||||
0
|
||||
].__self__.storage_collection
|
||||
|
||||
if input_number_id:
|
||||
async with self.hass.data.setdefault(
|
||||
f"{DOMAIN}_create_lock", asyncio.Lock()
|
||||
):
|
||||
desired_entity_id = f"{DOMAIN}.{input_number_id}"
|
||||
ent_reg = er.async_get(self.hass)
|
||||
if ent_reg.async_get(desired_entity_id) or self.hass.states.get(
|
||||
desired_entity_id
|
||||
):
|
||||
message = f"An input number with entity ID '{desired_entity_id}' already exists"
|
||||
raise HomeAssistantError(message)
|
||||
|
||||
item = await collection.async_create_item(data)
|
||||
|
||||
# The entity_id is derived from the name by default. Update the
|
||||
# entity registry to match the requested input_number_id instead.
|
||||
if (
|
||||
current_entity_id := ent_reg.async_get_entity_id(
|
||||
DOMAIN, DOMAIN, item[CONF_ID]
|
||||
)
|
||||
) and current_entity_id != desired_entity_id:
|
||||
ent_reg.async_update_entity(
|
||||
current_entity_id, new_entity_id=desired_entity_id
|
||||
)
|
||||
else:
|
||||
await collection.async_create_item(data)
|
||||
fields = _FIELDS
|
||||
|
||||
@@ -2,44 +2,12 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from homeassistant.components.input_number import DOMAIN
|
||||
|
||||
from homeassistant.components.input_number import (
|
||||
DOMAIN,
|
||||
InputNumber,
|
||||
NumberStorageCollection,
|
||||
)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from ....services import AbstractSpookEntityComponentService
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from homeassistant.core import ServiceCall
|
||||
from ....helper_collections import AbstractSpookDeleteHelperService
|
||||
|
||||
|
||||
class SpookService(AbstractSpookEntityComponentService[InputNumber]):
|
||||
"""Input number service to delete a helper on the fly."""
|
||||
class SpookService(AbstractSpookDeleteHelperService):
|
||||
"""Input number service to delete input numbers on the fly."""
|
||||
|
||||
domain = DOMAIN
|
||||
service = "delete"
|
||||
schema = {}
|
||||
|
||||
async def async_handle_service(
|
||||
self,
|
||||
entity: InputNumber,
|
||||
call: ServiceCall, # noqa: ARG002
|
||||
) -> None:
|
||||
"""Handle the service call."""
|
||||
if not entity.editable:
|
||||
message = f"This input number is not editable: {entity.entity_id}"
|
||||
raise HomeAssistantError(message)
|
||||
|
||||
collection: NumberStorageCollection
|
||||
if DOMAIN in self.hass.data:
|
||||
collection = self.hass.data[DOMAIN]
|
||||
else:
|
||||
# Major hack to get around edge cases. 👻
|
||||
collection = self.hass.data["websocket_api"]["input_number/list"][
|
||||
0
|
||||
].__self__.storage_collection
|
||||
await collection.async_delete_item(entity.unique_id)
|
||||
|
||||
Reference in New Issue
Block a user