Merge pull request #52043 from home-assistant/rc

pull/52302/head 2021.6.6
Paulus Schoutsen 2021-06-20 22:37:31 -07:00 committed by GitHub
commit 076227acbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 113 additions and 22 deletions

View File

@ -12,7 +12,7 @@ from homeassistant.const import (
CONF_NAME,
DEVICE_CLASS_TEMPERATURE,
)
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
@ -81,16 +81,11 @@ class AccuWeatherSensor(CoordinatorEntity, SensorEntity):
) -> None:
"""Initialize."""
super().__init__(coordinator)
self._sensor_data = _get_sensor_data(coordinator.data, forecast_day, kind)
if forecast_day is None:
self._description = SENSOR_TYPES[kind]
self._sensor_data: dict[str, Any]
if kind == "Precipitation":
self._sensor_data = coordinator.data["PrecipitationSummary"][kind]
else:
self._sensor_data = coordinator.data[kind]
else:
self._description = FORECAST_SENSOR_TYPES[kind]
self._sensor_data = coordinator.data[ATTR_FORECAST][forecast_day][kind]
self._unit_system = API_METRIC if coordinator.is_metric else API_IMPERIAL
self._name = name
self.kind = kind
@ -182,3 +177,24 @@ class AccuWeatherSensor(CoordinatorEntity, SensorEntity):
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return self._description[ATTR_ENABLED]
@callback
def _handle_coordinator_update(self) -> None:
"""Handle data update."""
self._sensor_data = _get_sensor_data(
self.coordinator.data, self.forecast_day, self.kind
)
self.async_write_ha_state()
def _get_sensor_data(
sensors: dict[str, Any], forecast_day: int | None, kind: str
) -> Any:
"""Get sensor data."""
if forecast_day is not None:
return sensors[ATTR_FORECAST][forecast_day][kind]
if kind == "Precipitation":
return sensors["PrecipitationSummary"][kind]
return sensors[kind]

View File

@ -3,7 +3,7 @@
"name": "Daikin AC",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/daikin",
"requirements": ["pydaikin==2.4.2"],
"requirements": ["pydaikin==2.4.3"],
"codeowners": ["@fredrike"],
"zeroconf": ["_dkapi._tcp.local."],
"quality_scale": "platinum",

View File

@ -160,7 +160,7 @@ def handle_push_notification_channel(hass, connection, msg):
registered_channels = hass.data[DOMAIN][DATA_PUSH_CHANNEL]
if webhook_id in registered_channels:
registered_channels.pop(webhook_id)()
registered_channels.pop(webhook_id)
@callback
def forward_push_notification(data):

View File

@ -153,8 +153,8 @@ class OmniLogicPumpControl(OmniLogicSwitch):
state_key=state_key,
)
self._max_speed = int(coordinator.data[item_id]["Max-Pump-Speed"])
self._min_speed = int(coordinator.data[item_id]["Min-Pump-Speed"])
self._max_speed = int(coordinator.data[item_id].get("Max-Pump-Speed", 100))
self._min_speed = int(coordinator.data[item_id].get("Min-Pump-Speed", 0))
if "Filter-Type" in coordinator.data[item_id]:
self._pump_type = PUMP_TYPES[coordinator.data[item_id]["Filter-Type"]]

View File

@ -2,7 +2,7 @@
"domain": "rfxtrx",
"name": "RFXCOM RFXtrx",
"documentation": "https://www.home-assistant.io/integrations/rfxtrx",
"requirements": ["pyRFXtrx==0.26.1"],
"requirements": ["pyRFXtrx==0.27.0"],
"codeowners": ["@danielhiversen", "@elupus", "@RobBie1221"],
"config_flow": true,
"iot_class": "local_push"

View File

@ -382,6 +382,14 @@ class SonosSpeaker:
"""Update device properties from an event."""
if more_info := event.variables.get("more_info"):
battery_dict = dict(x.split(":") for x in more_info.split(","))
if "BattChg" not in battery_dict:
_LOGGER.debug(
"Unknown device properties update for %s (%s), please report an issue: '%s'",
self.zone_name,
self.model_name,
more_info,
)
return
await self.async_update_battery_info(battery_dict)
self.async_write_entity_states()

View File

@ -118,6 +118,7 @@ class WhoisSensor(SensorEntity):
expiration_date = response["expiration_date"]
if isinstance(expiration_date, list):
attrs[ATTR_EXPIRES] = expiration_date[0].isoformat()
expiration_date = expiration_date[0]
else:
attrs[ATTR_EXPIRES] = expiration_date.isoformat()

View File

@ -5,7 +5,7 @@ from typing import Final
MAJOR_VERSION: Final = 2021
MINOR_VERSION: Final = 6
PATCH_VERSION: Final = "5"
PATCH_VERSION: Final = "6"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 8, 0)

