Skip to content

Commit

Permalink
Merge pull request #37836 from home-assistant/rc
Browse files Browse the repository at this point in the history
  • Loading branch information
balloob committed Jul 14, 2020
2 parents aa39ded + fb484e8 commit ec1df9b
Show file tree
Hide file tree
Showing 16 changed files with 381 additions and 57 deletions.
2 changes: 1 addition & 1 deletion homeassistant/components/blink/manifest.json
Expand Up @@ -2,7 +2,7 @@
"domain": "blink",
"name": "Blink",
"documentation": "https://www.home-assistant.io/integrations/blink",
"requirements": ["blinkpy==0.15.0"],
"requirements": ["blinkpy==0.15.1"],
"codeowners": ["@fronzbot"],
"config_flow": true
}
2 changes: 1 addition & 1 deletion homeassistant/components/deconz/manifest.json
Expand Up @@ -3,7 +3,7 @@
"name": "deCONZ",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/deconz",
"requirements": ["pydeconz==71"],
"requirements": ["pydeconz==72"],
"ssdp": [
{
"manufacturer": "Royal Philips Electronics"
Expand Down
90 changes: 68 additions & 22 deletions homeassistant/components/mqtt/__init__.py
Expand Up @@ -88,6 +88,8 @@
CONF_TLS_VERSION = "tls_version"

CONF_COMMAND_TOPIC = "command_topic"
CONF_TOPIC = "topic"
CONF_AVAILABILITY = "availability"
CONF_AVAILABILITY_TOPIC = "availability_topic"
CONF_PAYLOAD_AVAILABLE = "payload_available"
CONF_PAYLOAD_NOT_AVAILABLE = "payload_not_available"
Expand Down Expand Up @@ -203,9 +205,9 @@ def embedded_broker_deprecated(value):

SCHEMA_BASE = {vol.Optional(CONF_QOS, default=DEFAULT_QOS): _VALID_QOS_SCHEMA}

MQTT_AVAILABILITY_SCHEMA = vol.Schema(
MQTT_AVAILABILITY_SINGLE_SCHEMA = vol.Schema(
{
vol.Optional(CONF_AVAILABILITY_TOPIC): valid_subscribe_topic,
vol.Exclusive(CONF_AVAILABILITY_TOPIC, "availability"): valid_subscribe_topic,
vol.Optional(
CONF_PAYLOAD_AVAILABLE, default=DEFAULT_PAYLOAD_AVAILABLE
): cv.string,
Expand All @@ -215,6 +217,30 @@ def embedded_broker_deprecated(value):
}
)

MQTT_AVAILABILITY_LIST_SCHEMA = vol.Schema(
{
vol.Exclusive(CONF_AVAILABILITY, "availability"): vol.All(
cv.ensure_list,
[
{
vol.Optional(CONF_TOPIC): valid_subscribe_topic,
vol.Optional(
CONF_PAYLOAD_AVAILABLE, default=DEFAULT_PAYLOAD_AVAILABLE
): cv.string,
vol.Optional(
CONF_PAYLOAD_NOT_AVAILABLE,
default=DEFAULT_PAYLOAD_NOT_AVAILABLE,
): cv.string,
}
],
),
}
)

MQTT_AVAILABILITY_SCHEMA = MQTT_AVAILABILITY_SINGLE_SCHEMA.extend(
MQTT_AVAILABILITY_LIST_SCHEMA.schema
)

MQTT_ENTITY_DEVICE_INFO_SCHEMA = vol.All(
cv.deprecated(CONF_DEPRECATED_VIA_HUB, CONF_VIA_DEVICE),
vol.Schema(
Expand Down Expand Up @@ -989,54 +1015,75 @@ def __init__(self, config: dict) -> None:
"""Initialize the availability mixin."""
self._availability_sub_state = None
self._available = False

self._avail_config = config
self._availability_setup_from_config(config)

async def async_added_to_hass(self) -> None:
"""Subscribe MQTT events."""
await super().async_added_to_hass()
await self._availability_subscribe_topics()
async_dispatcher_connect(self.hass, MQTT_CONNECTED, self.async_mqtt_connect)
async_dispatcher_connect(self.hass, MQTT_DISCONNECTED, self.async_mqtt_connect)
self.async_on_remove(
async_dispatcher_connect(self.hass, MQTT_CONNECTED, self.async_mqtt_connect)
)
self.async_on_remove(
async_dispatcher_connect(
self.hass, MQTT_DISCONNECTED, self.async_mqtt_connect
)
)

async def availability_discovery_update(self, config: dict):
"""Handle updated discovery message."""
self._avail_config = config
self._availability_setup_from_config(config)
await self._availability_subscribe_topics()

def _availability_setup_from_config(self, config):
"""(Re)Setup."""
self._avail_topics = {}
if CONF_AVAILABILITY_TOPIC in config:
self._avail_topics[config[CONF_AVAILABILITY_TOPIC]] = {
CONF_PAYLOAD_AVAILABLE: config[CONF_PAYLOAD_AVAILABLE],
CONF_PAYLOAD_NOT_AVAILABLE: config[CONF_PAYLOAD_NOT_AVAILABLE],
}

if CONF_AVAILABILITY in config:
for avail in config[CONF_AVAILABILITY]:
self._avail_topics[avail[CONF_TOPIC]] = {
CONF_PAYLOAD_AVAILABLE: avail[CONF_PAYLOAD_AVAILABLE],
CONF_PAYLOAD_NOT_AVAILABLE: avail[CONF_PAYLOAD_NOT_AVAILABLE],
}

self._avail_config = config

async def _availability_subscribe_topics(self):
"""(Re)Subscribe to topics."""

@callback
@log_messages(self.hass, self.entity_id)
def availability_message_received(msg: Message) -> None:
"""Handle a new received MQTT availability message."""
if msg.payload == self._avail_config[CONF_PAYLOAD_AVAILABLE]:
topic = msg.topic
if msg.payload == self._avail_topics[topic][CONF_PAYLOAD_AVAILABLE]:
self._available = True
elif msg.payload == self._avail_config[CONF_PAYLOAD_NOT_AVAILABLE]:
elif msg.payload == self._avail_topics[topic][CONF_PAYLOAD_NOT_AVAILABLE]:
self._available = False

self.async_write_ha_state()

topics = {}
for topic in self._avail_topics:
topics[f"availability_{topic}"] = {
"topic": topic,
"msg_callback": availability_message_received,
"qos": self._avail_config[CONF_QOS],
}

self._availability_sub_state = await async_subscribe_topics(
self.hass,
self._availability_sub_state,
{
"availability_topic": {
"topic": self._avail_config.get(CONF_AVAILABILITY_TOPIC),
"msg_callback": availability_message_received,
"qos": self._avail_config[CONF_QOS],
}
},
self.hass, self._availability_sub_state, topics,
)

@callback
def async_mqtt_connect(self):
"""Update state on connection/disconnection to MQTT broker."""
if self.hass.is_running:
if not self.hass.is_stopping:
self.async_write_ha_state()

async def async_will_remove_from_hass(self):
Expand All @@ -1048,10 +1095,9 @@ async def async_will_remove_from_hass(self):
@property
def available(self) -> bool:
"""Return if the device is available."""
availability_topic = self._avail_config.get(CONF_AVAILABILITY_TOPIC)
if not self.hass.data[DATA_MQTT].connected:
if not self.hass.data[DATA_MQTT].connected and not self.hass.is_stopping:
return False
return availability_topic is None or self._available
return not self._avail_topics or self._available


async def cleanup_device_registry(hass, device_id):
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/mqtt/abbreviations.py
Expand Up @@ -7,6 +7,7 @@
"aux_cmd_t": "aux_command_topic",
"aux_stat_tpl": "aux_state_template",
"aux_stat_t": "aux_state_topic",
"avty": "availability",
"avty_t": "availability_topic",
"away_mode_cmd_t": "away_mode_command_topic",
"away_mode_stat_tpl": "away_mode_state_template",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/smappee/manifest.json
Expand Up @@ -5,7 +5,7 @@
"documentation": "https://www.home-assistant.io/integrations/smappee",
"dependencies": ["http"],
"requirements": [
"pysmappee==0.1.4"
"pysmappee==0.1.5"
],
"codeowners": [
"@bsmappee"
Expand Down
27 changes: 12 additions & 15 deletions homeassistant/components/speedtestdotnet/__init__.py
Expand Up @@ -105,16 +105,14 @@ def __init__(self, hass, config_entry):
self.api = None
self.servers = {}
super().__init__(
self.hass,
_LOGGER,
name=DOMAIN,
update_method=self.async_update,
update_interval=timedelta(
self.hass, _LOGGER, name=DOMAIN, update_method=self.async_update,
)
if not self.config_entry.options.get(CONF_MANUAL):
self.update_interval = timedelta(
minutes=self.config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
)
),
)
)

def update_servers(self):
"""Update list of test servers."""
Expand Down Expand Up @@ -189,12 +187,11 @@ async def request_update(call):

async def options_updated_listener(hass, entry):
"""Handle options update."""
if not entry.options[CONF_MANUAL]:
hass.data[DOMAIN].update_interval = timedelta(
minutes=entry.options[CONF_SCAN_INTERVAL]
)
await hass.data[DOMAIN].async_request_refresh()
if entry.options[CONF_MANUAL]:
hass.data[DOMAIN].update_interval = None
return
# set the update interval to a very long time
# if the user wants to disable auto update
hass.data[DOMAIN].update_interval = timedelta(days=7)

hass.data[DOMAIN].update_interval = timedelta(
minutes=entry.options[CONF_SCAN_INTERVAL]
)
await hass.data[DOMAIN].async_request_refresh()
2 changes: 1 addition & 1 deletion homeassistant/components/unifi/manifest.json
Expand Up @@ -3,7 +3,7 @@
"name": "Ubiquiti UniFi",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/unifi",
"requirements": ["aiounifi==22"],
"requirements": ["aiounifi==23"],
"codeowners": ["@Kane610"],
"quality_scale": "platinum"
}
5 changes: 3 additions & 2 deletions homeassistant/components/zeroconf/__init__.py
Expand Up @@ -200,7 +200,7 @@ def service_update(zeroconf, service_type, name, state_change):

# If we can handle it as a HomeKit discovery, we do that here.
if service_type == HOMEKIT_TYPE:
handle_homekit(hass, info)
discovery_was_forwarded = handle_homekit(hass, info)
# Continue on here as homekit_controller
# still needs to get updates on devices
# so it can see when the 'c#' field is updated.
Expand All @@ -209,7 +209,8 @@ def service_update(zeroconf, service_type, name, state_change):
# if the device is already paired in order to avoid
# offering a second discovery for the same device
if (
HOMEKIT_PROPERTIES in info
discovery_was_forwarded
and HOMEKIT_PROPERTIES in info
and HOMEKIT_PAIRED_STATUS_FLAG in info[HOMEKIT_PROPERTIES]
):
try:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/const.py
@@ -1,7 +1,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 112
PATCH_VERSION = "4"
PATCH_VERSION = "5"
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__ = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER = (3, 7, 0)
Expand Down
5 changes: 4 additions & 1 deletion homeassistant/helpers/update_coordinator.py
Expand Up @@ -30,7 +30,7 @@ def __init__(
logger: logging.Logger,
*,
name: str,
update_interval: timedelta,
update_interval: Optional[timedelta] = None,
update_method: Optional[Callable[[], Awaitable]] = None,
request_refresh_debouncer: Optional[Debouncer] = None,
):
Expand Down Expand Up @@ -91,6 +91,9 @@ def async_remove_listener(self, update_callback: CALLBACK_TYPE) -> None:
@callback
def _schedule_refresh(self) -> None:
"""Schedule a refresh."""
if self.update_interval is None:
return

if self._unsub_refresh:
self._unsub_refresh()
self._unsub_refresh = None
Expand Down
8 changes: 4 additions & 4 deletions requirements_all.txt
Expand Up @@ -230,7 +230,7 @@ aiopylgtv==0.3.3
aioswitcher==1.2.0

# homeassistant.components.unifi
aiounifi==22
aiounifi==23

# homeassistant.components.airly
airly==0.0.2
Expand Down Expand Up @@ -348,7 +348,7 @@ bizkaibus==0.1.1
blebox_uniapi==1.3.2

# homeassistant.components.blink
blinkpy==0.15.0
blinkpy==0.15.1

# homeassistant.components.blinksticklight
blinkstick==1.1.8
Expand Down Expand Up @@ -1282,7 +1282,7 @@ pydaikin==2.2.0
pydanfossair==0.1.0

# homeassistant.components.deconz
pydeconz==71
pydeconz==72

# homeassistant.components.delijn
pydelijn==0.6.0
Expand Down Expand Up @@ -1610,7 +1610,7 @@ pysignalclirestapi==0.3.4
pysma==0.3.5

# homeassistant.components.smappee
pysmappee==0.1.4
pysmappee==0.1.5

# homeassistant.components.smartthings
pysmartapp==0.3.2
Expand Down
8 changes: 4 additions & 4 deletions requirements_test_all.txt
Expand Up @@ -122,7 +122,7 @@ aiopylgtv==0.3.3
aioswitcher==1.2.0

# homeassistant.components.unifi
aiounifi==22
aiounifi==23

# homeassistant.components.airly
airly==0.0.2
Expand Down Expand Up @@ -171,7 +171,7 @@ bellows==0.17.0
blebox_uniapi==1.3.2

# homeassistant.components.blink
blinkpy==0.15.0
blinkpy==0.15.1

# homeassistant.components.bom
bomradarloop==0.1.4
Expand Down Expand Up @@ -576,7 +576,7 @@ pycountry==19.8.18
pydaikin==2.2.0

# homeassistant.components.deconz
pydeconz==71
pydeconz==72

# homeassistant.components.zwave
pydispatcher==2.0.5
Expand Down Expand Up @@ -715,7 +715,7 @@ pysignalclirestapi==0.3.4
pysma==0.3.5

# homeassistant.components.smappee
pysmappee==0.1.4
pysmappee==0.1.5

# homeassistant.components.smartthings
pysmartapp==0.3.2
Expand Down

0 comments on commit ec1df9b

Please sign in to comment.