Skip to content

Instantly share code, notes, and snippets.

@randyklein
Last active March 4, 2022 08:20
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save randyklein/9602cb01e1d9a58b52c9b4e162eef76c to your computer and use it in GitHub Desktop.
Save randyklein/9602cb01e1d9a58b52c9b4e162eef76c to your computer and use it in GitHub Desktop.
Simple NiceHash Monitor
This is a simple Python NiceHash script I created to monitor one BTC address & rig.
The script can be modified to monitor more addresses or rigs.
The script was made to run on Linux in Python 2.7.
At a high level, it does the following:
1.Check to see if the application is already running
2.Query nicehash API to get the current sum of the btc/day profitibility rates for all algos
3.If the sum = 0, send an alert that the miner is off.
4.If the sum is below the min threshold set in the config, send an alert
5.Alert when back above the set threshold then exit script
The the script uses the IFTTT Maker chanel to do the alerting. To configure and run:
1. Configure an IFTTT Maker applet. Name the event "nicehash". Take note of your Maker service key.
I configured mine to send both a text and an email
2. Setup the config.py settings. Add your BTC address and IFTTT key
3. Run nicehash_start.py (should probably configure through cron to run at regular intervals).
#config
minProf= .001 #min profit for alert in BTC/Day
slowAlertTimer = 300 #min time for slow alert in seconds
offTimer = 0 #min time of off alert in seconds
btcAddress = "address goes here" #niceHash BTC address to monitor
iftttKey = "key goes here" #key from IFTTT Maker applet
import config
try:
import time
import logging
import logging.handlers
LEVEL = logging.DEBUG # Pick minimum level of reporting logging - debug OR info
# Format to include when, who, where, what
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# Name is module name
logger = logging.getLogger(__name__)
logger.setLevel(LEVEL)
# Create file size limit and file name
handler = logging.handlers.RotatingFileHandler('debug.log', maxBytes=2000000, backupCount=10)
handler.setLevel(LEVEL)
handler.setFormatter(formatter)
# Add handler to logger
logger.addHandler(handler)
logger.debug("Starting app")
def getProf():
#query the nicehash API and sum the profitibility per day (in BTC)
import json, requests
url = 'https://api.nicehash.com/api'
params = dict(
method='stats.provider.ex',
addr= btcAddress
)
resp = requests.get(url=url, params=params)
stats = json.loads(resp.text)
#print (stats["result"]["current"])
totalProf = 0
for i in stats["result"]["current"]:
algoProf = float(i["profitability"])
if "a" in i["data"][0]:
#there is activity for this algo
#to get the profitibility per day in BTC, multiply "a" rate by algo profitibility and add to total prof
totalProf = totalProf + algoProf * float(i["data"][0]["a"])
logger.debug("current total profitibility in BTC/day is " + str(totalProf))
return totalProf
def sendAlert(message, alert):
#trigger IFTTT event
import requests
report = {}
report["value1"] = message
requests.post("https://maker.ifttt.com/trigger/" + alert + "/with/key/" + iftttKey, data=report)
timer = 0
messagesSent = 0
while getProf() == 0:
#looks like the miner is off, alert immediately
logger.info("The miner is off")
if timer >= offTimer and messagesSent == 0:
#has been below the minProf for greater than the slow alert threshold setting, raise an alert
sendAlert("NiceHash miner is off. Go fix it.","nicehash")
messagesSent = 1
time.sleep(30)
timer = timer + 30
while getProf() < minProf:
#currently making less that min profitability setting
#Check again every 30 seconds for 5 minutes
if timer >= slowAlertTimer and messagesSent == 0:
#has been below the minProf for greater than the slow alert threshold setting, raise an alert
sendAlert("NiceHash is running slow. Current rate is " + str(getProf()) + " BTC/Day","nicehash")
messagesSent = 1
logger.info("The miner has been slow for 5 minutes. Current speed is " + str(getProf()) + " BTC/Day")
time.sleep(30)
timer = timer + 30
if messagesSent == 1:
#if it got to this point with a messageSent=1, then it's had an issue and recovered, send recovery message
sendAlert("NiceHash is fast again. Current rate is " + str(getProf()) + " BTC/Day. It was down for " + str(timer / 60) + " mins","nicehash")
logger.info("The miner is back to a normal speed. Current speed is " + str(getProf()) + " BTC/Day")
logger.info("All is well. Nicehash is running above expected rate :) Closing.")
#if the script ends without entering either while statement, then all is well, it should run again via cron
except Exception as e:
logger.exception("something bad happened")
#this script checks to see if the proces already has a PID, and is actively running.
#Only start app if not already running
#/usr/bin/env python
import os
import sys
if os.access(os.path.expanduser("~/.lockfile.vestibular.lock"), os.F_OK):
#if the lockfile is already there then check the PID number
#in the lock file
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "r")
pidfile.seek(0)
old_pid = pidfile.readline()
# Now we check the PID from lock file matches to the current
# process PID
if os.path.exists("/proc/%s" % old_pid):
print "You already have an instance of the program running"
print "It is running as process %s," % old_pid
sys.exit(1)
else:
print "File is there but the program is not running"
print "Removing lock file for the: %s as it can be there because of the program last time it was run" % old_pid
os.remove(os.path.expanduser("~/.lockfile.vestibular.lock"))
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "w")
pidfile.write("%s" % os.getpid())
pidfile.close()
import nicehash
@transmitthis
Copy link

