From 66c9b3663e5b1407ccdbed0e300abe5d5ab55dc2 Mon Sep 17 00:00:00 2001 From: Brett Rowan <121075405+b-rowan@users.noreply.github.com> Date: Tue, 23 Sep 2025 12:39:16 -0600 Subject: [PATCH] feature: add serial number for antminers --- pyasic/data/__init__.py | 1 + pyasic/miners/backends/antminer.py | 19 +++++++++++++++++++ pyasic/miners/base.py | 11 +++++++++++ pyasic/miners/data.py | 1 + tests/miners_tests/__init__.py | 1 + 5 files changed, 33 insertions(+) diff --git a/pyasic/data/__init__.py b/pyasic/data/__init__.py index 7c585592..735dc2c8 100644 --- a/pyasic/data/__init__.py +++ b/pyasic/data/__init__.py @@ -83,6 +83,7 @@ class MinerData(BaseModel): # about device_info: DeviceInfo | None = None + serial_number: str | None = None mac: str | None = None api_ver: str | None = None fw_ver: str | None = None diff --git a/pyasic/miners/backends/antminer.py b/pyasic/miners/backends/antminer.py index 2b1f746e..b2c212b3 100644 --- a/pyasic/miners/backends/antminer.py +++ b/pyasic/miners/backends/antminer.py @@ -39,6 +39,10 @@ from pyasic.web.antminer import AntminerModernWebAPI, AntminerOldWebAPI ANTMINER_MODERN_DATA_LOC = DataLocations( **{ + str(DataOptions.SERIAL_NUMBER): DataFunction( + "_get_serial_number", + [WebAPICommand("web_get_system_info", "get_system_info")], + ), str(DataOptions.MAC): DataFunction( "_get_mac", [WebAPICommand("web_get_system_info", "get_system_info")], @@ -360,6 +364,21 @@ class AntminerModern(BMMiner): except LookupError: pass + async def _get_serial_number( + self, web_get_system_info: dict = None + ) -> Optional[str]: + if web_get_system_info is None: + try: + web_get_system_info = await self.web.get_system_info() + except APIError: + pass + + if web_get_system_info is not None: + try: + return web_get_system_info["serinum"] + except LookupError: + pass + async def set_static_ip( self, ip: str, diff --git a/pyasic/miners/base.py b/pyasic/miners/base.py index 99e25c75..ff51fa32 100644 --- a/pyasic/miners/base.py +++ b/pyasic/miners/base.py @@ -209,6 +209,14 @@ class MinerProtocol(Protocol): ### DATA GATHERING FUNCTIONS (get_{some_data}) ### ################################################## + async def get_serial_number(self) -> Optional[str]: + """Get the serial number of the miner and return it as a string. + + Returns: + A string representing the serial number of the miner. + """ + return await self._get_serial_number() + async def get_mac(self) -> Optional[str]: """Get the MAC address of the miner and return it as a string. @@ -379,6 +387,9 @@ class MinerProtocol(Protocol): """ return await self._get_pools() + async def _get_serial_number(self) -> Optional[str]: + pass + async def _get_mac(self) -> Optional[str]: pass diff --git a/pyasic/miners/data.py b/pyasic/miners/data.py index ad457de3..29ea23f2 100644 --- a/pyasic/miners/data.py +++ b/pyasic/miners/data.py @@ -20,6 +20,7 @@ from typing import List, Union class DataOptions(Enum): + SERIAL_NUMBER = "serial_number" MAC = "mac" API_VERSION = "api_ver" FW_VERSION = "fw_ver" diff --git a/tests/miners_tests/__init__.py b/tests/miners_tests/__init__.py index 11cde1b0..d5ecedeb 100644 --- a/tests/miners_tests/__init__.py +++ b/tests/miners_tests/__init__.py @@ -92,6 +92,7 @@ class MinersTest(unittest.TestCase): "hashrate", "hostname", "is_mining", + "serial_number", "mac", "expected_hashrate", "uptime",