mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 16:57:10 +00:00
Refactor JSON attribute parsing in rest (#97526)
* Refactor JSON attribute parsing in rest * Early return
This commit is contained in:
parent
832a8247de
commit
c62081430b
@ -5,7 +5,6 @@ import logging
|
|||||||
import ssl
|
import ssl
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from jsonpath import jsonpath
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
@ -39,13 +38,13 @@ from homeassistant.helpers.template_entity import (
|
|||||||
)
|
)
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
from homeassistant.util.json import json_loads
|
|
||||||
|
|
||||||
from . import async_get_config_and_coordinator, create_rest_data_from_config
|
from . import async_get_config_and_coordinator, create_rest_data_from_config
|
||||||
from .const import CONF_JSON_ATTRS, CONF_JSON_ATTRS_PATH, DEFAULT_SENSOR_NAME
|
from .const import CONF_JSON_ATTRS, CONF_JSON_ATTRS_PATH, DEFAULT_SENSOR_NAME
|
||||||
from .data import RestData
|
from .data import RestData
|
||||||
from .entity import RestEntity
|
from .entity import RestEntity
|
||||||
from .schema import RESOURCE_SCHEMA, SENSOR_SCHEMA
|
from .schema import RESOURCE_SCHEMA, SENSOR_SCHEMA
|
||||||
|
from .util import parse_json_attributes
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -163,32 +162,9 @@ class RestSensor(ManualTriggerSensorEntity, RestEntity, SensorEntity):
|
|||||||
value = self.rest.data_without_xml()
|
value = self.rest.data_without_xml()
|
||||||
|
|
||||||
if self._json_attrs:
|
if self._json_attrs:
|
||||||
if value:
|
self._attr_extra_state_attributes = parse_json_attributes(
|
||||||
try:
|
value, self._json_attrs, self._json_attrs_path
|
||||||
json_dict = json_loads(value)
|
|
||||||
if self._json_attrs_path is not None:
|
|
||||||
json_dict = jsonpath(json_dict, self._json_attrs_path)
|
|
||||||
# jsonpath will always store the result in json_dict[0]
|
|
||||||
# so the next line happens to work exactly as needed to
|
|
||||||
# find the result
|
|
||||||
if isinstance(json_dict, list):
|
|
||||||
json_dict = json_dict[0]
|
|
||||||
if isinstance(json_dict, dict):
|
|
||||||
attrs = {
|
|
||||||
k: json_dict[k] for k in self._json_attrs if k in json_dict
|
|
||||||
}
|
|
||||||
self._attr_extra_state_attributes = attrs
|
|
||||||
else:
|
|
||||||
_LOGGER.warning(
|
|
||||||
"JSON result was not a dictionary"
|
|
||||||
" or list with 0th element a dictionary"
|
|
||||||
)
|
)
|
||||||
except ValueError:
|
|
||||||
_LOGGER.warning("REST result could not be parsed as JSON")
|
|
||||||
_LOGGER.debug("Erroneous JSON: %s", value)
|
|
||||||
|
|
||||||
else:
|
|
||||||
_LOGGER.warning("Empty reply found when expecting JSON data")
|
|
||||||
|
|
||||||
raw_value = value
|
raw_value = value
|
||||||
|
|
||||||
|
40
homeassistant/components/rest/util.py
Normal file
40
homeassistant/components/rest/util.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
"""Helpers for RESTful API."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from jsonpath import jsonpath
|
||||||
|
|
||||||
|
from homeassistant.util.json import json_loads
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_json_attributes(
|
||||||
|
value: str | None, json_attrs: list[str], json_attrs_path: str | None
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Parse JSON attributes."""
|
||||||
|
if not value:
|
||||||
|
_LOGGER.warning("Empty reply found when expecting JSON data")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
json_dict = json_loads(value)
|
||||||
|
if json_attrs_path is not None:
|
||||||
|
json_dict = jsonpath(json_dict, json_attrs_path)
|
||||||
|
# jsonpath will always store the result in json_dict[0]
|
||||||
|
# so the next line happens to work exactly as needed to
|
||||||
|
# find the result
|
||||||
|
if isinstance(json_dict, list):
|
||||||
|
json_dict = json_dict[0]
|
||||||
|
if isinstance(json_dict, dict):
|
||||||
|
return {k: json_dict[k] for k in json_attrs if k in json_dict}
|
||||||
|
|
||||||
|
_LOGGER.warning(
|
||||||
|
"JSON result was not a dictionary or list with 0th element a dictionary"
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
_LOGGER.warning("REST result could not be parsed as JSON")
|
||||||
|
_LOGGER.debug("Erroneous JSON: %s", value)
|
||||||
|
|
||||||
|
return {}
|
Loading…
x
Reference in New Issue
Block a user