1 """Support for an exposed aREST RESTful API of a device."""
3 from __future__
import annotations
5 from datetime
import timedelta
6 from http
import HTTPStatus
10 import voluptuous
as vol
13 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
17 CONF_MONITORED_VARIABLES,
20 CONF_UNIT_OF_MEASUREMENT,
30 _LOGGER = logging.getLogger(__name__)
34 CONF_FUNCTIONS =
"functions"
37 DEFAULT_NAME =
"aREST sensor"
39 PIN_VARIABLE_SCHEMA = vol.Schema(
41 vol.Optional(CONF_NAME): cv.string,
42 vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
43 vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
47 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
49 vol.Required(CONF_RESOURCE): cv.url,
50 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
51 vol.Optional(CONF_PINS, default={}): vol.Schema(
52 {cv.string: PIN_VARIABLE_SCHEMA}
54 vol.Optional(CONF_MONITORED_VARIABLES, default={}): vol.Schema(
55 {cv.string: PIN_VARIABLE_SCHEMA}
64 add_entities: AddEntitiesCallback,
65 discovery_info: DiscoveryInfoType |
None =
None,
67 """Set up the aREST sensor."""
68 resource = config[CONF_RESOURCE]
69 var_conf = config[CONF_MONITORED_VARIABLES]
70 pins = config[CONF_PINS]
73 response = requests.get(resource, timeout=10).
json()
74 except requests.exceptions.MissingSchema:
76 "Missing resource or schema in configuration. Add http:// to your URL"
79 except requests.exceptions.ConnectionError:
80 _LOGGER.error(
"No route to device at %s", resource)
85 def make_renderer(value_template):
86 """Create a renderer based on variable_template value."""
87 if value_template
is None:
88 return lambda value: value
92 return value_template.async_render({
"value": value}, parse_result=
False)
94 _LOGGER.exception(
"Error parsing value")
101 if var_conf
is not None:
102 for variable, var_data
in var_conf.items():
103 if variable
not in response[
"variables"]:
104 _LOGGER.error(
"Variable: %s does not exist", variable)
107 renderer = make_renderer(var_data.get(CONF_VALUE_TEMPLATE))
112 config.get(CONF_NAME, response[CONF_NAME]),
113 var_data.get(CONF_NAME, variable),
115 unit_of_measurement=var_data.get(CONF_UNIT_OF_MEASUREMENT),
121 for pinnum, pin
in pins.items():
122 renderer = make_renderer(pin.get(CONF_VALUE_TEMPLATE))
127 config.get(CONF_NAME, response[CONF_NAME]),
130 unit_of_measurement=pin.get(CONF_UNIT_OF_MEASUREMENT),
139 """Implementation of an aREST sensor for exposed variables."""
149 unit_of_measurement=None,
152 """Initialize the sensor."""
154 self.
_attr_name_attr_name = f
"{location.title()} {name.title()}"
160 request = requests.get(f
"{resource}/mode/{pin}/i", timeout=10)
161 if request.status_code != HTTPStatus.OK:
162 _LOGGER.error(
"Can't set mode of %s", resource)
165 """Get the latest data from aREST API."""
168 values = self.
arestarest.data
169 if "error" in values:
173 values.get(
"value", values.get(self.
_variable_variable,
None))
178 """The Class for handling the data retrieval for variables."""
181 """Initialize the data object."""
187 @Throttle(MIN_TIME_BETWEEN_UPDATES)
189 """Get the latest data from aREST device."""
191 if self.
_pin_pin
is None:
192 response = requests.get(self.
_resource_resource, timeout=10)
193 self.
datadata = response.json()[
"variables"]
196 if str(self.
_pin_pin[0]) ==
"A":
197 response = requests.get(
198 f
"{self._resource}/analog/{self._pin[1:]}", timeout=10
200 self.
datadata = {
"value": response.json()[
"return_value"]}
202 response = requests.get(
203 f
"{self._resource}/digital/{self._pin}", timeout=10
205 self.
datadata = {
"value": response.json()[
"return_value"]}
207 except requests.exceptions.ConnectionError:
208 _LOGGER.error(
"No route to device %s", self.
_resource_resource)
def __init__(self, resource, pin=None)
def __init__(self, arest, resource, location, name, variable=None, pin=None, unit_of_measurement=None, renderer=None)
_attr_native_unit_of_measurement
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
def add_entities(account, async_add_entities, tracked)