From 21fe2b35da39ef7b3c0938e98e9ade43a20e68f0 Mon Sep 17 00:00:00 2001 From: jamaal Date: Thu, 19 Feb 2026 07:04:38 -0800 Subject: [PATCH 1/2] fix: handle float and string values for BTMiner V3 fan speed --- pyasic/miners/backends/btminer.py | 10 ++++ tests/miners_tests/backends_tests/__init__.py | 1 + .../backends_tests/btminer_tests/__init__.py | 1 + .../btminer_tests/test_v3_psu_fans.py | 46 +++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 tests/miners_tests/backends_tests/btminer_tests/__init__.py create mode 100644 tests/miners_tests/backends_tests/btminer_tests/test_v3_psu_fans.py diff --git a/pyasic/miners/backends/btminer.py b/pyasic/miners/backends/btminer.py index b78fd195a..b869df519 100644 --- a/pyasic/miners/backends/btminer.py +++ b/pyasic/miners/backends/btminer.py @@ -1131,6 +1131,16 @@ async def _get_psu_fans(self, rpc_get_device_info: dict | None = None) -> list[F if rpc_get_device_info is None: return [] rpm = rpc_get_device_info.get("msg", {}).get("power", {}).get("fanspeed") + if rpm is None: + return [] + + # Ensure rpm is an integer, as some models may return it as a string or float + if not isinstance(rpm, int): + try: + rpm = int(round(float(rpm))) + except (TypeError, ValueError): + return [] + return [Fan(speed=rpm)] if rpm is not None else [] async def _get_serial_number( diff --git a/tests/miners_tests/backends_tests/__init__.py b/tests/miners_tests/backends_tests/__init__.py index 81b200cd7..22fc033cb 100644 --- a/tests/miners_tests/backends_tests/__init__.py +++ b/tests/miners_tests/backends_tests/__init__.py @@ -1,3 +1,4 @@ from .avalonminer_tests import * +from .btminer_tests import * from .elphapex_tests import * from .hammer_tests import * diff --git a/tests/miners_tests/backends_tests/btminer_tests/__init__.py b/tests/miners_tests/backends_tests/btminer_tests/__init__.py new file mode 100644 index 000000000..5bbd430dc --- /dev/null +++ b/tests/miners_tests/backends_tests/btminer_tests/__init__.py @@ -0,0 +1 @@ +from .test_v3_psu_fans import TestBTMinerV3PSUFans diff --git a/tests/miners_tests/backends_tests/btminer_tests/test_v3_psu_fans.py b/tests/miners_tests/backends_tests/btminer_tests/test_v3_psu_fans.py new file mode 100644 index 000000000..ab51037c9 --- /dev/null +++ b/tests/miners_tests/backends_tests/btminer_tests/test_v3_psu_fans.py @@ -0,0 +1,46 @@ +"""Tests for BTMiner V3 PSU fan speed parsing.""" + +import unittest + +from pyasic.miners.backends.btminer import BTMinerV3 + + +class TestBTMinerV3PSUFans(unittest.IsolatedAsyncioTestCase): + async def test_get_psu_fans_keeps_int_value(self): + miner = BTMinerV3("127.0.0.1") + + fans = await miner._get_psu_fans( + rpc_get_device_info={"msg": {"power": {"fanspeed": 6000}}} + ) + + self.assertEqual(len(fans), 1) + self.assertEqual(fans[0].speed, 6000) + + async def test_get_psu_fans_converts_float_value(self): + miner = BTMinerV3("127.0.0.1") + + fans = await miner._get_psu_fans( + rpc_get_device_info={"msg": {"power": {"fanspeed": 26.1}}} + ) + + self.assertEqual(len(fans), 1) + self.assertEqual(fans[0].speed, 26) + + async def test_get_psu_fans_converts_string_float_value(self): + miner = BTMinerV3("127.0.0.1") + + fans = await miner._get_psu_fans( + rpc_get_device_info={"msg": {"power": {"fanspeed": "25.7"}}} + ) + + self.assertEqual(len(fans), 1) + self.assertEqual(fans[0].speed, 26) + + async def test_get_psu_fans_invalid_value_returns_empty(self): + miner = BTMinerV3("127.0.0.1") + + fans = await miner._get_psu_fans( + rpc_get_device_info={"msg": {"power": {"fanspeed": "n/a"}}} + ) + + self.assertEqual(fans, []) From b00e6965783605f23dcb39fd3c93c637cfdc6124 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 15:11:45 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyasic/miners/backends/btminer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyasic/miners/backends/btminer.py b/pyasic/miners/backends/btminer.py index b869df519..2a7eadb2c 100644 --- a/pyasic/miners/backends/btminer.py +++ b/pyasic/miners/backends/btminer.py @@ -1133,7 +1133,7 @@ async def _get_psu_fans(self, rpc_get_device_info: dict | None = None) -> list[F rpm = rpc_get_device_info.get("msg", {}).get("power", {}).get("fanspeed") if rpm is None: return [] - + # Ensure rpm is an integer, as some models may return it as a string or float if not isinstance(rpm, int): try: