From 6c63250fe39519c96d3a378c92c30376b249037d Mon Sep 17 00:00:00 2001 From: Onur Celep Date: Tue, 18 Feb 2025 10:53:18 +0100 Subject: [PATCH] Add gude8210 (snmp) power driver integration Signed-off-by: Onur Celep --- doc/configuration.rst | 3 ++ labgrid/driver/power/gude8210.py | 78 ++++++++++++++++++++++++++++++++ tests/test_powerdriver.py | 5 ++ 3 files changed, 86 insertions(+) create mode 100644 labgrid/driver/power/gude8210.py diff --git a/doc/configuration.rst b/doc/configuration.rst index bebedf77e..612bc7a54 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -192,6 +192,9 @@ Currently available are: ``gude8031`` Controls *Gude Expert Power Control 8031 PDUs* and *Gude Expert Power Control 87-1210-18 PDUs* via a simple HTTP API. +``gude8210`` + Controls *Gude Expert Power Control 8210 PDUs* via SNMP. + ``gude8225`` Controls *Gude Expert Power Control 8225 PDUs* via a simple HTTP API. diff --git a/labgrid/driver/power/gude8210.py b/labgrid/driver/power/gude8210.py new file mode 100644 index 000000000..96d48fb77 --- /dev/null +++ b/labgrid/driver/power/gude8210.py @@ -0,0 +1,78 @@ +import logging + +from ...util.snmp import SimpleSNMP +from ..exception import ExecutionError + +# Base OID for the Gude power switch as per the MIB file from gude8210 +POWER_OID_BASE = "1.3.6.1.4.1.28507.1.1.2.2.1.3" +NUMBER_OF_OUTLETS = 8 # Max number of outlets from the MIB + + +def power_set(host, port, index, value): + """ + Sets the power state of a specific outlet on the Gude power switch. + + Args: + host (str): The IP address of the power switch. + port (int or None): SNMP port, default is 161 or None. + index (int): Outlet index. + value (bool): True to turn on, False to turn off. + community (str): SNMP community string. + """ + # Validate index within allowable range + if index is None or not (1 <= int(index) <= NUMBER_OF_OUTLETS): + raise ExecutionError("Invalid outlet index. Ensure the index is within the range 1 to 8.") + + # Setup SNMP connection and OID for the target outlet + _snmp = SimpleSNMP(host, "private", port=port) + oid = f"{POWER_OID_BASE}.{index}" + snmp_value = "1" if value else "0" # SNMP value for on/off + logging.debug("Attempting SNMP SET on host %s, OID %s, value %s", host, oid, snmp_value) + + try: + # Set the power state for the specified outlet + _snmp.set(oid, snmp_value) + logging.debug("SNMP SET successful for OID %s with value %s", oid, snmp_value) + except Exception as e: + logging.debug("SNMP SET failed for OID %s with exception %s", oid, e) + raise ExecutionError("Failed to set power state on outlet %s: %s", index, e) from e + + +def power_get(host, port, index): + """ + Retrieves the current power state of a specific outlet on the Gude power switch. + + Args: + host (str): The IP address of the power switch. + port (int or None): SNMP port, default is 161 or None. + index (int): Outlet index. + community (str): SNMP community string. + + Returns: + bool: True if the outlet is on, False if it's off. + """ + # Validate index within allowable range + if index is None or not (1 <= int(index) <= NUMBER_OF_OUTLETS): + raise ExecutionError("Invalid outlet index. Ensure the index is within the range 1 to 8.") + + # Setup SNMP connection and OID for the target outlet + _snmp = SimpleSNMP(host, "public", port=port) + oid = f"{POWER_OID_BASE}.{index}" + + logging.debug("Attempting SNMP GET on host %s, OID %s", host, oid) + + try: + # Retrieve the current power state for the specified outlet + value = _snmp.get(oid) + logging.debug("SNMP GET returned value %s for OID %s", value, oid) + + # Verify and interpret the SNMP response + if str(value).strip() == "1": + return True # Outlet is on + elif str(value).strip() == "0": + return False # Outlet is off + else: + raise ExecutionError(f"Unexpected SNMP value '{value}' for outlet {index}") + except Exception as e: + logging.debug("SNMP GET failed for OID %s with exception %s", oid, e) + raise ExecutionError(f"Failed to get power state for outlet {index}: {e}") from e diff --git a/tests/test_powerdriver.py b/tests/test_powerdriver.py index 2ae8783b2..e3f61f957 100644 --- a/tests/test_powerdriver.py +++ b/tests/test_powerdriver.py @@ -282,6 +282,7 @@ def test_import_backends(self): import labgrid.driver.power.digitalloggers_restapi import labgrid.driver.power.eth008 import labgrid.driver.power.gude + import labgrid.driver.power.gude8210 import labgrid.driver.power.gude24 import labgrid.driver.power.netio import labgrid.driver.power.netio_kshell @@ -307,3 +308,7 @@ def test_import_backend_siglent(self): def test_import_backend_poe_mib(self): pytest.importorskip("pysnmp") import labgrid.driver.power.poe_mib + + def test_import_backend_gude8210(self): + pytest.importorskip("pysnmp") + import labgrid.driver.power.gude8210