parent
6ed3c69604
commit
5e8e2a8312
2 changed files with 93 additions and 0 deletions
|
@ -157,6 +157,7 @@ omit =
|
||||||
homeassistant/components/device_tracker/luci.py
|
homeassistant/components/device_tracker/luci.py
|
||||||
homeassistant/components/device_tracker/netgear.py
|
homeassistant/components/device_tracker/netgear.py
|
||||||
homeassistant/components/device_tracker/nmap_tracker.py
|
homeassistant/components/device_tracker/nmap_tracker.py
|
||||||
|
homeassistant/components/device_tracker/ping.py
|
||||||
homeassistant/components/device_tracker/snmp.py
|
homeassistant/components/device_tracker/snmp.py
|
||||||
homeassistant/components/device_tracker/swisscom.py
|
homeassistant/components/device_tracker/swisscom.py
|
||||||
homeassistant/components/device_tracker/thomson.py
|
homeassistant/components/device_tracker/thomson.py
|
||||||
|
|
92
homeassistant/components/device_tracker/ping.py
Normal file
92
homeassistant/components/device_tracker/ping.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
"""
|
||||||
|
Tracks devices by sending a ICMP ping.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/device_tracker.ping/
|
||||||
|
|
||||||
|
device_tracker:
|
||||||
|
- platform: ping
|
||||||
|
count: 2
|
||||||
|
hosts:
|
||||||
|
host_one: pc.local
|
||||||
|
host_two: 192.168.2.25
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.device_tracker import (
|
||||||
|
PLATFORM_SCHEMA, DEFAULT_SCAN_INTERVAL)
|
||||||
|
from homeassistant.helpers.event import track_point_in_utc_time
|
||||||
|
from homeassistant import util
|
||||||
|
from homeassistant import const
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
|
DEPENDENCIES = []
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CONF_PING_COUNT = 'count'
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
|
vol.Required(const.CONF_HOSTS): {cv.string: cv.string},
|
||||||
|
vol.Optional(CONF_PING_COUNT, default=1): cv.positive_int,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class Host:
|
||||||
|
"""Host object with ping detection."""
|
||||||
|
|
||||||
|
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]
|
||||||
|
if sys.platform == "win32":
|
||||||
|
self._ping_cmd = ['ping', '-n 1', '-w 1000', self.ip_address]
|
||||||
|
else:
|
||||||
|
self._ping_cmd = ['ping', '-n', '-q', '-c1', '-W1',
|
||||||
|
self.ip_address]
|
||||||
|
|
||||||
|
def ping(self):
|
||||||
|
"""Send ICMP ping and return True if success."""
|
||||||
|
pinger = subprocess.Popen(self._ping_cmd, stdout=subprocess.PIPE)
|
||||||
|
try:
|
||||||
|
pinger.communicate()
|
||||||
|
return pinger.returncode == 0
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def update(self, see):
|
||||||
|
"""Update device state by sending one or more ping messages."""
|
||||||
|
failed = 0
|
||||||
|
while failed < self._count: # check more times if host in unreachable
|
||||||
|
if self.ping():
|
||||||
|
see(dev_id=self.dev_id)
|
||||||
|
return True
|
||||||
|
failed += 1
|
||||||
|
|
||||||
|
_LOGGER.debug("ping KO on ip=%s failed=%d", self.ip_address, failed)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_scanner(hass, config, see):
|
||||||
|
"""Setup the Host objects and return the update function."""
|
||||||
|
hosts = [Host(ip, dev_id, hass, config) for (dev_id, ip) in
|
||||||
|
config[const.CONF_HOSTS].items()]
|
||||||
|
interval = timedelta(seconds=len(hosts) * config[CONF_PING_COUNT] +
|
||||||
|
DEFAULT_SCAN_INTERVAL)
|
||||||
|
_LOGGER.info("Started ping tracker with interval=%s on hosts: %s",
|
||||||
|
interval, ",".join([host.ip_address for host in hosts]))
|
||||||
|
|
||||||
|
def update(now):
|
||||||
|
"""Update all the hosts on every interval time."""
|
||||||
|
for host in hosts:
|
||||||
|
host.update(see)
|
||||||
|
track_point_in_utc_time(hass, update, now + interval)
|
||||||
|
return True
|
||||||
|
|
||||||
|
return update(util.dt.utcnow())
|
Loading…
Add table
Add a link
Reference in a new issue