-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathnice_switch
More file actions
121 lines (107 loc) · 5.01 KB
/
nice_switch
File metadata and controls
121 lines (107 loc) · 5.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python2.7
import urllib
import json
import subprocess
import time
import sys
import os
import datetime
# read configuration from file
cfg=json.loads(open(sys.argv[1]).read())
outputDir=cfg["output_dir"]
currency=cfg["currency"] # what's in your wallet?
pwrcost=cfg["pwrcost"] # currency units per kWh
min_profit=cfg["min_profit"] # in BTC per day; halt miners if we're below this
payment_addr=cfg["payment_addr"]
miner_name=cfg["miner_name"]
# speed in GH/s
# power in kW, measured at the wall
# power_limit in watts per card
# gpu_oc & mem_oc as offsets (+/-) from card default
# fan as % (0-100); 0=automatic control
# {ADDR} and {MINER} in cmd will be substituted with payment_addr & miner_name
#
# power_limit, gpu_oc, mem_oc, and fan may be expressed as either an integer that
# is applied to all cards or as an array of integers that get applied to each
# card in turn. This should better accomodate heterogeneous mining rigs.
performance=cfg["performance"]
os.environ["DISPLAY"]=":0"
# do string substitutions in miner commands
for algo in performance:
performance[algo]["cmd"]=performance[algo]["cmd"].format(ADDR=payment_addr, MINER=miner_name)
# fetch data from public APIs
exchrate=float(json.loads(urllib.urlopen("https://api.coinbase.com/v2/exchange-rates?currency=BTC").read())["data"]["rates"][currency])
rawrev=json.loads(urllib.urlopen("https://api.nicehash.com/api?method=simplemultialgo.info").read())["result"]["simplemultialgo"]
# calculate our profitability
profit={}
log=open(outputDir + "/current-profit", "w")
for i in range(0, len(rawrev)):
try:
profit[rawrev[i]["name"]]=float(rawrev[i]["paying"])*performance[rawrev[i]["name"]]["speed"]-24.0*performance[rawrev[i]["name"]]["power"]*pwrcost/exchrate
log.write(rawrev[i]["name"]+": "+format(profit[rawrev[i]["name"]], ".8f")+" BTC/day ("+format(exchrate*profit[rawrev[i]["name"]], ".2f")+" "+currency+"/day)\n")
except:
pass
log.close()
# find maximum
max_profit=0.0
for algo in profit:
if profit[algo]>max_profit:
max_profit_algo=algo
max_profit=profit[algo]
# exit if maximum is below minimum
if (max_profit<=min_profit):
algo_log=open(outputDir + "/algo-log", "a")
algo_log.write(str(datetime.datetime.now())+": **NONE**\n")
algo_log.close()
for algo in performance:
subprocess.call(["pkill", "-f", "^"+performance[algo]["cmd"].replace("+", "\\+")])
sys.exit(0)
try:
subprocess.check_output(["pgrep", "-f", "^"+performance[max_profit_algo]["cmd"].replace("+", "\\+")])
current=1
except:
current=0
if (current==0):
other=0
for algo in performance:
try:
subprocess.check_output(["pgrep", "-f", "^"+performance[algo]["cmd"].replace("+", "\\+")])
other=1
except:
pass
if (current==0):
# log a change
algo_log=open(outputDir + "/algo-log", "a")
algo_log.write(str(datetime.datetime.now())+": "+max_profit_algo+"\n")
algo_log.close()
if (other==1):
# kill existing miners
for algo in performance:
subprocess.call(["pkill", "-f", "^"+performance[algo]["cmd"].replace("+", "\\+")])
time.sleep(3)
if "cuda_ver" in performance[max_profit_algo]:
cudaVer=performance[max_profit_algo]["cuda_ver"]
else:
cudaVer="cuda"
# update card settings
cards=int(subprocess.check_output("nvidia-smi --query-gpu=count --format=csv,noheader,nounits".split(" ")).split("\n")[-2])
nv_settings="nvidia-settings"
for i in range(0, cards):
# power limit
if type(performance[max_profit_algo]["power_limit"]) is int:
subprocess.call(("sudo nvidia-smi -i "+str(i)+" -pl "+str(performance[max_profit_algo]["power_limit"])).split(" "))
else:
subprocess.call(("sudo nvidia-smi -i "+str(i)+" -pl "+str(performance[max_profit_algo]["power_limit"][i])).split(" "))
# core overclock
if type(performance[max_profit_algo]["gpu_oc"]) is int:
nv_settings+=" -a [gpu:"+str(i)+"]/GPUGraphicsClockOffset[2]="+str(performance[max_profit_algo]["gpu_oc"])+" -a [gpu:"+str(i)+"]/GPUGraphicsClockOffset[3]="+str(performance[max_profit_algo]["gpu_oc"])
else:
nv_settings+=" -a [gpu:"+str(i)+"]/GPUGraphicsClockOffset[2]="+str(performance[max_profit_algo]["gpu_oc"][i])+" -a [gpu:"+str(i)+"]/GPUGraphicsClockOffset[3]="+str(performance[max_profit_algo]["gpu_oc"][i])
# memory overclock
if type(performance[max_profit_algo]["mem_oc"]) is int:
nv_settings+=" -a [gpu:"+str(i)+"]/GPUMemoryTransferRateOffset[2]="+str(performance[max_profit_algo]["mem_oc"])+" -a [gpu:"+str(i)+"]/GPUMemoryTransferRateOffset[3]="+str(performance[max_profit_algo]["mem_oc"])
else:
nv_settings+=" -a [gpu:"+str(i)+"]/GPUMemoryTransferRateOffset[2]="+str(performance[max_profit_algo]["mem_oc"][i])+" -a [gpu:"+str(i)+"]/GPUMemoryTransferRateOffset[3]="+str(performance[max_profit_algo]["mem_oc"][i])
subprocess.call(nv_settings.split(" "))
# launch new miner
subprocess.call("PATH=/usr/local/"+str(cudaVer)+"/bin:$PATH LD_LIBRARY_PATH=/usr/local/"+str(cudaVer)+"/lib64:$LD_LIBRARY_PATH screen -c "+str(outputDir)+"/screenrc-miner -dmSL miner "+str(performance[max_profit_algo]["cmd"]), shell=True)