Use icmplib for ping when available (#39284)
* Use icmplib for ping when available
* Update homeassistant/components/ping/binary_sensor.py
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
* Revert "Update homeassistant/components/ping/binary_sensor.py"
This reverts commit 618f42512a
.
* move it up so its easier to see
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
b4bac0f7a0
commit
7c191388a9
5 changed files with 86 additions and 6 deletions
|
@ -6,6 +6,7 @@ import re
|
|||
import sys
|
||||
from typing import Any, Dict
|
||||
|
||||
from icmplib import SocketPermissionError, ping as icmp_ping
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorEntity
|
||||
|
@ -59,7 +60,17 @@ def setup_platform(hass, config, add_entities, discovery_info=None) -> None:
|
|||
count = config[CONF_PING_COUNT]
|
||||
name = config.get(CONF_NAME, f"{DEFAULT_NAME} {host}")
|
||||
|
||||
add_entities([PingBinarySensor(name, PingData(host, count))], True)
|
||||
try:
|
||||
# Verify we can create a raw socket, or
|
||||
# fallback to using a subprocess
|
||||
icmp_ping("127.0.0.1", count=0, timeout=0)
|
||||
ping_cls = PingDataICMPLib
|
||||
except SocketPermissionError:
|
||||
ping_cls = PingDataSubProcess
|
||||
|
||||
ping_data = ping_cls(hass, host, count)
|
||||
|
||||
add_entities([PingBinarySensor(name, ping_data)], True)
|
||||
|
||||
|
||||
class PingBinarySensor(BinarySensorEntity):
|
||||
|
@ -102,15 +113,42 @@ class PingBinarySensor(BinarySensorEntity):
|
|||
|
||||
|
||||
class PingData:
|
||||
"""The Class for handling the data retrieval."""
|
||||
"""The base class for handling the data retrieval."""
|
||||
|
||||
def __init__(self, host, count) -> None:
|
||||
def __init__(self, hass, host, count) -> None:
|
||||
"""Initialize the data object."""
|
||||
self.hass = hass
|
||||
self._ip_address = host
|
||||
self._count = count
|
||||
self.data = {}
|
||||
self.available = False
|
||||
|
||||
|
||||
class PingDataICMPLib(PingData):
|
||||
"""The Class for handling the data retrieval using icmplib."""
|
||||
|
||||
def ping(self):
|
||||
"""Send ICMP echo request and return details."""
|
||||
return icmp_ping(self._ip_address, count=self._count)
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Retrieve the latest details from the host."""
|
||||
data = await self.hass.async_add_executor_job(self.ping)
|
||||
self.data = {
|
||||
"min": data.min_rtt,
|
||||
"max": data.max_rtt,
|
||||
"avg": data.avg_rtt,
|
||||
"mdev": "",
|
||||
}
|
||||
self.available = data.is_alive
|
||||
|
||||
|
||||
class PingDataSubProcess(PingData):
|
||||
"""The Class for handling the data retrieval using the ping binary."""
|
||||
|
||||
def __init__(self, hass, host, count) -> None:
|
||||
"""Initialize the data object."""
|
||||
super().__init__(hass, host, count)
|
||||
if sys.platform == "win32":
|
||||
self._ping_cmd = [
|
||||
"ping",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue