Add ability to automatically determine if the LAN accounting sensor should be created depending on account-local-traffic in Mikrotik API

This commit is contained in:
Ivan Pavlina 2020-04-05 15:03:17 +02:00
parent 30c11db741
commit f9a458bbfb
4 changed files with 44 additions and 26 deletions

View file

@ -18,6 +18,7 @@ Features:
* System sensors (CPU, Memory, HDD) * System sensors (CPU, Memory, HDD)
* Firmware update binary sensor * Firmware update binary sensor
* Switches to run scripts * Switches to run scripts
* RX/TX traffic sensors per hosts from Mikrotik Accounting
# Integration preview # Integration preview
![Tracker and sensors](https://raw.githubusercontent.com/tomaae/homeassistant-mikrotik_router/master/docs/assets/images/ui/device_tracker.png) ![Tracker and sensors](https://raw.githubusercontent.com/tomaae/homeassistant-mikrotik_router/master/docs/assets/images/ui/device_tracker.png)

View file

@ -76,10 +76,12 @@ class MikrotikControllerData:
async_track_time_interval( async_track_time_interval(
self.hass, self.force_fwupdate_check, timedelta(hours=1) self.hass, self.force_fwupdate_check, timedelta(hours=1)
) )
self.account_local_traffic = False
if self.track_accounting: if self.track_accounting:
async_track_time_interval( async_track_time_interval(
self.hass, self.force_accounting_hosts_update, timedelta(minutes=15) self.hass, self.force_accounting_hosts_update, timedelta(minutes=15)
) )
self.account_local_traffic = self.api.is_accounting_local_traffic_enabled()
def _get_traffic_type_and_div(self): def _get_traffic_type_and_div(self):
traffic_type = self.option_traffic_type traffic_type = self.option_traffic_type
@ -769,13 +771,14 @@ class MikrotikControllerData:
# Also set traffic type for each item # Also set traffic type for each item
accounting_values = {} accounting_values = {}
for addr in self.data['accounting']: for addr in self.data['accounting']:
accounting_values[addr] = { accounting_values[addr] = {}
"wan-tx": 0, accounting_values[addr]["wan-tx"] = 0
"wan-rx": 0, accounting_values[addr]["wan-rx"] = 0
"lan-tx": 0, if self.account_local_traffic:
"lan-rx": 0 accounting_values[addr]["lan-tx"] = 0
} accounting_values[addr]["lan-rx"] = 0
self.data['accounting'][addr]["lan-wan-tx-rx-attr"] = traffic_type
self.data['accounting'][addr]["tx-rx-attr"] = traffic_type
time_diff = self.api.take_accounting_snapshot() time_diff = self.api.take_accounting_snapshot()
if time_diff: if time_diff:
@ -819,13 +822,13 @@ class MikrotikControllerData:
# Now that we have sum of all traffic in bytes for given period # Now that we have sum of all traffic in bytes for given period
# calculate real throughput and transform it to appropriate unit # calculate real throughput and transform it to appropriate unit
for addr in accounting_values: for addr in accounting_values:
self.data['accounting'][addr]['wan-tx'] = round(
accounting_values[addr]['wan-tx'] / time_diff * traffic_div, 2)
self.data['accounting'][addr]['wan-rx'] = round(
accounting_values[addr]['wan-rx'] / time_diff * traffic_div, 2)
if self.account_local_traffic:
self.data['accounting'][addr]['lan-tx'] = round( self.data['accounting'][addr]['lan-tx'] = round(
accounting_values[addr]['lan-tx'] / time_diff * traffic_div, 2) accounting_values[addr]['lan-tx'] / time_diff * traffic_div, 2)
self.data['accounting'][addr]['lan-rx'] = round( self.data['accounting'][addr]['lan-rx'] = round(
accounting_values[addr]['lan-rx'] / time_diff * traffic_div, 2) accounting_values[addr]['lan-rx'] / time_diff * traffic_div, 2)
self.data['accounting'][addr]['wan-tx'] = round(
accounting_values[addr]['wan-tx'] / time_diff * traffic_div, 2)
self.data['accounting'][addr]['wan-rx'] = round(
accounting_values[addr]['wan-rx'] / time_diff * traffic_div, 2)

View file

@ -488,7 +488,7 @@ class MikrotikAPI:
from time import time from time import time
return int(round(time() * 1000)) return int(round(time() * 1000))
def is_accounting_enabled(self): def is_accounting_enabled(self) -> bool:
accounting = self.path("/ip/accounting", return_list=True) accounting = self.path("/ip/accounting", return_list=True)
if accounting is None: if accounting is None:
return False return False
@ -500,6 +500,18 @@ class MikrotikAPI:
return True return True
return False return False
def is_accounting_local_traffic_enabled(self) -> bool:
accounting = self.path("/ip/accounting", return_list=True)
if accounting is None:
return False
for item in accounting:
if 'account-local-traffic' not in item:
continue
if item['account-local-traffic']:
return True
return False
# --------------------------- # ---------------------------
# take_accounting_snapshot # take_accounting_snapshot
# Returns float -> seconds period between last run and current run # Returns float -> seconds period between last run and current run

View file

@ -84,7 +84,7 @@ SENSOR_TYPES = {
ATTR_ICON: "mdi:download-network", ATTR_ICON: "mdi:download-network",
ATTR_LABEL: "LAN TX", ATTR_LABEL: "LAN TX",
ATTR_UNIT: "ps", ATTR_UNIT: "ps",
ATTR_UNIT_ATTR: "lan-wan-tx-rx-attr", ATTR_UNIT_ATTR: "tx-rx-attr",
ATTR_PATH: "accounting", ATTR_PATH: "accounting",
ATTR_ATTR: "lan-tx", ATTR_ATTR: "lan-tx",
}, },
@ -93,7 +93,7 @@ SENSOR_TYPES = {
ATTR_ICON: "mdi:upload-network", ATTR_ICON: "mdi:upload-network",
ATTR_LABEL: "LAN RX", ATTR_LABEL: "LAN RX",
ATTR_UNIT: "ps", ATTR_UNIT: "ps",
ATTR_UNIT_ATTR: "lan-wan-tx-rx-attr", ATTR_UNIT_ATTR: "tx-rx-attr",
ATTR_PATH: "accounting", ATTR_PATH: "accounting",
ATTR_ATTR: "lan-rx", ATTR_ATTR: "lan-rx",
}, },
@ -102,7 +102,7 @@ SENSOR_TYPES = {
ATTR_ICON: "mdi:download-network", ATTR_ICON: "mdi:download-network",
ATTR_LABEL: "WAN TX", ATTR_LABEL: "WAN TX",
ATTR_UNIT: "ps", ATTR_UNIT: "ps",
ATTR_UNIT_ATTR: "lan-wan-tx-rx-attr", ATTR_UNIT_ATTR: "tx-rx-attr",
ATTR_PATH: "accounting", ATTR_PATH: "accounting",
ATTR_ATTR: "wan-tx", ATTR_ATTR: "wan-tx",
}, },
@ -111,7 +111,7 @@ SENSOR_TYPES = {
ATTR_ICON: "mdi:upload-network", ATTR_ICON: "mdi:upload-network",
ATTR_LABEL: "WAN RX", ATTR_LABEL: "WAN RX",
ATTR_UNIT: "ps", ATTR_UNIT: "ps",
ATTR_UNIT_ATTR: "lan-wan-tx-rx-attr", ATTR_UNIT_ATTR: "tx-rx-attr",
ATTR_PATH: "accounting", ATTR_PATH: "accounting",
ATTR_ATTR: "wan-rx", ATTR_ATTR: "wan-rx",
}, },
@ -194,6 +194,7 @@ def update_items(inst, mikrotik_controller, async_add_entities, sensors):
sensors[item_id].async_schedule_update_ha_state() sensors[item_id].async_schedule_update_ha_state()
continue continue
if SENSOR_TYPES[sensor][ATTR_ATTR] in mikrotik_controller.data['accounting'][uid].keys():
sensors[item_id] = MikrotikAccountingSensor( sensors[item_id] = MikrotikAccountingSensor(
mikrotik_controller=mikrotik_controller, mikrotik_controller=mikrotik_controller,
inst=inst, inst=inst,
@ -201,7 +202,8 @@ def update_items(inst, mikrotik_controller, async_add_entities, sensors):
uid=uid, uid=uid,
) )
new_sensors.append(sensors[item_id]) new_sensors.append(sensors[item_id])
else:
_LOGGER.info(f"WONT CREATE {SENSOR_TYPES[sensor][ATTR_ATTR]} for {item_id}")
if new_sensors: if new_sensors:
async_add_entities(new_sensors, True) async_add_entities(new_sensors, True)