View File

@ -1253,7 +1253,7 @@ pyMetEireann==0.2
pyMetno==0.8.3
# homeassistant.components.rfxtrx
pyRFXtrx==0.26.1
pyRFXtrx==0.27.0
# homeassistant.components.switchmate
# pySwitchmate==0.4.6
@ -1352,7 +1352,7 @@ pycsspeechtts==1.0.4
# pycups==1.9.73
# homeassistant.components.daikin
pydaikin==2.4.2
pydaikin==2.4.3
# homeassistant.components.danfoss_air
pydanfossair==0.1.0

View File

@ -693,7 +693,7 @@ pyMetEireann==0.2
pyMetno==0.8.3
# homeassistant.components.rfxtrx
pyRFXtrx==0.26.1
pyRFXtrx==0.27.0
# homeassistant.components.tibber
pyTibber==0.17.0
@ -747,7 +747,7 @@ pycomfoconnect==0.4
pycoolmasternet-async==0.1.2
# homeassistant.components.daikin
pydaikin==2.4.2
pydaikin==2.4.3
# homeassistant.components.deconz
pydeconz==79

View File

@ -673,3 +673,36 @@ async def test_sensor_imperial_units(hass):
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_ICON) == "mdi:weather-fog"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == LENGTH_FEET
async def test_state_update(hass):
"""Ensure the sensor state changes after updating the data."""
await init_integration(hass)
state = hass.states.get("sensor.home_cloud_ceiling")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "3200"
future = utcnow() + timedelta(minutes=60)
current_condition = json.loads(
load_fixture("accuweather/current_conditions_data.json")
)
current_condition["Ceiling"]["Metric"]["Value"] = 3300
with patch(
"homeassistant.components.accuweather.AccuWeather.async_get_current_conditions",
return_value=current_condition,
), patch(
"homeassistant.components.accuweather.AccuWeather.requests_remaining",
new_callable=PropertyMock,
return_value=10,
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
state = hass.states.get("sensor.home_cloud_ceiling")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "3300"

View File

@ -136,6 +136,18 @@ async def test_notify_ws_works(
sub_result = await client.receive_json()
assert sub_result["success"]
# Subscribe twice, it should forward all messages to 2nd subscription
await client.send_json(
{
"id": 6,
"type": "mobile_app/push_notification_channel",
"webhook_id": "mock-webhook_id",
}
)
sub_result = await client.receive_json()
assert sub_result["success"]
assert await hass.services.async_call(
"notify", "mobile_app_test", {"message": "Hello world"}, blocking=True
)
@ -144,13 +156,14 @@ async def test_notify_ws_works(
msg_result = await client.receive_json()
assert msg_result["event"] == {"message": "Hello world"}
assert msg_result["id"] == 6 # This is the new subscription
# Unsubscribe, now it should go over http
await client.send_json(
{
"id": 6,
"id": 7,
"type": "unsubscribe_events",
"subscription": 5,
"subscription": 6,
}
)
sub_result = await client.receive_json()
@ -165,7 +178,7 @@ async def test_notify_ws_works(
# Test non-existing webhook ID
await client.send_json(
{
"id": 7,
"id": 8,
"type": "mobile_app/push_notification_channel",
"webhook_id": "non-existing",
}
@ -180,7 +193,7 @@ async def test_notify_ws_works(
# Test webhook ID linked to other user
await client.send_json(
{
"id": 8,
"id": 9,
"type": "mobile_app/push_notification_channel",
"webhook_id": "webhook_id_2",
}

View File

@ -117,7 +117,7 @@ async def test_fire_event(hass, rfxtrx):
"type_string": "Byron SX",
"id_string": "00:90",
"data": "0716000100900970",
"values": {"Command": "Chime", "Rssi numeric": 7, "Sound": 9},
"values": {"Command": "Sound 9", "Rssi numeric": 7, "Sound": 9},
"device_id": device_id_2.id,
},
]

View File

@ -83,3 +83,23 @@ async def test_battery_on_S1(hass, config_entry, config, soco, battery_event):
power_state = hass.states.get(power.entity_id)
assert power_state.state == STATE_OFF
assert power_state.attributes.get(ATTR_BATTERY_POWER_SOURCE) == "BATTERY"
async def test_device_payload_without_battery(
hass, config_entry, config, soco, battery_event, caplog
):
"""Test device properties event update without battery info."""
soco.get_battery_info.return_value = None
await setup_platform(hass, config_entry, config)
subscription = soco.deviceProperties.subscribe.return_value
sub_callback = subscription.callback
bad_payload = "BadKey:BadValue"
battery_event.variables["more_info"] = bad_payload
sub_callback(battery_event)
await hass.async_block_till_done()
assert bad_payload in caplog.text