mirror of
https://github.com/tomaae/homeassistant-mikrotik_router.git
synced 2025-07-22 03:34:23 +02:00
coordinator update
This commit is contained in:
parent
ce9ce906f5
commit
a21e95c36a
14 changed files with 445 additions and 496 deletions
|
@ -1,80 +1,62 @@
|
||||||
"""Mikrotik Router integration."""
|
"""Mikrotik Router integration."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.helpers import device_registry
|
from homeassistant.helpers import device_registry
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
PLATFORMS,
|
PLATFORMS,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
RUN_SCRIPT_COMMAND,
|
RUN_SCRIPT_COMMAND,
|
||||||
)
|
)
|
||||||
from .mikrotik_controller import MikrotikControllerData
|
from .coordinator import MikrotikCoordinator
|
||||||
|
|
||||||
SCRIPT_SCHEMA = vol.Schema(
|
SCRIPT_SCHEMA = vol.Schema(
|
||||||
{vol.Required("router"): cv.string, vol.Required("script"): cv.string}
|
{vol.Required("router"): cv.string, vol.Required("script"): cv.string}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
|
||||||
# async_setup
|
|
||||||
# ---------------------------
|
|
||||||
async def async_setup(hass, _config):
|
|
||||||
"""Set up configured Mikrotik Controller."""
|
|
||||||
hass.data[DOMAIN] = {}
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
|
||||||
# update_listener
|
|
||||||
# ---------------------------
|
|
||||||
async def update_listener(hass, config_entry) -> None:
|
|
||||||
"""Handle options update."""
|
|
||||||
await hass.config_entries.async_reload(config_entry.entry_id)
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# async_setup_entry
|
# async_setup_entry
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
async def async_setup_entry(hass, config_entry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||||
"""Set up Mikrotik Router as config entry."""
|
"""Set up a config entry."""
|
||||||
controller = MikrotikControllerData(hass, config_entry)
|
coordinator = MikrotikCoordinator(hass, config_entry)
|
||||||
await controller.async_hwinfo_update()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
if not controller.connected():
|
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = coordinator
|
||||||
raise ConfigEntryNotReady("Cannot connect to host")
|
|
||||||
|
|
||||||
await controller.async_update()
|
|
||||||
|
|
||||||
if not controller.data:
|
|
||||||
raise ConfigEntryNotReady()
|
|
||||||
|
|
||||||
await controller.async_init()
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id] = controller
|
|
||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
||||||
config_entry.async_on_unload(config_entry.add_update_listener(update_listener))
|
|
||||||
|
config_entry.async_on_unload(config_entry.add_update_listener(async_reload_entry))
|
||||||
|
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
DOMAIN, RUN_SCRIPT_COMMAND, controller.run_script, schema=SCRIPT_SCHEMA
|
DOMAIN, RUN_SCRIPT_COMMAND, coordinator.run_script, schema=SCRIPT_SCHEMA
|
||||||
)
|
)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# async_reload_entry
|
||||||
|
# ---------------------------
|
||||||
|
async def async_reload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
||||||
|
"""Reload the config entry when it changed."""
|
||||||
|
await hass.config_entries.async_reload(config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# async_unload_entry
|
# async_unload_entry
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
async def async_unload_entry(hass, config_entry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
unload_ok = await hass.config_entries.async_unload_platforms(
|
|
||||||
|
if unload_ok := await hass.config_entries.async_unload_platforms(
|
||||||
config_entry, PLATFORMS
|
config_entry, PLATFORMS
|
||||||
)
|
):
|
||||||
if unload_ok:
|
|
||||||
controller = hass.data[DOMAIN][config_entry.entry_id]
|
|
||||||
await controller.async_reset()
|
|
||||||
hass.services.async_remove(DOMAIN, RUN_SCRIPT_COMMAND)
|
hass.services.async_remove(DOMAIN, RUN_SCRIPT_COMMAND)
|
||||||
hass.data[DOMAIN].pop(config_entry.entry_id)
|
hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
"""API parser for JSON APIs"""
|
"""API parser for JSON APIs."""
|
||||||
from pytz import utc
|
|
||||||
from logging import getLogger
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from logging import getLogger
|
||||||
|
|
||||||
|
from pytz import utc
|
||||||
from voluptuous import Optional
|
from voluptuous import Optional
|
||||||
|
|
||||||
from homeassistant.components.diagnostics import async_redact_data
|
from homeassistant.components.diagnostics import async_redact_data
|
||||||
|
|
||||||
from .const import TO_REDACT
|
from .const import TO_REDACT
|
||||||
|
|
||||||
_LOGGER = getLogger(__name__)
|
_LOGGER = getLogger(__name__)
|
||||||
|
@ -13,7 +16,7 @@ _LOGGER = getLogger(__name__)
|
||||||
# utc_from_timestamp
|
# utc_from_timestamp
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def utc_from_timestamp(timestamp: float) -> datetime:
|
def utc_from_timestamp(timestamp: float) -> datetime:
|
||||||
"""Return a UTC time from a timestamp"""
|
"""Return a UTC time from a timestamp."""
|
||||||
return utc.localize(datetime.utcfromtimestamp(timestamp))
|
return utc.localize(datetime.utcfromtimestamp(timestamp))
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +24,7 @@ def utc_from_timestamp(timestamp: float) -> datetime:
|
||||||
# from_entry
|
# from_entry
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def from_entry(entry, param, default="") -> str:
|
def from_entry(entry, param, default="") -> str:
|
||||||
"""Validate and return str value an API dict"""
|
"""Validate and return str value an API dict."""
|
||||||
if "/" in param:
|
if "/" in param:
|
||||||
for tmp_param in param.split("/"):
|
for tmp_param in param.split("/"):
|
||||||
if isinstance(entry, dict) and tmp_param in entry:
|
if isinstance(entry, dict) and tmp_param in entry:
|
||||||
|
@ -50,7 +53,7 @@ def from_entry(entry, param, default="") -> str:
|
||||||
# from_entry_bool
|
# from_entry_bool
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def from_entry_bool(entry, param, default=False, reverse=False) -> bool:
|
def from_entry_bool(entry, param, default=False, reverse=False) -> bool:
|
||||||
"""Validate and return a bool value from an API dict"""
|
"""Validate and return a bool value from an API dict."""
|
||||||
if "/" in param:
|
if "/" in param:
|
||||||
for tmp_param in param.split("/"):
|
for tmp_param in param.split("/"):
|
||||||
if isinstance(entry, dict) and tmp_param in entry:
|
if isinstance(entry, dict) and tmp_param in entry:
|
||||||
|
@ -91,8 +94,11 @@ def parse_api(
|
||||||
only=None,
|
only=None,
|
||||||
skip=None,
|
skip=None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Get data from API"""
|
"""Get data from API."""
|
||||||
debug = _LOGGER.getEffectiveLevel() == 10
|
debug = _LOGGER.getEffectiveLevel() == 10
|
||||||
|
if type(source) == dict:
|
||||||
|
tmp = source
|
||||||
|
source = [tmp]
|
||||||
|
|
||||||
if not source:
|
if not source:
|
||||||
if not key and not key_search:
|
if not key and not key_search:
|
||||||
|
@ -138,7 +144,7 @@ def parse_api(
|
||||||
# get_uid
|
# get_uid
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_uid(entry, key, key_secondary, key_search, keymap) -> Optional(str):
|
def get_uid(entry, key, key_secondary, key_search, keymap) -> Optional(str):
|
||||||
"""Get UID for data list"""
|
"""Get UID for data list."""
|
||||||
uid = None
|
uid = None
|
||||||
if not key_search:
|
if not key_search:
|
||||||
key_primary_found = key in entry
|
key_primary_found = key in entry
|
||||||
|
@ -167,7 +173,7 @@ def get_uid(entry, key, key_secondary, key_search, keymap) -> Optional(str):
|
||||||
# generate_keymap
|
# generate_keymap
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def generate_keymap(data, key_search) -> Optional(dict):
|
def generate_keymap(data, key_search) -> Optional(dict):
|
||||||
"""Generate keymap"""
|
"""Generate keymap."""
|
||||||
return (
|
return (
|
||||||
{data[uid][key_search]: uid for uid in data if key_search in data[uid]}
|
{data[uid][key_search]: uid for uid in data if key_search in data[uid]}
|
||||||
if key_search
|
if key_search
|
||||||
|
@ -179,7 +185,7 @@ def generate_keymap(data, key_search) -> Optional(dict):
|
||||||
# matches_only
|
# matches_only
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def matches_only(entry, only) -> bool:
|
def matches_only(entry, only) -> bool:
|
||||||
"""Return True if all variables are matched"""
|
"""Return True if all variables are matched."""
|
||||||
ret = False
|
ret = False
|
||||||
for val in only:
|
for val in only:
|
||||||
if val["key"] in entry and entry[val["key"]] == val["value"]:
|
if val["key"] in entry and entry[val["key"]] == val["value"]:
|
||||||
|
@ -195,7 +201,7 @@ def matches_only(entry, only) -> bool:
|
||||||
# can_skip
|
# can_skip
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def can_skip(entry, skip) -> bool:
|
def can_skip(entry, skip) -> bool:
|
||||||
"""Return True if at least one variable matches"""
|
"""Return True if at least one variable matches."""
|
||||||
ret = False
|
ret = False
|
||||||
for val in skip:
|
for val in skip:
|
||||||
if val["name"] in entry and entry[val["name"]] == val["value"]:
|
if val["name"] in entry and entry[val["name"]] == val["value"]:
|
||||||
|
@ -213,7 +219,7 @@ def can_skip(entry, skip) -> bool:
|
||||||
# fill_defaults
|
# fill_defaults
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def fill_defaults(data, vals) -> dict:
|
def fill_defaults(data, vals) -> dict:
|
||||||
"""Fill defaults if source is not present"""
|
"""Fill defaults if source is not present."""
|
||||||
for val in vals:
|
for val in vals:
|
||||||
_name = val["name"]
|
_name = val["name"]
|
||||||
_type = val["type"] if "type" in val else "str"
|
_type = val["type"] if "type" in val else "str"
|
||||||
|
@ -242,7 +248,7 @@ def fill_defaults(data, vals) -> dict:
|
||||||
# fill_vals
|
# fill_vals
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def fill_vals(data, entry, uid, vals) -> dict:
|
def fill_vals(data, entry, uid, vals) -> dict:
|
||||||
"""Fill all data"""
|
"""Fill all data."""
|
||||||
for val in vals:
|
for val in vals:
|
||||||
_name = val["name"]
|
_name = val["name"]
|
||||||
_type = val["type"] if "type" in val else "str"
|
_type = val["type"] if "type" in val else "str"
|
||||||
|
@ -292,7 +298,7 @@ def fill_vals(data, entry, uid, vals) -> dict:
|
||||||
# fill_ensure_vals
|
# fill_ensure_vals
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def fill_ensure_vals(data, uid, ensure_vals) -> dict:
|
def fill_ensure_vals(data, uid, ensure_vals) -> dict:
|
||||||
"""Add required keys which are not available in data"""
|
"""Add required keys which are not available in data."""
|
||||||
for val in ensure_vals:
|
for val in ensure_vals:
|
||||||
if uid:
|
if uid:
|
||||||
if val["name"] not in data[uid]:
|
if val["name"] not in data[uid]:
|
||||||
|
@ -310,7 +316,7 @@ def fill_ensure_vals(data, uid, ensure_vals) -> dict:
|
||||||
# fill_vals_proc
|
# fill_vals_proc
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def fill_vals_proc(data, uid, vals_proc) -> dict:
|
def fill_vals_proc(data, uid, vals_proc) -> dict:
|
||||||
"""Add custom keys"""
|
"""Add custom keys."""
|
||||||
_data = data[uid] if uid else data
|
_data = data[uid] if uid else data
|
||||||
for val_sub in vals_proc:
|
for val_sub in vals_proc:
|
||||||
_name = None
|
_name = None
|
||||||
|
|
|
@ -13,7 +13,7 @@ from .const import (
|
||||||
CONF_SENSOR_PORT_TRACKER,
|
CONF_SENSOR_PORT_TRACKER,
|
||||||
DEFAULT_SENSOR_PORT_TRACKER,
|
DEFAULT_SENSOR_PORT_TRACKER,
|
||||||
)
|
)
|
||||||
from .model import model_async_setup_entry, MikrotikEntity
|
from .entity import model_async_setup_entry, MikrotikEntity
|
||||||
from .binary_sensor_types import (
|
from .binary_sensor_types import (
|
||||||
SENSOR_TYPES,
|
SENSOR_TYPES,
|
||||||
SENSOR_SERVICES,
|
SENSOR_SERVICES,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from homeassistant.components.button import ButtonEntity
|
from homeassistant.components.button import ButtonEntity
|
||||||
from .model import model_async_setup_entry, MikrotikEntity
|
from .entity import model_async_setup_entry, MikrotikEntity
|
||||||
from .button_types import (
|
from .button_types import (
|
||||||
SENSOR_TYPES,
|
SENSOR_TYPES,
|
||||||
SENSOR_SERVICES,
|
SENSOR_SERVICES,
|
||||||
|
|
|
@ -12,7 +12,6 @@ from homeassistant.const import (
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_PORT,
|
CONF_PORT,
|
||||||
CONF_UNIT_OF_MEASUREMENT,
|
|
||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
CONF_PASSWORD,
|
CONF_PASSWORD,
|
||||||
CONF_SSL,
|
CONF_SSL,
|
||||||
|
@ -55,8 +54,6 @@ from .const import (
|
||||||
DEFAULT_SENSOR_ENVIRONMENT,
|
DEFAULT_SENSOR_ENVIRONMENT,
|
||||||
CONF_TRACK_HOSTS_TIMEOUT,
|
CONF_TRACK_HOSTS_TIMEOUT,
|
||||||
DEFAULT_TRACK_HOST_TIMEOUT,
|
DEFAULT_TRACK_HOST_TIMEOUT,
|
||||||
LIST_UNIT_OF_MEASUREMENT,
|
|
||||||
DEFAULT_UNIT_OF_MEASUREMENT,
|
|
||||||
DEFAULT_HOST,
|
DEFAULT_HOST,
|
||||||
DEFAULT_USERNAME,
|
DEFAULT_USERNAME,
|
||||||
DEFAULT_PORT,
|
DEFAULT_PORT,
|
||||||
|
@ -193,12 +190,6 @@ class MikrotikControllerOptionsFlowHandler(OptionsFlow):
|
||||||
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
|
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
|
||||||
),
|
),
|
||||||
): int,
|
): int,
|
||||||
vol.Optional(
|
|
||||||
CONF_UNIT_OF_MEASUREMENT,
|
|
||||||
default=self.config_entry.options.get(
|
|
||||||
CONF_UNIT_OF_MEASUREMENT, DEFAULT_UNIT_OF_MEASUREMENT
|
|
||||||
),
|
|
||||||
): vol.In(LIST_UNIT_OF_MEASUREMENT),
|
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
CONF_TRACK_IFACE_CLIENTS,
|
CONF_TRACK_IFACE_CLIENTS,
|
||||||
default=self.config_entry.options.get(
|
default=self.config_entry.options.get(
|
||||||
|
|
|
@ -3,11 +3,11 @@ from homeassistant.const import Platform
|
||||||
|
|
||||||
PLATFORMS = [
|
PLATFORMS = [
|
||||||
Platform.SENSOR,
|
Platform.SENSOR,
|
||||||
Platform.BINARY_SENSOR,
|
# Platform.BINARY_SENSOR,
|
||||||
Platform.DEVICE_TRACKER,
|
# Platform.DEVICE_TRACKER,
|
||||||
Platform.SWITCH,
|
# Platform.SWITCH,
|
||||||
Platform.BUTTON,
|
# Platform.BUTTON,
|
||||||
Platform.UPDATE,
|
# Platform.UPDATE,
|
||||||
]
|
]
|
||||||
|
|
||||||
DOMAIN = "mikrotik_router"
|
DOMAIN = "mikrotik_router"
|
||||||
|
@ -27,8 +27,6 @@ DEFAULT_SSL = False
|
||||||
|
|
||||||
CONF_SCAN_INTERVAL = "scan_interval"
|
CONF_SCAN_INTERVAL = "scan_interval"
|
||||||
DEFAULT_SCAN_INTERVAL = 30
|
DEFAULT_SCAN_INTERVAL = 30
|
||||||
LIST_UNIT_OF_MEASUREMENT = ["bps", "Kbps", "Mbps", "B/s", "KB/s", "MB/s"]
|
|
||||||
DEFAULT_UNIT_OF_MEASUREMENT = "Kbps"
|
|
||||||
CONF_TRACK_IFACE_CLIENTS = "track_iface_clients"
|
CONF_TRACK_IFACE_CLIENTS = "track_iface_clients"
|
||||||
DEFAULT_TRACK_IFACE_CLIENTS = True
|
DEFAULT_TRACK_IFACE_CLIENTS = True
|
||||||
CONF_TRACK_HOSTS = "track_network_hosts"
|
CONF_TRACK_HOSTS = "track_network_hosts"
|
||||||
|
|
|
@ -1,26 +1,31 @@
|
||||||
"""Mikrotik Controller for Mikrotik Router."""
|
"""Mikrotik coordinator."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import pytz
|
import pytz
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from ipaddress import ip_address, IPv4Network
|
from ipaddress import ip_address, IPv4Network
|
||||||
from mac_vendor_lookup import AsyncMacLookup
|
from mac_vendor_lookup import AsyncMacLookup
|
||||||
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers import entity_registry
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from homeassistant.helpers.event import async_track_time_interval
|
from homeassistant.helpers.event import async_track_time_interval
|
||||||
from homeassistant.helpers import entity_registry
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
from homeassistant.util.dt import utcnow
|
from homeassistant.util.dt import utcnow
|
||||||
|
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_PORT,
|
CONF_PORT,
|
||||||
CONF_UNIT_OF_MEASUREMENT,
|
|
||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
CONF_PASSWORD,
|
CONF_PASSWORD,
|
||||||
CONF_SSL,
|
CONF_SSL,
|
||||||
|
@ -36,7 +41,6 @@ from .const import (
|
||||||
DEFAULT_TRACK_HOSTS,
|
DEFAULT_TRACK_HOSTS,
|
||||||
CONF_SCAN_INTERVAL,
|
CONF_SCAN_INTERVAL,
|
||||||
DEFAULT_SCAN_INTERVAL,
|
DEFAULT_SCAN_INTERVAL,
|
||||||
DEFAULT_UNIT_OF_MEASUREMENT,
|
|
||||||
CONF_SENSOR_PORT_TRAFFIC,
|
CONF_SENSOR_PORT_TRAFFIC,
|
||||||
DEFAULT_SENSOR_PORT_TRAFFIC,
|
DEFAULT_SENSOR_PORT_TRAFFIC,
|
||||||
CONF_SENSOR_CLIENT_TRAFFIC,
|
CONF_SENSOR_CLIENT_TRAFFIC,
|
||||||
|
@ -95,13 +99,21 @@ def as_local(dattim: datetime) -> datetime:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# MikrotikControllerData
|
# MikrotikControllerData
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
class MikrotikControllerData:
|
class MikrotikCoordinator(DataUpdateCoordinator):
|
||||||
"""MikrotikController Class"""
|
"""MikrotikCoordinator Class"""
|
||||||
|
|
||||||
def __init__(self, hass, config_entry):
|
def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry):
|
||||||
"""Initialize MikrotikController."""
|
"""Initialize MikrotikCoordinator."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self.config_entry = config_entry
|
self.config_entry: ConfigEntry = config_entry
|
||||||
|
super().__init__(
|
||||||
|
self.hass,
|
||||||
|
_LOGGER,
|
||||||
|
name=DOMAIN,
|
||||||
|
update_interval=timedelta(
|
||||||
|
seconds=10
|
||||||
|
), # update_interval=self.option_scan_interval
|
||||||
|
)
|
||||||
self.name = config_entry.data[CONF_NAME]
|
self.name = config_entry.data[CONF_NAME]
|
||||||
self.host = config_entry.data[CONF_HOST]
|
self.host = config_entry.data[CONF_HOST]
|
||||||
|
|
||||||
|
@ -143,7 +155,7 @@ class MikrotikControllerData:
|
||||||
|
|
||||||
self.notified_flags = []
|
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()
|
||||||
|
|
||||||
|
@ -185,22 +197,32 @@ class MikrotikControllerData:
|
||||||
self.async_mac_lookup = AsyncMacLookup()
|
self.async_mac_lookup = AsyncMacLookup()
|
||||||
self.accessrights_reported = False
|
self.accessrights_reported = False
|
||||||
|
|
||||||
async def async_init(self):
|
# self.listeners.append(
|
||||||
self.listeners.append(
|
# async_track_time_interval(
|
||||||
async_track_time_interval(
|
# self.hass, self.force_fwupdate_check, timedelta(hours=4)
|
||||||
self.hass, self.force_update, self.option_scan_interval
|
# )
|
||||||
)
|
# )
|
||||||
)
|
# self.listeners.append(
|
||||||
self.listeners.append(
|
# async_track_time_interval(
|
||||||
async_track_time_interval(
|
# self.hass, self.async_ping_tracked_hosts, timedelta(seconds=15)
|
||||||
self.hass, self.force_fwupdate_check, timedelta(hours=4)
|
# )
|
||||||
)
|
# )
|
||||||
)
|
|
||||||
self.listeners.append(
|
# ---------------------------
|
||||||
async_track_time_interval(
|
# async_init
|
||||||
self.hass, self.async_ping_tracked_hosts, timedelta(seconds=15)
|
# ---------------------------
|
||||||
)
|
# async def async_init(self):
|
||||||
)
|
# print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||||
|
# self.listeners.append(
|
||||||
|
# async_track_time_interval(
|
||||||
|
# self.hass, self.force_fwupdate_check, timedelta(hours=4)
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# self.listeners.append(
|
||||||
|
# async_track_time_interval(
|
||||||
|
# self.hass, self.async_ping_tracked_hosts, timedelta(seconds=15)
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# option_track_iface_clients
|
# option_track_iface_clients
|
||||||
|
@ -333,16 +355,6 @@ class MikrotikControllerData:
|
||||||
)
|
)
|
||||||
return timedelta(seconds=scan_interval)
|
return timedelta(seconds=scan_interval)
|
||||||
|
|
||||||
# ---------------------------
|
|
||||||
# option_unit_of_measurement
|
|
||||||
# ---------------------------
|
|
||||||
@property
|
|
||||||
def option_unit_of_measurement(self):
|
|
||||||
"""Config entry option to not track ARP."""
|
|
||||||
return self.config_entry.options.get(
|
|
||||||
CONF_UNIT_OF_MEASUREMENT, DEFAULT_UNIT_OF_MEASUREMENT
|
|
||||||
)
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# option_zone
|
# option_zone
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
|
@ -351,25 +363,6 @@ class MikrotikControllerData:
|
||||||
"""Config entry option zones."""
|
"""Config entry option zones."""
|
||||||
return self.config_entry.options.get(CONF_ZONE, STATE_HOME)
|
return self.config_entry.options.get(CONF_ZONE, STATE_HOME)
|
||||||
|
|
||||||
# ---------------------------
|
|
||||||
# signal_update
|
|
||||||
# ---------------------------
|
|
||||||
@property
|
|
||||||
def signal_update(self):
|
|
||||||
"""Event to signal new data."""
|
|
||||||
return f"{DOMAIN}-update-{self.name}"
|
|
||||||
|
|
||||||
# ---------------------------
|
|
||||||
# async_reset
|
|
||||||
# ---------------------------
|
|
||||||
async def async_reset(self):
|
|
||||||
"""Reset dispatchers"""
|
|
||||||
for unsub_dispatcher in self.listeners:
|
|
||||||
unsub_dispatcher()
|
|
||||||
|
|
||||||
self.listeners = []
|
|
||||||
return True
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# connected
|
# connected
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
|
@ -490,8 +483,8 @@ class MikrotikControllerData:
|
||||||
"""Update Mikrotik hardware info"""
|
"""Update Mikrotik hardware info"""
|
||||||
try:
|
try:
|
||||||
await asyncio.wait_for(self.lock.acquire(), timeout=30)
|
await asyncio.wait_for(self.lock.acquire(), timeout=30)
|
||||||
except Exception:
|
except Exception as error:
|
||||||
return
|
raise UpdateFailed(error) from error
|
||||||
|
|
||||||
await self.hass.async_add_executor_job(self.get_access)
|
await self.hass.async_add_executor_job(self.get_access)
|
||||||
|
|
||||||
|
@ -532,7 +525,6 @@ class MikrotikControllerData:
|
||||||
async def async_fwupdate_check(self):
|
async def async_fwupdate_check(self):
|
||||||
"""Update Mikrotik data"""
|
"""Update Mikrotik data"""
|
||||||
await self.hass.async_add_executor_job(self.get_firmware_update)
|
await self.hass.async_add_executor_job(self.get_firmware_update)
|
||||||
async_dispatcher_send(self.hass, self.signal_update)
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# async_ping_tracked_hosts
|
# async_ping_tracked_hosts
|
||||||
|
@ -596,25 +588,20 @@ class MikrotikControllerData:
|
||||||
self.lock_ping.release()
|
self.lock_ping.release()
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# force_update
|
# _async_update_data
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
@callback
|
async def _async_update_data(self):
|
||||||
async def force_update(self, _now=None):
|
|
||||||
"""Trigger update by timer"""
|
|
||||||
await self.async_update()
|
|
||||||
|
|
||||||
# ---------------------------
|
|
||||||
# async_update
|
|
||||||
# ---------------------------
|
|
||||||
async def async_update(self):
|
|
||||||
"""Update Mikrotik data"""
|
"""Update Mikrotik data"""
|
||||||
|
print(
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
)
|
||||||
if self.api.has_reconnected():
|
if self.api.has_reconnected():
|
||||||
await self.async_hwinfo_update()
|
await self.async_hwinfo_update()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await asyncio.wait_for(self.lock.acquire(), timeout=10)
|
await asyncio.wait_for(self.lock.acquire(), timeout=10)
|
||||||
except Exception:
|
except Exception as error:
|
||||||
return
|
raise UpdateFailed(error) from error
|
||||||
|
|
||||||
await self.hass.async_add_executor_job(self.get_system_resource)
|
await self.hass.async_add_executor_job(self.get_system_resource)
|
||||||
|
|
||||||
|
@ -693,13 +680,14 @@ class MikrotikControllerData:
|
||||||
if self.api.connected() and self.support_gps:
|
if self.api.connected() and self.support_gps:
|
||||||
await self.hass.async_add_executor_job(self.get_gps)
|
await self.hass.async_add_executor_job(self.get_gps)
|
||||||
|
|
||||||
async_dispatcher_send(self.hass, self.signal_update)
|
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
# async_dispatcher_send(self.hass, "update_sensors", self)
|
||||||
|
return self.data
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_access
|
# get_access
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_access(self):
|
def get_access(self) -> None:
|
||||||
"""Get access rights from Mikrotik"""
|
"""Get access rights from Mikrotik"""
|
||||||
tmp_user = parse_api(
|
tmp_user = parse_api(
|
||||||
data={},
|
data={},
|
||||||
|
@ -742,7 +730,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_interface
|
# get_interface
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_interface(self):
|
def get_interface(self) -> None:
|
||||||
"""Get all interfaces data from Mikrotik"""
|
"""Get all interfaces data from Mikrotik"""
|
||||||
self.data["interface"] = parse_api(
|
self.data["interface"] = parse_api(
|
||||||
data=self.data["interface"],
|
data=self.data["interface"],
|
||||||
|
@ -794,30 +782,22 @@ class MikrotikControllerData:
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.option_sensor_port_traffic:
|
if self.option_sensor_port_traffic:
|
||||||
uom_type, uom_div = self._get_unit_of_measurement()
|
|
||||||
for uid, vals in self.data["interface"].items():
|
for uid, vals in self.data["interface"].items():
|
||||||
self.data["interface"][uid]["rx-attr"] = uom_type
|
|
||||||
self.data["interface"][uid]["tx-attr"] = uom_type
|
|
||||||
|
|
||||||
current_tx = vals["tx-current"]
|
current_tx = vals["tx-current"]
|
||||||
previous_tx = vals["tx-previous"]
|
previous_tx = vals["tx-previous"] or current_tx
|
||||||
if not previous_tx:
|
|
||||||
previous_tx = current_tx
|
|
||||||
|
|
||||||
delta_tx = max(0, current_tx - previous_tx) * 8
|
delta_tx = max(0, current_tx - previous_tx)
|
||||||
self.data["interface"][uid]["tx"] = round(
|
self.data["interface"][uid]["tx"] = round(
|
||||||
delta_tx / self.option_scan_interval.seconds * uom_div, 2
|
delta_tx / self.option_scan_interval.seconds
|
||||||
)
|
)
|
||||||
self.data["interface"][uid]["tx-previous"] = current_tx
|
self.data["interface"][uid]["tx-previous"] = current_tx
|
||||||
|
|
||||||
current_rx = vals["rx-current"]
|
current_rx = vals["rx-current"]
|
||||||
previous_rx = vals["rx-previous"]
|
previous_rx = vals["rx-previous"] or current_rx
|
||||||
if not previous_rx:
|
|
||||||
previous_rx = current_rx
|
|
||||||
|
|
||||||
delta_rx = max(0, current_rx - previous_rx) * 8
|
delta_rx = max(0, current_rx - previous_rx)
|
||||||
self.data["interface"][uid]["rx"] = round(
|
self.data["interface"][uid]["rx"] = round(
|
||||||
delta_rx / self.option_scan_interval.seconds * uom_div, 2
|
delta_rx / self.option_scan_interval.seconds
|
||||||
)
|
)
|
||||||
self.data["interface"][uid]["rx-previous"] = current_rx
|
self.data["interface"][uid]["rx-previous"] = current_rx
|
||||||
|
|
||||||
|
@ -914,7 +894,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_bridge
|
# get_bridge
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_bridge(self):
|
def get_bridge(self) -> None:
|
||||||
"""Get system resources data from Mikrotik"""
|
"""Get system resources data from Mikrotik"""
|
||||||
self.data["bridge_host"] = parse_api(
|
self.data["bridge_host"] = parse_api(
|
||||||
data=self.data["bridge_host"],
|
data=self.data["bridge_host"],
|
||||||
|
@ -940,7 +920,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# process_interface_client
|
# process_interface_client
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def process_interface_client(self):
|
def process_interface_client(self) -> None:
|
||||||
# Remove data if disabled
|
# Remove data if disabled
|
||||||
if not self.option_track_iface_clients:
|
if not self.option_track_iface_clients:
|
||||||
for uid in self.data["interface"]:
|
for uid in self.data["interface"]:
|
||||||
|
@ -978,7 +958,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_nat
|
# get_nat
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_nat(self):
|
def get_nat(self) -> None:
|
||||||
"""Get NAT data from Mikrotik"""
|
"""Get NAT data from Mikrotik"""
|
||||||
self.data["nat"] = parse_api(
|
self.data["nat"] = parse_api(
|
||||||
data=self.data["nat"],
|
data=self.data["nat"],
|
||||||
|
@ -1060,7 +1040,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_mangle
|
# get_mangle
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_mangle(self):
|
def get_mangle(self) -> None:
|
||||||
"""Get Mangle data from Mikrotik"""
|
"""Get Mangle data from Mikrotik"""
|
||||||
self.data["mangle"] = parse_api(
|
self.data["mangle"] = parse_api(
|
||||||
data=self.data["mangle"],
|
data=self.data["mangle"],
|
||||||
|
@ -1154,7 +1134,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_filter
|
# get_filter
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_filter(self):
|
def get_filter(self) -> None:
|
||||||
"""Get Filter data from Mikrotik"""
|
"""Get Filter data from Mikrotik"""
|
||||||
self.data["filter"] = parse_api(
|
self.data["filter"] = parse_api(
|
||||||
data=self.data["filter"],
|
data=self.data["filter"],
|
||||||
|
@ -1266,7 +1246,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_kidcontrol
|
# get_kidcontrol
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_kidcontrol(self):
|
def get_kidcontrol(self) -> None:
|
||||||
"""Get Kid-control data from Mikrotik"""
|
"""Get Kid-control data from Mikrotik"""
|
||||||
self.data["kid-control"] = parse_api(
|
self.data["kid-control"] = parse_api(
|
||||||
data=self.data["kid-control"],
|
data=self.data["kid-control"],
|
||||||
|
@ -1302,7 +1282,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_ppp
|
# get_ppp
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_ppp(self):
|
def get_ppp(self) -> None:
|
||||||
"""Get PPP data from Mikrotik"""
|
"""Get PPP data from Mikrotik"""
|
||||||
self.data["ppp_secret"] = parse_api(
|
self.data["ppp_secret"] = parse_api(
|
||||||
data=self.data["ppp_secret"],
|
data=self.data["ppp_secret"],
|
||||||
|
@ -1366,7 +1346,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_system_routerboard
|
# get_system_routerboard
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_system_routerboard(self):
|
def get_system_routerboard(self) -> None:
|
||||||
"""Get routerboard data from Mikrotik"""
|
"""Get routerboard data from Mikrotik"""
|
||||||
if self.data["resource"]["board-name"] in ("x86", "CHR"):
|
if self.data["resource"]["board-name"] in ("x86", "CHR"):
|
||||||
self.data["routerboard"]["routerboard"] = False
|
self.data["routerboard"]["routerboard"] = False
|
||||||
|
@ -1396,7 +1376,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_system_health
|
# get_system_health
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_system_health(self):
|
def get_system_health(self) -> None:
|
||||||
"""Get routerboard data from Mikrotik"""
|
"""Get routerboard data from Mikrotik"""
|
||||||
if (
|
if (
|
||||||
"write" not in self.data["access"]
|
"write" not in self.data["access"]
|
||||||
|
@ -1434,7 +1414,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_system_resource
|
# get_system_resource
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_system_resource(self):
|
def get_system_resource(self) -> None:
|
||||||
"""Get system resources data from Mikrotik"""
|
"""Get system resources data from Mikrotik"""
|
||||||
tmp_rebootcheck = 0
|
tmp_rebootcheck = 0
|
||||||
if "uptime_epoch" in self.data["resource"]:
|
if "uptime_epoch" in self.data["resource"]:
|
||||||
|
@ -1487,16 +1467,12 @@ class MikrotikControllerData:
|
||||||
if not self.data["resource"]["uptime"]:
|
if not self.data["resource"]["uptime"]:
|
||||||
update_uptime = True
|
update_uptime = True
|
||||||
else:
|
else:
|
||||||
uptime_old = datetime.timestamp(
|
uptime_old = datetime.timestamp(self.data["resource"]["uptime"])
|
||||||
datetime.fromisoformat(self.data["resource"]["uptime"])
|
|
||||||
)
|
|
||||||
if uptime_tm > uptime_old + 10:
|
if uptime_tm > uptime_old + 10:
|
||||||
update_uptime = True
|
update_uptime = True
|
||||||
|
|
||||||
if update_uptime:
|
if update_uptime:
|
||||||
self.data["resource"]["uptime"] = str(
|
self.data["resource"]["uptime"] = utc_from_timestamp(uptime_tm)
|
||||||
as_local(utc_from_timestamp(uptime_tm)).isoformat()
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.data["resource"]["total-memory"] > 0:
|
if self.data["resource"]["total-memory"] > 0:
|
||||||
self.data["resource"]["memory-usage"] = round(
|
self.data["resource"]["memory-usage"] = round(
|
||||||
|
@ -1535,7 +1511,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_firmware_update
|
# get_firmware_update
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_firmware_update(self):
|
def get_firmware_update(self) -> None:
|
||||||
"""Check for firmware update on Mikrotik"""
|
"""Check for firmware update on Mikrotik"""
|
||||||
if (
|
if (
|
||||||
"write" not in self.data["access"]
|
"write" not in self.data["access"]
|
||||||
|
@ -1579,7 +1555,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_ups
|
# get_ups
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_ups(self):
|
def get_ups(self) -> None:
|
||||||
"""Get UPS info from Mikrotik"""
|
"""Get UPS info from Mikrotik"""
|
||||||
self.data["ups"] = parse_api(
|
self.data["ups"] = parse_api(
|
||||||
data=self.data["ups"],
|
data=self.data["ups"],
|
||||||
|
@ -1632,7 +1608,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_gps
|
# get_gps
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_gps(self):
|
def get_gps(self) -> None:
|
||||||
"""Get GPS data from Mikrotik"""
|
"""Get GPS data from Mikrotik"""
|
||||||
self.data["gps"] = parse_api(
|
self.data["gps"] = parse_api(
|
||||||
data=self.data["gps"],
|
data=self.data["gps"],
|
||||||
|
@ -1659,7 +1635,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_script
|
# get_script
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_script(self):
|
def get_script(self) -> None:
|
||||||
"""Get list of all scripts from Mikrotik"""
|
"""Get list of all scripts from Mikrotik"""
|
||||||
self.data["script"] = parse_api(
|
self.data["script"] = parse_api(
|
||||||
data=self.data["script"],
|
data=self.data["script"],
|
||||||
|
@ -1675,7 +1651,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_environment
|
# get_environment
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_environment(self):
|
def get_environment(self) -> None:
|
||||||
"""Get list of all environment variables from Mikrotik"""
|
"""Get list of all environment variables from Mikrotik"""
|
||||||
self.data["environment"] = parse_api(
|
self.data["environment"] = parse_api(
|
||||||
data=self.data["environment"],
|
data=self.data["environment"],
|
||||||
|
@ -1690,7 +1666,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_captive
|
# get_captive
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_captive(self):
|
def get_captive(self) -> None:
|
||||||
"""Get list of all environment variables from Mikrotik"""
|
"""Get list of all environment variables from Mikrotik"""
|
||||||
self.data["hostspot_host"] = parse_api(
|
self.data["hostspot_host"] = parse_api(
|
||||||
data={},
|
data={},
|
||||||
|
@ -1713,7 +1689,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_queue
|
# get_queue
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_queue(self):
|
def get_queue(self) -> None:
|
||||||
"""Get Queue data from Mikrotik"""
|
"""Get Queue data from Mikrotik"""
|
||||||
self.data["queue"] = parse_api(
|
self.data["queue"] = parse_api(
|
||||||
data=self.data["queue"],
|
data=self.data["queue"],
|
||||||
|
@ -1741,59 +1717,50 @@ class MikrotikControllerData:
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
uom_type, uom_div = self._get_unit_of_measurement()
|
|
||||||
for uid, vals in self.data["queue"].items():
|
for uid, vals in self.data["queue"].items():
|
||||||
self.data["queue"][uid]["comment"] = str(self.data["queue"][uid]["comment"])
|
self.data["queue"][uid]["comment"] = str(self.data["queue"][uid]["comment"])
|
||||||
|
|
||||||
upload_max_limit_bps, download_max_limit_bps = [
|
upload_max_limit_bps, download_max_limit_bps = [
|
||||||
int(x) for x in vals["max-limit"].split("/")
|
int(x) for x in vals["max-limit"].split("/")
|
||||||
]
|
]
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid]["upload-max-limit"] = f"{upload_max_limit_bps} bps"
|
||||||
"upload-max-limit"
|
|
||||||
] = f"{round(upload_max_limit_bps * uom_div)} {uom_type}"
|
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid][
|
||||||
"download-max-limit"
|
"download-max-limit"
|
||||||
] = f"{round(download_max_limit_bps * uom_div)} {uom_type}"
|
] = f"{download_max_limit_bps} bps"
|
||||||
|
|
||||||
upload_rate_bps, download_rate_bps = [
|
upload_rate_bps, download_rate_bps = [
|
||||||
int(x) for x in vals["rate"].split("/")
|
int(x) for x in vals["rate"].split("/")
|
||||||
]
|
]
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid]["upload-rate"] = f"{upload_rate_bps} bps"
|
||||||
"upload-rate"
|
self.data["queue"][uid]["download-rate"] = f"{download_rate_bps} bps"
|
||||||
] = f"{round(upload_rate_bps * uom_div)} {uom_type}"
|
|
||||||
self.data["queue"][uid][
|
|
||||||
"download-rate"
|
|
||||||
] = f"{round(download_rate_bps * uom_div)} {uom_type}"
|
|
||||||
|
|
||||||
upload_limit_at_bps, download_limit_at_bps = [
|
upload_limit_at_bps, download_limit_at_bps = [
|
||||||
int(x) for x in vals["limit-at"].split("/")
|
int(x) for x in vals["limit-at"].split("/")
|
||||||
]
|
]
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid]["upload-limit-at"] = f"{upload_limit_at_bps} bps"
|
||||||
"upload-limit-at"
|
|
||||||
] = f"{round(upload_limit_at_bps * uom_div)} {uom_type}"
|
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid][
|
||||||
"download-limit-at"
|
"download-limit-at"
|
||||||
] = f"{round(download_limit_at_bps * uom_div)} {uom_type}"
|
] = f"{download_limit_at_bps} bps"
|
||||||
|
|
||||||
upload_burst_limit_bps, download_burst_limit_bps = [
|
upload_burst_limit_bps, download_burst_limit_bps = [
|
||||||
int(x) for x in vals["burst-limit"].split("/")
|
int(x) for x in vals["burst-limit"].split("/")
|
||||||
]
|
]
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid][
|
||||||
"upload-burst-limit"
|
"upload-burst-limit"
|
||||||
] = f"{round(upload_burst_limit_bps * uom_div)} {uom_type}"
|
] = f"{upload_burst_limit_bps} bps"
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid][
|
||||||
"download-burst-limit"
|
"download-burst-limit"
|
||||||
] = f"{round(download_burst_limit_bps * uom_div)} {uom_type}"
|
] = f"{download_burst_limit_bps} bps"
|
||||||
|
|
||||||
upload_burst_threshold_bps, download_burst_threshold_bps = [
|
upload_burst_threshold_bps, download_burst_threshold_bps = [
|
||||||
int(x) for x in vals["burst-threshold"].split("/")
|
int(x) for x in vals["burst-threshold"].split("/")
|
||||||
]
|
]
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid][
|
||||||
"upload-burst-threshold"
|
"upload-burst-threshold"
|
||||||
] = f"{round(upload_burst_threshold_bps * uom_div)} {uom_type}"
|
] = f"{upload_burst_threshold_bps} bps"
|
||||||
self.data["queue"][uid][
|
self.data["queue"][uid][
|
||||||
"download-burst-threshold"
|
"download-burst-threshold"
|
||||||
] = f"{round(download_burst_threshold_bps * uom_div)} {uom_type}"
|
] = f"{download_burst_threshold_bps} bps"
|
||||||
|
|
||||||
upload_burst_time, download_burst_time = vals["burst-time"].split("/")
|
upload_burst_time, download_burst_time = vals["burst-time"].split("/")
|
||||||
self.data["queue"][uid]["upload-burst-time"] = upload_burst_time
|
self.data["queue"][uid]["upload-burst-time"] = upload_burst_time
|
||||||
|
@ -1802,7 +1769,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_arp
|
# get_arp
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_arp(self):
|
def get_arp(self) -> None:
|
||||||
"""Get ARP data from Mikrotik"""
|
"""Get ARP data from Mikrotik"""
|
||||||
self.data["arp"] = parse_api(
|
self.data["arp"] = parse_api(
|
||||||
data=self.data["arp"],
|
data=self.data["arp"],
|
||||||
|
@ -1835,7 +1802,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_dns
|
# get_dns
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_dns(self):
|
def get_dns(self) -> None:
|
||||||
"""Get static DNS data from Mikrotik"""
|
"""Get static DNS data from Mikrotik"""
|
||||||
self.data["dns"] = parse_api(
|
self.data["dns"] = parse_api(
|
||||||
data=self.data["dns"],
|
data=self.data["dns"],
|
||||||
|
@ -1850,7 +1817,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_dhcp
|
# get_dhcp
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_dhcp(self):
|
def get_dhcp(self) -> None:
|
||||||
"""Get DHCP data from Mikrotik"""
|
"""Get DHCP data from Mikrotik"""
|
||||||
self.data["dhcp"] = parse_api(
|
self.data["dhcp"] = parse_api(
|
||||||
data=self.data["dhcp"],
|
data=self.data["dhcp"],
|
||||||
|
@ -1926,7 +1893,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_dhcp_server
|
# get_dhcp_server
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_dhcp_server(self):
|
def get_dhcp_server(self) -> None:
|
||||||
"""Get DHCP server data from Mikrotik"""
|
"""Get DHCP server data from Mikrotik"""
|
||||||
self.data["dhcp-server"] = parse_api(
|
self.data["dhcp-server"] = parse_api(
|
||||||
data=self.data["dhcp-server"],
|
data=self.data["dhcp-server"],
|
||||||
|
@ -1941,7 +1908,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_dhcp_client
|
# get_dhcp_client
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_dhcp_client(self):
|
def get_dhcp_client(self) -> None:
|
||||||
"""Get DHCP client data from Mikrotik"""
|
"""Get DHCP client data from Mikrotik"""
|
||||||
self.data["dhcp-client"] = parse_api(
|
self.data["dhcp-client"] = parse_api(
|
||||||
data=self.data["dhcp-client"],
|
data=self.data["dhcp-client"],
|
||||||
|
@ -1956,7 +1923,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_dhcp_network
|
# get_dhcp_network
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_dhcp_network(self):
|
def get_dhcp_network(self) -> None:
|
||||||
"""Get DHCP network data from Mikrotik"""
|
"""Get DHCP network data from Mikrotik"""
|
||||||
self.data["dhcp-network"] = parse_api(
|
self.data["dhcp-network"] = parse_api(
|
||||||
data=self.data["dhcp-network"],
|
data=self.data["dhcp-network"],
|
||||||
|
@ -1981,7 +1948,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_capsman_hosts
|
# get_capsman_hosts
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_capsman_hosts(self):
|
def get_capsman_hosts(self) -> None:
|
||||||
"""Get CAPS-MAN hosts data from Mikrotik"""
|
"""Get CAPS-MAN hosts data from Mikrotik"""
|
||||||
self.data["capsman_hosts"] = parse_api(
|
self.data["capsman_hosts"] = parse_api(
|
||||||
data={},
|
data={},
|
||||||
|
@ -1997,7 +1964,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_wireless
|
# get_wireless
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_wireless(self):
|
def get_wireless(self) -> None:
|
||||||
"""Get wireless data from Mikrotik"""
|
"""Get wireless data from Mikrotik"""
|
||||||
wifimodule = "wifiwave2" if self.support_wifiwave2 else "wireless"
|
wifimodule = "wifiwave2" if self.support_wifiwave2 else "wireless"
|
||||||
self.data["wireless"] = parse_api(
|
self.data["wireless"] = parse_api(
|
||||||
|
@ -2047,7 +2014,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# get_wireless_hosts
|
# get_wireless_hosts
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def get_wireless_hosts(self):
|
def get_wireless_hosts(self) -> None:
|
||||||
"""Get wireless hosts data from Mikrotik"""
|
"""Get wireless hosts data from Mikrotik"""
|
||||||
wifimodule = "wifiwave2" if self.support_wifiwave2 else "wireless"
|
wifimodule = "wifiwave2" if self.support_wifiwave2 else "wireless"
|
||||||
self.data["wireless_hosts"] = parse_api(
|
self.data["wireless_hosts"] = parse_api(
|
||||||
|
@ -2065,7 +2032,7 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# async_process_host
|
# async_process_host
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
async def async_process_host(self):
|
async def async_process_host(self) -> None:
|
||||||
"""Get host tracking data"""
|
"""Get host tracking data"""
|
||||||
# Add hosts from CAPS-MAN
|
# Add hosts from CAPS-MAN
|
||||||
capsman_detected = {}
|
capsman_detected = {}
|
||||||
|
@ -2281,14 +2248,13 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# process_accounting
|
# process_accounting
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def process_accounting(self):
|
def process_accounting(self) -> None:
|
||||||
"""Get Accounting data from Mikrotik"""
|
"""Get Accounting data from Mikrotik"""
|
||||||
# Check if accounting and account-local-traffic is enabled
|
# Check if accounting and account-local-traffic is enabled
|
||||||
(
|
(
|
||||||
accounting_enabled,
|
accounting_enabled,
|
||||||
local_traffic_enabled,
|
local_traffic_enabled,
|
||||||
) = self.api.is_accounting_and_local_traffic_enabled()
|
) = self.api.is_accounting_and_local_traffic_enabled()
|
||||||
uom_type, uom_div = self._get_unit_of_measurement()
|
|
||||||
|
|
||||||
# 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():
|
||||||
|
@ -2297,7 +2263,6 @@ class MikrotikControllerData:
|
||||||
"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"],
|
||||||
"tx-rx-attr": uom_type,
|
|
||||||
"available": False,
|
"available": False,
|
||||||
"local_accounting": False,
|
"local_accounting": False,
|
||||||
}
|
}
|
||||||
|
@ -2351,7 +2316,7 @@ class MikrotikControllerData:
|
||||||
for item in accounting_data.values():
|
for item in accounting_data.values():
|
||||||
source_ip = str(item.get("src-address")).strip()
|
source_ip = str(item.get("src-address")).strip()
|
||||||
destination_ip = str(item.get("dst-address")).strip()
|
destination_ip = str(item.get("dst-address")).strip()
|
||||||
bits_count = int(str(item.get("bytes")).strip()) * 8
|
bits_count = int(str(item.get("bytes")).strip())
|
||||||
|
|
||||||
if self._address_part_of_local_network(
|
if self._address_part_of_local_network(
|
||||||
source_ip
|
source_ip
|
||||||
|
@ -2385,7 +2350,6 @@ class MikrotikControllerData:
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.data["client_traffic"][uid]["tx-rx-attr"] = uom_type
|
|
||||||
self.data["client_traffic"][uid]["available"] = accounting_enabled
|
self.data["client_traffic"][uid]["available"] = accounting_enabled
|
||||||
self.data["client_traffic"][uid]["local_accounting"] = local_traffic_enabled
|
self.data["client_traffic"][uid]["local_accounting"] = local_traffic_enabled
|
||||||
|
|
||||||
|
@ -2394,14 +2358,10 @@ class MikrotikControllerData:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.data["client_traffic"][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) if vals["wan-tx"] else 0.0
|
||||||
if vals["wan-tx"]
|
|
||||||
else 0.0
|
|
||||||
)
|
)
|
||||||
self.data["client_traffic"][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) if vals["wan-rx"] else 0.0
|
||||||
if vals["wan-rx"]
|
|
||||||
else 0.0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if not local_traffic_enabled:
|
if not local_traffic_enabled:
|
||||||
|
@ -2409,40 +2369,16 @@ class MikrotikControllerData:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.data["client_traffic"][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) if vals["lan-tx"] else 0.0
|
||||||
if vals["lan-tx"]
|
|
||||||
else 0.0
|
|
||||||
)
|
)
|
||||||
self.data["client_traffic"][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) if vals["lan-rx"] else 0.0
|
||||||
if vals["lan-rx"]
|
|
||||||
else 0.0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# ---------------------------
|
|
||||||
# _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
|
# _address_part_of_local_network
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def _address_part_of_local_network(self, address):
|
def _address_part_of_local_network(self, address) -> bool:
|
||||||
address = ip_address(address)
|
address = ip_address(address)
|
||||||
for vals in self.data["dhcp-network"].values():
|
for vals in self.data["dhcp-network"].values():
|
||||||
if address in vals["IPv4Network"]:
|
if address in vals["IPv4Network"]:
|
||||||
|
@ -2474,11 +2410,9 @@ class MikrotikControllerData:
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# process_kid_control
|
# process_kid_control
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
def process_kid_control_devices(self):
|
def process_kid_control_devices(self) -> None:
|
||||||
"""Get Kid Control Device data from Mikrotik"""
|
"""Get Kid Control Device data from Mikrotik"""
|
||||||
|
|
||||||
uom_type, uom_div = self._get_unit_of_measurement()
|
|
||||||
|
|
||||||
# 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["client_traffic"]:
|
if uid not in self.data["client_traffic"]:
|
||||||
|
@ -2490,7 +2424,6 @@ class MikrotikControllerData:
|
||||||
"previous-bytes-down": 0.0,
|
"previous-bytes-down": 0.0,
|
||||||
"tx": 0.0,
|
"tx": 0.0,
|
||||||
"rx": 0.0,
|
"rx": 0.0,
|
||||||
"tx-rx-attr": uom_type,
|
|
||||||
"available": False,
|
"available": False,
|
||||||
"local_accounting": False,
|
"local_accounting": False,
|
||||||
}
|
}
|
||||||
|
@ -2538,17 +2471,13 @@ class MikrotikControllerData:
|
||||||
current_tx = vals["bytes-up"]
|
current_tx = vals["bytes-up"]
|
||||||
previous_tx = self.data["client_traffic"][uid]["previous-bytes-up"]
|
previous_tx = self.data["client_traffic"][uid]["previous-bytes-up"]
|
||||||
if time_diff:
|
if time_diff:
|
||||||
delta_tx = max(0, current_tx - previous_tx) * 8
|
delta_tx = max(0, current_tx - previous_tx)
|
||||||
self.data["client_traffic"][uid]["tx"] = round(
|
self.data["client_traffic"][uid]["tx"] = round(delta_tx / time_diff)
|
||||||
delta_tx / time_diff * uom_div, 2
|
|
||||||
)
|
|
||||||
self.data["client_traffic"][uid]["previous-bytes-up"] = current_tx
|
self.data["client_traffic"][uid]["previous-bytes-up"] = current_tx
|
||||||
|
|
||||||
current_rx = vals["bytes-down"]
|
current_rx = vals["bytes-down"]
|
||||||
previous_rx = self.data["client_traffic"][uid]["previous-bytes-down"]
|
previous_rx = self.data["client_traffic"][uid]["previous-bytes-down"]
|
||||||
if time_diff:
|
if time_diff:
|
||||||
delta_rx = max(0, current_rx - previous_rx) * 8
|
delta_rx = max(0, current_rx - previous_rx)
|
||||||
self.data["client_traffic"][uid]["rx"] = round(
|
self.data["client_traffic"][uid]["rx"] = round(delta_rx / time_diff)
|
||||||
delta_rx / time_diff * uom_div, 2
|
|
||||||
)
|
|
||||||
self.data["client_traffic"][uid]["previous-bytes-down"] = current_rx
|
self.data["client_traffic"][uid]["previous-bytes-down"] = current_rx
|
|
@ -14,7 +14,7 @@ from .const import (
|
||||||
CONF_TRACK_HOSTS_TIMEOUT,
|
CONF_TRACK_HOSTS_TIMEOUT,
|
||||||
DEFAULT_TRACK_HOST_TIMEOUT,
|
DEFAULT_TRACK_HOST_TIMEOUT,
|
||||||
)
|
)
|
||||||
from .model import model_async_setup_entry, MikrotikEntity
|
from .entity import model_async_setup_entry, MikrotikEntity
|
||||||
from .device_tracker_types import SENSOR_TYPES, SENSOR_SERVICES
|
from .device_tracker_types import SENSOR_TYPES, SENSOR_SERVICES
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,13 +1,22 @@
|
||||||
"""Mikrotik HA shared entity model"""
|
"""Mikrotik HA shared entity model"""
|
||||||
from logging import getLogger
|
from __future__ import annotations
|
||||||
from typing import Any
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from homeassistant.helpers import entity_platform
|
from logging import getLogger
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from typing import Any, Callable
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import ATTR_ATTRIBUTION, CONF_NAME, CONF_HOST
|
from homeassistant.const import ATTR_ATTRIBUTION, CONF_NAME, CONF_HOST
|
||||||
from .helper import format_attribute
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers import (
|
||||||
|
entity_platform as ep,
|
||||||
|
entity_registry as er,
|
||||||
|
)
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||||
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
ATTRIBUTION,
|
ATTRIBUTION,
|
||||||
|
@ -18,14 +27,16 @@ from .const import (
|
||||||
CONF_SENSOR_PORT_TRACKER,
|
CONF_SENSOR_PORT_TRACKER,
|
||||||
DEFAULT_SENSOR_PORT_TRACKER,
|
DEFAULT_SENSOR_PORT_TRACKER,
|
||||||
)
|
)
|
||||||
|
from .coordinator import MikrotikCoordinator
|
||||||
|
from .helper import format_attribute
|
||||||
|
|
||||||
_LOGGER = getLogger(__name__)
|
_LOGGER = getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _skip_sensor(config_entry, uid_sensor, uid_data, uid) -> bool:
|
def _skip_sensor(config_entry, entity_description, data, uid) -> bool:
|
||||||
# Sensors
|
# Sensors
|
||||||
if (
|
if (
|
||||||
uid_sensor.func == "MikrotikInterfaceTrafficSensor"
|
entity_description.func == "MikrotikInterfaceTrafficSensor"
|
||||||
and not config_entry.options.get(
|
and not config_entry.options.get(
|
||||||
CONF_SENSOR_PORT_TRAFFIC, DEFAULT_SENSOR_PORT_TRAFFIC
|
CONF_SENSOR_PORT_TRAFFIC, DEFAULT_SENSOR_PORT_TRAFFIC
|
||||||
)
|
)
|
||||||
|
@ -33,33 +44,36 @@ def _skip_sensor(config_entry, uid_sensor, uid_data, uid) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if (
|
if (
|
||||||
uid_sensor.func == "MikrotikInterfaceTrafficSensor"
|
entity_description.func == "MikrotikInterfaceTrafficSensor"
|
||||||
and uid_data[uid]["type"] == "bridge"
|
and data[uid]["type"] == "bridge"
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if (
|
if (
|
||||||
uid_sensor.func == "MikrotikClientTrafficSensor"
|
entity_description.func == "MikrotikClientTrafficSensor"
|
||||||
and uid_sensor.data_attribute not in uid_data[uid].keys()
|
and entity_description.data_attribute not in data[uid].keys()
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Binary sensors
|
# Binary sensors
|
||||||
if (
|
if (
|
||||||
uid_sensor.func == "MikrotikPortBinarySensor"
|
entity_description.func == "MikrotikPortBinarySensor"
|
||||||
and uid_data[uid]["type"] == "wlan"
|
and data[uid]["type"] == "wlan"
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if uid_sensor.func == "MikrotikPortBinarySensor" and not config_entry.options.get(
|
if (
|
||||||
CONF_SENSOR_PORT_TRACKER, DEFAULT_SENSOR_PORT_TRACKER
|
entity_description.func == "MikrotikPortBinarySensor"
|
||||||
|
and not config_entry.options.get(
|
||||||
|
CONF_SENSOR_PORT_TRACKER, DEFAULT_SENSOR_PORT_TRACKER
|
||||||
|
)
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Device Tracker
|
# Device Tracker
|
||||||
if (
|
if (
|
||||||
# Skip if host tracking is disabled
|
# Skip if host tracking is disabled
|
||||||
uid_sensor.func == "MikrotikHostDeviceTracker"
|
entity_description.func == "MikrotikHostDeviceTracker"
|
||||||
and not config_entry.options.get(CONF_TRACK_HOSTS, DEFAULT_TRACK_HOSTS)
|
and not config_entry.options.get(CONF_TRACK_HOSTS, DEFAULT_TRACK_HOSTS)
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
@ -68,125 +82,99 @@ def _skip_sensor(config_entry, uid_sensor, uid_data, uid) -> bool:
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# model_async_setup_entry
|
# async_add_entities
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
async def model_async_setup_entry(
|
async def async_add_entities(
|
||||||
hass, config_entry, async_add_entities, sensor_services, sensor_types, dispatcher
|
hass: HomeAssistant, config_entry: ConfigEntry, dispatcher: dict[str, Callable]
|
||||||
):
|
):
|
||||||
inst = config_entry.data[CONF_NAME]
|
"""Add entities."""
|
||||||
mikrotik_controller = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
sensors = {}
|
platform = ep.async_get_current_platform()
|
||||||
|
services = platform.platform.SENSOR_SERVICES
|
||||||
|
descriptions = platform.platform.SENSOR_TYPES
|
||||||
|
|
||||||
platform = entity_platform.async_get_current_platform()
|
for service in services:
|
||||||
for service in sensor_services:
|
|
||||||
platform.async_register_entity_service(service[0], service[1], service[2])
|
platform.async_register_entity_service(service[0], service[1], service[2])
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def update_controller():
|
async def async_update_controller(coordinator):
|
||||||
"""Update the values of the controller"""
|
"""Update the values of the controller."""
|
||||||
model_update_items(
|
|
||||||
inst,
|
|
||||||
config_entry,
|
|
||||||
mikrotik_controller,
|
|
||||||
async_add_entities,
|
|
||||||
sensors,
|
|
||||||
dispatcher,
|
|
||||||
sensor_types,
|
|
||||||
)
|
|
||||||
|
|
||||||
mikrotik_controller.listeners.append(
|
async def async_check_exist(obj, coordinator, uid: None) -> None:
|
||||||
async_dispatcher_connect(
|
"""Check entity exists."""
|
||||||
hass, mikrotik_controller.signal_update, update_controller
|
entity_registry = er.async_get(hass)
|
||||||
)
|
if uid:
|
||||||
)
|
unique_id = f"{obj._inst.lower()}-{obj.entity_description.key}-{slugify(str(obj._data[obj.entity_description.data_reference]).lower())}"
|
||||||
update_controller()
|
else:
|
||||||
|
unique_id = f"{obj._inst.lower()}-{obj.entity_description.key}"
|
||||||
|
|
||||||
|
entity_id = entity_registry.async_get_entity_id(
|
||||||
# ---------------------------
|
platform.domain, DOMAIN, unique_id
|
||||||
# model_update_items
|
)
|
||||||
# ---------------------------
|
entity = entity_registry.async_get(entity_id)
|
||||||
def model_update_items(
|
if entity is None or (
|
||||||
inst,
|
(entity_id not in platform.entities) and (entity.disabled is False)
|
||||||
config_entry,
|
|
||||||
mikrotik_controller,
|
|
||||||
async_add_entities,
|
|
||||||
sensors,
|
|
||||||
dispatcher,
|
|
||||||
sensor_types,
|
|
||||||
):
|
|
||||||
def _register_entity(_sensors, _item_id, _uid, _uid_sensor):
|
|
||||||
_LOGGER.debug("Updating entity %s (%s)", inst, _item_id)
|
|
||||||
if _item_id in _sensors:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return dispatcher[_uid_sensor.func](
|
|
||||||
inst=inst,
|
|
||||||
uid=_uid,
|
|
||||||
mikrotik_controller=mikrotik_controller,
|
|
||||||
entity_description=_uid_sensor,
|
|
||||||
)
|
|
||||||
|
|
||||||
new_sensors = []
|
|
||||||
for sensor in sensor_types:
|
|
||||||
uid_sensor = sensor_types[sensor]
|
|
||||||
if not uid_sensor.data_reference:
|
|
||||||
if (
|
|
||||||
uid_sensor.data_attribute
|
|
||||||
not in mikrotik_controller.data[uid_sensor.data_path]
|
|
||||||
or mikrotik_controller.data[uid_sensor.data_path][
|
|
||||||
uid_sensor.data_attribute
|
|
||||||
]
|
|
||||||
== "unknown"
|
|
||||||
):
|
):
|
||||||
continue
|
_LOGGER.debug("Add entity %s", entity_id)
|
||||||
|
await platform.async_add_entities([obj])
|
||||||
|
|
||||||
item_id = f"{inst}-{sensor}"
|
for entity_description in descriptions:
|
||||||
if tmp := _register_entity(sensors, item_id, "", uid_sensor):
|
data = coordinator.data[entity_description.data_path]
|
||||||
sensors[item_id] = tmp
|
if not entity_description.data_reference:
|
||||||
new_sensors.append(sensors[item_id])
|
if data.get(entity_description.data_attribute) is None:
|
||||||
else:
|
|
||||||
for uid in mikrotik_controller.data[uid_sensor.data_path]:
|
|
||||||
uid_data = mikrotik_controller.data[uid_sensor.data_path]
|
|
||||||
if _skip_sensor(config_entry, uid_sensor, uid_data, uid):
|
|
||||||
continue
|
continue
|
||||||
|
obj = dispatcher[entity_description.func](
|
||||||
|
coordinator, entity_description
|
||||||
|
)
|
||||||
|
await async_check_exist(obj, coordinator, None)
|
||||||
|
else:
|
||||||
|
for uid in data:
|
||||||
|
if _skip_sensor(config_entry, entity_description, data, uid):
|
||||||
|
continue
|
||||||
|
obj = dispatcher[entity_description.func](
|
||||||
|
coordinator, entity_description, uid
|
||||||
|
)
|
||||||
|
await async_check_exist(obj, coordinator, uid)
|
||||||
|
|
||||||
item_id = f"{inst}-{sensor}-{str(uid_data[uid][uid_sensor.data_reference]).lower()}"
|
await async_update_controller(coordinator)
|
||||||
if tmp := _register_entity(sensors, item_id, uid, uid_sensor):
|
unsub = async_dispatcher_connect(hass, "update_sensors", async_update_controller)
|
||||||
sensors[item_id] = tmp
|
config_entry.async_on_unload(unsub)
|
||||||
new_sensors.append(sensors[item_id])
|
|
||||||
|
|
||||||
if new_sensors:
|
|
||||||
async_add_entities(new_sensors, True)
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# MikrotikEntity
|
# MikrotikEntity
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
class MikrotikEntity:
|
class MikrotikEntity(CoordinatorEntity[MikrotikCoordinator], Entity):
|
||||||
"""Define entity"""
|
"""Define entity"""
|
||||||
|
|
||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
inst,
|
coordinator: MikrotikCoordinator,
|
||||||
uid: "",
|
|
||||||
mikrotik_controller,
|
|
||||||
entity_description,
|
entity_description,
|
||||||
|
uid: str | None = None,
|
||||||
):
|
):
|
||||||
"""Initialize entity"""
|
"""Initialize entity"""
|
||||||
|
super().__init__(coordinator)
|
||||||
|
self.coordinator = coordinator
|
||||||
self.entity_description = entity_description
|
self.entity_description = entity_description
|
||||||
self._inst = inst
|
self._inst = coordinator.config_entry.data[CONF_NAME]
|
||||||
self._ctrl = mikrotik_controller
|
self._config_entry = self.coordinator.config_entry
|
||||||
self._config_entry = self._ctrl.config_entry
|
|
||||||
self._attr_extra_state_attributes = {ATTR_ATTRIBUTION: ATTRIBUTION}
|
self._attr_extra_state_attributes = {ATTR_ATTRIBUTION: ATTRIBUTION}
|
||||||
self._uid = uid
|
self._uid = uid
|
||||||
|
self._data = coordinator.data[self.entity_description.data_path]
|
||||||
if self._uid:
|
if self._uid:
|
||||||
self._data = mikrotik_controller.data[self.entity_description.data_path][
|
self._data = coordinator.data[self.entity_description.data_path][self._uid]
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _handle_coordinator_update(self) -> None:
|
||||||
|
self._data = self.coordinator.data[self.entity_description.data_path]
|
||||||
|
if self._uid:
|
||||||
|
self._data = self.coordinator.data[self.entity_description.data_path][
|
||||||
self._uid
|
self._uid
|
||||||
]
|
]
|
||||||
else:
|
super()._handle_coordinator_update()
|
||||||
self._data = mikrotik_controller.data[self.entity_description.data_path]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
|
@ -215,14 +203,14 @@ class MikrotikEntity:
|
||||||
def unique_id(self) -> str:
|
def unique_id(self) -> str:
|
||||||
"""Return a unique id for this entity"""
|
"""Return a unique id for this entity"""
|
||||||
if self._uid:
|
if self._uid:
|
||||||
return f"{self._inst.lower()}-{self.entity_description.key}-{str(self._data[self.entity_description.data_reference]).lower()}"
|
return f"{self._inst.lower()}-{self.entity_description.key}-{slugify(str(self._data[self.entity_description.data_reference]).lower())}"
|
||||||
else:
|
else:
|
||||||
return f"{self._inst.lower()}-{self.entity_description.key}"
|
return f"{self._inst.lower()}-{self.entity_description.key}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
"""Return if controller is available"""
|
"""Return if controller is available"""
|
||||||
return self._ctrl.connected()
|
return self.coordinator.connected()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
|
@ -231,8 +219,8 @@ class MikrotikEntity:
|
||||||
dev_connection_value = self.entity_description.data_reference
|
dev_connection_value = self.entity_description.data_reference
|
||||||
dev_group = self.entity_description.ha_group
|
dev_group = self.entity_description.ha_group
|
||||||
if self.entity_description.ha_group == "System":
|
if self.entity_description.ha_group == "System":
|
||||||
dev_group = self._ctrl.data["resource"]["board-name"]
|
dev_group = self.coordinator.data["resource"]["board-name"]
|
||||||
dev_connection_value = self._ctrl.data["routerboard"]["serial-number"]
|
dev_connection_value = self.coordinator.data["routerboard"]["serial-number"]
|
||||||
|
|
||||||
if self.entity_description.ha_group.startswith("data__"):
|
if self.entity_description.ha_group.startswith("data__"):
|
||||||
dev_group = self.entity_description.ha_group[6:]
|
dev_group = self.entity_description.ha_group[6:]
|
||||||
|
@ -253,19 +241,24 @@ class MikrotikEntity:
|
||||||
connections={(dev_connection, f"{dev_connection_value}")},
|
connections={(dev_connection, f"{dev_connection_value}")},
|
||||||
identifiers={(dev_connection, f"{dev_connection_value}")},
|
identifiers={(dev_connection, f"{dev_connection_value}")},
|
||||||
default_name=f"{self._inst} {dev_group}",
|
default_name=f"{self._inst} {dev_group}",
|
||||||
default_model=f"{self._ctrl.data['resource']['board-name']}",
|
default_model=f"{self.coordinator.data['resource']['board-name']}",
|
||||||
default_manufacturer=f"{self._ctrl.data['resource']['platform']}",
|
default_manufacturer=f"{self.coordinator.data['resource']['platform']}",
|
||||||
sw_version=f"{self._ctrl.data['resource']['version']}",
|
sw_version=f"{self.coordinator.data['resource']['version']}",
|
||||||
configuration_url=f"http://{self._ctrl.config_entry.data[CONF_HOST]}",
|
configuration_url=f"http://{self.coordinator.config_entry.data[CONF_HOST]}",
|
||||||
via_device=(DOMAIN, f"{self._ctrl.data['routerboard']['serial-number']}"),
|
via_device=(
|
||||||
|
DOMAIN,
|
||||||
|
f"{self.coordinator.data['routerboard']['serial-number']}",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
if "mac-address" in self.entity_description.data_reference:
|
if "mac-address" in self.entity_description.data_reference:
|
||||||
dev_group = self._data[self.entity_description.data_name]
|
dev_group = self._data[self.entity_description.data_name]
|
||||||
dev_manufacturer = ""
|
dev_manufacturer = ""
|
||||||
if dev_connection_value in self._ctrl.data["host"]:
|
if dev_connection_value in self.coordinator.data["host"]:
|
||||||
dev_group = self._ctrl.data["host"][dev_connection_value]["host-name"]
|
dev_group = self.coordinator.data["host"][dev_connection_value][
|
||||||
dev_manufacturer = self._ctrl.data["host"][dev_connection_value][
|
"host-name"
|
||||||
|
]
|
||||||
|
dev_manufacturer = self.coordinator.data["host"][dev_connection_value][
|
||||||
"manufacturer"
|
"manufacturer"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -275,7 +268,7 @@ class MikrotikEntity:
|
||||||
default_manufacturer=f"{dev_manufacturer}",
|
default_manufacturer=f"{dev_manufacturer}",
|
||||||
via_device=(
|
via_device=(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
f"{self._ctrl.data['routerboard']['serial-number']}",
|
f"{self.coordinator.data['routerboard']['serial-number']}",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -301,16 +294,16 @@ class MikrotikEntity:
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
"""Dummy run function"""
|
"""Dummy run function"""
|
||||||
_LOGGER.error("Start functionality does not exist for %s", self.unique_id)
|
raise NotImplementedError()
|
||||||
|
|
||||||
async def stop(self):
|
async def stop(self):
|
||||||
"""Dummy stop function"""
|
"""Dummy stop function"""
|
||||||
_LOGGER.error("Stop functionality does not exist for %s", self.unique_id)
|
raise NotImplementedError()
|
||||||
|
|
||||||
async def restart(self):
|
async def restart(self):
|
||||||
"""Dummy restart function"""
|
"""Dummy restart function"""
|
||||||
_LOGGER.error("Restart functionality does not exist for %s", self.unique_id)
|
raise NotImplementedError()
|
||||||
|
|
||||||
async def reload(self):
|
async def reload(self):
|
||||||
"""Dummy reload function"""
|
"""Dummy reload function"""
|
||||||
_LOGGER.error("Reload functionality does not exist for %s", self.unique_id)
|
raise NotImplementedError()
|
|
@ -44,7 +44,7 @@ class MikrotikAPI:
|
||||||
|
|
||||||
self._connection = None
|
self._connection = None
|
||||||
self._connected = False
|
self._connected = False
|
||||||
self._reconnected = False
|
self._reconnected = True
|
||||||
self._connection_epoch = 0
|
self._connection_epoch = 0
|
||||||
self._connection_retry_sec = 58
|
self._connection_retry_sec = 58
|
||||||
self.error = None
|
self.error = None
|
||||||
|
|
|
@ -1,11 +1,21 @@
|
||||||
"""Implementation of Mikrotik Router sensor entities."""
|
"""Mikrotik sensor platform."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
from logging import getLogger
|
||||||
from typing import Any, Optional
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
|
from datetime import date, datetime
|
||||||
|
from decimal import Decimal
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.sensor import SensorEntity
|
from homeassistant.components.sensor import SensorEntity
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.typing import StateType
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from .entity import MikrotikEntity, async_add_entities
|
||||||
|
from .coordinator import MikrotikCoordinator
|
||||||
from .helper import format_attribute
|
from .helper import format_attribute
|
||||||
from .model import model_async_setup_entry, MikrotikEntity
|
|
||||||
from .sensor_types import (
|
from .sensor_types import (
|
||||||
SENSOR_TYPES,
|
SENSOR_TYPES,
|
||||||
SENSOR_SERVICES,
|
SENSOR_SERVICES,
|
||||||
|
@ -14,52 +24,56 @@ from .sensor_types import (
|
||||||
DEVICE_ATTRIBUTES_IFACE_WIRELESS,
|
DEVICE_ATTRIBUTES_IFACE_WIRELESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# async_setup_entry
|
# async_setup_entry
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
_async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
"""Set up entry for component"""
|
"""Set up entry for component"""
|
||||||
dispatcher = {
|
dispatcher = {
|
||||||
"MikrotikSensor": MikrotikSensor,
|
"MikrotikSensor": MikrotikSensor,
|
||||||
"MikrotikInterfaceTrafficSensor": MikrotikInterfaceTrafficSensor,
|
"MikrotikInterfaceTrafficSensor": MikrotikInterfaceTrafficSensor,
|
||||||
"MikrotikClientTrafficSensor": MikrotikClientTrafficSensor,
|
"MikrotikClientTrafficSensor": MikrotikClientTrafficSensor,
|
||||||
}
|
}
|
||||||
await model_async_setup_entry(
|
await async_add_entities(hass, config_entry, dispatcher)
|
||||||
hass,
|
|
||||||
config_entry,
|
|
||||||
async_add_entities,
|
|
||||||
SENSOR_SERVICES,
|
|
||||||
SENSOR_TYPES,
|
|
||||||
dispatcher,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# MikrotikSensor
|
# MikrotikSensor
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
class MikrotikSensor(MikrotikEntity, SensorEntity):
|
class MikrotikSensor(MikrotikEntity, SensorEntity):
|
||||||
"""Define an Mikrotik Controller sensor."""
|
"""Define an Mikrotik sensor."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
coordinator: MikrotikCoordinator,
|
||||||
|
entity_description,
|
||||||
|
uid: str | None = None,
|
||||||
|
):
|
||||||
|
super().__init__(coordinator, entity_description, uid)
|
||||||
|
self._attr_suggested_unit_of_measurement = (
|
||||||
|
self.entity_description.suggested_unit_of_measurement
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self) -> Optional[str]:
|
def native_value(self) -> StateType | date | datetime | Decimal:
|
||||||
"""Return the state."""
|
"""Return the value reported by the sensor."""
|
||||||
if self.entity_description.data_attribute:
|
return self._data[self.entity_description.data_attribute]
|
||||||
return self._data[self.entity_description.data_attribute]
|
|
||||||
else:
|
|
||||||
return "unknown"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_unit_of_measurement(self):
|
def native_unit_of_measurement(self) -> str | None:
|
||||||
"""Return the unit the value is expressed in."""
|
"""Return the unit the value is expressed in."""
|
||||||
if self.entity_description.native_unit_of_measurement:
|
if self.entity_description.native_unit_of_measurement:
|
||||||
if self.entity_description.native_unit_of_measurement.startswith("data__"):
|
if self.entity_description.native_unit_of_measurement.startswith("data__"):
|
||||||
uom = self.entity_description.native_unit_of_measurement[6:]
|
uom = self.entity_description.native_unit_of_measurement[6:]
|
||||||
if uom in self._data:
|
if uom in self._data:
|
||||||
uom = self._data[uom]
|
return self._data[uom]
|
||||||
return uom
|
|
||||||
|
|
||||||
return self.entity_description.native_unit_of_measurement
|
return self.entity_description.native_unit_of_measurement
|
||||||
|
|
||||||
|
@ -113,9 +127,9 @@ class MikrotikClientTrafficSensor(MikrotikSensor):
|
||||||
"""
|
"""
|
||||||
if self.entity_description.data_attribute in ["lan-tx", "lan-rx"]:
|
if self.entity_description.data_attribute in ["lan-tx", "lan-rx"]:
|
||||||
return (
|
return (
|
||||||
self._ctrl.connected()
|
self.coordinator.connected()
|
||||||
and self._data["available"]
|
and self._data["available"]
|
||||||
and self._data["local_accounting"]
|
and self._data["local_accounting"]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return self._ctrl.connected() and self._data["available"]
|
return self.coordinator.connected() and self._data["available"]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
"""Definitions for Mikrotik Router sensor entities."""
|
"""Definitions for sensor entities."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import List
|
from typing import List
|
||||||
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
|
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
|
||||||
|
@ -9,11 +11,13 @@ from homeassistant.components.sensor import (
|
||||||
SensorEntityDescription,
|
SensorEntityDescription,
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
TEMP_CELSIUS,
|
|
||||||
ELECTRIC_POTENTIAL_VOLT,
|
|
||||||
POWER_WATT,
|
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
DATA_BYTES,
|
REVOLUTIONS_PER_MINUTE,
|
||||||
|
UnitOfTemperature,
|
||||||
|
UnitOfDataRate,
|
||||||
|
UnitOfInformation,
|
||||||
|
UnitOfElectricPotential,
|
||||||
|
UnitOfPower,
|
||||||
)
|
)
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
|
@ -113,28 +117,30 @@ DEVICE_ATTRIBUTES_GPS = [
|
||||||
class MikrotikSensorEntityDescription(SensorEntityDescription):
|
class MikrotikSensorEntityDescription(SensorEntityDescription):
|
||||||
"""Class describing mikrotik entities."""
|
"""Class describing mikrotik entities."""
|
||||||
|
|
||||||
ha_group: str = ""
|
ha_group: str | None = None
|
||||||
ha_connection: str = ""
|
ha_connection: str | None = None
|
||||||
ha_connection_value: str = ""
|
ha_connection_value: str | None = None
|
||||||
data_path: str = ""
|
data_path: str | None = None
|
||||||
data_attribute: str = ""
|
data_attribute: str | None = None
|
||||||
data_name: str = ""
|
data_name: str | None = None
|
||||||
data_name_comment: bool = False
|
data_name_comment: bool = False
|
||||||
data_uid: str = ""
|
data_uid: str | None = None
|
||||||
data_reference: str = ""
|
data_reference: str | None = None
|
||||||
data_attributes_list: List = field(default_factory=lambda: [])
|
data_attributes_list: List = field(default_factory=lambda: [])
|
||||||
func: str = "MikrotikSensor"
|
func: str = "MikrotikSensor"
|
||||||
|
|
||||||
|
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES: tuple[MikrotikSensorEntityDescription, ...] = (
|
||||||
"system_temperature": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_temperature",
|
key="system_temperature",
|
||||||
name="Temperature",
|
name="Temperature",
|
||||||
icon="mdi:thermometer",
|
icon="mdi:thermometer",
|
||||||
native_unit_of_measurement=TEMP_CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
suggested_display_precision=0,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
ha_group="System",
|
ha_group="System",
|
||||||
data_path="health",
|
data_path="health",
|
||||||
data_attribute="temperature",
|
data_attribute="temperature",
|
||||||
|
@ -142,11 +148,13 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_voltage": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_voltage",
|
key="system_voltage",
|
||||||
name="Voltage",
|
name="Voltage",
|
||||||
icon="mdi:lightning-bolt",
|
icon="mdi:lightning-bolt",
|
||||||
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
|
suggested_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
|
suggested_display_precision=1,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
@ -157,14 +165,16 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_cpu-temperature": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_cpu-temperature",
|
key="system_cpu-temperature",
|
||||||
name="CPU temperature",
|
name="CPU temperature",
|
||||||
icon="mdi:thermometer",
|
icon="mdi:thermometer",
|
||||||
native_unit_of_measurement=TEMP_CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
suggested_display_precision=0,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
ha_group="System",
|
ha_group="System",
|
||||||
data_path="health",
|
data_path="health",
|
||||||
data_attribute="cpu-temperature",
|
data_attribute="cpu-temperature",
|
||||||
|
@ -172,14 +182,16 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_switch-temperature": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_switch-temperature",
|
key="system_switch-temperature",
|
||||||
name="Switch temperature",
|
name="Switch temperature",
|
||||||
icon="mdi:thermometer",
|
icon="mdi:thermometer",
|
||||||
native_unit_of_measurement=TEMP_CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
suggested_display_precision=0,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
ha_group="System",
|
ha_group="System",
|
||||||
data_path="health",
|
data_path="health",
|
||||||
data_attribute="switch-temperature",
|
data_attribute="switch-temperature",
|
||||||
|
@ -187,14 +199,16 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_board-temperature1": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_board-temperature1",
|
key="system_board-temperature1",
|
||||||
name="Board temperature",
|
name="Board temperature",
|
||||||
icon="mdi:thermometer",
|
icon="mdi:thermometer",
|
||||||
native_unit_of_measurement=TEMP_CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
suggested_display_precision=0,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
ha_group="System",
|
ha_group="System",
|
||||||
data_path="health",
|
data_path="health",
|
||||||
data_attribute="board-temperature1",
|
data_attribute="board-temperature1",
|
||||||
|
@ -202,14 +216,16 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_power-consumption": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_power-consumption",
|
key="system_power-consumption",
|
||||||
name="Power consumption",
|
name="Power consumption",
|
||||||
icon="mdi:transmission-tower",
|
icon="mdi:transmission-tower",
|
||||||
native_unit_of_measurement=POWER_WATT,
|
native_unit_of_measurement=UnitOfPower.WATT,
|
||||||
|
suggested_unit_of_measurement=UnitOfPower.WATT,
|
||||||
|
suggested_display_precision=0,
|
||||||
device_class=SensorDeviceClass.POWER,
|
device_class=SensorDeviceClass.POWER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
ha_group="System",
|
ha_group="System",
|
||||||
data_path="health",
|
data_path="health",
|
||||||
data_attribute="power-consumption",
|
data_attribute="power-consumption",
|
||||||
|
@ -217,14 +233,14 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_fan1-speed": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_fan1-speed",
|
key="system_fan1-speed",
|
||||||
name="Fan1 speed",
|
name="Fan1 speed",
|
||||||
icon="mdi:fan",
|
icon="mdi:fan",
|
||||||
native_unit_of_measurement="RPM",
|
native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
|
||||||
device_class=None,
|
device_class=None,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
ha_group="System",
|
ha_group="System",
|
||||||
data_path="health",
|
data_path="health",
|
||||||
data_attribute="fan1-speed",
|
data_attribute="fan1-speed",
|
||||||
|
@ -232,14 +248,14 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_fan2-speed": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_fan2-speed",
|
key="system_fan2-speed",
|
||||||
name="Fan2 speed",
|
name="Fan2 speed",
|
||||||
icon="mdi:fan",
|
icon="mdi:fan",
|
||||||
native_unit_of_measurement="RPM",
|
native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
|
||||||
device_class=None,
|
device_class=None,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
ha_group="System",
|
ha_group="System",
|
||||||
data_path="health",
|
data_path="health",
|
||||||
data_attribute="fan2-speed",
|
data_attribute="fan2-speed",
|
||||||
|
@ -247,7 +263,7 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_uptime": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_uptime",
|
key="system_uptime",
|
||||||
name="Uptime",
|
name="Uptime",
|
||||||
icon=None,
|
icon=None,
|
||||||
|
@ -262,7 +278,7 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_cpu-load": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_cpu-load",
|
key="system_cpu-load",
|
||||||
name="CPU load",
|
name="CPU load",
|
||||||
icon="mdi:speedometer",
|
icon="mdi:speedometer",
|
||||||
|
@ -277,7 +293,7 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_memory-usage": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_memory-usage",
|
key="system_memory-usage",
|
||||||
name="Memory usage",
|
name="Memory usage",
|
||||||
icon="mdi:memory",
|
icon="mdi:memory",
|
||||||
|
@ -292,7 +308,7 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_hdd-usage": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_hdd-usage",
|
key="system_hdd-usage",
|
||||||
name="HDD usage",
|
name="HDD usage",
|
||||||
icon="mdi:harddisk",
|
icon="mdi:harddisk",
|
||||||
|
@ -307,7 +323,7 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_clients-wired": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_clients-wired",
|
key="system_clients-wired",
|
||||||
name="Wired clients",
|
name="Wired clients",
|
||||||
icon="mdi:lan",
|
icon="mdi:lan",
|
||||||
|
@ -322,7 +338,7 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_clients-wireless": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_clients-wireless",
|
key="system_clients-wireless",
|
||||||
name="Wireless clients",
|
name="Wireless clients",
|
||||||
icon="mdi:wifi",
|
icon="mdi:wifi",
|
||||||
|
@ -337,7 +353,7 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_captive-authorized": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_captive-authorized",
|
key="system_captive-authorized",
|
||||||
name="Captive portal clients",
|
name="Captive portal clients",
|
||||||
icon="mdi:key-wireless",
|
icon="mdi:key-wireless",
|
||||||
|
@ -352,7 +368,7 @@ SENSOR_TYPES = {
|
||||||
data_uid="",
|
data_uid="",
|
||||||
data_reference="",
|
data_reference="",
|
||||||
),
|
),
|
||||||
"system_gps-latitude": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_gps-latitude",
|
key="system_gps-latitude",
|
||||||
name="Latitude",
|
name="Latitude",
|
||||||
icon="mdi:latitude",
|
icon="mdi:latitude",
|
||||||
|
@ -368,7 +384,7 @@ SENSOR_TYPES = {
|
||||||
data_reference="",
|
data_reference="",
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_GPS,
|
data_attributes_list=DEVICE_ATTRIBUTES_GPS,
|
||||||
),
|
),
|
||||||
"system_gps-longitude": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="system_gps-longitude",
|
key="system_gps-longitude",
|
||||||
name="Longitude",
|
name="Longitude",
|
||||||
icon="mdi:longitude",
|
icon="mdi:longitude",
|
||||||
|
@ -384,12 +400,14 @@ SENSOR_TYPES = {
|
||||||
data_reference="",
|
data_reference="",
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_GPS,
|
data_attributes_list=DEVICE_ATTRIBUTES_GPS,
|
||||||
),
|
),
|
||||||
"traffic_tx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="traffic_tx",
|
key="traffic_tx",
|
||||||
name="TX",
|
name="TX",
|
||||||
icon="mdi:upload-network-outline",
|
icon="mdi:upload-network-outline",
|
||||||
native_unit_of_measurement="data__tx-attr",
|
native_unit_of_measurement=UnitOfDataRate.BITS_PER_SECOND,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_RATE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="data__default-name",
|
ha_group="data__default-name",
|
||||||
|
@ -403,12 +421,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_IFACE,
|
data_attributes_list=DEVICE_ATTRIBUTES_IFACE,
|
||||||
func="MikrotikInterfaceTrafficSensor",
|
func="MikrotikInterfaceTrafficSensor",
|
||||||
),
|
),
|
||||||
"traffic_rx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="traffic_rx",
|
key="traffic_rx",
|
||||||
name="RX",
|
name="RX",
|
||||||
icon="mdi:download-network-outline",
|
icon="mdi:download-network-outline",
|
||||||
native_unit_of_measurement="data__rx-attr",
|
native_unit_of_measurement=UnitOfDataRate.BITS_PER_SECOND,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_RATE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="data__default-name",
|
ha_group="data__default-name",
|
||||||
|
@ -422,12 +442,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_IFACE,
|
data_attributes_list=DEVICE_ATTRIBUTES_IFACE,
|
||||||
func="MikrotikInterfaceTrafficSensor",
|
func="MikrotikInterfaceTrafficSensor",
|
||||||
),
|
),
|
||||||
"total_tx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="tx-total",
|
key="tx-total",
|
||||||
name="TX total",
|
name="TX total",
|
||||||
icon="mdi:upload-network",
|
icon="mdi:upload-network",
|
||||||
native_unit_of_measurement=DATA_BYTES,
|
native_unit_of_measurement=UnitOfInformation.BITS,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfInformation.GIGABYTES,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_SIZE,
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="data__default-name",
|
ha_group="data__default-name",
|
||||||
|
@ -441,12 +463,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_IFACE,
|
data_attributes_list=DEVICE_ATTRIBUTES_IFACE,
|
||||||
func="MikrotikInterfaceTrafficSensor",
|
func="MikrotikInterfaceTrafficSensor",
|
||||||
),
|
),
|
||||||
"total_rx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="rx-total",
|
key="rx-total",
|
||||||
name="RX total",
|
name="RX total",
|
||||||
icon="mdi:download-network",
|
icon="mdi:download-network",
|
||||||
native_unit_of_measurement=DATA_BYTES,
|
native_unit_of_measurement=UnitOfInformation.BITS,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfInformation.GIGABYTES,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_SIZE,
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="data__default-name",
|
ha_group="data__default-name",
|
||||||
|
@ -460,12 +484,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_IFACE,
|
data_attributes_list=DEVICE_ATTRIBUTES_IFACE,
|
||||||
func="MikrotikInterfaceTrafficSensor",
|
func="MikrotikInterfaceTrafficSensor",
|
||||||
),
|
),
|
||||||
"client_traffic_lan_tx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="client_traffic_lan_tx",
|
key="client_traffic_lan_tx",
|
||||||
name="LAN TX",
|
name="LAN TX",
|
||||||
icon="mdi:upload-network",
|
icon="mdi:upload-network",
|
||||||
native_unit_of_measurement="data__tx-rx-attr",
|
native_unit_of_measurement=UnitOfDataRate.BITS_PER_SECOND,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_RATE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="",
|
ha_group="",
|
||||||
|
@ -479,12 +505,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
||||||
func="MikrotikClientTrafficSensor",
|
func="MikrotikClientTrafficSensor",
|
||||||
),
|
),
|
||||||
"client_traffic_lan_rx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="client_traffic_lan_rx",
|
key="client_traffic_lan_rx",
|
||||||
name="LAN RX",
|
name="LAN RX",
|
||||||
icon="mdi:download-network",
|
icon="mdi:download-network",
|
||||||
native_unit_of_measurement="data__tx-rx-attr",
|
native_unit_of_measurement=UnitOfDataRate.BITS_PER_SECOND,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_RATE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="",
|
ha_group="",
|
||||||
|
@ -498,12 +526,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
||||||
func="MikrotikClientTrafficSensor",
|
func="MikrotikClientTrafficSensor",
|
||||||
),
|
),
|
||||||
"client_traffic_wan_tx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="client_traffic_wan_tx",
|
key="client_traffic_wan_tx",
|
||||||
name="WAN TX",
|
name="WAN TX",
|
||||||
icon="mdi:upload-network",
|
icon="mdi:upload-network",
|
||||||
native_unit_of_measurement="data__tx-rx-attr",
|
native_unit_of_measurement=UnitOfDataRate.BITS_PER_SECOND,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_RATE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="",
|
ha_group="",
|
||||||
|
@ -517,12 +547,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
||||||
func="MikrotikClientTrafficSensor",
|
func="MikrotikClientTrafficSensor",
|
||||||
),
|
),
|
||||||
"client_traffic_wan_rx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="client_traffic_wan_rx",
|
key="client_traffic_wan_rx",
|
||||||
name="WAN RX",
|
name="WAN RX",
|
||||||
icon="mdi:download-network",
|
icon="mdi:download-network",
|
||||||
native_unit_of_measurement="data__tx-rx-attr",
|
native_unit_of_measurement=UnitOfDataRate.BITS_PER_SECOND,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_RATE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="",
|
ha_group="",
|
||||||
|
@ -536,12 +568,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
||||||
func="MikrotikClientTrafficSensor",
|
func="MikrotikClientTrafficSensor",
|
||||||
),
|
),
|
||||||
"client_traffic_tx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="client_traffic_tx",
|
key="client_traffic_tx",
|
||||||
name="TX",
|
name="TX",
|
||||||
icon="mdi:upload-network",
|
icon="mdi:upload-network",
|
||||||
native_unit_of_measurement="data__tx-rx-attr",
|
native_unit_of_measurement=UnitOfDataRate.BITS_PER_SECOND,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_RATE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="",
|
ha_group="",
|
||||||
|
@ -555,12 +589,14 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
||||||
func="MikrotikClientTrafficSensor",
|
func="MikrotikClientTrafficSensor",
|
||||||
),
|
),
|
||||||
"client_traffic_rx": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="client_traffic_rx",
|
key="client_traffic_rx",
|
||||||
name="RX",
|
name="RX",
|
||||||
icon="mdi:download-network",
|
icon="mdi:download-network",
|
||||||
native_unit_of_measurement="data__tx-rx-attr",
|
native_unit_of_measurement=UnitOfDataRate.BITS_PER_SECOND,
|
||||||
device_class=None,
|
suggested_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
device_class=SensorDeviceClass.DATA_RATE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=None,
|
entity_category=None,
|
||||||
ha_group="",
|
ha_group="",
|
||||||
|
@ -574,7 +610,7 @@ SENSOR_TYPES = {
|
||||||
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
data_attributes_list=DEVICE_ATTRIBUTES_CLIENT_TRAFFIC,
|
||||||
func="MikrotikClientTrafficSensor",
|
func="MikrotikClientTrafficSensor",
|
||||||
),
|
),
|
||||||
"environment": MikrotikSensorEntityDescription(
|
MikrotikSensorEntityDescription(
|
||||||
key="environment",
|
key="environment",
|
||||||
name="",
|
name="",
|
||||||
icon="mdi:clipboard-list",
|
icon="mdi:clipboard-list",
|
||||||
|
@ -591,6 +627,6 @@ SENSOR_TYPES = {
|
||||||
data_uid="name",
|
data_uid="name",
|
||||||
data_reference="name",
|
data_reference="name",
|
||||||
),
|
),
|
||||||
}
|
)
|
||||||
|
|
||||||
SENSOR_SERVICES = {}
|
SENSOR_SERVICES = []
|
||||||
|
|
|
@ -6,7 +6,7 @@ from collections.abc import Mapping
|
||||||
from homeassistant.components.switch import SwitchEntity
|
from homeassistant.components.switch import SwitchEntity
|
||||||
from homeassistant.helpers.restore_state import RestoreEntity
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
from .helper import format_attribute
|
from .helper import format_attribute
|
||||||
from .model import model_async_setup_entry, MikrotikEntity
|
from .entity import model_async_setup_entry, MikrotikEntity
|
||||||
from .switch_types import (
|
from .switch_types import (
|
||||||
SENSOR_TYPES,
|
SENSOR_TYPES,
|
||||||
SENSOR_SERVICES,
|
SENSOR_SERVICES,
|
||||||
|
|
|
@ -8,7 +8,7 @@ from homeassistant.components.update import (
|
||||||
UpdateDeviceClass,
|
UpdateDeviceClass,
|
||||||
UpdateEntityFeature,
|
UpdateEntityFeature,
|
||||||
)
|
)
|
||||||
from .model import model_async_setup_entry, MikrotikEntity
|
from .entity import model_async_setup_entry, MikrotikEntity
|
||||||
from .update_types import (
|
from .update_types import (
|
||||||
SENSOR_TYPES,
|
SENSOR_TYPES,
|
||||||
SENSOR_SERVICES,
|
SENSOR_SERVICES,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue