From 11d5671ee0a4dbf98c5e9f58a2dec85bdb35f4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Tue, 2 Oct 2018 11:43:34 +0200 Subject: [PATCH] De-syncing binary_sensor.ping (#17056) * Quick and dirty asyncing of binary_sensor.ping * Minor changes --- .../components/binary_sensor/ping.py | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/homeassistant/components/binary_sensor/ping.py b/homeassistant/components/binary_sensor/ping.py index 4c597dd63e1..f12957e6129 100644 --- a/homeassistant/components/binary_sensor/ping.py +++ b/homeassistant/components/binary_sensor/ping.py @@ -4,18 +4,19 @@ Tracks the latency of a host by sending ICMP echo requests (ping). For more details about this platform, please refer to the documentation at https://home-assistant.io/components/binary_sensor.ping/ """ -import logging -import subprocess -import re -import sys +import asyncio from datetime import timedelta +import logging +import re +import subprocess +import sys import voluptuous as vol -import homeassistant.helpers.config_validation as cv from homeassistant.components.binary_sensor import ( - BinarySensorDevice, PLATFORM_SCHEMA) -from homeassistant.const import CONF_NAME, CONF_HOST + PLATFORM_SCHEMA, BinarySensorDevice) +from homeassistant.const import CONF_HOST, CONF_NAME +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) @@ -48,13 +49,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def setup_platform(hass, config, add_entities, discovery_info=None): +async def async_setup_platform( + hass, config, async_add_entities, discovery_info=None): """Set up the Ping Binary sensor.""" name = config.get(CONF_NAME) host = config.get(CONF_HOST) count = config.get(CONF_PING_COUNT) - add_entities([PingBinarySensor(name, PingData(host, count))], True) + async_add_entities([PingBinarySensor(name, PingData(host, count))], True) class PingBinarySensor(BinarySensorDevice): @@ -91,9 +93,9 @@ class PingBinarySensor(BinarySensorDevice): ATTR_ROUND_TRIP_TIME_MIN: self.ping.data['min'], } - def update(self): + async def async_update(self): """Get the latest data.""" - self.ping.update() + await self.ping.update() class PingData: @@ -114,12 +116,13 @@ class PingData: 'ping', '-n', '-q', '-c', str(self._count), '-W1', self._ip_address] - def ping(self): + async def ping(self): """Send ICMP echo request and return details if success.""" - pinger = subprocess.Popen( - self._ping_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + pinger = await asyncio.create_subprocess_shell( + ' '.join(self._ping_cmd), stdout=subprocess.PIPE, + stderr=subprocess.PIPE) try: - out = pinger.communicate() + out = await pinger.communicate() _LOGGER.debug("Output is %s", str(out)) if sys.platform == 'win32': match = WIN32_PING_MATCHER.search(str(out).split('\n')[-1]) @@ -128,7 +131,8 @@ class PingData: 'min': rtt_min, 'avg': rtt_avg, 'max': rtt_max, - 'mdev': ''} + 'mdev': '', + } if 'max/' not in str(out): match = PING_MATCHER_BUSYBOX.search(str(out).split('\n')[-1]) rtt_min, rtt_avg, rtt_max = match.groups() @@ -136,18 +140,20 @@ class PingData: 'min': rtt_min, 'avg': rtt_avg, 'max': rtt_max, - 'mdev': ''} + 'mdev': '', + } match = PING_MATCHER.search(str(out).split('\n')[-1]) rtt_min, rtt_avg, rtt_max, rtt_mdev = match.groups() return { 'min': rtt_min, 'avg': rtt_avg, 'max': rtt_max, - 'mdev': rtt_mdev} + 'mdev': rtt_mdev, + } except (subprocess.CalledProcessError, AttributeError): return False - def update(self): + async def update(self): """Retrieve the latest details from the host.""" - self.data = self.ping() + self.data = await self.ping() self.available = bool(self.data)