mirror of
https://github.com/tomaae/homeassistant-mikrotik_router.git
synced 2025-07-13 19:04:30 +02:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
8d3e86a988
5 changed files with 202 additions and 95 deletions
25
README.md
25
README.md
|
@ -47,7 +47,7 @@ Monitor and control your Mikrotik device from Home Assistant.
|
||||||
* Enable/disable Filter switches
|
* Enable/disable Filter switches
|
||||||
* Monitor and control PPP users
|
* Monitor and control PPP users
|
||||||
* Kid Control
|
* Kid Control
|
||||||
* Mikrotik Accounting traffic sensors per hosts for RX/TX WAN/LAN
|
* Client Traffic RX/TX WAN/LAN monitoring though Accounting or Kid Control Devices (depending on RouterOS FW version)
|
||||||
* Device tracker for hosts in network
|
* Device tracker for hosts in network
|
||||||
* System sensors (CPU, Memory, HDD, Temperature)
|
* System sensors (CPU, Memory, HDD, Temperature)
|
||||||
* Check firmware update
|
* Check firmware update
|
||||||
|
@ -112,9 +112,10 @@ Monitor and control.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Client Traffic
|
||||||
|
|
||||||
## Accounting
|
#### RouterOS v6
|
||||||
*RouterOS 7+ no longer support accounting*
|
###### Accounting
|
||||||
|
|
||||||
Monitor per-IP throughput tracking based on Mikrotik Accounting.
|
Monitor per-IP throughput tracking based on Mikrotik Accounting.
|
||||||
|
|
||||||
|
@ -124,6 +125,20 @@ More information about Accounting can be found on [Mikrotik support page](https:
|
||||||
|
|
||||||
NOTE: Accounting does not count in FastTracked packets.
|
NOTE: Accounting does not count in FastTracked packets.
|
||||||
|
|
||||||
|
|
||||||
|
#### RouterOS v7
|
||||||
|
###### Kid Control Devices
|
||||||
|
|
||||||
|
In RouterOS v7 Accounting feature is deprecated so alternative approach for is to use
|
||||||
|
Kid Control Devices feature (IP - Kid Control - Devices).
|
||||||
|
|
||||||
|
This feature requires at least one 'kid' to be defined,
|
||||||
|
after that Mikrotik will dynamically start tracking bandwidth usage of all known devices.
|
||||||
|
|
||||||
|
Simple dummy Kid entry can be defined with
|
||||||
|
|
||||||
|
```/ip kid-control add name=Monitor mon=0s-1d tue=0s-1d wed=0s-1d thu=0s-1d fri=0s-1d sat=0s-1d sun=0s-1d```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# Install integration
|
# Install integration
|
||||||
|
@ -132,14 +147,12 @@ This integration is distributed using [HACS](https://hacs.xyz/).
|
||||||
You can find it under "Integrations", named "Mikrotik Router"
|
You can find it under "Integrations", named "Mikrotik Router"
|
||||||
|
|
||||||
Minimum requirements:
|
Minimum requirements:
|
||||||
* RouterOS v6.43
|
* RouterOS v6.43/v7.1
|
||||||
* Home Assistant 0.114.0
|
* Home Assistant 0.114.0
|
||||||
|
|
||||||
## Using Mikrotik development branch
|
## Using Mikrotik development branch
|
||||||
If you are using development branch for mikrotik, some features may stop working due to major changes in RouterOS.
|
If you are using development branch for mikrotik, some features may stop working due to major changes in RouterOS.
|
||||||
Use integration master branch instead of latest release to keep up with RouterOS beta adjustments.
|
Use integration master branch instead of latest release to keep up with RouterOS beta adjustments.
|
||||||
* beta 7.3 was fully tested.
|
|
||||||
* beta 7.4 have been reported to miss system health information.
|
|
||||||
|
|
||||||
## Setup integration
|
## Setup integration
|
||||||
1. Create user for homeassistant on your mikrotik router with following permissions:
|
1. Create user for homeassistant on your mikrotik router with following permissions:
|
||||||
|
|
|
@ -129,10 +129,12 @@ class MikrotikControllerData:
|
||||||
"wireless_hosts": {},
|
"wireless_hosts": {},
|
||||||
"host": {},
|
"host": {},
|
||||||
"host_hass": {},
|
"host_hass": {},
|
||||||
"accounting": {},
|
"client_traffic": {},
|
||||||
"environment": {},
|
"environment": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.notified_flags = []
|
||||||
|
|
||||||
self.listeners = []
|
self.listeners = []
|
||||||
self.lock = asyncio.Lock()
|
self.lock = asyncio.Lock()
|
||||||
self.lock_ping = asyncio.Lock()
|
self.lock_ping = asyncio.Lock()
|
||||||
|
@ -612,12 +614,11 @@ class MikrotikControllerData:
|
||||||
if self.api.connected():
|
if self.api.connected():
|
||||||
await self.hass.async_add_executor_job(self.get_system_resource)
|
await self.hass.async_add_executor_job(self.get_system_resource)
|
||||||
|
|
||||||
if (
|
if self.api.connected() and self.option_sensor_client_traffic:
|
||||||
self.api.connected()
|
if 0 < self.major_fw_version < 7:
|
||||||
and self.option_sensor_client_traffic
|
await self.hass.async_add_executor_job(self.process_accounting)
|
||||||
and 0 < self.major_fw_version < 7
|
elif 0 < self.major_fw_version >= 7:
|
||||||
):
|
await self.hass.async_add_executor_job(self.process_kid_control_devices)
|
||||||
await self.hass.async_add_executor_job(self.process_accounting)
|
|
||||||
|
|
||||||
if self.api.connected() and self.option_sensor_simple_queues:
|
if self.api.connected() and self.option_sensor_simple_queues:
|
||||||
await self.hass.async_add_executor_job(self.get_queue)
|
await self.hass.async_add_executor_job(self.get_queue)
|
||||||
|
@ -952,6 +953,8 @@ class MikrotikControllerData:
|
||||||
{"name": "src-port", "default": "any"},
|
{"name": "src-port", "default": "any"},
|
||||||
{"name": "dst-address", "default": "any"},
|
{"name": "dst-address", "default": "any"},
|
||||||
{"name": "dst-port", "default": "any"},
|
{"name": "dst-port", "default": "any"},
|
||||||
|
{"name": "src-address-list", "default": "any"},
|
||||||
|
{"name": "dst-address-list", "default": "any"},
|
||||||
{
|
{
|
||||||
"name": "enabled",
|
"name": "enabled",
|
||||||
"source": "disabled",
|
"source": "disabled",
|
||||||
|
@ -976,6 +979,10 @@ class MikrotikControllerData:
|
||||||
{"key": "dst-address"},
|
{"key": "dst-address"},
|
||||||
{"text": ":"},
|
{"text": ":"},
|
||||||
{"key": "dst-port"},
|
{"key": "dst-port"},
|
||||||
|
{"text": ","},
|
||||||
|
{"key": "src-address-list"},
|
||||||
|
{"text": "-"},
|
||||||
|
{"key": "dst-address-list"},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{"name": "name"},
|
{"name": "name"},
|
||||||
|
@ -1869,8 +1876,8 @@ class MikrotikControllerData:
|
||||||
|
|
||||||
# Build missing hosts from main hosts dict
|
# Build missing hosts from main hosts dict
|
||||||
for uid, vals in self.data["host"].items():
|
for uid, vals in self.data["host"].items():
|
||||||
if uid not in self.data["accounting"]:
|
if uid not in self.data["client_traffic"]:
|
||||||
self.data["accounting"][uid] = {
|
self.data["client_traffic"][uid] = {
|
||||||
"address": vals["address"],
|
"address": vals["address"],
|
||||||
"mac-address": vals["mac-address"],
|
"mac-address": vals["mac-address"],
|
||||||
"host-name": vals["host-name"],
|
"host-name": vals["host-name"],
|
||||||
|
@ -1879,11 +1886,13 @@ class MikrotikControllerData:
|
||||||
"local_accounting": False,
|
"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
|
# Build temp accounting values dict with ip address as key
|
||||||
tmp_accounting_values = {}
|
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"]] = {
|
tmp_accounting_values[vals["address"]] = {
|
||||||
"wan-tx": 0,
|
"wan-tx": 0,
|
||||||
"wan-rx": 0,
|
"wan-rx": 0,
|
||||||
|
@ -1891,7 +1900,7 @@ class MikrotikControllerData:
|
||||||
"lan-rx": 0,
|
"lan-rx": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
time_diff = self.api.take_accounting_snapshot()
|
time_diff = self.api.take_client_traffic_snapshot(True)
|
||||||
if time_diff:
|
if time_diff:
|
||||||
accounting_data = parse_api(
|
accounting_data = parse_api(
|
||||||
data={},
|
data={},
|
||||||
|
@ -1959,20 +1968,20 @@ class MikrotikControllerData:
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.data["accounting"][uid]["tx-rx-attr"] = uom_type
|
self.data["client_traffic"][uid]["tx-rx-attr"] = uom_type
|
||||||
self.data["accounting"][uid]["available"] = accounting_enabled
|
self.data["client_traffic"][uid]["available"] = accounting_enabled
|
||||||
self.data["accounting"][uid]["local_accounting"] = local_traffic_enabled
|
self.data["client_traffic"][uid]["local_accounting"] = local_traffic_enabled
|
||||||
|
|
||||||
if not accounting_enabled:
|
if not accounting_enabled:
|
||||||
# Skip calculation for WAN and LAN if accounting is disabled
|
# Skip calculation for WAN and LAN if accounting is disabled
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.data["accounting"][uid]["wan-tx"] = (
|
self.data["client_traffic"][uid]["wan-tx"] = (
|
||||||
round(vals["wan-tx"] / time_diff * uom_div, 2)
|
round(vals["wan-tx"] / time_diff * uom_div, 2)
|
||||||
if vals["wan-tx"]
|
if vals["wan-tx"]
|
||||||
else 0.0
|
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)
|
round(vals["wan-rx"] / time_diff * uom_div, 2)
|
||||||
if vals["wan-rx"]
|
if vals["wan-rx"]
|
||||||
else 0.0
|
else 0.0
|
||||||
|
@ -1982,12 +1991,12 @@ class MikrotikControllerData:
|
||||||
# Skip calculation for LAN if LAN accounting is disabled
|
# Skip calculation for LAN if LAN accounting is disabled
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.data["accounting"][uid]["lan-tx"] = (
|
self.data["client_traffic"][uid]["lan-tx"] = (
|
||||||
round(vals["lan-tx"] / time_diff * uom_div, 2)
|
round(vals["lan-tx"] / time_diff * uom_div, 2)
|
||||||
if vals["lan-tx"]
|
if vals["lan-tx"]
|
||||||
else 0.0
|
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)
|
round(vals["lan-rx"] / time_diff * uom_div, 2)
|
||||||
if vals["lan-rx"]
|
if vals["lan-rx"]
|
||||||
else 0.0
|
else 0.0
|
||||||
|
@ -2027,7 +2036,7 @@ class MikrotikControllerData:
|
||||||
# _get_accounting_uid_by_ip
|
# _get_accounting_uid_by_ip
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def _get_accounting_uid_by_ip(self, requested_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:
|
if vals.get("address") is requested_ip:
|
||||||
return mac
|
return mac
|
||||||
return None
|
return None
|
||||||
|
@ -2044,3 +2053,85 @@ class MikrotikControllerData:
|
||||||
break
|
break
|
||||||
|
|
||||||
return uid
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
time_diff = self.api.take_client_traffic_snapshot(False)
|
||||||
|
|
||||||
|
if not kid_control_devices_data:
|
||||||
|
if "kid-control-devices" not in self.notified_flags:
|
||||||
|
_LOGGER.error(
|
||||||
|
"No kid control devices found on your Mikrotik device, make sure kid-control feature is configured"
|
||||||
|
)
|
||||||
|
self.notified_flags.append("kid-control-devices")
|
||||||
|
return
|
||||||
|
elif "kid-control-devices" in self.notified_flags:
|
||||||
|
self.notified_flags.remove("kid-control-devices")
|
||||||
|
|
||||||
|
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"]
|
||||||
|
if time_diff:
|
||||||
|
delta_tx = max(0, current_tx - previous_tx) * 8
|
||||||
|
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"]
|
||||||
|
if time_diff:
|
||||||
|
delta_rx = max(0, current_rx - previous_rx) * 8
|
||||||
|
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
|
||||||
|
|
|
@ -52,7 +52,7 @@ class MikrotikAPI:
|
||||||
self._connection_retry_sec = 58
|
self._connection_retry_sec = 58
|
||||||
self.error = None
|
self.error = None
|
||||||
self.connection_error_reported = False
|
self.connection_error_reported = False
|
||||||
self.accounting_last_run = None
|
self.client_traffic_last_run = None
|
||||||
|
|
||||||
# Default ports
|
# Default ports
|
||||||
if not self._port:
|
if not self._port:
|
||||||
|
@ -644,64 +644,65 @@ class MikrotikAPI:
|
||||||
return True, True
|
return True, True
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# take_accounting_snapshot
|
# take_client_traffic_snapshot
|
||||||
# Returns float -> period in seconds between last and current run
|
# Returns float -> period in seconds between last and current run
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def take_accounting_snapshot(self) -> float:
|
def take_client_traffic_snapshot(self, use_accounting) -> float:
|
||||||
"""Get accounting data"""
|
"""Tako accounting snapshot and return time diff"""
|
||||||
if not self.connection_check():
|
if not self.connection_check():
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
accounting = self.path("/ip/accounting", return_list=False)
|
if use_accounting:
|
||||||
|
accounting = self.path("/ip/accounting", return_list=False)
|
||||||
|
|
||||||
self.lock.acquire()
|
self.lock.acquire()
|
||||||
try:
|
try:
|
||||||
# Prepare command
|
# Prepare command
|
||||||
take = accounting("snapshot/take")
|
take = accounting("snapshot/take")
|
||||||
except librouteros.exceptions.ConnectionClosed:
|
except librouteros.exceptions.ConnectionClosed:
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
return 0
|
return 0
|
||||||
except (
|
except (
|
||||||
librouteros.exceptions.TrapError,
|
librouteros.exceptions.TrapError,
|
||||||
librouteros.exceptions.MultiTrapError,
|
librouteros.exceptions.MultiTrapError,
|
||||||
librouteros.exceptions.ProtocolError,
|
librouteros.exceptions.ProtocolError,
|
||||||
librouteros.exceptions.FatalError,
|
librouteros.exceptions.FatalError,
|
||||||
socket_timeout,
|
socket_timeout,
|
||||||
socket_error,
|
socket_error,
|
||||||
ssl.SSLError,
|
ssl.SSLError,
|
||||||
BrokenPipeError,
|
BrokenPipeError,
|
||||||
OSError,
|
OSError,
|
||||||
ValueError,
|
ValueError,
|
||||||
) as api_error:
|
) as api_error:
|
||||||
self.disconnect("accounting_snapshot", api_error)
|
self.disconnect("accounting_snapshot", api_error)
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
return 0
|
return 0
|
||||||
except:
|
except:
|
||||||
self.disconnect("accounting_snapshot")
|
self.disconnect("accounting_snapshot")
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
list(take)
|
list(take)
|
||||||
except librouteros.exceptions.ConnectionClosed as api_error:
|
except librouteros.exceptions.ConnectionClosed as api_error:
|
||||||
self.disconnect("accounting_snapshot", api_error)
|
self.disconnect("accounting_snapshot", api_error)
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
return 0
|
return 0
|
||||||
except:
|
except:
|
||||||
self.disconnect("accounting_snapshot")
|
self.disconnect("accounting_snapshot")
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
# First request will be discarded because we cannot know when the last data was retrieved
|
# First request will be discarded because we cannot know when the last data was retrieved
|
||||||
# prevents spikes in data
|
# prevents spikes in data
|
||||||
if not self.accounting_last_run:
|
if not self.client_traffic_last_run:
|
||||||
self.accounting_last_run = self._current_milliseconds()
|
self.client_traffic_last_run = self._current_milliseconds()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# Calculate time difference in seconds and return
|
# Calculate time difference in seconds and return
|
||||||
time_diff = self._current_milliseconds() - self.accounting_last_run
|
time_diff = self._current_milliseconds() - self.client_traffic_last_run
|
||||||
self.accounting_last_run = self._current_milliseconds()
|
self.client_traffic_last_run = self._current_milliseconds()
|
||||||
return time_diff / 1000
|
return time_diff / 1000
|
||||||
|
|
|
@ -186,49 +186,49 @@ SENSOR_TYPES = {
|
||||||
ATTR_ATTR: "rx-bits-per-second",
|
ATTR_ATTR: "rx-bits-per-second",
|
||||||
ATTR_CTGR: None,
|
ATTR_CTGR: None,
|
||||||
},
|
},
|
||||||
"accounting_lan_tx": {
|
"client_traffic_lan_tx": {
|
||||||
ATTR_DEVICE_CLASS: None,
|
ATTR_DEVICE_CLASS: None,
|
||||||
ATTR_ICON: "mdi:upload-network",
|
ATTR_ICON: "mdi:upload-network",
|
||||||
ATTR_LABEL: "LAN TX",
|
ATTR_LABEL: "LAN TX",
|
||||||
ATTR_UNIT: "ps",
|
ATTR_UNIT: "ps",
|
||||||
ATTR_UNIT_ATTR: "tx-rx-attr",
|
ATTR_UNIT_ATTR: "tx-rx-attr",
|
||||||
ATTR_PATH: "accounting",
|
ATTR_PATH: "client_traffic",
|
||||||
ATTR_ATTR: "lan-tx",
|
ATTR_ATTR: "lan-tx",
|
||||||
ATTR_CTGR: None,
|
ATTR_CTGR: None,
|
||||||
},
|
},
|
||||||
"accounting_lan_rx": {
|
"client_traffic_lan_rx": {
|
||||||
ATTR_DEVICE_CLASS: None,
|
ATTR_DEVICE_CLASS: None,
|
||||||
ATTR_ICON: "mdi:download-network",
|
ATTR_ICON: "mdi:download-network",
|
||||||
ATTR_LABEL: "LAN RX",
|
ATTR_LABEL: "LAN RX",
|
||||||
ATTR_UNIT: "ps",
|
ATTR_UNIT: "ps",
|
||||||
ATTR_UNIT_ATTR: "tx-rx-attr",
|
ATTR_UNIT_ATTR: "tx-rx-attr",
|
||||||
ATTR_PATH: "accounting",
|
ATTR_PATH: "client_traffic",
|
||||||
ATTR_ATTR: "lan-rx",
|
ATTR_ATTR: "lan-rx",
|
||||||
ATTR_CTGR: None,
|
ATTR_CTGR: None,
|
||||||
},
|
},
|
||||||
"accounting_wan_tx": {
|
"client_traffic_wan_tx": {
|
||||||
ATTR_DEVICE_CLASS: None,
|
ATTR_DEVICE_CLASS: None,
|
||||||
ATTR_ICON: "mdi:upload-network",
|
ATTR_ICON: "mdi:upload-network",
|
||||||
ATTR_LABEL: "WAN TX",
|
ATTR_LABEL: "WAN TX",
|
||||||
ATTR_UNIT: "ps",
|
ATTR_UNIT: "ps",
|
||||||
ATTR_UNIT_ATTR: "tx-rx-attr",
|
ATTR_UNIT_ATTR: "tx-rx-attr",
|
||||||
ATTR_PATH: "accounting",
|
ATTR_PATH: "client_traffic",
|
||||||
ATTR_ATTR: "wan-tx",
|
ATTR_ATTR: "wan-tx",
|
||||||
ATTR_CTGR: None,
|
ATTR_CTGR: None,
|
||||||
},
|
},
|
||||||
"accounting_wan_rx": {
|
"client_traffic_wan_rx": {
|
||||||
ATTR_DEVICE_CLASS: None,
|
ATTR_DEVICE_CLASS: None,
|
||||||
ATTR_ICON: "mdi:download-network",
|
ATTR_ICON: "mdi:download-network",
|
||||||
ATTR_LABEL: "WAN RX",
|
ATTR_LABEL: "WAN RX",
|
||||||
ATTR_UNIT: "ps",
|
ATTR_UNIT: "ps",
|
||||||
ATTR_UNIT_ATTR: "tx-rx-attr",
|
ATTR_UNIT_ATTR: "tx-rx-attr",
|
||||||
ATTR_PATH: "accounting",
|
ATTR_PATH: "client_traffic",
|
||||||
ATTR_ATTR: "wan-rx",
|
ATTR_ATTR: "wan-rx",
|
||||||
ATTR_CTGR: None,
|
ATTR_CTGR: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
DEVICE_ATTRIBUTES_ACCOUNTING = ["address", "mac-address", "host-name"]
|
DEVICE_ATTRIBUTES_CLIENT_TRAFFIC = ["address", "mac-address", "host-name"]
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
|
@ -305,7 +305,7 @@ def update_items(inst, config_entry, mikrotik_controller, async_add_entities, se
|
||||||
new_sensors.append(sensors[item_id])
|
new_sensors.append(sensors[item_id])
|
||||||
|
|
||||||
for sensor in SENSOR_TYPES:
|
for sensor in SENSOR_TYPES:
|
||||||
if "system_" in sensor:
|
if sensor.startswith("system_"):
|
||||||
if (
|
if (
|
||||||
SENSOR_TYPES[sensor][ATTR_ATTR]
|
SENSOR_TYPES[sensor][ATTR_ATTR]
|
||||||
not in mikrotik_controller.data[SENSOR_TYPES[sensor][ATTR_PATH]]
|
not in mikrotik_controller.data[SENSOR_TYPES[sensor][ATTR_PATH]]
|
||||||
|
@ -327,7 +327,7 @@ def update_items(inst, config_entry, mikrotik_controller, async_add_entities, se
|
||||||
)
|
)
|
||||||
new_sensors.append(sensors[item_id])
|
new_sensors.append(sensors[item_id])
|
||||||
|
|
||||||
if "traffic_" in sensor:
|
if sensor.startswith("traffic_"):
|
||||||
if not config_entry.options.get(
|
if not config_entry.options.get(
|
||||||
CONF_SENSOR_PORT_TRAFFIC, DEFAULT_SENSOR_PORT_TRAFFIC
|
CONF_SENSOR_PORT_TRAFFIC, DEFAULT_SENSOR_PORT_TRAFFIC
|
||||||
):
|
):
|
||||||
|
@ -350,9 +350,9 @@ def update_items(inst, config_entry, mikrotik_controller, async_add_entities, se
|
||||||
)
|
)
|
||||||
new_sensors.append(sensors[item_id])
|
new_sensors.append(sensors[item_id])
|
||||||
|
|
||||||
if "accounting_" in sensor:
|
if sensor.startswith("client_traffic_"):
|
||||||
for uid in mikrotik_controller.data["accounting"]:
|
for uid in mikrotik_controller.data["client_traffic"]:
|
||||||
item_id = f"{inst}-{sensor}-{mikrotik_controller.data['accounting'][uid]['mac-address']}"
|
item_id = f"{inst}-{sensor}-{mikrotik_controller.data['client_traffic'][uid]['mac-address']}"
|
||||||
if item_id in sensors:
|
if item_id in sensors:
|
||||||
if sensors[item_id].enabled:
|
if sensors[item_id].enabled:
|
||||||
sensors[item_id].async_schedule_update_ha_state()
|
sensors[item_id].async_schedule_update_ha_state()
|
||||||
|
@ -360,9 +360,9 @@ def update_items(inst, config_entry, mikrotik_controller, async_add_entities, se
|
||||||
|
|
||||||
if (
|
if (
|
||||||
SENSOR_TYPES[sensor][ATTR_ATTR]
|
SENSOR_TYPES[sensor][ATTR_ATTR]
|
||||||
in mikrotik_controller.data["accounting"][uid].keys()
|
in mikrotik_controller.data["client_traffic"][uid].keys()
|
||||||
):
|
):
|
||||||
sensors[item_id] = MikrotikAccountingSensor(
|
sensors[item_id] = MikrotikClientTrafficSensor(
|
||||||
mikrotik_controller=mikrotik_controller,
|
mikrotik_controller=mikrotik_controller,
|
||||||
inst=inst,
|
inst=inst,
|
||||||
sensor=sensor,
|
sensor=sensor,
|
||||||
|
@ -534,10 +534,10 @@ class MikrotikControllerTrafficSensor(MikrotikControllerSensor):
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# MikrotikAccountingSensor
|
# MikrotikClientTrafficSensor
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
class MikrotikAccountingSensor(MikrotikControllerSensor):
|
class MikrotikClientTrafficSensor(MikrotikControllerSensor):
|
||||||
"""Define an Mikrotik Accounting sensor."""
|
"""Define an Mikrotik MikrotikClientTrafficSensor sensor."""
|
||||||
|
|
||||||
def __init__(self, mikrotik_controller, inst, sensor, uid):
|
def __init__(self, mikrotik_controller, inst, sensor, uid):
|
||||||
"""Initialize."""
|
"""Initialize."""
|
||||||
|
@ -585,7 +585,7 @@ class MikrotikAccountingSensor(MikrotikControllerSensor):
|
||||||
def extra_state_attributes(self) -> Dict[str, Any]:
|
def extra_state_attributes(self) -> Dict[str, Any]:
|
||||||
"""Return the state attributes."""
|
"""Return the state attributes."""
|
||||||
attributes = self._attrs
|
attributes = self._attrs
|
||||||
for variable in DEVICE_ATTRIBUTES_ACCOUNTING:
|
for variable in DEVICE_ATTRIBUTES_CLIENT_TRAFFIC:
|
||||||
if variable in self._data:
|
if variable in self._data:
|
||||||
attributes[format_attribute(variable)] = self._data[variable]
|
attributes[format_attribute(variable)] = self._data[variable]
|
||||||
|
|
||||||
|
|
|
@ -619,7 +619,8 @@ class MikrotikControllerMangleSwitch(MikrotikControllerSwitch):
|
||||||
if self._ctrl.data["mangle"][uid]["uniq-id"] == (
|
if self._ctrl.data["mangle"][uid]["uniq-id"] == (
|
||||||
f"{self._data['chain']},{self._data['action']},{self._data['protocol']},"
|
f"{self._data['chain']},{self._data['action']},{self._data['protocol']},"
|
||||||
f"{self._data['src-address']}:{self._data['src-port']}-"
|
f"{self._data['src-address']}:{self._data['src-port']}-"
|
||||||
f"{self._data['dst-address']}:{self._data['dst-port']}"
|
f"{self._data['dst-address']}:{self._data['dst-port']},"
|
||||||
|
f"{self._data['src-address-list']}-{self._data['dst-address-list']}"
|
||||||
):
|
):
|
||||||
value = self._ctrl.data["mangle"][uid][".id"]
|
value = self._ctrl.data["mangle"][uid][".id"]
|
||||||
|
|
||||||
|
@ -637,7 +638,8 @@ class MikrotikControllerMangleSwitch(MikrotikControllerSwitch):
|
||||||
if self._ctrl.data["mangle"][uid]["uniq-id"] == (
|
if self._ctrl.data["mangle"][uid]["uniq-id"] == (
|
||||||
f"{self._data['chain']},{self._data['action']},{self._data['protocol']},"
|
f"{self._data['chain']},{self._data['action']},{self._data['protocol']},"
|
||||||
f"{self._data['src-address']}:{self._data['src-port']}-"
|
f"{self._data['src-address']}:{self._data['src-port']}-"
|
||||||
f"{self._data['dst-address']}:{self._data['dst-port']}"
|
f"{self._data['dst-address']}:{self._data['dst-port']},"
|
||||||
|
f"{self._data['src-address-list']}-{self._data['dst-address-list']}"
|
||||||
):
|
):
|
||||||
value = self._ctrl.data["mangle"][uid][".id"]
|
value = self._ctrl.data["mangle"][uid][".id"]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue