@@ -626,6 +626,47 @@ async def _safe_list_post(
626626 result = await self ._post (path = path , payload = payload )
627627 return result if isinstance (result , list ) else []
628628
629+ async def _get_check (self , path : str ) -> bool :
630+ """Check if the given API path is accessible.
631+
632+ Parameters
633+ ----------
634+ path : str
635+ The API path to check for accessibility.
636+
637+ Returns
638+ -------
639+ bool
640+ True if the path is accessible (HTTP 200 OK), False otherwise.
641+
642+ """
643+ # /api/<module>/<controller>/<command>/[<param1>/[<param2>/...]]
644+ self ._rest_api_query_count += 1
645+ url : str = f"{ self ._url } { path } "
646+ _LOGGER .debug ("[get_check] url: %s" , url )
647+ try :
648+ async with self ._session .get (
649+ url ,
650+ auth = aiohttp .BasicAuth (self ._username , self ._password ),
651+ timeout = aiohttp .ClientTimeout (total = DEFAULT_TIMEOUT ),
652+ ssl = self ._verify_ssl ,
653+ ) as response :
654+ _LOGGER .debug ("[get_check] Response %s: %s" , response .status , response .reason )
655+ if response .ok :
656+ return True
657+ if response .status == 403 :
658+ _LOGGER .error (
659+ "Permission Error in get_check. Path: %s. Ensure the OPNsense user connected to HA has appropriate access. Recommend full admin access" ,
660+ url ,
661+ )
662+ return False
663+ except aiohttp .ClientError as e :
664+ _LOGGER .error ("Client error. %s: %s" , type (e ).__name__ , e )
665+ if self ._initial :
666+ raise
667+
668+ return False
669+
629670 @_log_errors
630671 async def _filter_configure (self ) -> None :
631672 script : str = r"""
@@ -1140,7 +1181,17 @@ async def _get_dnsmasq_leases(self) -> list:
11401181 return leases
11411182
11421183 async def _get_isc_dhcpv4_leases (self ) -> list :
1143- """Return IPv4 DHCP Leases by ISC."""
1184+ """Return IPv4 DHCP Leases by ISC.
1185+
1186+ Returns
1187+ -------
1188+ list
1189+ A list of dictionaries representing IPv4 DHCP leases.
1190+
1191+ """
1192+ if not self ._get_check ("/api/dhcpv4/service/status" ):
1193+ _LOGGER .debug ("ISC DHCPv4 service is not running, skipping lease retrieval" )
1194+ return []
11441195 if self ._use_snake_case :
11451196 response = await self ._safe_dict_get ("/api/dhcpv4/leases/search_lease" )
11461197 else :
@@ -1184,7 +1235,17 @@ async def _get_isc_dhcpv4_leases(self) -> list:
11841235 return leases
11851236
11861237 async def _get_isc_dhcpv6_leases (self ) -> list :
1187- """Return IPv6 DHCP Leases by ISC."""
1238+ """Return IPv6 DHCP Leases by ISC.
1239+
1240+ Returns
1241+ -------
1242+ list
1243+ A list of dictionaries representing IPv6 DHCP leases.
1244+
1245+ """
1246+ if not self ._get_check ("/api/dhcpv6/service/status" ):
1247+ _LOGGER .debug ("ISC DHCPv6 service is not running, skipping lease retrieval" )
1248+ return []
11881249 if self ._use_snake_case :
11891250 response = await self ._safe_dict_get ("/api/dhcpv6/leases/search_lease" )
11901251 else :
0 commit comments