Use a unique id for each icmplib ping to avoid mixing unrelated responses (#39830)
This commit is contained in:
parent
b0b0b15d9d
commit
b7ad83c655
6 changed files with 54 additions and 12 deletions
|
@ -1,4 +1,28 @@
|
|||
"""The ping component."""
|
||||
|
||||
from homeassistant.core import callback
|
||||
|
||||
DOMAIN = "ping"
|
||||
PLATFORMS = ["binary_sensor"]
|
||||
|
||||
PING_ID = "ping_id"
|
||||
DEFAULT_START_ID = 129
|
||||
MAX_PING_ID = 65534
|
||||
|
||||
|
||||
@callback
|
||||
def async_get_next_ping_id(hass):
|
||||
"""Find the next id to use in the outbound ping.
|
||||
|
||||
Must be called in async
|
||||
"""
|
||||
current_id = hass.data.setdefault(DOMAIN, {}).get(PING_ID, DEFAULT_START_ID)
|
||||
|
||||
if current_id == MAX_PING_ID:
|
||||
next_id = DEFAULT_START_ID
|
||||
else:
|
||||
next_id = current_id + 1
|
||||
|
||||
hass.data[DOMAIN][PING_ID] = next_id
|
||||
|
||||
return next_id
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Tracks the latency of a host by sending ICMP echo requests (ping)."""
|
||||
import asyncio
|
||||
from datetime import timedelta
|
||||
from functools import partial
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
|
@ -14,7 +15,7 @@ from homeassistant.const import CONF_HOST, CONF_NAME
|
|||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.reload import setup_reload_service
|
||||
|
||||
from . import DOMAIN, PLATFORMS
|
||||
from . import DOMAIN, PLATFORMS, async_get_next_ping_id
|
||||
from .const import PING_TIMEOUT
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -131,20 +132,28 @@ class PingData:
|
|||
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)
|
||||
_LOGGER.warning("ping address: %s", self._ip_address)
|
||||
data = await self.hass.async_add_executor_job(
|
||||
partial(
|
||||
icmp_ping,
|
||||
self._ip_address,
|
||||
count=self._count,
|
||||
id=async_get_next_ping_id(self.hass),
|
||||
)
|
||||
)
|
||||
self.available = data.is_alive
|
||||
if not self.available:
|
||||
self.data = False
|
||||
return
|
||||
|
||||
self.data = {
|
||||
"min": data.min_rtt,
|
||||
"max": data.max_rtt,
|
||||
"avg": data.avg_rtt,
|
||||
"mdev": "",
|
||||
}
|
||||
self.available = data.is_alive
|
||||
|
||||
|
||||
class PingDataSubProcess(PingData):
|
||||
|
|
|
@ -15,8 +15,10 @@ from homeassistant.components.device_tracker.const import (
|
|||
SOURCE_TYPE_ROUTER,
|
||||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util.async_ import run_callback_threadsafe
|
||||
from homeassistant.util.process import kill_subprocess
|
||||
|
||||
from . import async_get_next_ping_id
|
||||
from .const import PING_ATTEMPTS_COUNT, PING_TIMEOUT
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -76,15 +78,22 @@ class HostSubProcess:
|
|||
class HostICMPLib:
|
||||
"""Host object with ping detection."""
|
||||
|
||||
def __init__(self, ip_address, dev_id, _, config):
|
||||
def __init__(self, ip_address, dev_id, hass, config):
|
||||
"""Initialize the Host pinger."""
|
||||
self.hass = hass
|
||||
self.ip_address = ip_address
|
||||
self.dev_id = dev_id
|
||||
self._count = config[CONF_PING_COUNT]
|
||||
|
||||
def ping(self):
|
||||
"""Send an ICMP echo request and return True if success."""
|
||||
return icmp_ping(self.ip_address, count=PING_ATTEMPTS_COUNT).is_alive
|
||||
next_id = run_callback_threadsafe(
|
||||
self.hass.loop, async_get_next_ping_id, self.hass
|
||||
).result()
|
||||
|
||||
return icmp_ping(
|
||||
self.ip_address, count=PING_ATTEMPTS_COUNT, id=next_id
|
||||
).is_alive
|
||||
|
||||
def update(self, see):
|
||||
"""Update device state by sending one or more ping messages."""
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
"name": "Ping (ICMP)",
|
||||
"documentation": "https://www.home-assistant.io/integrations/ping",
|
||||
"codeowners": [],
|
||||
"requirements": ["icmplib==1.1.1"],
|
||||
"requirements": ["icmplib==1.1.3"],
|
||||
"quality_scale": "internal"
|
||||
}
|
||||
|
|
|
@ -789,7 +789,7 @@ ibm-watson==4.0.1
|
|||
ibmiotf==0.3.4
|
||||
|
||||
# homeassistant.components.ping
|
||||
icmplib==1.1.1
|
||||
icmplib==1.1.3
|
||||
|
||||
# homeassistant.components.iglo
|
||||
iglo==1.2.7
|
||||
|
|
|
@ -392,7 +392,7 @@ huawei-lte-api==1.4.12
|
|||
iaqualink==0.3.4
|
||||
|
||||
# homeassistant.components.ping
|
||||
icmplib==1.1.1
|
||||
icmplib==1.1.3
|
||||
|
||||
# homeassistant.components.influxdb
|
||||
influxdb-client==1.8.0
|
||||
|
|
Loading…
Add table
Reference in a new issue