Skip to content

Conversation

@cniweb
Copy link
Contributor

@cniweb cniweb commented Dec 22, 2025

Summary

This PR implements support for retrieving serial numbers from Braiins OS Plus miners as described in issue #390.

Features

  • Miner Serial Number: Available via get_serial_number() and miner_data.serial_number
  • PSU Serial Number: Available via get_psu_serial_number() and miner_data.psu_serial_number
  • Hashboard Serial Numbers: Populated in miner_data.hashboards[n].serial_number

Implementation Details

Changes Made

  1. Updated BOS gRPC Proto Definitions

    • Added ControlBoardSocFamily enum for control board SoC identification
    • Added PsuInfo message with PSU serial number, version, firmware, and model fields
    • Extended GetMinerDetailsResponse with miner serial number and PSU info
    • Extended Hashboard message with serial number and additional fields
    • Marked PSU voltage fields as optional per upstream proto
  2. Extended Data Model

    • Added PSU_SERIAL_NUMBER to DataOptions enum
    • Added psu_serial_number field to MinerData class
    • Documented PSU serial in MinerData docstring
  3. Updated Base Miner Class

    • Added public get_psu_serial_number() method
    • Added protected _get_psu_serial_number() method with default no-op implementation
  4. Implemented for BOSer Miners

    • Implemented _get_serial_number() to fetch miner serial from gRPC
    • Implemented _get_psu_serial_number() to fetch PSU serial from psuInfo
    • Updated BOSER_DATA_LOC mapping with both serial options
    • Populated hashboard serial numbers from get_hashboards response
  5. Updated Tests

    • Added psu_serial_number to expected data location keys

Compatibility

  • Requires Braiins OS Plus API v1.5.0 and firmware 25.03 or newer
  • Tested with all 99 unit tests passing
  • Pre-commit hooks (ruff-check) passing

Related Issues

Closes #390

- Add ControlBoardSocFamily enum for control board SoC identification
- Add PsuInfo message with PSU serial number, version, firmware, model
- Extend GetMinerDetailsResponse with miner serial number and PSU info
- Extend Hashboard message with serial number and additional fields
  (lowest inlet temperature, highest outlet temperature, board name, chip type)
- Mark PSU voltage fields as optional to match upstream proto

Supports API v1.5.0+ and firmware 25.03+

Closes UpstreamData#390
- Add PSU_SERIAL_NUMBER to DataOptions enum
- Add psu_serial_number field to MinerData class
- Document PSU serial number in MinerData docstring
- Enables collecting and exposing PSU serials from compatible miners
- Add public get_psu_serial_number() method to miner interface
- Add protected _get_psu_serial_number() method with default no-op impl
- Allows subclasses to implement PSU serial retrieval
- Add _get_serial_number() for miner serial from get_miner_details gRPC
- Add _get_psu_serial_number() for PSU serial from psuInfo
- Add SERIAL_NUMBER and PSU_SERIAL_NUMBER to BOSER_DATA_LOC mapping
- Populate hashboard.serial_number from get_hashboards response

Supports API v1.5.0+ (firmware 25.03+) with miner, PSU, and hashboard
serial numbers now available via get_data() method
- Add psu_serial_number to expected data location keys in MinersTest
- Ensures all miner types include PSU serial in data mapping
@b-rowan
Copy link
Collaborator

b-rowan commented Dec 22, 2025

Did you do the gRPC implementation updates manually?

cniweb and others added 3 commits December 22, 2025 18:12
- Add tests/local_tests/ directory for manual hardware tests
- Add test_braiins_serials.py script to test miner, PSU, and hashboard serials
- Add README.md with usage instructions and troubleshooting
- Add __init__.py to mark directory as package

These are optional local tests for developers testing with real hardware
@cniweb
Copy link
Contributor Author

cniweb commented Dec 22, 2025

Did you do the gRPC implementation updates manually?

Here's a response to the reviewer's question in English:

No, the gRPC implementation updates were not done entirely manually. The file init.py is a generated file (as indicated by the header: "Generated by the protocol buffer compiler. DO NOT EDIT!").

The new message types and fields were generated from the upstream Braiins OS Plus API v1.5.0+ Protocol Buffer definitions. Here's how the process works:

  1. Proto Sources: The original .proto files are sourced from the braiins/bos-plus-api repository
  2. Code Generation: Using protoc with the python-betterproto plugin, the Python implementation file was generated
  3. Betterproto v2.0.0b7: The project uses betterproto for gRPC communication

Added Components (all derived from the latest Proto definitions):

  • ControlBoardSocFamily enum - for identifying the control board type
  • PsuInfo message - containing serial_number and other PSU specifications
  • GetMinerDetailsResponse.psu_info field - for PSU information
  • GetMinerDetailsResponse.serial_number field - for miner serial number
  • Hashboard.serial_number field - for hashboard serial numbers

All these fields align with the current Braiins API specification. The implementation layer (braiins_os.py) was written manually to extract and expose these proto fields through the standard pyasic interface.

- Remove try-except blocks for AttributeError since dict.get() doesn't raise it
- Simplify code flow for better static analysis compliance
- Remove trailing colons from headings
- Add blank line before list items for better readability
- Reduce function complexity by splitting into smaller functions
- Remove hardcoded passwords from function defaults (security)
- Fix README line length issues (80 char limit)
- Change H1 to H2 header for proper document structure
- Simplify text for better readability
Tested locally on Braiins BMM100 miner
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.

Braiins Serial Number Support

2 participants