Source code for labgrid.driver.power.poe_netgear_plus

"""Control NETGEAR Plus devices via HTTP.

Available switch models:
https://github.com/foxey/py-netgear-plus?tab=readme-ov-file#supported-and-tested-netgear-modelsproducts-and-firmware-versions

The password defaults to "P4ssword", but can be configured on a per-device basis like this:

NetworkPowerPort:
  model: poe_netgear_plus
  host: 'http://username_is_unused:AnotherP4ssword@192.168.0.239/'
  index: 7

Omitting the password defaults as described above.

NetworkPowerPort:
  model: poe_netgear_plus
  host: 'http://192.168.0.239/'
  index: 7

"""

from urllib.parse import urlparse

from ..exception import ExecutionError


def _get_hostname_and_password(url: str) -> tuple[str, str]:
    """Obtain credentials from url or default and return hostname and password.

    If no password is in the URL return "P4ssword", which fulfills  the minimal requirements from Netgear:
    - 8-20 characters
    - at least one upper case character
    - at least one lower case character
    - at least one number

    Args:
        url: A URL with an optional basic auth prefix.

    Returns:
        A tuple of the hostname, and the extracted or default password

    """
    parse_result = urlparse(url)
    if parse_result.scheme != "http":
        raise ExecutionError(f"URL must start with http://, found {parse_result.scheme} for {url}.")

    password = "P4ssword" if parse_result.password is None else parse_result.password

    return parse_result.hostname, password


[docs] def power_set(host: str, _port: int, index: int, value: bool) -> None: """Set the PoE output index based for a given host. Args: host: The netloc with optional password e.g. "192.168.0.239" or ":P4ssword@192.168.0.239" _port: As the webserver of the switch is always on port 80, this is ignored index: Zero based access to the switches network ports value: Whether the port should enable PoE output """ from py_netgear_plus import NetgearSwitchConnector index = int(index) netgear_port_number = index + 1 (hostname, password) = _get_hostname_and_password(host) sw = NetgearSwitchConnector(hostname, password) sw.autodetect_model() try: sw.get_login_cookie() sw._get_switch_metadata() if value: sw.turn_on_poe_port(netgear_port_number) else: sw.turn_off_poe_port(netgear_port_number) finally: sw.delete_login_cookie()
[docs] def power_get(host: str, _port: int, index: int) -> bool: """Determine whether a given Port has PoE enabled. Args: host: The netloc with optional password e.g. "192.168.0.239" or ":P4ssword@192.168.0.239" _port: As the webserver of the switch is always on port 80, this is ignored index: Zero based access to the switches network ports Returns: Whether the PoE output is enabled. Raises: ExecutionError: In case the status dictionary contains unexpected PoE status values. """ from py_netgear_plus import NetgearSwitchConnector index = int(index) netgear_port_number = index + 1 (hostname, password) = _get_hostname_and_password(host) sw = NetgearSwitchConnector(hostname, password) sw.autodetect_model() try: sw.get_login_cookie() sw._get_switch_metadata() data = sw._get_poe_port_config() key = f"port_{netgear_port_number}_poe_power_active" if data[key] == "on": return True if data[key] == "off": return False msg = f"Expected literal 'on'|'off', found {data[key]}" raise ExecutionError(msg) finally: sw.delete_login_cookie()