"""Get your own public IP address or that of any host.""" from datetime import timedelta import logging import aiodns from aiodns.error import DNSError import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_NAME import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) CONF_HOSTNAME = "hostname" CONF_IPV6 = "ipv6" CONF_RESOLVER = "resolver" CONF_RESOLVER_IPV6 = "resolver_ipv6" DEFAULT_HOSTNAME = "myip.opendns.com" DEFAULT_IPV6 = False DEFAULT_NAME = "myip" DEFAULT_RESOLVER = "208.67.222.222" DEFAULT_RESOLVER_IPV6 = "2620:0:ccc::2" SCAN_INTERVAL = timedelta(seconds=120) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Optional(CONF_NAME): cv.string, vol.Optional(CONF_HOSTNAME, default=DEFAULT_HOSTNAME): cv.string, vol.Optional(CONF_RESOLVER, default=DEFAULT_RESOLVER): cv.string, vol.Optional(CONF_RESOLVER_IPV6, default=DEFAULT_RESOLVER_IPV6): cv.string, vol.Optional(CONF_IPV6, default=DEFAULT_IPV6): cv.boolean, } ) async def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up the DNS IP sensor.""" hostname = config[CONF_HOSTNAME] name = config.get(CONF_NAME) if not name: if hostname == DEFAULT_HOSTNAME: name = DEFAULT_NAME else: name = hostname ipv6 = config[CONF_IPV6] if ipv6: resolver = config[CONF_RESOLVER_IPV6] else: resolver = config[CONF_RESOLVER] async_add_devices([WanIpSensor(hass, name, hostname, resolver, ipv6)], True) class WanIpSensor(Entity): """Implementation of a DNS IP sensor.""" def __init__(self, hass, name, hostname, resolver, ipv6): """Initialize the DNS IP sensor.""" self.hass = hass self._name = name self.hostname = hostname self.resolver = aiodns.DNSResolver() self.resolver.nameservers = [resolver] self.querytype = "AAAA" if ipv6 else "A" self._state = None @property def name(self): """Return the name of the sensor.""" return self._name @property def state(self): """Return the current DNS IP address for hostname.""" return self._state async def async_update(self): """Get the current DNS IP address for hostname.""" try: response = await self.resolver.query(self.hostname, self.querytype) except DNSError as err: _LOGGER.warning("Exception while resolving host: %s", err) response = None if response: self._state = response[0].host else: self._state = None