Update betterproto and regenerate protoc files

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
This commit is contained in:
James Hilliard
2024-10-29 12:14:47 -06:00
committed by Brett Rowan
parent 50cfcf9796
commit b90a92c0df
9 changed files with 272 additions and 207 deletions

14
poetry.lock generated
View File

@@ -59,21 +59,23 @@ pywin32 = ["pywin32 (>=227)"]
[[package]] [[package]]
name = "betterproto" name = "betterproto"
version = "2.0.0b6" version = "2.0.0b7"
description = "A better Protobuf / gRPC generator & library" description = "A better Protobuf / gRPC generator & library"
optional = false optional = false
python-versions = ">=3.7,<4.0" python-versions = "<4.0,>=3.7"
files = [ files = [
{file = "betterproto-2.0.0b6-py3-none-any.whl", hash = "sha256:a0839ec165d110a69d0d116f4d0e2bec8d186af4db826257931f0831dab73fcf"}, {file = "betterproto-2.0.0b7-py3-none-any.whl", hash = "sha256:401ab8055e2f814e77b9c88a74d0e1ae3d1e8a969cced6aeb1b59f71ad63fbd2"},
{file = "betterproto-2.0.0b6.tar.gz", hash = "sha256:720ae92697000f6fcf049c69267d957f0871654c8b0d7458906607685daee784"}, {file = "betterproto-2.0.0b7.tar.gz", hash = "sha256:1b1458ca5278d519bcd62556a4c236f998a91d503f0f71c67b0b954747052af2"},
] ]
[package.dependencies] [package.dependencies]
grpclib = ">=0.4.1,<0.5.0" grpclib = ">=0.4.1,<0.5.0"
python-dateutil = ">=2.8,<3.0" python-dateutil = ">=2.8,<3.0"
typing-extensions = ">=4.7.1,<5.0.0"
[package.extras] [package.extras]
compiler = ["black (>=19.3b0)", "isort (>=5.11.5,<6.0.0)", "jinja2 (>=3.0.3)"] compiler = ["black (>=23.1.0)", "isort (>=5.11.5,<6.0.0)", "jinja2 (>=3.0.3)"]
rust-codec = ["betterproto-rust-codec (==0.1.1)"]
[[package]] [[package]]
name = "certifi" name = "certifi"
@@ -1181,4 +1183,4 @@ type = ["pytest-mypy"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "fdcee9d1f9de23d7c35ab73ca06127e70638929f5db176f6b789cbd7b76bf6b5" content-hash = "d611b5e8b0c5611d6ee916cedfb7f07f20dfc90a675ebaed04188e8b3c96aabe"

View File

@@ -198,7 +198,7 @@ class MiningModePowerTune(MinerConfigValue):
def as_boser(self) -> dict: def as_boser(self) -> dict:
cfg = { cfg = {
"set_performance_mode": SetPerformanceModeRequest( "set_performance_mode": SetPerformanceModeRequest(
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action=SaveAction.SAVE_AND_APPLY,
mode=PerformanceMode( mode=PerformanceMode(
tuner_mode=TunerPerformanceMode( tuner_mode=TunerPerformanceMode(
power_target=PowerTargetMode( power_target=PowerTargetMode(
@@ -275,7 +275,7 @@ class MiningModeHashrateTune(MinerConfigValue):
def as_boser(self) -> dict: def as_boser(self) -> dict:
cfg = { cfg = {
"set_performance_mode": SetPerformanceModeRequest( "set_performance_mode": SetPerformanceModeRequest(
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action=SaveAction.SAVE_AND_APPLY,
mode=PerformanceMode( mode=PerformanceMode(
tuner_mode=TunerPerformanceMode( tuner_mode=TunerPerformanceMode(
hashrate_target=HashrateTargetMode( hashrate_target=HashrateTargetMode(

View File

@@ -467,7 +467,7 @@ class PoolConfig(MinerConfigValue):
def as_boser(self, user_suffix: str = None) -> dict: def as_boser(self, user_suffix: str = None) -> dict:
return { return {
"set_pool_groups": SetPoolGroupsRequest( "set_pool_groups": SetPoolGroupsRequest(
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action=SaveAction.SAVE_AND_APPLY,
pool_groups=[g.as_boser(user_suffix=user_suffix) for g in self.groups], pool_groups=[g.as_boser(user_suffix=user_suffix) for g in self.groups],
) )
} }

View File

@@ -798,7 +798,7 @@ class BOSer(BraiinsOSFirmware):
async def set_power_limit(self, wattage: int) -> bool: async def set_power_limit(self, wattage: int) -> bool:
try: try:
result = await self.web.set_power_target( result = await self.web.set_power_target(
wattage, save_action=SaveAction.SAVE_ACTION_SAVE_AND_FORCE_APPLY wattage, save_action=SaveAction.SAVE_AND_FORCE_APPLY
) )
except APIError: except APIError:
return False return False

View File

@@ -0,0 +1,93 @@
from datetime import datetime, timedelta
from typing import Any, Dict
from betterproto import DATETIME_ZERO, TYPE_MAP, TYPE_MESSAGE, Casing, Message
# https://github.com/danielgtaylor/python-betterproto/pull/609
def to_pydict(
self, casing: Casing = Casing.CAMEL, include_default_values: bool = False
) -> Dict[str, Any]:
"""
Returns a python dict representation of this object.
Parameters
-----------
casing: :class:`Casing`
The casing to use for key values. Default is :attr:`Casing.CAMEL` for
compatibility purposes.
include_default_values: :class:`bool`
If ``True`` will include the default values of fields. Default is ``False``.
E.g. an ``int32`` field will be included with a value of ``0`` if this is
set to ``True``, otherwise this would be ignored.
Returns
--------
Dict[:class:`str`, Any]
The python dict representation of this object.
"""
output: Dict[str, Any] = {}
defaults = self._betterproto.default_gen
for field_name, meta in self._betterproto.meta_by_field_name.items():
field_is_repeated = defaults[field_name] is list
try:
value = getattr(self, field_name)
except AttributeError:
value = self._get_field_default(field_name)
cased_name = casing(field_name).rstrip("_") # type: ignore
if meta.proto_type == TYPE_MESSAGE:
if isinstance(value, datetime):
if (
value != DATETIME_ZERO
or include_default_values
or self._include_default_value_for_oneof(
field_name=field_name, meta=meta
)
):
output[cased_name] = value
elif isinstance(value, timedelta):
if (
value != timedelta(0)
or include_default_values
or self._include_default_value_for_oneof(
field_name=field_name, meta=meta
)
):
output[cased_name] = value
elif meta.wraps:
if value is not None or include_default_values:
output[cased_name] = value
elif field_is_repeated:
# Convert each item.
value = [i.to_pydict(casing, include_default_values) for i in value]
if value or include_default_values:
output[cased_name] = value
elif value is None:
if include_default_values:
output[cased_name] = None
elif (
value._serialized_on_wire
or include_default_values
or self._include_default_value_for_oneof(
field_name=field_name, meta=meta
)
):
output[cased_name] = value.to_pydict(casing, include_default_values)
elif meta.proto_type == TYPE_MAP:
for k in value:
if hasattr(value[k], "to_pydict"):
value[k] = value[k].to_pydict(casing, include_default_values)
if value or include_default_values:
output[cased_name] = value
elif (
value != self._get_field_default(field_name)
or include_default_values
or self._include_default_value_for_oneof(field_name=field_name, meta=meta)
):
output[cased_name] = value
return output
def patch():
Message.to_pydict = to_pydict

View File

@@ -26,6 +26,9 @@ from grpclib.client import Channel
from pyasic import settings from pyasic import settings
from pyasic.errors import APIError from pyasic.errors import APIError
from pyasic.web.base import BaseWebAPI from pyasic.web.base import BaseWebAPI
from pyasic.web.braiins_os.better_monkey import patch
patch()
from .proto.braiins.bos import * from .proto.braiins.bos import *
from .proto.braiins.bos.v1 import * from .proto.braiins.bos.v1 import *
@@ -206,7 +209,7 @@ class BOSerWebAPI(BaseWebAPI):
async def set_immersion_mode( async def set_immersion_mode(
self, self,
enable: bool, enable: bool,
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"set_immersion_mode", "set_immersion_mode",
@@ -227,7 +230,7 @@ class BOSerWebAPI(BaseWebAPI):
) )
async def set_default_power_target( async def set_default_power_target(
self, save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY self, save_action: SaveAction = SaveAction.SAVE_AND_APPLY
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"set_default_power_target", "set_default_power_target",
@@ -238,7 +241,7 @@ class BOSerWebAPI(BaseWebAPI):
async def set_power_target( async def set_power_target(
self, self,
power_target: int, power_target: int,
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"set_power_target", "set_power_target",
@@ -251,7 +254,7 @@ class BOSerWebAPI(BaseWebAPI):
async def increment_power_target( async def increment_power_target(
self, self,
power_target_increment: int, power_target_increment: int,
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"increment_power_target", "increment_power_target",
@@ -265,7 +268,7 @@ class BOSerWebAPI(BaseWebAPI):
async def decrement_power_target( async def decrement_power_target(
self, self,
power_target_decrement: int, power_target_decrement: int,
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"decrement_power_target", "decrement_power_target",
@@ -277,7 +280,7 @@ class BOSerWebAPI(BaseWebAPI):
) )
async def set_default_hashrate_target( async def set_default_hashrate_target(
self, save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY self, save_action: SaveAction = SaveAction.SAVE_AND_APPLY
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"set_default_hashrate_target", "set_default_hashrate_target",
@@ -288,7 +291,7 @@ class BOSerWebAPI(BaseWebAPI):
async def set_hashrate_target( async def set_hashrate_target(
self, self,
hashrate_target: float, hashrate_target: float,
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"set_hashrate_target", "set_hashrate_target",
@@ -302,7 +305,7 @@ class BOSerWebAPI(BaseWebAPI):
async def increment_hashrate_target( async def increment_hashrate_target(
self, self,
hashrate_target_increment: int, hashrate_target_increment: int,
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"increment_hashrate_target", "increment_hashrate_target",
@@ -318,7 +321,7 @@ class BOSerWebAPI(BaseWebAPI):
async def decrement_hashrate_target( async def decrement_hashrate_target(
self, self,
hashrate_target_decrement: int, hashrate_target_decrement: int,
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"decrement_hashrate_target", "decrement_hashrate_target",
@@ -359,7 +362,7 @@ class BOSerWebAPI(BaseWebAPI):
self, self,
wattage_target: int = None, wattage_target: int = None,
hashrate_target: int = None, hashrate_target: int = None,
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
if wattage_target is not None and hashrate_target is not None: if wattage_target is not None and hashrate_target is not None:
logging.error( logging.error(
@@ -459,7 +462,7 @@ class BOSerWebAPI(BaseWebAPI):
async def enable_hashboards( async def enable_hashboards(
self, self,
hashboard_ids: List[str], hashboard_ids: List[str],
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"enable_hashboards", "enable_hashboards",
@@ -472,7 +475,7 @@ class BOSerWebAPI(BaseWebAPI):
async def disable_hashboards( async def disable_hashboards(
self, self,
hashboard_ids: List[str], hashboard_ids: List[str],
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"disable_hashboards", "disable_hashboards",
@@ -485,7 +488,7 @@ class BOSerWebAPI(BaseWebAPI):
async def set_pool_groups( async def set_pool_groups(
self, self,
pool_groups: List[PoolGroupConfiguration], pool_groups: List[PoolGroupConfiguration],
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY, save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
) -> dict: ) -> dict:
return await self.send_command( return await self.send_command(
"set_pool_groups", "set_pool_groups",

View File

@@ -18,7 +18,7 @@ if TYPE_CHECKING:
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class ApiVersion(betterproto.Message): class ApiVersion(betterproto.Message):
"""LATEST_API_VERSION=1.2.0""" """LATEST_API_VERSION=1.3.0"""
major: int = betterproto.uint64_field(1) major: int = betterproto.uint64_field(1)
minor: int = betterproto.uint64_field(2) minor: int = betterproto.uint64_field(2)

View File

@@ -20,125 +20,129 @@ if TYPE_CHECKING:
class SaveAction(betterproto.Enum): class SaveAction(betterproto.Enum):
"""Save action for different operations""" """Save action for different operations"""
SAVE_ACTION_UNSPECIFIED = 0 UNSPECIFIED = 0
SAVE_ACTION_SAVE = 1 SAVE = 1
SAVE_ACTION_SAVE_AND_APPLY = 2 SAVE_AND_APPLY = 2
SAVE_ACTION_SAVE_AND_FORCE_APPLY = 3 SAVE_AND_FORCE_APPLY = 3
class CoolingMode(betterproto.Enum): class CoolingMode(betterproto.Enum):
COOLING_MODE_UNSPECIFIED = 0 UNSPECIFIED = 0
COOLING_MODE_AUTO = 1 AUTO = 1
COOLING_MODE_MANUAL = 2 MANUAL = 2
COOLING_MODE_DISABLED = 3 DISABLED = 3
class SensorLocation(betterproto.Enum): class SensorLocation(betterproto.Enum):
SENSOR_LOCATION_UNSPECIFIED = 0 UNSPECIFIED = 0
SENSOR_LOCATION_CHIP = 1 CHIP = 1
SENSOR_LOCATION_PCB = 2 PCB = 2
class TunerMode(betterproto.Enum): class TunerMode(betterproto.Enum):
TUNER_MODE_UNSPECIFIED = 0 UNSPECIFIED = 0
TUNER_MODE_POWER_TARGET = 1 POWER_TARGET = 1
TUNER_MODE_HASHRATE_TARGET = 2 HASHRATE_TARGET = 2
class TunerState(betterproto.Enum): class TunerState(betterproto.Enum):
TUNER_STATE_UNSPECIFIED = 0 UNSPECIFIED = 0
TUNER_STATE_DISABLED = 1 DISABLED = 1
TUNER_STATE_STABLE = 2 STABLE = 2
TUNER_STATE_TUNING = 3 TUNING = 3
TUNER_STATE_ERROR = 4 ERROR = 4
class LicenseType(betterproto.Enum): class LicenseType(betterproto.Enum):
LICENSE_TYPE_UNSPECIFIED = 0 UNSPECIFIED = 0
LICENSE_TYPE_STANDARD = 1 STANDARD = 1
LICENSE_TYPE_CUSTOM = 2 CUSTOM = 2
class Platform(betterproto.Enum): class Platform(betterproto.Enum):
"""Supported platforms""" """Supported platforms"""
PLATFORM_UNSPECIFIED = 0 UNSPECIFIED = 0
PLATFORM_AM1_S9 = 1 AM1_S9 = 1
PLATFORM_AM2_S17 = 2 AM2_S17 = 2
PLATFORM_AM3_BBB = 3 AM3_BBB = 3
PLATFORM_AM3_AML = 4 AM3_AML = 4
PLATFORM_STM32MP157C_II1_AM2 = 5 STM32MP157C_II1_AM2 = 5
PLATFORM_CVITEK_BM1_AM2 = 6 CVITEK_BM1_AM2 = 6
PLATFORM_ZYNQ_BM3_AM2 = 7 ZYNQ_BM3_AM2 = 7
STM32MP157C_II2_BMM1 = 8
class BosMode(betterproto.Enum): class BosMode(betterproto.Enum):
"""BOS modes enumeration""" """BOS modes enumeration"""
BOS_MODE_UNSPECIFIED = 0 UNSPECIFIED = 0
BOS_MODE_UPGRADE = 1 UPGRADE = 1
BOS_MODE_RECOVERY = 2 RECOVERY = 2
BOS_MODE_SD = 3 SD = 3
BOS_MODE_NAND = 4 NAND = 4
BOS_MODE_EMMC = 5 EMMC = 5
class MinerBrand(betterproto.Enum): class MinerBrand(betterproto.Enum):
MINER_BRAND_UNSPECIFIED = 0 UNSPECIFIED = 0
MINER_BRAND_ANTMINER = 1 ANTMINER = 1
MINER_BRAND_WHATSMINER = 2 WHATSMINER = 2
class MinerModel(betterproto.Enum): class MinerModel(betterproto.Enum):
"""Deprecated: This enumeration is not longer maintained""" """Deprecated: This enumeration is not longer maintained"""
MINER_MODEL_UNSPECIFIED = 0 UNSPECIFIED = 0
MINER_MODEL_ANTMINER_S9 = 1 ANTMINER_S9 = 1
MINER_MODEL_ANTMINER_X17 = 2 ANTMINER_X17 = 2
MINER_MODEL_ANTMINER_S17 = 3 ANTMINER_S17 = 3
MINER_MODEL_ANTMINER_S17_PLUS = 4 ANTMINER_S17_PLUS = 4
MINER_MODEL_ANTMINER_S17_PRO = 5 ANTMINER_S17_PRO = 5
MINER_MODEL_ANTMINER_S17E = 6 ANTMINER_S17E = 6
MINER_MODEL_ANTMINER_T17 = 7 ANTMINER_T17 = 7
MINER_MODEL_ANTMINER_T17E = 8 ANTMINER_T17E = 8
MINER_MODEL_ANTMINER_T17_PLUS = 9 ANTMINER_T17_PLUS = 9
MINER_MODEL_ANTMINER_X19 = 10 ANTMINER_X19 = 10
MINER_MODEL_ANTMINER_S19 = 11 ANTMINER_S19 = 11
MINER_MODEL_ANTMINER_S19_PRO = 12 ANTMINER_S19_PRO = 12
MINER_MODEL_ANTMINER_S19_PLUS = 13 ANTMINER_S19_PLUS = 13
MINER_MODEL_ANTMINER_S19J = 14 ANTMINER_S19J = 14
MINER_MODEL_ANTMINER_S19J_PRO = 15 ANTMINER_S19J_PRO = 15
MINER_MODEL_ANTMINER_S19A = 16 ANTMINER_S19A = 16
MINER_MODEL_ANTMINER_S19A_PRO = 17 ANTMINER_S19A_PRO = 17
MINER_MODEL_ANTMINER_S19XP = 18 ANTMINER_S19XP = 18
MINER_MODEL_ANTMINER_T19 = 19 ANTMINER_T19 = 19
MINER_MODEL_ANTMINER_S19J_PRO_PLUS = 20 ANTMINER_S19J_PRO_PLUS = 20
class MinerStatus(betterproto.Enum): class MinerStatus(betterproto.Enum):
MINER_STATUS_UNSPECIFIED = 0 UNSPECIFIED = 0
MINER_STATUS_NOT_STARTED = 1 NOT_STARTED = 1
MINER_STATUS_NORMAL = 2 NORMAL = 2
MINER_STATUS_PAUSED = 3 PAUSED = 3
MINER_STATUS_SUSPENDED = 4 SUSPENDED = 4
MINER_STATUS_RESTRICTED = 5 RESTRICTED = 5
class SupportArchiveFormat(betterproto.Enum): class SupportArchiveFormat(betterproto.Enum):
"""Enumeration for support archive format""" """Enumeration for support archive format"""
SUPPORT_ARCHIVE_FORMAT_UNSPECIFIED = 0 UNSPECIFIED = 0
SUPPORT_ARCHIVE_FORMAT_ZIP = 1 ZIP = 1
"""Compressed zip format""" """Compressed zip format"""
SUPPORT_ARCHIVE_FORMAT_BOS = 2 BOS = 2
"""BOS custom format""" """BOS custom format"""
ZIP_ENCRYPTED = 3
"""Compressed encrypted zip format"""
class NetworkProtocol(betterproto.Enum): class NetworkProtocol(betterproto.Enum):
NETWORK_PROTOCOL_UNSPECIFIED = 0 UNSPECIFIED = 0
NETWORK_PROTOCOL_DHCP = 1 DHCP = 1
NETWORK_PROTOCOL_STATIC = 2 STATIC = 2
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
@@ -268,8 +272,8 @@ class LoginResponse(betterproto.Message):
timeout_s: int = betterproto.uint32_field(2) timeout_s: int = betterproto.uint32_field(2)
""" """
Authentication token validity/timeout in seconds. Token validity refreshed Authentication token validity/timeout in seconds.
to this value with each request. Token validity refreshed to this value with each request.
""" """
@@ -277,9 +281,7 @@ class LoginResponse(betterproto.Message):
class SetPasswordRequest(betterproto.Message): class SetPasswordRequest(betterproto.Message):
"""Request for set password action.""" """Request for set password action."""
password: Optional[str] = betterproto.string_field( password: Optional[str] = betterproto.string_field(1, optional=True)
1, optional=True, group="_password"
)
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
@@ -335,8 +337,8 @@ class BasesPoints(betterproto.Message):
bsp: int = betterproto.uint32_field(1) bsp: int = betterproto.uint32_field(1)
""" """
A basis point is one hundredth of 1 percentage point. For example: 1bps = A basis point is one hundredth of 1 percentage point.
0.01%, 250bps = 2.5% For example: 1bps = 0.01%, 250bps = 2.5%
""" """
@@ -409,8 +411,8 @@ class VoltageConstraints(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class CoolingAutoMode(betterproto.Message): class CoolingAutoMode(betterproto.Message):
""" """
The temperature control modes. Miner software tries to regulate the fan The temperature control modes.
speed so that miner temperature is approximately at the target temperature. Miner software tries to regulate the fan speed so that miner temperature is approximately at the target temperature.
The allowed temperature range is 0-200 degree Celsius. The allowed temperature range is 0-200 degree Celsius.
""" """
@@ -422,8 +424,7 @@ class CoolingAutoMode(betterproto.Message):
dangerous_temperature: "Temperature" = betterproto.message_field(3) dangerous_temperature: "Temperature" = betterproto.message_field(3)
""" """
Temperature threshold at which BOSMiner shuts down in order to prevent Temperature threshold at which BOSMiner shuts down in order to prevent overheating and damaging the miner.
overheating and damaging the miner.
""" """
@@ -433,12 +434,11 @@ class CoolingManualMode(betterproto.Message):
Fans are kept at a fixed, user-defined speed, no matter the temperature. Fans are kept at a fixed, user-defined speed, no matter the temperature.
""" """
fan_speed_ratio: Optional[float] = betterproto.double_field( fan_speed_ratio: Optional[float] = betterproto.double_field(1, optional=True)
1, optional=True, group="_fan_speed_ratio"
)
""" """
User defined fan speed expressed as a ratio between 0.0 and 1.0 where 0.0 User defined fan speed expressed as a ratio between 0.0 and 1.0
means completely turned off and 1.0 means running at full speed possible where 0.0 means completely turned off and
1.0 means running at full speed possible
""" """
hot_temperature: "Temperature" = betterproto.message_field(2) hot_temperature: "Temperature" = betterproto.message_field(2)
@@ -446,8 +446,7 @@ class CoolingManualMode(betterproto.Message):
dangerous_temperature: "Temperature" = betterproto.message_field(3) dangerous_temperature: "Temperature" = betterproto.message_field(3)
""" """
Temperature threshold at which BOSMiner shuts down in order to prevent Temperature threshold at which BOSMiner shuts down in order to prevent overheating and damaging the miner.
overheating and damaging the miner.
""" """
@@ -455,20 +454,17 @@ class CoolingManualMode(betterproto.Message):
class CoolingDisabledMode(betterproto.Message): class CoolingDisabledMode(betterproto.Message):
"""Disable temperature control. May be dangerous.""" """Disable temperature control. May be dangerous."""
fan_speed_ratio: Optional[float] = betterproto.double_field( fan_speed_ratio: Optional[float] = betterproto.double_field(1, optional=True)
1, optional=True, group="_fan_speed_ratio"
)
""" """
User defined fan speed expressed as a ratio between 0.0 and 1.0 where 0.0 User defined fan speed expressed as a ratio between 0.0 and 1.0
means completely turned off and 1.0 means running at full speed possible where 0.0 means completely turned off and
1.0 means running at full speed possible
""" """
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class CoolingConfiguration(betterproto.Message): class CoolingConfiguration(betterproto.Message):
minimum_required_fans: Optional[int] = betterproto.uint32_field( minimum_required_fans: Optional[int] = betterproto.uint32_field(1, optional=True)
1, optional=True, group="_minimum_required_fans"
)
auto: "CoolingAutoMode" = betterproto.message_field(2, group="mode") auto: "CoolingAutoMode" = betterproto.message_field(2, group="mode")
manual: "CoolingManualMode" = betterproto.message_field(3, group="mode") manual: "CoolingManualMode" = betterproto.message_field(3, group="mode")
disabled: "CoolingDisabledMode" = betterproto.message_field(4, group="mode") disabled: "CoolingDisabledMode" = betterproto.message_field(4, group="mode")
@@ -488,23 +484,19 @@ class CoolingConstraints(betterproto.Message):
class FanState(betterproto.Message): class FanState(betterproto.Message):
"""Structure which contain info about one specific miner fan.""" """Structure which contain info about one specific miner fan."""
position: Optional[int] = betterproto.uint32_field( position: Optional[int] = betterproto.uint32_field(1, optional=True)
1, optional=True, group="_position"
)
"""Fan positions/ID""" """Fan positions/ID"""
rpm: int = betterproto.uint32_field(2) rpm: int = betterproto.uint32_field(2)
"""Actual fan RPM (Revolutions/Rotation Per Minute)""" """Actual fan RPM (Revolutions/Rotation Per Minute)"""
target_speed_ratio: Optional[float] = betterproto.double_field( target_speed_ratio: Optional[float] = betterproto.double_field(3, optional=True)
3, optional=True, group="_target_speed_ratio"
)
"""Actual fan speed ratio(PWM) in range 0.0 - 1.0""" """Actual fan speed ratio(PWM) in range 0.0 - 1.0"""
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class TemperatureSensor(betterproto.Message): class TemperatureSensor(betterproto.Message):
id: Optional[int] = betterproto.uint32_field(1, optional=True, group="_id") id: Optional[int] = betterproto.uint32_field(1, optional=True)
"""Sensor id""" """Sensor id"""
location: "SensorLocation" = betterproto.enum_field(2) location: "SensorLocation" = betterproto.enum_field(2)
@@ -523,7 +515,10 @@ class GetCoolingStateRequest(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class GetCoolingStateResponse(betterproto.Message): class GetCoolingStateResponse(betterproto.Message):
"""Response to get current fan states and temperature measurements""" """
Response to get current fan states and
temperature measurements
"""
fans: List["FanState"] = betterproto.message_field(1) fans: List["FanState"] = betterproto.message_field(1)
"""All Fans state""" """All Fans state"""
@@ -551,12 +546,10 @@ class SetImmersionModeResponse(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class TunerConfiguration(betterproto.Message): class TunerConfiguration(betterproto.Message):
enabled: Optional[bool] = betterproto.bool_field(1, optional=True, group="_enabled") enabled: Optional[bool] = betterproto.bool_field(1, optional=True)
"""Flag if tuner is enabled""" """Flag if tuner is enabled"""
tuner_mode: Optional["TunerMode"] = betterproto.enum_field( tuner_mode: Optional["TunerMode"] = betterproto.enum_field(2, optional=True)
2, optional=True, group="_tuner_mode"
)
"""Tuner mode""" """Tuner mode"""
power_target: "Power" = betterproto.message_field(3) power_target: "Power" = betterproto.message_field(3)
@@ -583,7 +576,7 @@ class TunerConstraints(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class DpsConfiguration(betterproto.Message): class DpsConfiguration(betterproto.Message):
enabled: Optional[bool] = betterproto.bool_field(1, optional=True, group="_enabled") enabled: Optional[bool] = betterproto.bool_field(1, optional=True)
"""Flag if Dynamic Performance Scaling is enabled""" """Flag if Dynamic Performance Scaling is enabled"""
power_step: "Power" = betterproto.message_field(2) power_step: "Power" = betterproto.message_field(2)
@@ -598,9 +591,7 @@ class DpsConfiguration(betterproto.Message):
min_hashrate_target: "TeraHashrate" = betterproto.message_field(5) min_hashrate_target: "TeraHashrate" = betterproto.message_field(5)
"""Dynamic Performance Scaling minimal hashrate target""" """Dynamic Performance Scaling minimal hashrate target"""
shutdown_enabled: Optional[bool] = betterproto.bool_field( shutdown_enabled: Optional[bool] = betterproto.bool_field(6, optional=True)
6, optional=True, group="_shutdown_enabled"
)
"""Flag if shutdown for Dynamic Performance Scaling is enabled""" """Flag if shutdown for Dynamic Performance Scaling is enabled"""
shutdown_duration: "Hours" = betterproto.message_field(7) shutdown_duration: "Hours" = betterproto.message_field(7)
@@ -879,17 +870,13 @@ class SetDpsRequest(betterproto.Message):
save_action: "SaveAction" = betterproto.enum_field(1) save_action: "SaveAction" = betterproto.enum_field(1)
"""Save action""" """Save action"""
enable: Optional[bool] = betterproto.bool_field(2, optional=True, group="_enable") enable: Optional[bool] = betterproto.bool_field(2, optional=True)
"""Flag if Dynamic Performance Scaling should be enabled""" """Flag if Dynamic Performance Scaling should be enabled"""
enable_shutdown: Optional[bool] = betterproto.bool_field( enable_shutdown: Optional[bool] = betterproto.bool_field(3, optional=True)
3, optional=True, group="_enable_shutdown"
)
"""Flag if shutdown for Dynamic Performance Scaling should be enabled""" """Flag if shutdown for Dynamic Performance Scaling should be enabled"""
shutdown_duration: Optional["Hours"] = betterproto.message_field( shutdown_duration: Optional["Hours"] = betterproto.message_field(4, optional=True)
4, optional=True, group="_shutdown_duration"
)
"""Dynamic Performance Scaling shutdown duration""" """Dynamic Performance Scaling shutdown duration"""
target: "DpsTarget" = betterproto.message_field(5) target: "DpsTarget" = betterproto.message_field(5)
@@ -898,17 +885,13 @@ class SetDpsRequest(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class SetDpsResponse(betterproto.Message): class SetDpsResponse(betterproto.Message):
enabled: Optional[bool] = betterproto.bool_field(1, optional=True, group="_enabled") enabled: Optional[bool] = betterproto.bool_field(1, optional=True)
"""Flag if Dynamic Performance Scaling is enabled""" """Flag if Dynamic Performance Scaling is enabled"""
shutdown_enabled: Optional[bool] = betterproto.bool_field( shutdown_enabled: Optional[bool] = betterproto.bool_field(2, optional=True)
2, optional=True, group="_shutdown_enabled"
)
"""Flag if shutdown for Dynamic Performance Scaling should be enabled""" """Flag if shutdown for Dynamic Performance Scaling should be enabled"""
shutdown_duration: Optional["Hours"] = betterproto.message_field( shutdown_duration: Optional["Hours"] = betterproto.message_field(3, optional=True)
3, optional=True, group="_shutdown_duration"
)
"""Dynamic Performance Scaling shutdown duration""" """Dynamic Performance Scaling shutdown duration"""
power_target: "DpsPowerTarget" = betterproto.message_field(4) power_target: "DpsPowerTarget" = betterproto.message_field(4)
@@ -935,7 +918,7 @@ class HashboardConfig(betterproto.Message):
id: str = betterproto.string_field(1) id: str = betterproto.string_field(1)
"""Hashboard id""" """Hashboard id"""
enabled: Optional[bool] = betterproto.bool_field(2, optional=True, group="_enabled") enabled: Optional[bool] = betterproto.bool_field(2, optional=True)
"""Flag if HB si enabled""" """Flag if HB si enabled"""
frequency: "Frequency" = betterproto.message_field(3) frequency: "Frequency" = betterproto.message_field(3)
@@ -1019,9 +1002,9 @@ class Quota(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class FixedShareRatio(betterproto.Message): class FixedShareRatio(betterproto.Message):
""" """
Structure for fixed share ratio load balance strategy Fixed share ratio is Structure for fixed share ratio load balance strategy
value between 0.0 to 1.0 where 1.0 represents that all work is generated Fixed share ratio is value between 0.0 to 1.0 where 1.0 represents that all work is
from the group generated from the group
""" """
value: float = betterproto.double_field(1) value: float = betterproto.double_field(1)
@@ -1058,12 +1041,10 @@ class PoolConfiguration(betterproto.Message):
user: str = betterproto.string_field(3) user: str = betterproto.string_field(3)
"""Pool connection user""" """Pool connection user"""
password: Optional[str] = betterproto.string_field( password: Optional[str] = betterproto.string_field(4, optional=True)
4, optional=True, group="_password"
)
"""Pool connection password if set""" """Pool connection password if set"""
enabled: Optional[bool] = betterproto.bool_field(5, optional=True, group="_enabled") enabled: Optional[bool] = betterproto.bool_field(5, optional=True)
"""Flag if pool connection is enabled""" """Flag if pool connection is enabled"""
@@ -1130,9 +1111,7 @@ class PoolStats(betterproto.Message):
generated_work: int = betterproto.uint64_field(6) generated_work: int = betterproto.uint64_field(6)
"""Generated work""" """Generated work"""
last_share_time: Optional[datetime] = betterproto.message_field( last_share_time: Optional[datetime] = betterproto.message_field(7, optional=True)
7, optional=True, group="_last_share_time"
)
"""Last share time""" """Last share time"""
@@ -1154,9 +1133,9 @@ class GetPoolGroupsResponse(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class CreatePoolGroupRequest(betterproto.Message): class CreatePoolGroupRequest(betterproto.Message):
""" """
Request for pool group create action group.uid must not be specified (it Request for pool group create action
will be generated) group.pools[].uid must not be specified (it will be group.uid must not be specified (it will be generated)
generated) group.pools[].uid must not be specified (it will be generated)
""" """
save_action: "SaveAction" = betterproto.enum_field(1) save_action: "SaveAction" = betterproto.enum_field(1)
@@ -1177,9 +1156,9 @@ class CreatePoolGroupResponse(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class UpdatePoolGroupRequest(betterproto.Message): class UpdatePoolGroupRequest(betterproto.Message):
""" """
Request for pool group update action group.uid must be specified and Request for pool group update action
represents unique id of group which will be updated group.pools[].uid must group.uid must be specified and represents unique id of group which will be updated
not be specified (it will be generated) group.pools[].uid must not be specified (it will be generated)
""" """
save_action: "SaveAction" = betterproto.enum_field(1) save_action: "SaveAction" = betterproto.enum_field(1)
@@ -1221,16 +1200,15 @@ class SetPoolGroupsRequest(betterproto.Message):
save_action: "SaveAction" = betterproto.enum_field(1) save_action: "SaveAction" = betterproto.enum_field(1)
""" """
Save action SAVE just update config but changes will not be applied Save action
SAVE_AND_APPLY and SAVE_AND_FORCE_APPLY are equal for this method. Pools SAVE just update config but changes will not be applied
config will be updated and changes will be applied that will trigger SAVE_AND_APPLY and SAVE_AND_FORCE_APPLY are equal for this method. Pools config will be updated and changes will be applied that will trigger restart.
restart.
""" """
pool_groups: List["PoolGroupConfiguration"] = betterproto.message_field(2) pool_groups: List["PoolGroupConfiguration"] = betterproto.message_field(2)
""" """
Pool groups configuration `uid` must not be specified (it will be Pool groups configuration
generated) `uid` must not be specified (it will be generated)
""" """
@@ -1292,9 +1270,8 @@ class NoneLicense(betterproto.Message):
time_to_restricted: int = betterproto.uint32_field(1) time_to_restricted: int = betterproto.uint32_field(1)
""" """
BOS Initialization timeout - number of seconds elapsed since bosminer start BOS Initialization timeout - number of seconds elapsed since bosminer start
i.e., number of seconds BOS will start mining in restricted mode burning 5% i.e., number of seconds BOS will start mining in restricted mode burning 5% of hashrate
of hashrate For more, see Section 3.10 of For more, see Section 3.10 of https://braiins.com/os/plus/license
https://braiins.com/os/plus/license
""" """
@@ -1313,9 +1290,8 @@ class ValidLicense(betterproto.Message):
time_to_restricted: int = betterproto.uint32_field(3) time_to_restricted: int = betterproto.uint32_field(3)
""" """
Current license expiration - number of seconds since the moment the license Current license expiration - number of seconds since the moment the license was received
was received i.e., number of seconds BOS will start mining in restricted i.e., number of seconds BOS will start mining in restricted mode burning 15% of hashrate
mode burning 15% of hashrate
""" """
dev_fee: "BasesPoints" = betterproto.message_field(4) dev_fee: "BasesPoints" = betterproto.message_field(4)
@@ -1388,7 +1364,8 @@ class MinerIdentity(betterproto.Message):
brand: "MinerBrand" = betterproto.enum_field(1) brand: "MinerBrand" = betterproto.enum_field(1)
model: "MinerModel" = betterproto.enum_field(2) model: "MinerModel" = betterproto.enum_field(2)
""" """
Deprecated: Use miner_model instead. This field is no longer supported. Deprecated: Use miner_model instead.
This field is no longer supported.
""" """
name: str = betterproto.string_field(3) name: str = betterproto.string_field(3)
@@ -1564,7 +1541,7 @@ class Hashboard(betterproto.Message):
stats: "WorkSolverStats" = betterproto.message_field(8) stats: "WorkSolverStats" = betterproto.message_field(8)
"""Hashboard stats""" """Hashboard stats"""
model: Optional[str] = betterproto.string_field(9, optional=True, group="_model") model: Optional[str] = betterproto.string_field(9, optional=True)
"""Hashboard model""" """Hashboard model"""
@@ -1644,9 +1621,7 @@ class GetNetworkConfigurationResponse(betterproto.Message):
class SetNetworkConfigurationRequest(betterproto.Message): class SetNetworkConfigurationRequest(betterproto.Message):
dhcp: "Dhcp" = betterproto.message_field(1, group="protocol") dhcp: "Dhcp" = betterproto.message_field(1, group="protocol")
static: "Static" = betterproto.message_field(2, group="protocol") static: "Static" = betterproto.message_field(2, group="protocol")
hostname: Optional[str] = betterproto.string_field( hostname: Optional[str] = betterproto.string_field(3, optional=True)
3, optional=True, group="_hostname"
)
"""Hostname. Existing value will be preserved if this field is not set.""" """Hostname. Existing value will be preserved if this field is not set."""
@@ -1691,27 +1666,21 @@ class GetNetworkInfoRequest(betterproto.Message):
@dataclass(eq=False, repr=False) @dataclass(eq=False, repr=False)
class GetNetworkInfoResponse(betterproto.Message): class GetNetworkInfoResponse(betterproto.Message):
""" """
Response message for GetCurrentNetworkConfiguration Represents the current Response message for GetCurrentNetworkConfiguration
network configuration for the default network interface. Only IPv4 is Represents the current network configuration for the default network interface.
supported. Only IPv4 is supported.
""" """
name: str = betterproto.string_field(1) name: str = betterproto.string_field(1)
"""Name of the network interface""" """Name of the network interface"""
mac_address: Optional[str] = betterproto.string_field( mac_address: Optional[str] = betterproto.string_field(2, optional=True)
2, optional=True, group="_mac_address"
)
"""MAC address of the network interface""" """MAC address of the network interface"""
hostname: Optional[str] = betterproto.string_field( hostname: Optional[str] = betterproto.string_field(3, optional=True)
3, optional=True, group="_hostname"
)
"""Miner hostname""" """Miner hostname"""
protocol: Optional["NetworkProtocol"] = betterproto.enum_field( protocol: Optional["NetworkProtocol"] = betterproto.enum_field(4, optional=True)
4, optional=True, group="_protocol"
)
"""Network protocol""" """Network protocol"""
dns_servers: List[str] = betterproto.string_field(5) dns_servers: List[str] = betterproto.string_field(5)
@@ -1720,9 +1689,7 @@ class GetNetworkInfoResponse(betterproto.Message):
networks: List["IpNetwork"] = betterproto.message_field(6) networks: List["IpNetwork"] = betterproto.message_field(6)
"""List of assigned IP addresses""" """List of assigned IP addresses"""
default_gateway: Optional[str] = betterproto.string_field( default_gateway: Optional[str] = betterproto.string_field(7, optional=True)
7, optional=True, group="_default_gateway"
)
"""Default gateway/route for the interface""" """Default gateway/route for the interface"""
@@ -2332,7 +2299,7 @@ class MinerServiceStub(betterproto.ServiceStub):
timeout: Optional[float] = None, timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None, deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None metadata: Optional["MetadataLike"] = None
) -> AsyncIterator["GetMinerStatusResponse"]: ) -> AsyncIterator[GetMinerStatusResponse]:
async for response in self._unary_stream( async for response in self._unary_stream(
"/braiins.bos.v1.MinerService/GetMinerStatus", "/braiins.bos.v1.MinerService/GetMinerStatus",
get_miner_status_request, get_miner_status_request,
@@ -2418,7 +2385,7 @@ class MinerServiceStub(betterproto.ServiceStub):
timeout: Optional[float] = None, timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None, deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None metadata: Optional["MetadataLike"] = None
) -> AsyncIterator["GetSupportArchiveResponse"]: ) -> AsyncIterator[GetSupportArchiveResponse]:
async for response in self._unary_stream( async for response in self._unary_stream(
"/braiins.bos.v1.MinerService/GetSupportArchive", "/braiins.bos.v1.MinerService/GetSupportArchive",
get_support_archive_request, get_support_archive_request,
@@ -3195,7 +3162,7 @@ class MinerServiceBase(ServiceBase):
async def get_miner_status( async def get_miner_status(
self, get_miner_status_request: "GetMinerStatusRequest" self, get_miner_status_request: "GetMinerStatusRequest"
) -> AsyncIterator["GetMinerStatusResponse"]: ) -> AsyncIterator[GetMinerStatusResponse]:
raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
yield GetMinerStatusResponse() yield GetMinerStatusResponse()
@@ -3221,7 +3188,7 @@ class MinerServiceBase(ServiceBase):
async def get_support_archive( async def get_support_archive(
self, get_support_archive_request: "GetSupportArchiveRequest" self, get_support_archive_request: "GetSupportArchiveRequest"
) -> AsyncIterator["GetSupportArchiveResponse"]: ) -> AsyncIterator[GetSupportArchiveResponse]:
raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
yield GetSupportArchiveResponse() yield GetSupportArchiveResponse()

View File

@@ -15,7 +15,7 @@ passlib = ">=1.7.4"
pyaml = ">=23.12.0" pyaml = ">=23.12.0"
tomli = { version = ">=2.0.1", python = "<3.11" } tomli = { version = ">=2.0.1", python = "<3.11" }
tomli-w = "^1.0.0" tomli-w = "^1.0.0"
betterproto = "2.0.0b6" betterproto = "2.0.0b7"
aiofiles = ">=23.2.1" aiofiles = ">=23.2.1"
[tool.poetry.group.dev] [tool.poetry.group.dev]