mirror of
https://github.com/tomaae/homeassistant-mikrotik_router.git
synced 2025-07-07 07:54:31 +02:00
Accounting feature renamed to Client traffic. In case of older firmware fallback to accounting fetature for client traffic monitoring, instead use kid-control-devices
This commit is contained in:
parent
0120409382
commit
e93b02e71d
3 changed files with 225 additions and 100 deletions
|
@ -129,8 +129,8 @@ class MikrotikControllerData:
|
|||
"wireless_hosts": {},
|
||||
"host": {},
|
||||
"host_hass": {},
|
||||
"accounting": {},
|
||||
"environment": {},
|
||||
"client_traffic": {},
|
||||
"environment": {}
|
||||
}
|
||||
|
||||
self.listeners = []
|
||||
|
@ -612,12 +612,13 @@ class MikrotikControllerData:
|
|||
if self.api.connected():
|
||||
await self.hass.async_add_executor_job(self.get_system_resource)
|
||||
|
||||
if (
|
||||
self.api.connected()
|
||||
and self.option_sensor_client_traffic
|
||||
and 0 < self.major_fw_version < 7
|
||||
):
|
||||
await self.hass.async_add_executor_job(self.process_accounting)
|
||||
if self.api.connected() and self.option_sensor_client_traffic:
|
||||
if 0 < self.major_fw_version < 7:
|
||||
_LOGGER.info("Using accounting feature for client traffic processing")
|
||||
await self.hass.async_add_executor_job(self.process_accounting)
|
||||
elif 0 < self.major_fw_version >= 7:
|
||||
_LOGGER.info("Using accounting kid control devices for client traffic processing")
|
||||
await self.hass.async_add_executor_job(self.process_kid_control_devices)
|
||||
|
||||
if self.api.connected() and self.option_sensor_simple_queues:
|
||||
await self.hass.async_add_executor_job(self.get_queue)
|
||||
|
@ -1875,8 +1876,8 @@ class MikrotikControllerData:
|
|||
|
||||
# Build missing hosts from main hosts dict
|
||||
for uid, vals in self.data["host"].items():
|
||||
if uid not in self.data["accounting"]:
|
||||
self.data["accounting"][uid] = {
|
||||
if uid not in self.data["client_traffic"]:
|
||||
self.data["client_traffic"][uid] = {
|
||||
"address": vals["address"],
|
||||
"mac-address": vals["mac-address"],
|
||||
"host-name": vals["host-name"],
|
||||
|
@ -1885,11 +1886,11 @@ class MikrotikControllerData:
|
|||
"local_accounting": False,
|
||||
}
|
||||
|
||||
_LOGGER.debug(f"Working with {len(self.data['accounting'])} accounting devices")
|
||||
_LOGGER.debug(f"Working with {len(self.data['client_traffic'])} accounting devices")
|
||||
|
||||
# Build temp accounting values dict with ip address as key
|
||||
tmp_accounting_values = {}
|
||||
for uid, vals in self.data["accounting"].items():
|
||||
for uid, vals in self.data["client_traffic"].items():
|
||||
tmp_accounting_values[vals["address"]] = {
|
||||
"wan-tx": 0,
|
||||
"wan-rx": 0,
|
||||
|
@ -1897,7 +1898,7 @@ class MikrotikControllerData:
|
|||
"lan-rx": 0,
|
||||
}
|
||||
|
||||
time_diff = self.api.take_accounting_snapshot()
|
||||
time_diff = self.api.take_client_traffic_snapshot(True)
|
||||
if time_diff:
|
||||
accounting_data = parse_api(
|
||||
data={},
|
||||
|
@ -1965,20 +1966,20 @@ class MikrotikControllerData:
|
|||
)
|
||||
continue
|
||||
|
||||
self.data["accounting"][uid]["tx-rx-attr"] = uom_type
|
||||
self.data["accounting"][uid]["available"] = accounting_enabled
|
||||
self.data["accounting"][uid]["local_accounting"] = local_traffic_enabled
|
||||
self.data["client_traffic"][uid]["tx-rx-attr"] = uom_type
|
||||
self.data["client_traffic"][uid]["available"] = accounting_enabled
|
||||
self.data["client_traffic"][uid]["local_accounting"] = local_traffic_enabled
|
||||
|
||||
if not accounting_enabled:
|
||||
# Skip calculation for WAN and LAN if accounting is disabled
|
||||
continue
|
||||
|
||||
self.data["accounting"][uid]["wan-tx"] = (
|
||||
self.data["client_traffic"][uid]["wan-tx"] = (
|
||||
round(vals["wan-tx"] / time_diff * uom_div, 2)
|
||||
if vals["wan-tx"]
|
||||
else 0.0
|
||||
)
|
||||
self.data["accounting"][uid]["wan-rx"] = (
|
||||
self.data["client_traffic"][uid]["wan-rx"] = (
|
||||
round(vals["wan-rx"] / time_diff * uom_div, 2)
|
||||
if vals["wan-rx"]
|
||||
else 0.0
|
||||
|
@ -1988,12 +1989,12 @@ class MikrotikControllerData:
|
|||
# Skip calculation for LAN if LAN accounting is disabled
|
||||
continue
|
||||
|
||||
self.data["accounting"][uid]["lan-tx"] = (
|
||||
self.data["client_traffic"][uid]["lan-tx"] = (
|
||||
round(vals["lan-tx"] / time_diff * uom_div, 2)
|
||||
if vals["lan-tx"]
|
||||
else 0.0
|
||||
)
|
||||
self.data["accounting"][uid]["lan-rx"] = (
|
||||
self.data["client_traffic"][uid]["lan-rx"] = (
|
||||
round(vals["lan-rx"] / time_diff * uom_div, 2)
|
||||
if vals["lan-rx"]
|
||||
else 0.0
|
||||
|
@ -2033,7 +2034,7 @@ class MikrotikControllerData:
|
|||
# _get_accounting_uid_by_ip
|
||||
# ---------------------------
|
||||
def _get_accounting_uid_by_ip(self, requested_ip):
|
||||
for mac, vals in self.data["accounting"].items():
|
||||
for mac, vals in self.data["client_traffic"].items():
|
||||
if vals.get("address") is requested_ip:
|
||||
return mac
|
||||
return None
|
||||
|
@ -2050,3 +2051,125 @@ class MikrotikControllerData:
|
|||
break
|
||||
|
||||
return uid
|
||||
|
||||
# ---------------------------
|
||||
# process_kid_control
|
||||
# ---------------------------
|
||||
def process_kid_control_devices(self):
|
||||
"""Get Kid Control Device data from Mikrotik"""
|
||||
|
||||
uom_type, uom_div = self._get_unit_of_measurement()
|
||||
|
||||
# Build missing hosts from main hosts dict
|
||||
for uid, vals in self.data["host"].items():
|
||||
if uid not in self.data["client_traffic"]:
|
||||
self.data["client_traffic"][uid] = {
|
||||
"address": vals["address"],
|
||||
"mac-address": vals["mac-address"],
|
||||
"host-name": vals["host-name"],
|
||||
"previous-bytes-up": 0.0,
|
||||
"previous-bytes-down": 0.0,
|
||||
"wan-tx": 0.0,
|
||||
"wan-rx": 0.0,
|
||||
"tx-rx-attr": uom_type,
|
||||
"available": False,
|
||||
"local_accounting": False,
|
||||
}
|
||||
|
||||
_LOGGER.debug(f"Working with {len(self.data['client_traffic'])} kid control devices")
|
||||
|
||||
time_diff = self.api.take_client_traffic_snapshot(False)
|
||||
if not time_diff:
|
||||
return
|
||||
|
||||
kid_control_devices_data = parse_api(
|
||||
data={},
|
||||
source=self.api.path("/ip/kid-control/device"),
|
||||
key="mac-address",
|
||||
vals=[
|
||||
{"name": "mac-address"},
|
||||
{"name": "bytes-down"},
|
||||
{"name": "bytes-up"},
|
||||
{
|
||||
"name": "enabled",
|
||||
"source": "disabled",
|
||||
"type": "bool",
|
||||
"reverse": True,
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
if not kid_control_devices_data:
|
||||
_LOGGER.debug("No kid control devices found, make sure kid-control feature is configured")
|
||||
|
||||
for uid, vals in kid_control_devices_data.items():
|
||||
if uid not in self.data["client_traffic"]:
|
||||
_LOGGER.debug(f"Skipping unknown device {uid}")
|
||||
continue
|
||||
|
||||
self.data["client_traffic"][uid]["available"] = vals['enabled']
|
||||
|
||||
current_tx = vals['bytes-up']
|
||||
previous_tx = self.data["client_traffic"][uid]['previous-bytes-up']
|
||||
delta_tx = max(0, current_tx - previous_tx)
|
||||
self.data["client_traffic"][uid]['wan-tx'] = round(delta_tx / time_diff * uom_div, 2)
|
||||
self.data["client_traffic"][uid]['previous-bytes-up'] = current_tx
|
||||
|
||||
current_rx = vals['bytes-down']
|
||||
previous_rx = self.data["client_traffic"][uid]['previous-bytes-down']
|
||||
delta_rx = max(0, current_rx - previous_rx)
|
||||
self.data["client_traffic"][uid]['wan-rx'] = round(delta_rx / time_diff * uom_div, 2)
|
||||
self.data["client_traffic"][uid]['previous-bytes-down'] = current_rx
|
||||
|
||||
# ---------------------------
|
||||
# _get_unit_of_measurement
|
||||
# ---------------------------
|
||||
def _get_unit_of_measurement(self):
|
||||
uom_type = self.option_unit_of_measurement
|
||||
if uom_type == "Kbps":
|
||||
uom_div = 0.001
|
||||
elif uom_type == "Mbps":
|
||||
uom_div = 0.000001
|
||||
elif uom_type == "B/s":
|
||||
uom_div = 0.125
|
||||
elif uom_type == "KB/s":
|
||||
uom_div = 0.000125
|
||||
elif uom_type == "MB/s":
|
||||
uom_div = 0.000000125
|
||||
else:
|
||||
uom_type = "bps"
|
||||
uom_div = 1
|
||||
return uom_type, uom_div
|
||||
|
||||
# ---------------------------
|
||||
# _address_part_of_local_network
|
||||
# ---------------------------
|
||||
def _address_part_of_local_network(self, address):
|
||||
address = ip_address(address)
|
||||
for vals in self.data["dhcp-network"].values():
|
||||
if address in vals["IPv4Network"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
# ---------------------------
|
||||
# _get_accounting_uid_by_ip
|
||||
# ---------------------------
|
||||
def _get_accounting_uid_by_ip(self, requested_ip):
|
||||
for mac, vals in self.data["client_traffic"].items():
|
||||
if vals.get("address") is requested_ip:
|
||||
return mac
|
||||
return None
|
||||
|
||||
# ---------------------------
|
||||
# _get_iface_from_entry
|
||||
# ---------------------------
|
||||
def _get_iface_from_entry(self, entry):
|
||||
"""Get interface default-name using name from interface dict"""
|
||||
uid = None
|
||||
for ifacename in self.data["interface"]:
|
||||
if self.data["interface"][ifacename]["name"] == entry["interface"]:
|
||||
uid = ifacename
|
||||
break
|
||||
|
||||
return uid
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue