mirror of
https://github.com/tomaae/homeassistant-mikrotik_router.git
synced 2025-07-30 15:34:31 +02:00
Build hosts dynamically on every update
This commit is contained in:
parent
e51304a5e3
commit
8244a146de
2 changed files with 97 additions and 35 deletions
|
@ -57,8 +57,8 @@ async def async_setup_entry(hass, config_entry):
|
||||||
)
|
)
|
||||||
await mikrotik_controller.hwinfo_update()
|
await mikrotik_controller.hwinfo_update()
|
||||||
|
|
||||||
if track_accounting:
|
#if track_accounting:
|
||||||
await mikrotik_controller.async_accounting_hosts_update()
|
# await mikrotik_controller.async_accounting_hosts_update()
|
||||||
|
|
||||||
await mikrotik_controller.async_update()
|
await mikrotik_controller.async_update()
|
||||||
|
|
||||||
|
|
|
@ -81,10 +81,10 @@ class MikrotikControllerData:
|
||||||
async_track_time_interval(
|
async_track_time_interval(
|
||||||
self.hass, self.force_fwupdate_check, timedelta(hours=1)
|
self.hass, self.force_fwupdate_check, timedelta(hours=1)
|
||||||
)
|
)
|
||||||
if self.track_accounting:
|
# if self.track_accounting:
|
||||||
async_track_time_interval(
|
# async_track_time_interval(
|
||||||
self.hass, self.force_accounting_hosts_update, timedelta(minutes=15)
|
# self.hass, self.force_accounting_hosts_update, timedelta(minutes=15)
|
||||||
)
|
# )
|
||||||
|
|
||||||
def _get_traffic_type_and_div(self):
|
def _get_traffic_type_and_div(self):
|
||||||
traffic_type = self.option_traffic_type
|
traffic_type = self.option_traffic_type
|
||||||
|
@ -114,10 +114,10 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# force_accounting_hosts_update
|
# force_accounting_hosts_update
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
@callback
|
# @callback
|
||||||
async def force_accounting_hosts_update(self, _now=None):
|
# async def force_accounting_hosts_update(self, _now=None):
|
||||||
"""Trigger update by timer"""
|
# """Trigger update by timer"""
|
||||||
await self.async_accounting_hosts_update()
|
# await self.async_accounting_hosts_update()
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# force_fwupdate_check
|
# force_fwupdate_check
|
||||||
|
@ -188,15 +188,15 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# async_accounting_hosts_update
|
# async_accounting_hosts_update
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
async def async_accounting_hosts_update(self):
|
# async def async_accounting_hosts_update(self):
|
||||||
"""Update Mikrotik accounting hosts"""
|
# """Update Mikrotik accounting hosts"""
|
||||||
try:
|
# try:
|
||||||
await asyncio.wait_for(self.lock.acquire(), timeout=10)
|
# await asyncio.wait_for(self.lock.acquire(), timeout=10)
|
||||||
except:
|
# except:
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
await self.hass.async_add_executor_job(self.build_accounting_hosts)
|
# await self.hass.async_add_executor_job(self.build_accounting_hosts)
|
||||||
self.lock.release()
|
# self.lock.release()
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# async_fwupdate_check
|
# async_fwupdate_check
|
||||||
|
@ -708,6 +708,20 @@ class MikrotikControllerData:
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Build list of local DHCP networks
|
||||||
|
dhcp_networks = parse_api(
|
||||||
|
data={},
|
||||||
|
source=self.api.path("/ip/dhcp-server/network"),
|
||||||
|
key="address",
|
||||||
|
vals=[
|
||||||
|
{"name": "address"},
|
||||||
|
],
|
||||||
|
ensure_vals=[
|
||||||
|
{"name": "address"},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.local_dhcp_networks = [IPv4Network(network) for network in dhcp_networks]
|
||||||
|
|
||||||
self.data["dhcp"] = parse_api(
|
self.data["dhcp"] = parse_api(
|
||||||
data=self.data["dhcp"],
|
data=self.data["dhcp"],
|
||||||
source=self.api.path("/ip/dhcp-server/lease"),
|
source=self.api.path("/ip/dhcp-server/lease"),
|
||||||
|
@ -760,7 +774,7 @@ class MikrotikControllerData:
|
||||||
# ]
|
# ]
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# Also retrieve all entries in ARP table. If some hosts are missing, build it here
|
# Also add hosts not found in DHCP Leases from ARP table
|
||||||
arp_hosts = parse_api(
|
arp_hosts = parse_api(
|
||||||
data={},
|
data={},
|
||||||
source=self.api.path("/ip/arp", return_list=True),
|
source=self.api.path("/ip/arp", return_list=True),
|
||||||
|
@ -788,7 +802,7 @@ class MikrotikControllerData:
|
||||||
"mac-address": arp_hosts[mac]['address']
|
"mac-address": arp_hosts[mac]['address']
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build name for host.
|
# Build name for host
|
||||||
dns_data = parse_api(
|
dns_data = parse_api(
|
||||||
data={},
|
data={},
|
||||||
source=self.api.path("/ip/dns/static", return_list=True),
|
source=self.api.path("/ip/dns/static", return_list=True),
|
||||||
|
@ -816,20 +830,6 @@ class MikrotikControllerData:
|
||||||
_LOGGER.debug(f"Generated {len(self.data['accounting'])} accounting devices")
|
_LOGGER.debug(f"Generated {len(self.data['accounting'])} accounting devices")
|
||||||
_LOGGER.debug(self.data['accounting'])
|
_LOGGER.debug(self.data['accounting'])
|
||||||
|
|
||||||
# Build list of local networks
|
|
||||||
dhcp_networks = parse_api(
|
|
||||||
data={},
|
|
||||||
source=self.api.path("/ip/dhcp-server/network", return_list=True),
|
|
||||||
key="address",
|
|
||||||
vals=[
|
|
||||||
{"name": "address"},
|
|
||||||
],
|
|
||||||
ensure_vals=[
|
|
||||||
{"name": "address"},
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.local_dhcp_networks = [IPv4Network(network) for network in dhcp_networks]
|
|
||||||
|
|
||||||
def _address_part_of_local_network(self, address):
|
def _address_part_of_local_network(self, address):
|
||||||
address = ip_address(address)
|
address = ip_address(address)
|
||||||
|
@ -846,6 +846,68 @@ class MikrotikControllerData:
|
||||||
|
|
||||||
def get_accounting(self):
|
def get_accounting(self):
|
||||||
"""Get Accounting data from Mikrotik"""
|
"""Get Accounting data from Mikrotik"""
|
||||||
|
|
||||||
|
# Build missing hosts from already retrieved DHCP Server leases
|
||||||
|
for mac in self.data["dhcp"]:
|
||||||
|
if mac not in self.data["accounting"]:
|
||||||
|
self.data["accounting"][mac] = self.data["dhcp"][mac]
|
||||||
|
|
||||||
|
# Also add hosts not found in DHCP Leases from ARP table
|
||||||
|
arp_hosts = parse_api(
|
||||||
|
data={},
|
||||||
|
source=self.api.path("/ip/arp"),
|
||||||
|
key="mac-address",
|
||||||
|
vals=[
|
||||||
|
{"name": "address"},
|
||||||
|
{"name": "mac-address"},
|
||||||
|
{"name": "disabled", "default": True},
|
||||||
|
{"name": "invalid", "default": True},
|
||||||
|
],
|
||||||
|
only=[
|
||||||
|
{"key": "disabled", "value": False},
|
||||||
|
{"key": "invalid", "value": False}
|
||||||
|
],
|
||||||
|
ensure_vals=[
|
||||||
|
{"name": "address"},
|
||||||
|
{"name": "mac-address"},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
for mac in arp_hosts:
|
||||||
|
if mac not in self.data["accounting"]:
|
||||||
|
self.data["accounting"][mac] = {
|
||||||
|
"address": arp_hosts[mac]['address'],
|
||||||
|
"mac-address": arp_hosts[mac]['mac-address']
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build name for host
|
||||||
|
dns_data = parse_api(
|
||||||
|
data={},
|
||||||
|
source=self.api.path("/ip/dns/static"),
|
||||||
|
key="address",
|
||||||
|
vals=[
|
||||||
|
{"name": "address"},
|
||||||
|
{"name": "name"},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
for mac, vals in self.data["accounting"].items():
|
||||||
|
# First try getting DHCP lease comment
|
||||||
|
if str(vals.get('comment', '').strip()):
|
||||||
|
self.data["accounting"][mac]['name'] = vals['comment']
|
||||||
|
# Then entry in static DNS entry
|
||||||
|
elif vals['address'] in dns_data and str(dns_data[vals['address']].get('name', '').strip()):
|
||||||
|
self.data["accounting"][mac]['name'] = dns_data[vals['address']]['name']
|
||||||
|
# And then DHCP lease host-name
|
||||||
|
elif str(vals.get('host-name', '').strip()):
|
||||||
|
self.data["accounting"][mac]['name'] = vals['host-name']
|
||||||
|
# If everything fails use hosts IP address as name
|
||||||
|
else:
|
||||||
|
self.data["accounting"][mac]['name'] = vals['address']
|
||||||
|
|
||||||
|
_LOGGER.debug(f"Generated {len(self.data['accounting'])} accounting devices")
|
||||||
|
_LOGGER.debug(self.data['accounting'])
|
||||||
|
|
||||||
traffic_type, traffic_div = self._get_traffic_type_and_div()
|
traffic_type, traffic_div = self._get_traffic_type_and_div()
|
||||||
|
|
||||||
# Build temp accounting values dict with ip address as key
|
# Build temp accounting values dict with ip address as key
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue