Skip to content

Commit

Permalink
Show peers and wireless clients as entity attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
kvj committed Oct 13, 2021
1 parent 2212185 commit 6c6837e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 24 deletions.
4 changes: 3 additions & 1 deletion custom_components/openwrt/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ async def update_hostapd_clients(self, interface_id: str) -> dict:
'get_clients',
dict()
)
macs = list(map(lambda x: x.lower(), response['clients'].keys()))
macs = dict()
for key, value in response['clients'].items():
macs[key] = dict(signal=value.get("signal"))
response = await self._ubus.api_call(
f"hostapd.{interface_id}",
'wps_status',
Expand Down
38 changes: 32 additions & 6 deletions custom_components/openwrt/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
Expand All @@ -28,7 +29,8 @@ async def async_setup_entry(
wireless.append(sensor)
entities.append(sensor)
if len(wireless) > 0:
entities.append(WirelessTotalClientsSensor(device, device_id, wireless))
entities.append(WirelessTotalClientsSensor(
device, device_id, wireless))
for net_id in device.coordinator.data['mesh']:
entities.append(
MeshSignalSensor(device, device_id, net_id)
Expand All @@ -43,6 +45,7 @@ async def async_setup_entry(
async_add_entities(entities)
return True


class OpenWrtSensor(OpenWrtEntity, SensorEntity):
def __init__(self, coordinator, device: str):
super().__init__(coordinator, device)
Expand All @@ -51,9 +54,10 @@ def __init__(self, coordinator, device: str):
def state_class(self):
return 'measurement'


class WirelessClientsSensor(OpenWrtSensor):

def __init__(self, device, device_id: str, interface: string):
def __init__(self, device, device_id: str, interface: str):
super().__init__(device, device_id)
self._interface_id = interface

Expand All @@ -73,6 +77,15 @@ def state(self):
def icon(self):
return 'mdi:wifi-off' if self.state == 0 else 'mdi:wifi'

@property
def extra_state_attributes(self):
result = dict()
data = self.data['wireless'][self._interface_id]
for key, value in data.get("macs", {}).items():
signal = value.get("signal", 0)
result[key] = f"{signal} dBm"
return result


class MeshSignalSensor(OpenWrtSensor):

Expand Down Expand Up @@ -102,15 +115,17 @@ def signal_strength(self):
value = self.data['mesh'][self._interface_id]['signal']
levels = [-50, -60, -67, -70, -80]
for idx, level in enumerate(levels):
if value >=level:
if value >= level:
return idx
return len(levels)

@property
def icon(self):
icons = ['mdi:network-strength-4', 'mdi:network-strength-3', 'mdi:network-strength-2', 'mdi:network-strength-1', 'mdi:network-strength-outline', 'mdi:network-strength-off-outline']
icons = ['mdi:network-strength-4', 'mdi:network-strength-3', 'mdi:network-strength-2',
'mdi:network-strength-1', 'mdi:network-strength-outline', 'mdi:network-strength-off-outline']
return icons[self.signal_strength]


class MeshPeersSensor(OpenWrtSensor):

def __init__(self, device, device_id: str, interface: str):
Expand All @@ -134,6 +149,16 @@ def state(self):
def icon(self):
return 'mdi:server-network' if self.state > 0 else 'mdi:server-network-off'

@property
def extra_state_attributes(self):
result = dict()
data = self.data["mesh"][self._interface_id]
for key, value in data.get("peers", {}).items():
signal = value.get("signal", 0)
result[key] = f"{signal} dBm"
return result


class WirelessTotalClientsSensor(OpenWrtSensor):

def __init__(self, device, device_id: str, sensors):
Expand All @@ -159,6 +184,7 @@ def state(self):
def icon(self):
return 'mdi:wifi-off' if self.state == 0 else 'mdi:wifi'


class Mwan3OnlineSensor(OpenWrtSensor):

def __init__(self, device, device_id: str, interface: str):
Expand All @@ -176,10 +202,10 @@ def name(self):
@property
def state(self):
data = self.data["mwan3"][self._interface_id]
value = data["online_sec"] / data["uptime_sec"] * 100 if data["uptime_sec"] else 100
value = data["online_sec"] / data["uptime_sec"] * \
100 if data["uptime_sec"] else 100
return f"{round(value, 1)}%"

@property
def icon(self):
return "mdi:router-network"

32 changes: 15 additions & 17 deletions custom_components/openwrt/ubus.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

DEFAULT_TIMEOUT: int = 15


class Ubus:
def __init__(
self,
Expand All @@ -29,9 +30,9 @@ def __init__(
self.rpc_id = 1

async def api_call(
self,
subsystem: str,
method: str,
self,
subsystem: str,
method: str,
params: dict,
rpc_method: str = "call"
) -> dict:
Expand All @@ -46,18 +47,18 @@ async def api_call(
async def _login(self):
result = await self._api_call(
"call",
"session",
"login",
"session",
"login",
dict(username=self.username, password=self.password),
"00000000000000000000000000000000")
_LOGGER.debug(f"Login result: {result}")
self.session_id = result["ubus_rpc_session"]

async def _api_call(
self,
self,
rpc_method: str,
subsystem: str,
method: str,
subsystem: str,
method: str,
params: dict,
session: str = None,
) -> dict:
Expand All @@ -81,9 +82,9 @@ async def _api_call(
try:
def post():
return requests.post(
self.url,
data=data,
timeout=self.timeout,
self.url,
data=data,
timeout=self.timeout,
verify=self.verify
)
response = await self.executor_job(post)
Expand All @@ -107,17 +108,14 @@ def post():
if code == -32000:
raise NameError(message)
raise ConnectionError(f"rpc error: {message}")
result = json_response['result']
result = json_response['result']
if rpc_method == "list":
return result
result_code = result[0]
if result_code == 8:
raise ConnectionError(f"rpc error: not allowed")
raise ConnectionError(f"rpc error: not allowed")
if result_code == 6:
raise PermissionError(f"rpc error: insufficient permissions")
if result_code == 0:
if result_code == 0:
return json_response['result'][1] if len(result) > 1 else {}
raise ConnectionError(f"rpc error: {result[0]}")



0 comments on commit 6c6837e

Please sign in to comment.