fix: enable unbuffered Python output in Docker#10
fix: enable unbuffered Python output in Docker#10mkhnsn wants to merge 32 commits intomrv777:mainfrom
Conversation
Couple of changes: - color not working in windows terminal - suffix in filename in case of voltage/frequency argument - limited (1 successive) retries in case of overheat (previously any chip overheat reached ended the benchmark)
Couple of changes: - color not working in windows terminal - timestamp in filename - suffix in filename in case of voltage/frequency argument - filename computation refactored (called twice) - limited (1 successive) retries in case of overheat (previously any chip overheat reached ended the benchmark)
…solve API mapping and initial state issues
This commit introduces significant enhancements to the Bitaxe Hashrate Benchmark script, focusing on collecting more comprehensive performance data and resolving key issues related to API data retrieval and script robustness.
**Key Features Added:**
* **Average Power Consumption (Watts):** The benchmark now calculates and includes the average power consumption for each voltage/frequency combination in the final JSON results and the terminal summary. This provides a direct metric for power efficiency analysis.
* **Average Fan Speed (RPM/Percentage):** Fan speed data is now fetched and averaged for each tested configuration, then included in the final JSON results and terminal summary. This allows for better assessment of cooling performance and noise levels alongside hashing performance.
* **Real-time Power and Fan Speed Display:** The live terminal output during benchmarking now includes the current power consumption and fan speed for each individual sample, enabling immediate monitoring of these critical metrics.
**Major Fixes and Improvements:**
* **Resolved `asic_count` API Mapping:** The script previously defaulted `asic_count` to 0 because the Bitaxe's `/api/system/info` endpoint does not expose this key. `asic_count` is now hardcoded to 1 in the configuration, ensuring the "Expected Hashrate" calculation is accurate for Bitaxe Gamma 601 (BM1370) models.
* **Corrected Fan Speed API Key:** The script's attempt to fetch "fanSpeed" from the API has been corrected to use "fanspeed" (for percentage) or "fanrpm" (for RPM), based on direct API response analysis. This ensures fan speed data is correctly retrieved.
* **Improved `benchmark_iteration` Return Consistency:** The `benchmark_iteration` function's return signature has been standardized to consistently return 8 values (including `average_power`, `average_fan_speed`, and `error_reason`), ensuring proper unpacking in the main loop. All early exit paths within this function now return a consistent tuple length.
* **Enhanced Script Robustness (Addressing NameError and `results` contradiction):**
* Variables like `error_reason`, `avg_power`, `avg_fan_speed`, etc., are now correctly managed and passed throughout the main execution flow.
* Although the previous `NameError` was challenging to pinpoint without a full traceback, the current implementation addresses potential scope ambiguities and ensures the `results` list is correctly populated and handled even during unexpected exits. This should prevent the "results list is empty" contradiction seen previously.
* **Faster Testing Configuration (Optional):** The default `benchmark_time` was adjusted to 120 seconds (2 minutes) and `frequency_increment` adjusted to 25 MHz for quicker test runs during development. (These can be reverted to original for more exhaustive testing).
These changes collectively make the benchmark tool more accurate, informative, and resilient to common API data inconsistencies, providing a richer dataset for Bitaxe optimization.#
This commit introduces a new command-line option to directly set the core voltage and frequency on the Bitaxe miner, bypassing the full benchmarking process. **Motivation:** Previously, applying specific desired settings required either temporarily modifying the script or running a full benchmark starting at those settings. This new functionality provides a quick, convenient, and direct way to configure the miner to a known good state or a specific operating point without needing to run an entire benchmark cycle. This is particularly useful for fine-tuning after initial benchmarks, or for quickly re-applying optimal settings. **Implementation:** A new command-line flag, -sor--set-values, has been added using argparse. When this flag is detected, the script will: 1. Parse the provided core voltage (-v) and frequency (-f) as the target settings. 2. Call the existing set_system_settings() function to apply these parameters to the Bitaxe. 3. Print confirmation messages. 4. Exit immediately using sys.exit(0), preventing the benchmark loop from initiating. **Usage:** To use this new mode, run the script with the --set-values flag, specifying your desired voltage and frequency: python bitaxe_hasrate_benchmark.py <bitaxe_ip> --set-values -v <desired_voltage_mV> -f <desired_frequency_MHz> Example: python bitaxe_hasrate_benchmark.py 192.168.1.136 --set-values -v 1150 -f 780 This enhancement streamlines the process of applying specific configurations to the Bitaxe miner.#
Enhanced the script's command-line help message to be more user-friendly and informative. Key improvements include: * **Clearer Descriptions:** Detailed explanations for each argument, including their dual purpose for benchmarking and setting values. * **Usage Examples:** Added explicit command examples for both benchmark and set-only modes in the help message's epilog. * **Improved Formatting:** Utilized a custom formatter to preserve multi-line text, add default values, and incorporate color for better readability.#
Resolved rendering issues in argument lists by correctly applying single backticks for inline code, ensuring proper display on GitHub.
Resolved rendering issues in argument lists by correctly applying single backticks for inline code, ensuring proper display on GitHub.
Without PYTHONUNBUFFERED=1, Python fully buffers stdout when not connected to a TTY, causing docker logs to appear empty until the container exits. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds an unbuffered Python setting and a default Changes
Sequence DiagramssequenceDiagram
actor User
participant CLI as CLI Parser
participant Device as Bitaxe Device
participant FS as Result File
User->>CLI: Run with --set-values + voltage/frequency
CLI->>CLI: Validate inputs
CLI->>Device: set_system_settings(voltage, frequency)
Device->>Device: Apply settings & restart
Device-->>CLI: Return status (success/fail)
CLI->>FS: Optionally log/apply result_filename()
CLI->>User: Exit with status
sequenceDiagram
actor User
participant Bench as Benchmark Loop
participant Device as Bitaxe Device
participant Monitor as Stabilization Monitor
participant Results as Result Storage
User->>Bench: Start benchmark run
Bench->>Device: set_system_settings(voltage, frequency)
Bench->>Device: restart_system()
Device-->>Monitor: Emit streaming metrics (hashrate, temp, power, fan)
Monitor->>Monitor: Evaluate stabilization (variance, temp, retries)
alt Stabilized
Bench->>Bench: Compute running_stddev, averages
Bench->>Results: Save JSON via result_filename()
else Overheat / Unstable
Bench->>Bench: Adjust voltage/frequency and retry
Bench->>Device: Re-apply adjusted settings
end
Bench-->>User: Return enriched result payload
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@bitaxe_hashrate_benchmark.py`:
- Around line 46-58: The help/epilog text in the ArgumentParser (where parser =
argparse.ArgumentParser(...)) contains a typo in the script name
("bitaxe_hasrate_benchmark.py" missing the "h"); update all example lines in the
epilog that reference that filename to the correct
"bitaxe_hashrate_benchmark.py" so the usage examples match the actual script
name and avoid user confusion.
- Around line 339-363: The stabilization loop that calls get_system_info()
currently swallows all exceptions and can treat repeated telemetry failures as a
successful stabilization; update the loop in bitaxe_hashrate_benchmark.py to
track consecutive read errors (e.g., add a failure_counter initialized before
the while, increment on exception or when info is falsy, and reset on a
successful read), log the failure reason via print or a logger when an error
occurs, and if the failure_counter exceeds a small threshold (e.g., 3
consecutive failures) exit the function with False to fail stabilization; keep
the existing temperature/power/vr checks (temp, vr_temp, power) and only reset
the counter when a valid info dict is returned.
In `@README.md`:
- Around line 132-133: Update the README description of the benchmark output
filename to match the actual behavior: change the static name
"bitaxe_benchmark_results_<ip_address>.json" to the runtime filename pattern
that includes the timestamp/suffix (e.g.,
"bitaxe_benchmark_results_<ip_address>_<timestamp>.json" or similar), and ensure
any surrounding text or examples reference that updated filename format so docs
match the code that writes the timestamped files.
Results are written to /results inside the container by default, making them accessible on the host via a bind mount: docker run -v $(pwd)/results:/results bitaxe-benchmark ... Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix script name typo in help examples (hasrate -> hashrate) - Track consecutive failures during stabilization instead of silently ignoring them - Update README output filename to reflect timestamp pattern Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
bitaxe_hashrate_benchmark.py (1)
508-513:⚠️ Potential issue | 🟠 MajorGuard VR-temp trimming to avoid ZeroDivisionError on short series.
trimmed_vr_tempscan be empty when fewer than 7 VR temp samples are available, causing division by zero. Consider trimming only when enough samples exist, otherwise average the available values or skip VR temp.🛠️ Suggested fix
- if vr_temps: - sorted_vr_temps = sorted(vr_temps) - trimmed_vr_temps = sorted_vr_temps[6:] # Remove first 6 elements only - average_vr_temp = sum(trimmed_vr_temps) / len(trimmed_vr_temps) + if vr_temps: + sorted_vr_temps = sorted(vr_temps) + if len(sorted_vr_temps) > 6: + trimmed_vr_temps = sorted_vr_temps[6:] # Remove first 6 elements only + else: + trimmed_vr_temps = sorted_vr_temps + average_vr_temp = sum(trimmed_vr_temps) / len(trimmed_vr_temps)
Summary
ENV PYTHONUNBUFFERED=1to the Dockerfile so container logs appear in real-timedocker logs -fto show nothing until the container exitsDepends on
Test plan
docker logs -f <container>shows output in real-time during benchmarking🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes / Reliability
Documentation
Chores