1 """Support for RESTful API sensors."""
3 from __future__
import annotations
8 from xml.parsers.expat
import ExpatError
10 import voluptuous
as vol
14 DOMAIN
as SENSOR_DOMAIN,
15 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
25 CONF_RESOURCE_TEMPLATE,
27 CONF_UNIT_OF_MEASUREMENT,
38 ManualTriggerSensorEntity,
43 from .
import async_get_config_and_coordinator, create_rest_data_from_config
44 from .const
import CONF_JSON_ATTRS, CONF_JSON_ATTRS_PATH, DEFAULT_SENSOR_NAME
45 from .data
import RestData
46 from .entity
import RestEntity
47 from .schema
import RESOURCE_SCHEMA, SENSOR_SCHEMA
48 from .util
import parse_json_attributes
50 _LOGGER = logging.getLogger(__name__)
52 PLATFORM_SCHEMA = vol.All(
53 SENSOR_PLATFORM_SCHEMA.extend({**RESOURCE_SCHEMA, **SENSOR_SCHEMA}),
54 cv.has_at_least_one_key(CONF_RESOURCE, CONF_RESOURCE_TEMPLATE),
57 TRIGGER_ENTITY_OPTIONS = (
64 CONF_UNIT_OF_MEASUREMENT,
71 async_add_entities: AddEntitiesCallback,
72 discovery_info: DiscoveryInfoType |
None =
None,
74 """Set up the RESTful sensor."""
77 if discovery_info
is not None:
79 hass, SENSOR_DOMAIN, discovery_info
85 await rest.async_update(log_errors=
False)
88 if rest.last_exception:
89 if isinstance(rest.last_exception, ssl.SSLError):
91 "Error connecting %s failed with %s",
96 raise PlatformNotReady
from rest.last_exception
97 raise PlatformNotReady
99 name = conf.get(CONF_NAME)
or Template(DEFAULT_SENSOR_NAME, hass)
101 trigger_entity_config = {CONF_NAME: name}
103 for key
in TRIGGER_ENTITY_OPTIONS:
106 trigger_entity_config[key] = conf[key]
115 trigger_entity_config,
122 """Implementation of a REST sensor."""
127 coordinator: DataUpdateCoordinator[
None] |
None,
130 trigger_entity_config: ConfigType,
132 """Initialize the REST sensor."""
133 ManualTriggerSensorEntity.__init__(self, hass, trigger_entity_config)
138 config.get(CONF_RESOURCE_TEMPLATE),
139 config[CONF_FORCE_UPDATE],
148 """Return if entity is available."""
149 available1 = RestEntity.available.fget(self)
150 available2 = ManualTriggerSensorEntity.available.fget(self)
151 return bool(available1
and available2)
155 """Return extra attributes."""
159 """Update state from the rest data."""
161 value = self.
restrest.data_without_xml()
162 except ExpatError
as err:
164 "REST xml result could not be parsed and converted to JSON: %s", err
166 value = self.
restrest.data
175 if value
is not None and self.
_value_template_value_template
is not None:
176 value = self.
_value_template_value_template.async_render_with_possible_json_value(
181 SensorDeviceClass.DATE,
182 SensorDeviceClass.TIMESTAMP,
_attr_extra_state_attributes
None _update_from_rest_data(self)
dict[str, Any] extra_state_attributes(self)
None __init__(self, HomeAssistant hass, DataUpdateCoordinator[None]|None coordinator, RestData rest, ConfigType config, ConfigType trigger_entity_config)
SensorDeviceClass|None device_class(self)
str|None device_class(self)
None async_write_ha_state(self)
None _process_manual_data(self, Any|None value=None)
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)
dict[str, Any] parse_json_attributes(str|None value, list[str] json_attrs, str|None json_attrs_path)
RestData create_rest_data_from_config(HomeAssistant hass, ConfigType config)
tuple[ConfigType, DataUpdateCoordinator[None], RestData] async_get_config_and_coordinator(HomeAssistant hass, str platform_domain, DiscoveryInfoType discovery_info)
datetime|date|None async_parse_date_datetime(str value, str entity_id, SensorDeviceClass|str|None device_class)