Evening,
That's an interesting script.
I had an idea, wondered if you thought it possible;
Monitor NHML for the global rate (mBTC/Day)
If it falls below a user set amount - restart the program (or more gracefully get the internal switcher to activate)

The default switcher even with adjusted timings seems to have a long tail, so you end up mining for a while with low rates.
In any case, thanks for posting that script, I'll have a go at parsing it and getting my old brain around it.
Kind Regards
TT

@fyrecoins
Copy link

Is this the same script as the chrome extensions? It looks the same, and I am really liking the SNHM on Chrome. It looks like you have a lot better concept of how nicehash, API and Json works.

Is there anyway I can get my unpaid balance into a google spreadsheet?

@rawbertp
Copy link

rawbertp commented Jan 25, 2018

Hi!

Thanks for these scripts. However, I'm having issues getting them to run. Already fixed a few things, but currently I am stuck with the following error:

Traceback (most recent call last):
  File "/.../nicehash.py", line 72, in <module>
    while getProf() < config.minProf:
  File "/.../nicehash.py", line 40, in getProf
    print (stats["result"]["current"])
KeyError: 'current'

I'm running python_start.py with Python 2.7.12.

Edit: I have to add that when uncommenting the print in line 42 it correctly prints out the API results as follows:

[{u'algo': 7, u'suffix': u'MH', u'data': [{u'a': u'314.96'}, u'0.00021474'], u'profitability': u'0.00000634', u'name': u'Nist5'}, {u'algo': 8, u'suffix': u'MH', u'data': [{}, u'0.00004988'], u'profitability': u'0.00035722', u'name': u'NeoScrypt'}, {u'algo': 14, u'suffix': u'MH', u'data': [{}, u'0.00006316'], u'profitability': u'0.00000745', u'name': u'Lyra2REv2'}, {u'algo': 20, u'suffix': u'MH', u'data': [{u'a': u'61.82'}, u'0.00008241'], u'profitability': u'0.00000945', u'name': u'DaggerHashimoto'}, {u'algo': 21, u'suffix': u'GH', u'data': [{u'a': u'1.52', u'rt': u'0.06'}, u'0.00000832'], u'profitability': u'0.00003263', u'name': u'Decred'}, {u'algo': 24, u'suffix': u'Sol', u'data': [{}, u'0.00015454'], u'profitability': u'0.00000071', u'name': u'Equihash'}, {u'algo': 26, u'suffix': u'MH', u'data': [{}, u'0.0000236'], u'profitability': u'0.0000117', u'name': u'X11Gost'}, {u'algo': 29, u'suffix': u'MH', u'data': [{}, u'0.00004465'], u'profitability': u'0.00000974', u'name': u'Skunk'}]

Thanks

@sybalear
Copy link

sybalear commented Mar 4, 2022

Hello,
first of all many thanks for this script. looks awesome. I have a rig that suddenly stops profitability, and would be great to run a google routine to stop ans start the outlet where it is...
I am new to IFTTT, and I can't get the applpet. Wehen I create the new applet, i need to choose a service, but can't find the correct one. Sorry to ask, but please, can you orientate me a little bit? I have been searching on google, but can't find nothing related.
Sorry and many thanks in advance!
best regards
Sergi,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment