Skip to content

HelixNewton/Bitaxe_agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bitaxe Agent

Guarded Bitaxe controller that polls AxeOS and adjusts frequency, core voltage, and fan settings in small steps. It is designed to keep the miner inside explicit thermal and electrical limits first, then push upward only when there is headroom.

Bitaxe Agent dashboard preview

Two modes are supported:

  • rules: local control loop with no external AI dependency
  • openai: asks an LLM for the next action, but still enforces the same hard safety rails

The controller can tune in two styles:

  • custom numeric steps via BITAXE_FREQ_STEP and BITAXE_VOLTAGE_STEP
  • ASIC option stepping via BITAXE_USE_ASIC_OPTIONS=true

It also keeps a local learning file. The learning layer records observed frequency/core-voltage pairs, marks them stable or unstable against your guardrails, scores them using 10-minute hashrate plus efficiency, remembers the best safe setting, and avoids retrying settings that repeatedly failed.

What it talks to

This controller targets the AxeOS API exposed by bitaxeorg/ESP-Miner:

  • GET /api/system/info
  • GET /api/system/asic
  • PATCH /api/system

The upstream ESP-Miner README documents those endpoints and points to main/http_server/openapi.yaml for the full schema.

Safety model

This is not an unrestricted autotuner.

  • It only changes one step at a time.
  • It enforces min/max frequency and voltage.
  • It clamps operator and AI tuning rails to code-level absolute caps.
  • It applies emergency rollback if thermal limits are exceeded.
  • It raises fan speed before pushing performance.
  • It waits between tuning steps so the miner can settle.
  • It learns only from settings that remain inside your configured temperature, power, error-rate, input-voltage, and domain-spread limits.
  • It can adapt its cooldown: faster when a setting has stable history and plenty of headroom, slower near heat, power, error, or domain-spread limits.

You should keep BITAXE_DRY_RUN=true until you confirm the reported field names and values match your firmware.

Quick start

  1. Copy .env.example to .env.
  2. Set BITAXE_URL to your miner, for example http://192.168.1.50.
  3. Start with conservative limits for your specific board and cooling setup.
  4. Run one dry-run pass:
set -a
source .env
set +a
python3 controller.py --once
  1. If the state looks correct, keep dry-run on for a few loop cycles:
set -a
source .env
set +a
python3 controller.py
  1. Only then set BITAXE_DRY_RUN=false.

Run as services

Both services run on the machine where you install them, not on the Bitaxe itself.

  • bitaxe-agent.service: the controller loop that polls and tunes the miner
  • bitaxe-agent-ui.service: the local dashboard on port 8787 by default

The checked-in service files are examples and expect:

  • project path: /home/x/git/bitaxe_agent
  • env file: /home/x/git/bitaxe_agent/.env

Portable install for the current checkout:

chmod +x install_linux.sh
./install_linux.sh
sudo systemctl status bitaxe-agent
sudo systemctl status bitaxe-agent-ui

After that, open http://YOUR-HOST-IP:8787/ in a browser on your LAN.

The installer generates systemd units for the current checkout path, so the folder can be named bitaxe_agent, Bitaxe_agent, or anything else. It also creates local status.json and learning.json files if they do not exist.

Swarm Dashboard

The dashboard can monitor several miners at once by reading their local status files. Keep one controller process per miner so each device has its own guardrails, learning file, and status file.

  1. Copy swarm.example.json to swarm.json.
  2. Add one entry per miner with a unique status_file.
  3. Run a separate controller service for each miner, each with its own .env or environment file.

Example swarm entry:

{
  "id": "garage",
  "name": "Garage Bitaxe",
  "url": "http://192.168.1.50",
  "api_profile": "axeos",
  "status_file": "status-garage.json"
}

Supported miner profiles are:

  • axeos: AxeOS / ESP-Miner compatible Bitaxe devices
  • generic-json: read-compatible HTTP JSON miners where paths are configured manually
  • nerdminer and esp32: ESP32/NerdMiner monitoring profiles. Stock NerdMiner_v2 currently uses WiFiManager for setup and does not publish a full live telemetry API, so the dashboard can show that the device is reachable and will normalize JSON stats if custom firmware exposes /api/status, /status, /api, or /.
  • futurebit and braiins: placeholders for configured-path monitoring; write actions still require compatible fields

For non-AxeOS miners, start with BITAXE_DRY_RUN=true, set MINER_INFO_PATH, MINER_ASIC_PATH, and MINER_SETTINGS_PATH, then verify the dashboard fields before allowing live control.

For NerdMiner serial logs in the dashboard, connect the ESP32 by USB and make sure the service user can read the serial port:

sudo usermod -aG dialout $USER

Log out and back in, then restart bitaxe-agent-ui. If auto-detect picks the wrong port, set NERDMINER_SERIAL_PORT=/dev/ttyUSB0 in .env.

NerdMiner firmware API

Stock NerdMiner_v2 does not expose the config/status API that this dashboard needs for live pool, Wi-Fi, and wallet changes. For ESP32 boards without SD card access or a usable WiFiManager portal:

  1. Clone NerdMiner_v2 beside this project or set NERDMINER_ROOT=/path/to/NerdMiner_v2 in .env.
  2. Open the dashboard, go to NerdMiner Tools, and enter the ESP32 Wi-Fi, pool, wallet, and optional device URL.
  3. Click Build Config Into Firmware. This installs the API patch and writes a private src/config_api_local.h file inside your local NerdMiner_v2 workspace.
  4. Rebuild and flash the NerdMiner_v2 PlatformIO environment for your board.
  5. After the ESP32 boots on Wi-Fi, use Apply to Patched ESP32 for future live config changes.

The generated config_api_local.h may contain Wi-Fi/password/wallet values. It is written outside this repo and added to the local NerdMiner_v2 git exclude file when possible. Do not commit that generated file.

Patched firmware endpoints:

  • GET /api/status: simple live NerdMiner telemetry for the fleet dashboard.
  • GET /api/config: current pool/wallet settings without exposing passwords.
  • POST /api/config: updates Wi-Fi, pool, wallet, timezone, and stats settings, then restarts the ESP32 by default.

If a miner accepts different setting keys, map them in .env:

MINER_FREQUENCY_FIELD=frequency
MINER_VOLTAGE_FIELD=coreVoltage
MINER_FAN_SPEED_FIELD=fanspeed
MINER_AUTO_FAN_FIELD=autofanspeed

The parser already accepts several common telemetry names for temperature, frequency, voltage, hashrate, fan, power, and domain data. Write control is still guarded by the same min/max rails and dry-run switch.

Updates

The dashboard includes a Check Updates button that compares the local checkout with the configured Git upstream. It does not pull or restart automatically. To update manually:

cd ~/git/bitaxe_agent
git pull
sudo systemctl restart bitaxe-agent
sudo systemctl restart bitaxe-agent-ui

AI mode

Set:

  • BITAXE_MODE=openai
  • an AI API key in your private .env file
  • AI_MODEL=gpt-4.1-mini or another Responses API model available to your account

The model does not get direct authority over the miner. It only proposes the next action, and the controller clamps that action to your configured limits. Before calling OpenAI, the controller still runs the local safety guard; emergency thermal, power, error-rate, input-voltage, and domain-instability rollback decisions bypass AI advice.

Example:

BITAXE_MODE=openai
AI_MODEL=gpt-4.1-mini

This project calls the OpenAI Responses API directly at https://api.openai.com/v1/responses. If you later want a fuller OpenAI Agents SDK integration, keep the same safety split: expose read-only telemetry and a single guarded "propose action" tool, while controller.py remains the only code allowed to write to /api/system.

Learning Controls

These values are in .env.example and windows.env.example:

