Local fan control and temperature monitoring for Goldshell ASIC miners. It talks directly to the miner over your LAN and provides:
- a CLI for reading temperatures, fan RPM, and setting a fan bias;
- safe adaptive mode, which leaves Goldshell temperature control enabled;
- an explicitly confirmed fixed-speed mode;
- a temperature-triggered watchdog that can run continuously;
- a loopback-only web dashboard for miner status, pools, and power mode.
No cloud account, external server, or npm package installation is required.
Important
This is an independent community project, not an official Goldshell product.
It was tested with a Goldshell SC Lite using the firmware 2.x dashboard API.
Other models may use a different power-plan format. Read the current settings
with ./goldshell fans before applying a change.
- Node.js 20 or newer
- A Mac or Linux computer on the same trusted LAN as the miner
- The miner's local IP address and dashboard password
- Git, if installing by cloning the repository
Check Node.js:
node --versionClone the repository and enter it:
git clone https://github.com/f4u57ox/goldshell-fan-manager.git
cd goldshell-fan-manager
chmod +x goldshell scripts/*.shThere are no third-party JavaScript dependencies, so npm install is not
required.
Configure the miner connection. Replace the address and password with your own:
./goldshell configure \
--miner-url http://miner.local \
--miner-username admin \
--miner-password 'YOUR-DASHBOARD-PASSWORD'The generated .data/config.json file is readable only by your user and is
excluded from Git. Never upload it or paste its API token or password into an
issue.
Start the local bridge:
npm startKeep that terminal open. In another terminal, verify the connection:
./goldshell bridge
./goldshell status
./goldshell fansThe optional dashboard is available only on this computer at http://127.0.0.1:4317.
This command sets both fan values to 90 while keeping Goldshell's automatic temperature control enabled:
./goldshell fan --bias 90Valid values are integers from 10 through 100. The firmware labels these values
as RPM inside manualPowerplan, but they behave as fan bias values rather than
literal RPM targets.
With temperature control enabled, actual RPM can decrease after the miner cools.
That is expected: the requested bias remains saved while the firmware continues
managing the physical fan speed. Use ./goldshell fans to see both the saved plan
and live RPM.
Examples:
./goldshell fan --bias 70
./goldshell fan --bias 85
./goldshell fan --bias 100
./goldshell fansEvery safe-mode write preserves the miner's existing MHz, voltage, and PV values,
selects the manual plan, changes only the two fan fields, and keeps
tempcontrol=true.
Goldshell's automatic temperature control must be disabled for firmware that otherwise lowers RPM as the miner cools. This is a materially different and less safe operating mode, so the CLI requires an explicit confirmation:
./goldshell fan --bias 90 --constant --yesFixed mode means the firmware may not automatically increase fan speed if temperatures rise. Some Goldshell firmware accepts this setting, briefly raises the fans, and later reduces RPM anyway. The command confirms the saved setting; it cannot guarantee that the firmware will continue honoring it.
Monitor every board, keep the miner in a ventilated area, and do not use a low fixed bias. Restore automatic temperature control at any time by running the normal command again:
./goldshell fan --bias 90The watchdog polls board telemetry. In its default adaptive mode it reapplies a configured fan bias whenever the hottest board reaches the threshold, while keeping Goldshell temperature control enabled. At the emergency temperature it applies the emergency bias.
Its optional fixed-watchdog mode handles firmware that drifts away from a saved fixed fan setting: it samples every physical fan and reasserts the selected bias only when the lowest fan falls below a configured RPM floor. This avoids writing settings on every poll.
Run it in the foreground with defaults:
npm run fan-managerDefault profile:
| Setting | Default | Allowed range |
|---|---|---|
| Temperature threshold | 70°C | 40–89°C |
| Fan bias | 70 | 10–100 |
| Emergency temperature | 90°C | 70–94°C |
| Emergency bias | 100 | 70–100 |
| Poll interval | 5 seconds | 3–300 seconds |
| Reapply cooldown | 120 seconds | 30–3,600 seconds |
| Fixed watchdog | false | true/false |
| Minimum fan RPM | 1,800 RPM | 500–10,000 RPM |
Customize it with environment variables:
GOLDSHELL_FAN_THRESHOLD_C=68 \
GOLDSHELL_FAN_BIAS=90 \
GOLDSHELL_FAN_EMERGENCY_C=85 \
GOLDSHELL_FAN_EMERGENCY_BIAS=100 \
GOLDSHELL_FAN_POLL_SECONDS=5 \
GOLDSHELL_FAN_COOLDOWN_SECONDS=60 \
npm run fan-managerThe watchdog applies a higher bias when a threshold is crossed; it does not automatically write a lower bias when the miner cools.
For firmware that keeps lowering RPM, run the fixed watchdog:
GOLDSHELL_FAN_FIXED=true \
GOLDSHELL_FAN_MINIMUM_RPM=1800 \
GOLDSHELL_FAN_BIAS=90 \
GOLDSHELL_FAN_EMERGENCY_C=85 \
GOLDSHELL_FAN_EMERGENCY_BIAS=100 \
GOLDSHELL_FAN_POLL_SECONDS=5 \
GOLDSHELL_FAN_COOLDOWN_SECONDS=30 \
npm run fan-managerThis mode disables the miner's automatic temperature-control flag and therefore requires close temperature monitoring. If the process stops, the firmware may reduce RPM again.
The installer creates a per-user LaunchAgent and starts it immediately. Pass the desired profile on the installation command:
GOLDSHELL_FAN_THRESHOLD_C=68 \
GOLDSHELL_FAN_BIAS=90 \
GOLDSHELL_FAN_EMERGENCY_C=85 \
GOLDSHELL_FAN_EMERGENCY_BIAS=100 \
./scripts/install-fan-manager-launchagent.shTo install the fixed watchdog instead:
GOLDSHELL_FAN_FIXED=true \
GOLDSHELL_FAN_MINIMUM_RPM=1800 \
GOLDSHELL_FAN_BIAS=90 \
GOLDSHELL_FAN_EMERGENCY_C=85 \
GOLDSHELL_FAN_EMERGENCY_BIAS=100 \
GOLDSHELL_FAN_COOLDOWN_SECONDS=30 \
./scripts/install-fan-manager-launchagent.shCheck the service and logs:
launchctl print "gui/$(id -u)/io.github.f4u57ox.goldshell-fan-manager"
tail -f .data/fan-manager.logTo change the profile, run the installer again with new values. To stop and disable it without deleting configuration or logs:
./scripts/uninstall-fan-manager-launchagent.shFirst verify npm run fan-manager in the foreground. Then copy and edit the
included systemd example:
sudo cp systemd/goldshell-fan-manager.service.example \
/etc/systemd/system/goldshell-fan-manager.service
sudoedit /etc/systemd/system/goldshell-fan-manager.service
sudo systemctl daemon-reload
sudo systemctl enable --now goldshell-fan-manager.service
sudo systemctl status goldshell-fan-manager.serviceReplace every YOUR_USER and /path/to/goldshell-fan-manager placeholder before
starting the service. The selected user must be able to read .data/config.json.
The bridge also exposes deliberately scoped commands for inspecting status and managing pools:
./goldshell status
./goldshell pools
./goldshell add-pool --url 'stratum+tcp://pool.example.com:3333' \
--user 'wallet.worker' --password 'x'
./goldshell mode --level 0Run ./goldshell help for the full command list. Pool deletion and miner restart
require explicit confirmation. Factory reset, firmware upload, network changes,
and dashboard password changes are intentionally not exposed.
- Confirm the computer and miner are on the same LAN or VLAN.
- Open the miner dashboard in a browser using its current IP address.
- Check whether DHCP assigned the miner a new address.
- Update the address with
./goldshell configure --miner-url http://NEW-IP. - Update the saved password if read-only status works but fan changes fail.
- Restart
npm startafter changing bridge configuration.
Run ./goldshell fans. If tempcontrol is true, the firmware is adapting RPM
as temperatures change. This is the default safe behavior. If tempcontrol is
false but RPM still falls, the firmware is overriding the saved manual plan;
use the fixed watchdog only after reading its warning above.
The tool only rewrites a plan shaped like:
615 MHz 9100 V 90 RPM 90 RPM PV 9400
It refuses unknown formats instead of guessing. Open an issue with the plan after removing any private information, along with the miner model and firmware version.
- The web/API bridge refuses to bind beyond loopback.
- Miner targets must be private IP addresses or
.localhostnames by default. - Control requests require a random token stored in the mode-0600 local config.
- Cross-origin browser requests are rejected.
- Generic miner commands are read-only and allowlisted.
- Runtime data, credentials, tokens, and logs are excluded from Git.
Do not expose port 4317 to the Internet or run this on an untrusted LAN. See SECURITY.md for vulnerability reporting and operational guidance.
npm test
npm run checkTests use fake local servers and do not contact or modify a real miner.
MIT. See LICENSE.