Skip to content
Merged

2021.4.1 #48896

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"screenshots": [
{
"src": "/static/images/screenshots/screenshot-1.png",
"sizes": "413×792",
"sizes": "413x792",
"type": "image/png",
}
],
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Home Assistant Frontend",
"documentation": "https://www.home-assistant.io/integrations/frontend",
"requirements": [
"home-assistant-frontend==20210407.1"
"home-assistant-frontend==20210407.2"
],
"dependencies": [
"api",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/icloud/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,6 @@ def location(self) -> dict[str, any]:
return self._location

@property
def exta_state_attributes(self) -> dict[str, any]:
def extra_state_attributes(self) -> dict[str, any]:
"""Return the attributes."""
return self._attrs
2 changes: 1 addition & 1 deletion homeassistant/components/icloud/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def icon(self) -> str:
@property
def extra_state_attributes(self) -> dict[str, any]:
"""Return the device state attributes."""
return self._device.state_attributes
return self._device.extra_state_attributes

@property
def device_info(self) -> dict[str, any]:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/icloud/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def icon(self) -> str:
@property
def extra_state_attributes(self) -> dict[str, any]:
"""Return default attributes for the iCloud device entity."""
return self._device.state_attributes
return self._device.extra_state_attributes

@property
def device_info(self) -> dict[str, any]:
Expand Down
14 changes: 14 additions & 0 deletions homeassistant/components/light/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@
COLOR_MODES_BRIGHTNESS = VALID_COLOR_MODES - {COLOR_MODE_ONOFF}
COLOR_MODES_COLOR = {COLOR_MODE_HS, COLOR_MODE_RGB, COLOR_MODE_XY}


def valid_supported_color_modes(color_modes):
"""Validate the given color modes."""
color_modes = set(color_modes)
if (
not color_modes
or COLOR_MODE_UNKNOWN in color_modes
or (COLOR_MODE_BRIGHTNESS in color_modes and len(color_modes) > 1)
or (COLOR_MODE_ONOFF in color_modes and len(color_modes) > 1)
):
raise vol.Error(f"Invalid supported_color_modes {sorted(color_modes)}")
return color_modes


# Float that represents transition time in seconds to make change.
ATTR_TRANSITION = "transition"

Expand Down
10 changes: 7 additions & 3 deletions homeassistant/components/motion_blinds/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,14 @@ def available(self):
if self.coordinator.data is None:
return False

if not self.coordinator.data[KEY_GATEWAY][ATTR_AVAILABLE]:
return False
gateway_available = self.coordinator.data[KEY_GATEWAY][ATTR_AVAILABLE]
if self._device_type == TYPE_GATEWAY:
return gateway_available

return self.coordinator.data[self._device.mac][ATTR_AVAILABLE]
return (
gateway_available
and self.coordinator.data[self._device.mac][ATTR_AVAILABLE]
)

@property
def unit_of_measurement(self):
Expand Down
6 changes: 5 additions & 1 deletion homeassistant/components/mqtt/light/schema_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
SUPPORT_WHITE_VALUE,
VALID_COLOR_MODES,
LightEntity,
valid_supported_color_modes,
)
from homeassistant.const import (
CONF_BRIGHTNESS,
Expand Down Expand Up @@ -130,7 +131,10 @@ def valid_color_configuration(config):
vol.Optional(CONF_RGB, default=DEFAULT_RGB): cv.boolean,
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Inclusive(CONF_SUPPORTED_COLOR_MODES, "color_mode"): vol.All(
cv.ensure_list, [vol.In(VALID_COLOR_MODES)], vol.Unique()
cv.ensure_list,
[vol.In(VALID_COLOR_MODES)],
vol.Unique(),
valid_supported_color_modes,
),
vol.Optional(CONF_WHITE_VALUE, default=DEFAULT_WHITE_VALUE): cv.boolean,
vol.Optional(CONF_XY, default=DEFAULT_XY): cv.boolean,
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/mysensors/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ def get_cover_state(self):
else:
amount = 100 if self._values.get(set_req.V_LIGHT) == STATE_ON else 0

if amount == 0:
return CoverState.CLOSED
if v_up and not v_down and not v_stop:
return CoverState.OPENING
if not v_up and v_down and not v_stop:
return CoverState.CLOSING
if not v_up and not v_down and v_stop and amount == 0:
return CoverState.CLOSED
return CoverState.OPEN

@property
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/prowl/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async def async_send_message(self, message, **kwargs):
"description": message,
"priority": data["priority"] if data and "priority" in data else 0,
}
if data.get("url"):
if data and data.get("url"):
payload["url"] = data["url"]

_LOGGER.debug("Attempting call Prowl service at %s", url)
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/components/speedtestdotnet/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"name": "Speedtest.net",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/speedtestdotnet",
"requirements": ["speedtest-cli==2.1.2"],
"requirements": [
"speedtest-cli==2.1.3"
],
"codeowners": ["@rohankapoorcom", "@engrbm87"]
}
15 changes: 8 additions & 7 deletions homeassistant/components/stream/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@

_LOGGER = logging.getLogger(__name__)

STREAM_SOURCE_RE = re.compile("//(.*):(.*)@")
STREAM_SOURCE_RE = re.compile("//.*:.*@")


def redact_credentials(data):
"""Redact credentials from string data."""
return STREAM_SOURCE_RE.sub("//****:****@", data)


def create_stream(hass, stream_source, options=None):
Expand Down Expand Up @@ -176,9 +181,7 @@ def start(self):
target=self._run_worker,
)
self._thread.start()
_LOGGER.info(
"Started stream: %s", STREAM_SOURCE_RE.sub("//", str(self.source))
)
_LOGGER.info("Started stream: %s", redact_credentials(str(self.source)))

def update_source(self, new_source):
"""Restart the stream with a new stream source."""
Expand Down Expand Up @@ -244,9 +247,7 @@ def _stop(self):
self._thread_quit.set()
self._thread.join()
self._thread = None
_LOGGER.info(
"Stopped stream: %s", STREAM_SOURCE_RE.sub("//", str(self.source))
)
_LOGGER.info("Stopped stream: %s", redact_credentials(str(self.source)))

async def async_record(self, video_path, duration=30, lookback=5):
"""Make a .mp4 recording from a provided stream."""
Expand Down
6 changes: 2 additions & 4 deletions homeassistant/components/stream/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import av

from . import STREAM_SOURCE_RE
from . import redact_credentials
from .const import (
AUDIO_CODECS,
MAX_MISSING_DTS,
Expand Down Expand Up @@ -128,9 +128,7 @@ def stream_worker(source, options, segment_buffer, quit_event):
try:
container = av.open(source, options=options, timeout=STREAM_TIMEOUT)
except av.AVError:
_LOGGER.error(
"Error opening stream %s", STREAM_SOURCE_RE.sub("//", str(source))
)
_LOGGER.error("Error opening stream %s", redact_credentials(str(source)))
return
try:
video_stream = container.streams.video[0]
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/verisure/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def _handle_coordinator_update(self) -> None:
self._state = ALARM_STATE_TO_HA.get(
self.coordinator.data["alarm"]["statusType"]
)
self._changed_by = self.coordinator.data["alarm"]["name"]
self._changed_by = self.coordinator.data["alarm"].get("name")
super()._handle_coordinator_update()

async def async_added_to_hass(self) -> None:
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/verisure/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(
):
"""Initialize Verisure File Camera component."""
super().__init__(coordinator)
Camera.__init__(self)

self.serial_number = serial_number
self._directory_path = directory_path
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/zwave_js/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,13 @@ def __init__(
THERMOSTAT_MODE_PROPERTY,
CommandClass.THERMOSTAT_FAN_MODE,
add_to_watched_value_ids=True,
check_all_endpoints=True,
)
self._fan_state = self.get_zwave_value(
THERMOSTAT_OPERATING_STATE_PROPERTY,
CommandClass.THERMOSTAT_FAN_STATE,
add_to_watched_value_ids=True,
check_all_endpoints=True,
)
self._set_modes_and_presets()
self._supported_features = 0
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/const.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 2021
MINOR_VERSION = 4
PATCH_VERSION = "0"
PATCH_VERSION = "1"
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__ = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER = (3, 8, 0)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/package_constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defusedxml==0.6.0
distro==1.5.0
emoji==1.2.0
hass-nabucasa==0.42.0
home-assistant-frontend==20210407.1
home-assistant-frontend==20210407.2
httpx==0.17.1
jinja2>=2.11.3
netdisco==2.8.2
Expand Down
4 changes: 2 additions & 2 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ hole==0.5.1
holidays==0.10.5.2

# homeassistant.components.frontend
home-assistant-frontend==20210407.1
home-assistant-frontend==20210407.2

# homeassistant.components.zwave
homeassistant-pyozw==0.1.10
Expand Down Expand Up @@ -2108,7 +2108,7 @@ sonarr==0.3.0
speak2mary==1.4.0

# homeassistant.components.speedtestdotnet
speedtest-cli==2.1.2
speedtest-cli==2.1.3

# homeassistant.components.spider
spiderpy==1.4.2
Expand Down
4 changes: 2 additions & 2 deletions requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ hole==0.5.1
holidays==0.10.5.2

# homeassistant.components.frontend
home-assistant-frontend==20210407.1
home-assistant-frontend==20210407.2

# homeassistant.components.zwave
homeassistant-pyozw==0.1.10
Expand Down Expand Up @@ -1095,7 +1095,7 @@ sonarr==0.3.0
speak2mary==1.4.0

# homeassistant.components.speedtestdotnet
speedtest-cli==2.1.2
speedtest-cli==2.1.3

# homeassistant.components.spider
spiderpy==1.4.2
Expand Down
27 changes: 27 additions & 0 deletions tests/components/mqtt/test_light_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,33 @@ async def test_fail_setup_if_color_mode_deprecated(hass, mqtt_mock, deprecated):
assert hass.states.get("light.test") is None


@pytest.mark.parametrize(
"supported_color_modes", [["onoff", "rgb"], ["brightness", "rgb"], ["unknown"]]
)
async def test_fail_setup_if_color_modes_invalid(
hass, mqtt_mock, supported_color_modes
):
"""Test if setup fails if supported color modes is invalid."""
config = {
light.DOMAIN: {
"brightness": True,
"color_mode": True,
"command_topic": "test_light_rgb/set",
"name": "test",
"platform": "mqtt",
"schema": "json",
"supported_color_modes": supported_color_modes,
}
}
assert await async_setup_component(
hass,
light.DOMAIN,
config,
)
await hass.async_block_till_done()
assert hass.states.get("light.test") is None


async def test_rgb_light(hass, mqtt_mock):
"""Test RGB light flags brightness support."""
assert await async_setup_component(
Expand Down
2 changes: 1 addition & 1 deletion tests/components/stream/test_recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,4 @@ async def test_recorder_log(hass, caplog):
with patch.object(hass.config, "is_allowed_path", return_value=True):
await stream.async_record("/example/path")
assert "https://abcd:efgh@foo.bar" not in caplog.text
assert "https://foo.bar" in caplog.text
assert "https://****:****@foo.bar" in caplog.text
2 changes: 1 addition & 1 deletion tests/components/stream/test_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,4 +588,4 @@ async def test_worker_log(hass, caplog):
)
await hass.async_block_till_done()
assert "https://abcd:efgh@foo.bar" not in caplog.text
assert "https://foo.bar" in caplog.text
assert "https://****:****@foo.bar" in caplog.text
4 changes: 3 additions & 1 deletion tests/components/zwave_js/test_climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,9 @@ async def test_thermostat_different_endpoints(
"""Test an entity with values on a different endpoint from the primary value."""
state = hass.states.get(CLIMATE_RADIO_THERMOSTAT_ENTITY)

assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 22.5
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 22.8
assert state.attributes[ATTR_FAN_MODE] == "Auto low"
assert state.attributes[ATTR_FAN_STATE] == "Idle / off"


async def test_setpoint_thermostat(hass, client, climate_danfoss_lc_13, integration):
Expand Down
13 changes: 5 additions & 8 deletions tests/components/zwave_js/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,27 +495,24 @@ async def test_poll_value(
assert args["valueId"] == {
"commandClassName": "Thermostat Mode",
"commandClass": 64,
"endpoint": 0,
"endpoint": 1,
"property": "mode",
"propertyName": "mode",
"metadata": {
"type": "number",
"readable": True,
"writeable": True,
"min": 0,
"max": 31,
"max": 255,
"label": "Thermostat mode",
"states": {
"0": "Off",
"1": "Heat",
"2": "Cool",
"3": "Auto",
"11": "Energy heat",
"12": "Energy cool",
},
},
"value": 1,
"ccVersion": 2,
"value": 2,
"ccVersion": 0,
}

client.async_send_command.reset_mock()
Expand All @@ -531,7 +528,7 @@ async def test_poll_value(
},
blocking=True,
)
assert len(client.async_send_command.call_args_list) == 8
assert len(client.async_send_command.call_args_list) == 7

# Test polling against an invalid entity raises ValueError
with pytest.raises(ValueError):
Expand Down
Loading