Skip to content

Conversation

@wilfredallyn
Copy link
Contributor

Summary

Adds set_profile(name: str) -> bool method to the LuxOS backend for programmatic switching between profiles (e.g., 190MHz, 415MHz, 565MHz).

Follows same pattern as set_power_limit() method, including ATM (Advanced Thermal Management) handling.

Motivation

I want to be able to select a profile in Home Assistant using hass-miner. Currently, it only allows choosing a wattage. Adding set_profile is necessary for hass-miner to be able to select a profile.

Changes

pyasic/miners/backends/luxminer.py

  • Added set_profile(name: str) -> bool method to LUXMiner
  • Validates profile name against available profiles with fuzzy matching: "190", "190mhz", and "190MHz" all resolve correctly
  • Extracted _switch_profile() helper to handle ATM disable/re-enable around rpc.profileset() (shared with set_power_limit())
  • If ATM re-enable fails after a successful switch, returns True with a warning (profile did change)
  • Returns False on invalid profile name or RPC failure
  • Re-raises APIError for callers to handle

pyasic/miners/base.py

  • Added set_profile(name: str) -> bool stub to MinerProtocol base class (returns False)
  • Follows the existing convention for set_power_limit() and other control methods

Tests

  • Added 7 tests in tests/miners_tests/backends_tests/luxminer_tests/test_set_preset.py:
    a. Switches profile with ATM enabled (disable → switch → re-enable)
    b. Switches profile with ATM disabled (no ATM toggling)
    c. Returns False for invalid profile name (no RPC call made)
    d. Returns True + logs warning when ATM re-enable fails
    e. Fuzzy matches case-insensitive input ("190mhz" → "190MHz")
    f. Fuzzy matches number-only input ("190" → "190MHz")
    g. Returns False when rpc.profileset() raises an exception

Usage

from pyasic import get_miner

miner = await get_miner("192.168.1.237")
success = await miner.set_profile("190")

Testing

python -m unittest tests.miners_tests.backends_tests.luxminer_tests.test_set_preset -v

wilfredallyn and others added 5 commits February 8, 2026 19:02
Add set_preset(name) method to LUXMiner for switching mining presets by
name. Validates preset against available presets before making RPC calls.

Refactored the ATM disable/re-enable logic shared by set_preset() and
set_power_limit() into a private _switch_profile() helper. This fixes a
bug in set_power_limit() where ATM could stay disabled if the profile
switch failed (the re-enable was inside the same try block as the switch).

The new _switch_profile() uses a finally block to ensure ATM is always
re-enabled if it was disabled, regardless of whether the profile switch
succeeds or fails.
Rename public API to match LuxOS terminology. Accept flexible
input: "190", "190mhz", or "190MHz" all resolve to the correct
firmware profile name.
pass
return None

async def _switch_profile(self, profile_name: str) -> dict:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created helper method that disables and re-enables ATM so don’t duplicate logic in methods that need to do this

)

@staticmethod
def _match_profile_name(name: str, profile_names: list[str]) -> str | None:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When calling set_profile, will accept 190MHz, 190mhz, or 190

result = await self.rpc.profileset(new_preset)
if re_enable_atm:
await self.rpc.atmset(enabled=True)
result = await self._switch_profile(new_preset)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated set_power_limit to use helper method _switch_profile

@wilfredallyn
Copy link
Contributor Author

I went back and forth between naming it set_profile vs set_preset. Do you have a preference?

@b-rowan
Copy link
Collaborator

b-rowan commented Feb 10, 2026

Set profile is fine, I don't think it matters. In theory you could add them both and have one point to the other if you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants