Allow removal of sensor settings in scrape (#90412)
* Allow removal of sensor settings in scrape * Adjust * Adjust * Add comment * Simplify * Simplify * Adjust * Don't allow empty string * Only allow None * Use default as None * Use sentinel "none" * Not needed * Adjust unit of measurement * Add translation keys for "none" * Use translations * Sort * Add enum and timestamp * Use translation references * Remove default and set suggested_values * Disallow enum device class * Adjust tests * Adjust _strip_sentinelpull/90579/head
parent
ea32cc5d92
commit
4f54e33f67
|
@ -95,6 +95,8 @@ RESOURCE_SETUP = {
|
|||
vol.Optional(CONF_ENCODING, default=DEFAULT_ENCODING): TextSelector(),
|
||||
}
|
||||
|
||||
NONE_SENTINEL = "none"
|
||||
|
||||
SENSOR_SETUP = {
|
||||
vol.Required(CONF_SELECT): TextSelector(),
|
||||
vol.Optional(CONF_INDEX, default=0): NumberSelector(
|
||||
|
@ -102,28 +104,45 @@ SENSOR_SETUP = {
|
|||
),
|
||||
vol.Optional(CONF_ATTRIBUTE): TextSelector(),
|
||||
vol.Optional(CONF_VALUE_TEMPLATE): TemplateSelector(),
|
||||
vol.Optional(CONF_DEVICE_CLASS): SelectSelector(
|
||||
vol.Required(CONF_DEVICE_CLASS): SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[cls.value for cls in SensorDeviceClass],
|
||||
options=[NONE_SENTINEL]
|
||||
+ sorted(
|
||||
[
|
||||
cls.value
|
||||
for cls in SensorDeviceClass
|
||||
if cls != SensorDeviceClass.ENUM
|
||||
]
|
||||
),
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
translation_key="device_class",
|
||||
)
|
||||
),
|
||||
vol.Optional(CONF_STATE_CLASS): SelectSelector(
|
||||
vol.Required(CONF_STATE_CLASS): SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[cls.value for cls in SensorStateClass],
|
||||
options=[NONE_SENTINEL] + sorted([cls.value for cls in SensorStateClass]),
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
translation_key="state_class",
|
||||
)
|
||||
),
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): SelectSelector(
|
||||
vol.Required(CONF_UNIT_OF_MEASUREMENT): SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[cls.value for cls in UnitOfTemperature],
|
||||
options=[NONE_SENTINEL] + sorted([cls.value for cls in UnitOfTemperature]),
|
||||
custom_value=True,
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
translation_key="unit_of_measurement",
|
||||
)
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def _strip_sentinel(options: dict[str, Any]) -> None:
|
||||
"""Convert sentinel to None."""
|
||||
for key in (CONF_DEVICE_CLASS, CONF_STATE_CLASS, CONF_UNIT_OF_MEASUREMENT):
|
||||
if options[key] == NONE_SENTINEL:
|
||||
options.pop(key)
|
||||
|
||||
|
||||
async def validate_rest_setup(
|
||||
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
|
||||
) -> dict[str, Any]:
|
||||
|
@ -150,6 +169,7 @@ async def validate_sensor_setup(
|
|||
# Standard behavior is to merge the result with the options.
|
||||
# In this case, we want to add a sub-item so we update the options directly.
|
||||
sensors: list[dict[str, Any]] = handler.options.setdefault(SENSOR_DOMAIN, [])
|
||||
_strip_sentinel(user_input)
|
||||
sensors.append(user_input)
|
||||
return {}
|
||||
|
||||
|
@ -181,7 +201,11 @@ async def get_edit_sensor_suggested_values(
|
|||
) -> dict[str, Any]:
|
||||
"""Return suggested values for sensor editing."""
|
||||
idx: int = handler.flow_state["_idx"]
|
||||
return cast(dict[str, Any], handler.options[SENSOR_DOMAIN][idx])
|
||||
suggested_values: dict[str, Any] = dict(handler.options[SENSOR_DOMAIN][idx])
|
||||
for key in (CONF_DEVICE_CLASS, CONF_STATE_CLASS, CONF_UNIT_OF_MEASUREMENT):
|
||||
if not suggested_values.get(key):
|
||||
suggested_values[key] = NONE_SENTINEL
|
||||
return suggested_values
|
||||
|
||||
|
||||
async def validate_sensor_edit(
|
||||
|
@ -194,6 +218,7 @@ async def validate_sensor_edit(
|
|||
# In this case, we want to add a sub-item so we update the options directly.
|
||||
idx: int = handler.flow_state["_idx"]
|
||||
handler.options[SENSOR_DOMAIN][idx].update(user_input)
|
||||
_strip_sentinel(handler.options[SENSOR_DOMAIN][idx])
|
||||
return {}
|
||||
|
||||
|
||||
|
|
|
@ -125,5 +125,72 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"device_class": {
|
||||
"options": {
|
||||
"none": "No device class",
|
||||
"date": "[%key:component::sensor::entity_component::date::name%]",
|
||||
"duration": "[%key:component::sensor::entity_component::duration::name%]",
|
||||
"apparent_power": "[%key:component::sensor::entity_component::apparent_power::name%]",
|
||||
"aqi": "[%key:component::sensor::entity_component::aqi::name%]",
|
||||
"atmospheric_pressure": "[%key:component::sensor::entity_component::atmospheric_pressure::name%]",
|
||||
"battery": "[%key:component::sensor::entity_component::battery::name%]",
|
||||
"carbon_monoxide": "[%key:component::sensor::entity_component::carbon_monoxide::name%]",
|
||||
"carbon_dioxide": "[%key:component::sensor::entity_component::carbon_dioxide::name%]",
|
||||
"current": "[%key:component::sensor::entity_component::current::name%]",
|
||||
"data_rate": "[%key:component::sensor::entity_component::data_rate::name%]",
|
||||
"data_size": "[%key:component::sensor::entity_component::data_size::name%]",
|
||||
"distance": "[%key:component::sensor::entity_component::distance::name%]",
|
||||
"energy": "[%key:component::sensor::entity_component::energy::name%]",
|
||||
"energy_storage": "[%key:component::sensor::entity_component::energy_storage::name%]",
|
||||
"frequency": "[%key:component::sensor::entity_component::frequency::name%]",
|
||||
"gas": "[%key:component::sensor::entity_component::gas::name%]",
|
||||
"humidity": "[%key:component::sensor::entity_component::humidity::name%]",
|
||||
"illuminance": "[%key:component::sensor::entity_component::illuminance::name%]",
|
||||
"irradiance": "[%key:component::sensor::entity_component::irradiance::name%]",
|
||||
"moisture": "[%key:component::sensor::entity_component::moisture::name%]",
|
||||
"monetary": "[%key:component::sensor::entity_component::monetary::name%]",
|
||||
"nitrogen_dioxide": "[%key:component::sensor::entity_component::nitrogen_dioxide::name%]",
|
||||
"nitrogen_monoxide": "[%key:component::sensor::entity_component::nitrogen_monoxide::name%]",
|
||||
"nitrous_oxide": "[%key:component::sensor::entity_component::nitrous_oxide::name%]",
|
||||
"ozone": "[%key:component::sensor::entity_component::ozone::name%]",
|
||||
"pm1": "[%key:component::sensor::entity_component::pm1::name%]",
|
||||
"pm10": "[%key:component::sensor::entity_component::pm10::name%]",
|
||||
"pm25": "[%key:component::sensor::entity_component::pm25::name%]",
|
||||
"power_factor": "[%key:component::sensor::entity_component::power_factor::name%]",
|
||||
"power": "[%key:component::sensor::entity_component::power::name%]",
|
||||
"precipitation": "[%key:component::sensor::entity_component::precipitation::name%]",
|
||||
"precipitation_intensity": "[%key:component::sensor::entity_component::precipitation_intensity::name%]",
|
||||
"pressure": "[%key:component::sensor::entity_component::pressure::name%]",
|
||||
"reactive_power": "[%key:component::sensor::entity_component::reactive_power::name%]",
|
||||
"signal_strength": "[%key:component::sensor::entity_component::signal_strength::name%]",
|
||||
"sound_pressure": "[%key:component::sensor::entity_component::sound_pressure::name%]",
|
||||
"speed": "[%key:component::sensor::entity_component::speed::name%]",
|
||||
"sulphur_dioxide": "[%key:component::sensor::entity_component::sulphur_dioxide::name%]",
|
||||
"temperature": "[%key:component::sensor::entity_component::temperature::name%]",
|
||||
"timestamp": "[%key:component::sensor::entity_component::timestamp::name%]",
|
||||
"volatile_organic_compounds": "[%key:component::sensor::entity_component::volatile_organic_compounds::name%]",
|
||||
"voltage": "[%key:component::sensor::entity_component::voltage::name%]",
|
||||
"volume": "[%key:component::sensor::entity_component::volume::name%]",
|
||||
"volume_storage": "[%key:component::sensor::entity_component::volume_storage::name%]",
|
||||
"water": "[%key:component::sensor::entity_component::water::name%]",
|
||||
"weight": "[%key:component::sensor::entity_component::weight::name%]",
|
||||
"wind_speed": "[%key:component::sensor::entity_component::wind_speed::name%]"
|
||||
}
|
||||
},
|
||||
"state_class": {
|
||||
"options": {
|
||||
"none": "No state class",
|
||||
"measurement": "[%key:component::sensor::entity_component::_::state_attributes::state_class::state::measurement%]",
|
||||
"total": "[%key:component::sensor::entity_component::_::state_attributes::state_class::state::total%]",
|
||||
"total_increasing": "[%key:component::sensor::entity_component::_::state_attributes::state_class::state::total_increasing%]"
|
||||
}
|
||||
},
|
||||
"unit_of_measurement": {
|
||||
"options": {
|
||||
"none": "No unit of measurement"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""Fixtures for the Scrape integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import AsyncMock, patch
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
|
@ -32,6 +33,16 @@ from . import MockRestData
|
|||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_setup_entry() -> Generator[AsyncMock, None, None]:
|
||||
"""Automatically path uuid generator."""
|
||||
with patch(
|
||||
"homeassistant.components.scrape.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
yield mock_setup_entry
|
||||
|
||||
|
||||
@pytest.fixture(name="get_config")
|
||||
async def get_config_to_integration_load() -> dict[str, Any]:
|
||||
"""Return default minimal configuration.
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
"""Test the Scrape config flow."""
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import AsyncMock, patch
|
||||
import uuid
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.rest.data import DEFAULT_TIMEOUT
|
||||
from homeassistant.components.rest.schema import DEFAULT_METHOD
|
||||
from homeassistant.components.scrape import DOMAIN
|
||||
from homeassistant.components.scrape.config_flow import NONE_SENTINEL
|
||||
from homeassistant.components.scrape.const import (
|
||||
CONF_ENCODING,
|
||||
CONF_INDEX,
|
||||
|
@ -15,14 +16,18 @@ from homeassistant.components.scrape.const import (
|
|||
DEFAULT_ENCODING,
|
||||
DEFAULT_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.components.sensor import CONF_STATE_CLASS
|
||||
from homeassistant.const import (
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_METHOD,
|
||||
CONF_NAME,
|
||||
CONF_PASSWORD,
|
||||
CONF_RESOURCE,
|
||||
CONF_TIMEOUT,
|
||||
CONF_UNIQUE_ID,
|
||||
CONF_UNIT_OF_MEASUREMENT,
|
||||
CONF_USERNAME,
|
||||
CONF_VALUE_TEMPLATE,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -34,7 +39,9 @@ from . import MockRestData
|
|||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_form(hass: HomeAssistant, get_data: MockRestData) -> None:
|
||||
async def test_form(
|
||||
hass: HomeAssistant, get_data: MockRestData, mock_setup_entry: AsyncMock
|
||||
) -> None:
|
||||
"""Test we get the form."""
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -46,10 +53,7 @@ async def test_form(hass: HomeAssistant, get_data: MockRestData) -> None:
|
|||
with patch(
|
||||
"homeassistant.components.rest.RestData",
|
||||
return_value=get_data,
|
||||
) as mock_data, patch(
|
||||
"homeassistant.components.scrape.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
) as mock_data:
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
|
@ -66,6 +70,9 @@ async def test_form(hass: HomeAssistant, get_data: MockRestData) -> None:
|
|||
CONF_NAME: "Current version",
|
||||
CONF_SELECT: ".current-version h1",
|
||||
CONF_INDEX: 0.0,
|
||||
CONF_DEVICE_CLASS: NONE_SENTINEL,
|
||||
CONF_STATE_CLASS: NONE_SENTINEL,
|
||||
CONF_UNIT_OF_MEASUREMENT: NONE_SENTINEL,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -92,7 +99,9 @@ async def test_form(hass: HomeAssistant, get_data: MockRestData) -> None:
|
|||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_flow_fails(hass: HomeAssistant, get_data: MockRestData) -> None:
|
||||
async def test_flow_fails(
|
||||
hass: HomeAssistant, get_data: MockRestData, mock_setup_entry: AsyncMock
|
||||
) -> None:
|
||||
"""Test config flow error."""
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -137,9 +146,6 @@ async def test_flow_fails(hass: HomeAssistant, get_data: MockRestData) -> None:
|
|||
with patch(
|
||||
"homeassistant.components.rest.RestData",
|
||||
return_value=get_data,
|
||||
), patch(
|
||||
"homeassistant.components.scrape.async_setup_entry",
|
||||
return_value=True,
|
||||
):
|
||||
result3 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
|
@ -157,6 +163,9 @@ async def test_flow_fails(hass: HomeAssistant, get_data: MockRestData) -> None:
|
|||
CONF_NAME: "Current version",
|
||||
CONF_SELECT: ".current-version h1",
|
||||
CONF_INDEX: 0.0,
|
||||
CONF_DEVICE_CLASS: NONE_SENTINEL,
|
||||
CONF_STATE_CLASS: NONE_SENTINEL,
|
||||
CONF_UNIT_OF_MEASUREMENT: NONE_SENTINEL,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -278,6 +287,9 @@ async def test_options_add_remove_sensor_flow(
|
|||
CONF_NAME: "Template",
|
||||
CONF_SELECT: "template",
|
||||
CONF_INDEX: 0.0,
|
||||
CONF_DEVICE_CLASS: NONE_SENTINEL,
|
||||
CONF_STATE_CLASS: NONE_SENTINEL,
|
||||
CONF_UNIT_OF_MEASUREMENT: NONE_SENTINEL,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -405,6 +417,9 @@ async def test_options_edit_sensor_flow(
|
|||
user_input={
|
||||
CONF_SELECT: "template",
|
||||
CONF_INDEX: 0.0,
|
||||
CONF_DEVICE_CLASS: NONE_SENTINEL,
|
||||
CONF_STATE_CLASS: NONE_SENTINEL,
|
||||
CONF_UNIT_OF_MEASUREMENT: NONE_SENTINEL,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -434,3 +449,161 @@ async def test_options_edit_sensor_flow(
|
|||
# Check the state of the entity has changed as expected
|
||||
state = hass.states.get("sensor.current_version")
|
||||
assert state.state == "Trying to get"
|
||||
|
||||
|
||||
async def test_sensor_options_add_device_class(
|
||||
hass: HomeAssistant, mock_setup_entry: AsyncMock
|
||||
) -> None:
|
||||
"""Test options flow to edit a sensor."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
options={
|
||||
CONF_RESOURCE: "https://www.home-assistant.io",
|
||||
CONF_METHOD: DEFAULT_METHOD,
|
||||
CONF_VERIFY_SSL: DEFAULT_VERIFY_SSL,
|
||||
CONF_TIMEOUT: DEFAULT_TIMEOUT,
|
||||
CONF_ENCODING: DEFAULT_ENCODING,
|
||||
"sensor": [
|
||||
{
|
||||
CONF_NAME: "Current Temp",
|
||||
CONF_SELECT: ".current-temp h3",
|
||||
CONF_INDEX: 0,
|
||||
CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}",
|
||||
CONF_UNIQUE_ID: "3699ef88-69e6-11ed-a1eb-0242ac120002",
|
||||
}
|
||||
],
|
||||
},
|
||||
entry_id="1",
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||
assert result["type"] == FlowResultType.MENU
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
{"next_step_id": "select_edit_sensor"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "select_edit_sensor"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
{"index": "0"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "edit_sensor"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
CONF_SELECT: ".current-temp h3",
|
||||
CONF_INDEX: 0.0,
|
||||
CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}",
|
||||
CONF_DEVICE_CLASS: "temperature",
|
||||
CONF_STATE_CLASS: "measurement",
|
||||
CONF_UNIT_OF_MEASUREMENT: "°C",
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
CONF_RESOURCE: "https://www.home-assistant.io",
|
||||
CONF_METHOD: "GET",
|
||||
CONF_VERIFY_SSL: True,
|
||||
CONF_TIMEOUT: 10,
|
||||
CONF_ENCODING: "UTF-8",
|
||||
"sensor": [
|
||||
{
|
||||
CONF_NAME: "Current Temp",
|
||||
CONF_SELECT: ".current-temp h3",
|
||||
CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}",
|
||||
CONF_INDEX: 0,
|
||||
CONF_DEVICE_CLASS: "temperature",
|
||||
CONF_STATE_CLASS: "measurement",
|
||||
CONF_UNIT_OF_MEASUREMENT: "°C",
|
||||
CONF_UNIQUE_ID: "3699ef88-69e6-11ed-a1eb-0242ac120002",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
async def test_sensor_options_remove_device_class(
|
||||
hass: HomeAssistant, mock_setup_entry: AsyncMock
|
||||
) -> None:
|
||||
"""Test options flow to edit a sensor."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
options={
|
||||
CONF_RESOURCE: "https://www.home-assistant.io",
|
||||
CONF_METHOD: DEFAULT_METHOD,
|
||||
CONF_VERIFY_SSL: DEFAULT_VERIFY_SSL,
|
||||
CONF_TIMEOUT: DEFAULT_TIMEOUT,
|
||||
CONF_ENCODING: DEFAULT_ENCODING,
|
||||
"sensor": [
|
||||
{
|
||||
CONF_NAME: "Current Temp",
|
||||
CONF_SELECT: ".current-temp h3",
|
||||
CONF_INDEX: 0,
|
||||
CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}",
|
||||
CONF_DEVICE_CLASS: "temperature",
|
||||
CONF_STATE_CLASS: "measurement",
|
||||
CONF_UNIT_OF_MEASUREMENT: "°C",
|
||||
CONF_UNIQUE_ID: "3699ef88-69e6-11ed-a1eb-0242ac120002",
|
||||
}
|
||||
],
|
||||
},
|
||||
entry_id="1",
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||
assert result["type"] == FlowResultType.MENU
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
{"next_step_id": "select_edit_sensor"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "select_edit_sensor"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
{"index": "0"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "edit_sensor"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
CONF_SELECT: ".current-temp h3",
|
||||
CONF_INDEX: 0.0,
|
||||
CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}",
|
||||
CONF_DEVICE_CLASS: NONE_SENTINEL,
|
||||
CONF_STATE_CLASS: NONE_SENTINEL,
|
||||
CONF_UNIT_OF_MEASUREMENT: NONE_SENTINEL,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
CONF_RESOURCE: "https://www.home-assistant.io",
|
||||
CONF_METHOD: "GET",
|
||||
CONF_VERIFY_SSL: True,
|
||||
CONF_TIMEOUT: 10,
|
||||
CONF_ENCODING: "UTF-8",
|
||||
"sensor": [
|
||||
{
|
||||
CONF_NAME: "Current Temp",
|
||||
CONF_SELECT: ".current-temp h3",
|
||||
CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}",
|
||||
CONF_INDEX: 0,
|
||||
CONF_UNIQUE_ID: "3699ef88-69e6-11ed-a1eb-0242ac120002",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue