commit
5ee373869a
|
@ -791,7 +791,7 @@ class TemperatureSettingTrait(_Trait):
|
|||
if preset in self.preset_to_google:
|
||||
response["thermostatMode"] = self.preset_to_google[preset]
|
||||
else:
|
||||
response["thermostatMode"] = self.hvac_to_google.get(operation)
|
||||
response["thermostatMode"] = self.hvac_to_google.get(operation, "none")
|
||||
|
||||
current_temp = attrs.get(climate.ATTR_CURRENT_TEMPERATURE)
|
||||
if current_temp is not None:
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
"name": "Meteorologisk institutt (Met.no)",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/met",
|
||||
"requirements": ["pyMetno==0.8.1"],
|
||||
"requirements": ["pyMetno==0.8.2"],
|
||||
"codeowners": ["@danielhiversen", "@thimic"]
|
||||
}
|
||||
|
|
|
@ -319,7 +319,19 @@ class ModbusRegisterSensor(RestoreEntity, SensorEntity):
|
|||
# If unpack() returns a tuple greater than 1, don't try to process the value.
|
||||
# Instead, return the values of unpack(...) separated by commas.
|
||||
if len(val) > 1:
|
||||
self._value = ",".join(map(str, val))
|
||||
# Apply scale and precision to floats and ints
|
||||
v_result = []
|
||||
for entry in val:
|
||||
v_temp = self._scale * entry + self._offset
|
||||
|
||||
# We could convert int to float, and the code would still work; however
|
||||
# we lose some precision, and unit tests will fail. Therefore, we do
|
||||
# the conversion only when it's absolutely necessary.
|
||||
if isinstance(v_temp, int) and self._precision == 0:
|
||||
v_result.append(str(v_temp))
|
||||
else:
|
||||
v_result.append(f"{float(v_temp):.{self._precision}f}")
|
||||
self._value = ",".join(map(str, v_result))
|
||||
else:
|
||||
val = val[0]
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ def round_state(func):
|
|||
|
||||
|
||||
class AirSensor(AirQualityEntity):
|
||||
"""Representation of an Yr.no sensor."""
|
||||
"""Representation of an air quality sensor."""
|
||||
|
||||
def __init__(self, name, coordinates, forecast, session):
|
||||
"""Initialize the sensor."""
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
"domain": "norway_air",
|
||||
"name": "Om Luftkvalitet i Norge (Norway Air)",
|
||||
"documentation": "https://www.home-assistant.io/integrations/norway_air",
|
||||
"requirements": ["pyMetno==0.8.1"],
|
||||
"requirements": ["pyMetno==0.8.2"],
|
||||
"codeowners": []
|
||||
}
|
||||
|
|
|
@ -328,9 +328,8 @@ async def _async_discover_roombas(hass, host):
|
|||
discovery = _async_get_roomba_discovery()
|
||||
try:
|
||||
if host:
|
||||
discovered = [
|
||||
await hass.async_add_executor_job(discovery.get, host)
|
||||
]
|
||||
device = await hass.async_add_executor_job(discovery.get, host)
|
||||
discovered = [device] if device else []
|
||||
else:
|
||||
discovered = await hass.async_add_executor_job(discovery.get_all)
|
||||
except OSError:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Constants used by Home Assistant components."""
|
||||
MAJOR_VERSION = 2021
|
||||
MINOR_VERSION = 4
|
||||
PATCH_VERSION = "5"
|
||||
PATCH_VERSION = "6"
|
||||
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
||||
REQUIRED_PYTHON_VER = (3, 8, 0)
|
||||
|
|
|
@ -1203,12 +1203,9 @@ class Script:
|
|||
self._changed()
|
||||
raise
|
||||
|
||||
async def _async_stop(self, update_state, spare=None):
|
||||
aws = [
|
||||
asyncio.create_task(run.async_stop()) for run in self._runs if run != spare
|
||||
]
|
||||
if not aws:
|
||||
return
|
||||
async def _async_stop(
|
||||
self, aws: list[asyncio.Task], update_state: bool, spare: _ScriptRun | None
|
||||
) -> None:
|
||||
await asyncio.wait(aws)
|
||||
if update_state:
|
||||
self._changed()
|
||||
|
@ -1217,7 +1214,15 @@ class Script:
|
|||
self, update_state: bool = True, spare: _ScriptRun | None = None
|
||||
) -> None:
|
||||
"""Stop running script."""
|
||||
await asyncio.shield(self._async_stop(update_state, spare))
|
||||
# Collect a a list of script runs to stop. This must be done before calling
|
||||
# asyncio.shield as asyncio.shield yields to the event loop, which would cause
|
||||
# us to wait for script runs added after the call to async_stop.
|
||||
aws = [
|
||||
asyncio.create_task(run.async_stop()) for run in self._runs if run != spare
|
||||
]
|
||||
if not aws:
|
||||
return
|
||||
await asyncio.shield(self._async_stop(aws, update_state, spare))
|
||||
|
||||
async def _async_get_condition(self, config):
|
||||
if isinstance(config, template.Template):
|
||||
|
|
|
@ -1229,7 +1229,7 @@ pyHS100==0.3.5.2
|
|||
|
||||
# homeassistant.components.met
|
||||
# homeassistant.components.norway_air
|
||||
pyMetno==0.8.1
|
||||
pyMetno==0.8.2
|
||||
|
||||
# homeassistant.components.rfxtrx
|
||||
pyRFXtrx==0.26.1
|
||||
|
|
|
@ -648,7 +648,7 @@ pyHS100==0.3.5.2
|
|||
|
||||
# homeassistant.components.met
|
||||
# homeassistant.components.norway_air
|
||||
pyMetno==0.8.1
|
||||
pyMetno==0.8.2
|
||||
|
||||
# homeassistant.components.rfxtrx
|
||||
pyRFXtrx==0.26.1
|
||||
|
|
|
@ -14,6 +14,7 @@ from homeassistant.components.modbus.const import (
|
|||
CONF_REVERSE_ORDER,
|
||||
CONF_SCALE,
|
||||
CONF_SENSORS,
|
||||
DATA_TYPE_CUSTOM,
|
||||
DATA_TYPE_FLOAT,
|
||||
DATA_TYPE_INT,
|
||||
DATA_TYPE_STRING,
|
||||
|
@ -26,6 +27,7 @@ from homeassistant.const import (
|
|||
CONF_NAME,
|
||||
CONF_OFFSET,
|
||||
CONF_SLAVE,
|
||||
CONF_STRUCTURE,
|
||||
)
|
||||
|
||||
from .conftest import base_config_test, base_test
|
||||
|
@ -338,6 +340,7 @@ async def test_config_sensor(hass, do_discovery, do_config):
|
|||
)
|
||||
async def test_all_sensor(hass, cfg, regs, expected):
|
||||
"""Run test for sensor."""
|
||||
|
||||
sensor_name = "modbus_test_sensor"
|
||||
state = await base_test(
|
||||
hass,
|
||||
|
@ -352,3 +355,41 @@ async def test_all_sensor(hass, cfg, regs, expected):
|
|||
scan_interval=5,
|
||||
)
|
||||
assert state == expected
|
||||
|
||||
|
||||
async def test_struct_sensor(hass):
|
||||
"""Run test for sensor struct."""
|
||||
|
||||
sensor_name = "modbus_test_sensor"
|
||||
# floats: 7.931250095367432, 10.600000381469727,
|
||||
# 1.000879611487865e-28, 10.566553115844727
|
||||
expected = "7.93,10.60,0.00,10.57"
|
||||
state = await base_test(
|
||||
hass,
|
||||
{
|
||||
CONF_NAME: sensor_name,
|
||||
CONF_REGISTER: 1234,
|
||||
CONF_COUNT: 8,
|
||||
CONF_PRECISION: 2,
|
||||
CONF_DATA_TYPE: DATA_TYPE_CUSTOM,
|
||||
CONF_STRUCTURE: ">4f",
|
||||
},
|
||||
sensor_name,
|
||||
SENSOR_DOMAIN,
|
||||
CONF_SENSORS,
|
||||
CONF_REGISTERS,
|
||||
[
|
||||
0x40FD,
|
||||
0xCCCD,
|
||||
0x4129,
|
||||
0x999A,
|
||||
0x10FD,
|
||||
0xC0CD,
|
||||
0x4129,
|
||||
0x109A,
|
||||
],
|
||||
expected,
|
||||
method_discovery=False,
|
||||
scan_interval=5,
|
||||
)
|
||||
assert state == expected
|
||||
|
|
|
@ -711,7 +711,7 @@ async def test_dhcp_discovery_and_roomba_discovery_finds(hass, discovery_data):
|
|||
|
||||
@pytest.mark.parametrize("discovery_data", DHCP_DISCOVERY_DEVICES_WITHOUT_MATCHING_IP)
|
||||
async def test_dhcp_discovery_falls_back_to_manual(hass, discovery_data):
|
||||
"""Test we can process the discovery from dhcp but roomba discovery cannot find the device."""
|
||||
"""Test we can process the discovery from dhcp but roomba discovery cannot find the specific device."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
mocked_roomba = _create_mocked_roomba(
|
||||
|
@ -782,6 +782,68 @@ async def test_dhcp_discovery_falls_back_to_manual(hass, discovery_data):
|
|||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("discovery_data", DHCP_DISCOVERY_DEVICES_WITHOUT_MATCHING_IP)
|
||||
async def test_dhcp_discovery_no_devices_falls_back_to_manual(hass, discovery_data):
|
||||
"""Test we can process the discovery from dhcp but roomba discovery cannot find any devices."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
mocked_roomba = _create_mocked_roomba(
|
||||
roomba_connected=True,
|
||||
master_state={"state": {"reported": {"name": "myroomba"}}},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.roomba.config_flow.RoombaDiscovery",
|
||||
_mocked_no_devices_found_discovery,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_DHCP},
|
||||
data=discovery_data,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["errors"] is None
|
||||
assert result["step_id"] == "manual"
|
||||
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{CONF_HOST: MOCK_IP, CONF_BLID: "blid"},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result2["errors"] is None
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.roomba.config_flow.Roomba",
|
||||
return_value=mocked_roomba,
|
||||
), patch(
|
||||
"homeassistant.components.roomba.config_flow.RoombaPassword",
|
||||
_mocked_getpassword,
|
||||
), patch(
|
||||
"homeassistant.components.roomba.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result3 = await hass.config_entries.flow.async_configure(
|
||||
result2["flow_id"],
|
||||
{},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result3["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result3["title"] == "myroomba"
|
||||
assert result3["result"].unique_id == "BLID"
|
||||
assert result3["data"] == {
|
||||
CONF_BLID: "BLID",
|
||||
CONF_CONTINUOUS: True,
|
||||
CONF_DELAY: 1,
|
||||
CONF_HOST: MOCK_IP,
|
||||
CONF_PASSWORD: "password",
|
||||
}
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_dhcp_discovery_with_ignored(hass):
|
||||
"""Test ignored entries do not break checking for existing entries."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
|
Loading…
Reference in New Issue