BITAXE_LEARNING_ENABLED=true
BITAXE_LEARNING_MIN_SAMPLES=3
BITAXE_LEARNING_BAD_LIMIT=2
BITAXE_LEARNING_RESTORE_MARGIN=0.03
BITAXE_LEARNING_EFFICIENCY_WEIGHT=0.25
BITAXE_ADAPTIVE_COOLDOWN_ENABLED=true
BITAXE_ADAPTIVE_MIN_COOLDOWN_SECONDS=45
BITAXE_ADAPTIVE_MAX_COOLDOWN_SECONDS=240
BITAXE_ADAPTIVE_STABLE_SAMPLES=8
BITAXE_LEARNING_FILE=learning.json
  • BITAXE_LEARNING_MIN_SAMPLES: how many stable samples a setting needs before it can become the best-known target.
  • BITAXE_LEARNING_BAD_LIMIT: how many unstable samples make an unproven candidate blocked.
  • BITAXE_LEARNING_RESTORE_MARGIN: if current hashrate is worse than the best stable setting by this fraction, the controller steps back toward the best known safe pair.
  • BITAXE_LEARNING_EFFICIENCY_WEIGHT: how much GH/W contributes to the learned performance score alongside stable 10-minute hashrate.
  • BITAXE_ADAPTIVE_MIN_COOLDOWN_SECONDS: fastest climb interval when the current setting has stable history and clean headroom.
  • BITAXE_ADAPTIVE_MAX_COOLDOWN_SECONDS: slowest climb interval near safety limits or after unstable samples.
  • BITAXE_ADAPTIVE_STABLE_SAMPLES: stable samples required before the controller is allowed to use the fastest climb interval.
  • BITAXE_LEARNING_FILE: local persistent learning database.

Hard caps are also configured, but the Python controller still enforces conservative built-in ceilings even if .env is set higher:

BITAXE_ABSOLUTE_MAX_FREQUENCY=625
BITAXE_ABSOLUTE_MAX_VOLTAGE=1150
BITAXE_ABSOLUTE_MAX_POWER_W=18
BITAXE_CLIMB_POWER_RATIO=0.90
BITAXE_ABSOLUTE_MAX_EMERGENCY_TEMP_C=70
BITAXE_ABSOLUTE_MAX_VR_TEMP_C=75

The learning score is risk-adjusted. It rewards stable 10-minute hashrate and GH/W, then subtracts penalties for high power, high fan, high temperature, error rate, and domain imbalance.

BITAXE_CLIMB_POWER_RATIO controls how much of the configured power budget may be used before the controller is allowed to raise frequency. For example, BITAXE_MAX_POWER_W=17.5 and BITAXE_CLIMB_POWER_RATIO=0.95 gives a climb gate of 16.625W.

Operating Profiles

These are starting points, not promises. Cooling, PSU quality, ambient temperature, and board silicon all matter.

Profile Max frequency Max voltage Cool temp Max power Cooldown
Cool 525 MHz 1060 mV 61C 15.5 W 240 s
Balanced 535 MHz 1090 mV 63C 16.5 W 180 s
Performance 575 MHz 1125 mV 64C 17.5 W 120 s

The included .env.example defaults to the balanced profile with slightly slower domain-spread confirmation, which is a better daily baseline after an overnight run than pushing straight to the highest observed hashrate. The dashboard preset buttons can apply these values to .env; restart bitaxe-agent after saving.

Runtime Privacy

The private .env file is ignored by Git. Runtime status.json is also generated locally and now redacts common sensitive raw telemetry fields such as Wi-Fi identifiers, MAC/IP values, pool usernames, stratum URLs, scripts, certificates, and coinbase output data before the dashboard exposes the raw status panel.

Notes

  • Different AxeOS versions may expose slightly different JSON field names. controller.py already checks several common variants, but you should verify one sample response from your device.
  • This project is preconfigured for an AxeOS-compatible Bitaxe profile. Replace the sample miner URL and guardrails with values that match your own device before live control.
  • The current write mapping uses frequency, coreVoltage, fanspeed, and autofanspeed to match that firmware.
  • The UI writes safe config edits back to .env. Restart bitaxe-agent after saving changes so the controller reloads them.
  • The safest production pattern is to run this on the same LAN as the miner, behind your firewall, not exposed to the internet.

Support

If this project helps you keep your miner cooler, safer, or just a little less dramatic, you can support it here:

Buy me a coffee

References

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors