Skip to content

Commit

Permalink
Merge pull request #206 from Snuffy2/Move-services-to-REST-API
Browse files Browse the repository at this point in the history
Move OPNsense services functions to REST API
  • Loading branch information
alexdelprete authored Sep 23, 2024
2 parents ef25472 + c3c183d commit dfc9593
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 150 deletions.
8 changes: 4 additions & 4 deletions custom_components/opnsense/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,12 @@ def __init__(
@callback
def process_entities(self):
entities = self.process_entities_callback(self.hass, self.config_entry)
i_entity_unqiue_ids = set()
i_entity_unique_ids = set()
for entity in entities:
unique_id = entity.unique_id
if unique_id is None:
raise Exception("unique_id is missing from entity")
i_entity_unqiue_ids.add(unique_id)
raise ValueError("unique_id is missing from entity")
i_entity_unique_ids.add(unique_id)
if unique_id not in self.entity_unique_ids:
self.async_add_entities([entity])
self.entity_unique_ids.add(unique_id)
Expand All @@ -244,7 +244,7 @@ def process_entities(self):

# check for missing entities
for entity_unique_id in self.entity_unique_ids:
if entity_unique_id not in i_entity_unqiue_ids:
if entity_unique_id not in i_entity_unique_ids:
pass
# print("should remove entity: " + str(self.entities[entity_unique_id].entry_id))
# print("candidate to remove entity: " + str(entity_unique_id))
Expand Down
24 changes: 12 additions & 12 deletions custom_components/opnsense/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ async def _async_update_data(self):
if previous_interface is None:
break

for property in [
for prop_name in [
"inbytes",
"outbytes",
# "inbytespass",
Expand All @@ -193,24 +193,24 @@ async def _async_update_data(self):
# "inpktsblock",
# "outpktsblock",
]:
current_parent_value = interface[property]
previous_parent_value = previous_interface[property]
current_parent_value = interface[prop_name]
previous_parent_value = previous_interface[prop_name]
change = abs(current_parent_value - previous_parent_value)
rate = change / elapsed_time

value = 0
if "pkts" in property:
if "pkts" in prop_name:
label = "packets_per_second"
value = rate
if "bytes" in property:
if "bytes" in prop_name:
label = "kilobytes_per_second"
# 1 Byte = 8 bits
# 1 byte is equal to 0.001 kilobytes
KBs = rate / 1000
# Kbs = KBs * 8
value = KBs

new_property = f"{property}_{label}"
new_property = f"{prop_name}_{label}"
interface[new_property] = int(round(value, 0))

for server_name in dict_get(
Expand All @@ -237,27 +237,27 @@ async def _async_update_data(self):
"openvpn"
]["servers"][server_name]

for property in [
for prop_name in [
"total_bytes_recv",
"total_bytes_sent",
]:
current_parent_value = server[property]
previous_parent_value = previous_server[property]
current_parent_value = server[prop_name]
previous_parent_value = previous_server[prop_name]
change = abs(current_parent_value - previous_parent_value)
rate = change / elapsed_time

value = 0
if "pkts" in property:
if "pkts" in prop_name:
label = "packets_per_second"
value = rate
if "bytes" in property:
if "bytes" in prop_name:
label = "kilobytes_per_second"
# 1 Byte = 8 bits
# 1 byte is equal to 0.001 kilobytes
KBs = rate / 1000
# Kbs = KBs * 8
value = KBs

new_property: str = f"{property}_{label}"
new_property: str = f"{prop_name}_{label}"
server[new_property] = int(round(value, 0))
return self._state
4 changes: 2 additions & 2 deletions custom_components/opnsense/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ def _extra_state_attributes(self) -> Mapping[str, Any] | None:
"""Return extra state attributes."""
entry = self._get_opnsense_arp_entry()
if entry is not None:
for property in ["interface", "expires", "type"]:
self._extra_state[property] = entry.get(property)
for prop_name in ["interface", "expires", "type"]:
self._extra_state[prop_name] = entry.get(prop_name)

if self._last_known_hostname is not None:
self._extra_state["last_known_hostname"] = self._last_known_hostname
Expand Down
96 changes: 42 additions & 54 deletions custom_components/opnsense/pyopnsense/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,38 +179,6 @@ async def get_host_firmware_version(self) -> None | str:
_LOGGER.debug(f"[get_host_firmware_version] firmware: {firmware}")
return firmware

@_xmlrpc_timeout
@_log_errors
async def _list_services(self):
response = await self._loop.run_in_executor(
None, self._get_proxy().opnsense.list_services
)
if response is None or not isinstance(response, Mapping):
_LOGGER.error("Invalid data returned from list_services")
return {}
return response

@_xmlrpc_timeout
@_log_errors
async def _start_service(self, params):
return await self._loop.run_in_executor(
None, self._get_proxy().opnsense.start_service, params
)

@_xmlrpc_timeout
@_log_errors
async def _stop_service(self, params):
return await self._loop.run_in_executor(
None, self._get_proxy().opnsense.stop_service, params
)

@_xmlrpc_timeout
@_log_errors
async def _restart_service(self, params):
return await self._loop.run_in_executor(
None, self._get_proxy().opnsense.restart_service, params
)

async def _get_from_stream(self, path: str) -> Mapping[str, Any] | list:
url: str = f"{self._url}{path}"
_LOGGER.debug(f"[get_from_stream] url: {url}")
Expand Down Expand Up @@ -631,39 +599,59 @@ async def get_arp_table(self, resolve_hostnames=False) -> Mapping[str, Any]:
return arp_table

@_log_errors
async def get_services(self):
response = await self._list_services()
services = []
for key in response.keys():
services.append(response[key])

async def get_services(self) -> list:
response: Mapping[str, Any] | list = await self._get("/api/core/service/search")
if response is None or not isinstance(response, Mapping):
_LOGGER.error("Invalid data returned from get_services")
return []
# _LOGGER.debug(f"[get_services] response: {response}")
services: list = response.get("rows", [])
for service in services:
service["status"] = service.get("running", 0) == 1
_LOGGER.debug(f"[get_services] services: {services}")
return services

@_log_errors
async def get_service_is_running(self, service_name):
services = await self.get_services()
for service in services:
if service["name"] == service_name:
return service["status"]

async def get_service_is_running(self, service: str) -> bool:
services: list = await self.get_services()
if services is None or not isinstance(services, list):
return False
for svc in services:
if (
svc.get("name", None) == service or svc.get("id", None) == service
) and svc.get("status", False):
return True
return False

async def _manage_service(self, action: str, service: str) -> bool:
if not service:
return False
api_addr: str = f"/api/core/service/{action}/{service}"
response: Mapping[str, Any] | list = await self._post(api_addr)
_LOGGER.debug(f"[{action}_service] service: {service}, response: {response}")
return not (
response is None
or not isinstance(response, Mapping)
or response.get("result", "failed") != "ok"
)

@_log_errors
async def start_service(self, service_name):
self._start_service({"service": service_name})
async def start_service(self, service: str) -> bool:
return await self._manage_service("start", service)

@_log_errors
async def stop_service(self, service_name):
await self._stop_service({"service": service_name})
async def stop_service(self, service: str) -> bool:
return await self._manage_service("stop", service)

@_log_errors
async def restart_service(self, service_name):
await self._restart_service({"service": service_name})
async def restart_service(self, service: str) -> bool:
return await self._manage_service("restart", service)

@_log_errors
async def restart_service_if_running(self, service_name):
if await self.get_service_is_running(service_name):
await self.restart_service(service_name)
async def restart_service_if_running(self, service: str) -> bool:
if await self.get_service_is_running(service):
return await self.restart_service(service)
return True

@_log_errors
async def get_dhcp_leases(self):
Expand Down Expand Up @@ -705,7 +693,7 @@ async def get_carp_status(self) -> Mapping[str, Any]:
"""
response: Mapping[str, Any] = await self._exec_php(script)
if response is None or not isinstance(response, Mapping):
_LOGGER.error("Invalid data returned from list_services")
_LOGGER.error("Invalid data returned from get_carp_status")
return {}
return response.get("data", {})

Expand Down
Loading

0 comments on commit dfc9593

Please sign in to comment.