· 4 years ago · Apr 14, 2021, 03:40 PM
1#!/usr/bin/python3
2
3import os
4import sys
5import time
6import re
7import requests
8from urllib.request import Request, urlopen
9import json
10import datetime
11import signal
12from subprocess import PIPE, run
13
14CEND = '\033[0m'
15CBOLD = '\033[1m'
16CRED = '\033[91m'
17CGREEN = '\033[32m'
18CYELLOW = '\033[33m'
19CBLUE = '\033[34m'
20CVIOLET = '\033[35m'
21CBEIGE = '\033[36m'
22
23marketcap_api = "" # Get a free API key at https://pro.coinmarketcap.com/
24wallet_adress = "" # Your ETH wallet address to check the balance on.
25etherscan_api_key = "" # Get a free API key at https://coinmarketcap.com/api/
26worker_key = "" # Your worker key from minerstat to check the mining stats api
27worker_timezone = "America/New_York" # Use your timezone
28# Urls to check
29minerstat_summary_api_url = "http://IP-ADDRESS:4068/summary" # change to miner IP address running T-Rex api. If you use another miner you can get the info from minerstat api
30minerstat_stats_api_url = "https://api.minerstat.com/v2/stats/"+ worker_key
31etherscan_api_url = "https://api.etherscan.io/api?module=account&action=balance&address=" + wallet_adress + "&tag=latest&apikey=" + etherscan_api_key
32etherpool_api_url = "https://api.ethermine.org/miner/" + wallet_adress + "/currentstats"
33headers = {'User-Agent': 'Mozilla/5.0'}
34req_url2 = Request('https://api.minerstat.com/v2/stats/'+ worker_key, headers=headers)
35coin_url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest"
36conversion_factor = 1000000000000000000 # {:.5f} after division
37
38def get_coin_data():
39 url = coin_url
40 parameters = {
41 'symbol':'ETH',
42 'convert':'USD'
43 }
44 headers = {
45 'Accepts': 'application/json',
46 'X-CMC_PRO_API_KEY': marketcap_api,
47 }
48 session = requests.Session()
49 session.headers.update(headers)
50 try:
51 response = session.get(url, params=parameters)
52 data = json.loads(response.text)
53 percent_change = data['data']['ETH']['quote']['USD']['percent_change_24h']
54 latest_price = "${:,.2f}".format(data['data']['ETH']['quote']['USD']['price'])
55 raw_price = data['data']['ETH']['quote']['USD']['price']
56 if percent_change >= 0:
57 latest_change = CGREEN + "{:.2f}%".format(percent_change) + CEND
58 else:
59 latest_change = CRED + "{:.2f}%".format(percent_change) + CEND
60 coin_info = [latest_price, latest_change, raw_price]
61 return coin_info
62 except (ConnectionError, Timeout, TooManyRedirects) as e:
63 print(e)
64
65def numberAbbr(num):
66 num /= 1000
67
68 while len(str(num)) > 4:
69 num = str(num)
70 num = num[:-1]
71
72 return num + "k"
73
74def api_miner_stats():
75 try:
76 data2 = urlopen(req_url2).read().decode()
77 except:
78 print("failed to get URL ({})\nError: {}".format(req_url2,data2.status_code))
79 obj2 = json.loads(data2)
80 revenue_d = obj2['MINER1']['revenue']['usd_day']
81 revenue_day = "${:.2f}".format(revenue_d)
82 revenue_w = obj2['MINER1']['revenue']['usd_week']
83 revenue_week = "${:.2f}".format(revenue_w)
84 revenue_m = obj2['MINER1']['revenue']['usd_month']
85 revenue_month = "${:.2f}".format(revenue_m)
86 try:
87 response = requests.get(etherscan_api_url)
88 except:
89 print("failed to get URL ({})\nError: {}".format(etherscan_api_url,response.status_code))
90
91 data = response.json()
92 latest_wallet = float(data['result']) / conversion_factor
93 p_latest_wallet = "{:.5f} ETH".format(latest_wallet)
94 try:
95 etherpool_response = requests.get(etherpool_api_url)
96 except:
97 print("failed to get URL ({})\nError: {}".format(etherpool_api_url,response.status_code))
98 etherpool_data = etherpool_response.json()
99 latest_pool_pending = float(etherpool_data['data']['unpaid']) / conversion_factor
100 p_latest_pool_pending = "{:.5f} ETH".format(latest_pool_pending)
101 try:
102 response = requests.get(minerstat_stats_api_url)
103 except:
104 print("failed to get URL ({})\nError: {}".format(minerstat_stats_api_url,response.status_code))
105 if response:
106 print("Success! {}".format(response.status_code))
107 else:
108 print("WOOPS! cannot connect!! ({})".format(response.status_code))
109 data2 = response.json()
110 hashrate_raw = data2['MINER1']['mining']['hashrate']['hashrate']
111 hashrate_pretty = "{:.2f} MH/s".format(hashrate_raw)
112 uptime = data2['MINER1']['info']['os']['uptime']
113 api_revenue = [revenue_day, revenue_week, revenue_month, p_latest_pool_pending, p_latest_wallet, latest_wallet, hashrate_pretty, uptime]
114 return api_revenue
115
116def signal_handler(sig, frame):
117 print("\nExiting Tracker...\n")
118 sys.exit(0)
119
120signal.signal(signal.SIGINT, signal_handler)
121
122def bash(command):
123 result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True)
124 return result.stdout
125
126def main():
127 # Generate a program start date and time
128 os.system('clear')
129 difference = [0] * 4
130 cfr = [0] * 2
131
132 while True:
133 now = datetime.datetime.now()
134 stattime = now.strftime("%m/%d/%Y %H:%M:%S")
135 # Write four lines of text.
136 os.system('clear')
137 print("[{0}!{2}] Scraping APIs {1}Please wait...{2}".format(CYELLOW,CVIOLET,CEND))
138
139 try:
140 print_stats = api_miner_stats()
141 coin_data = get_coin_data()
142 except Exception as e:
143 print("[" + CRED + "!" + CEND + "] Error retrieving stats; website most likely denied request. Reattempting in 60 seconds")
144 time.sleep(60)
145 try:
146 print_stats = api_miner_stats()
147 coin_data = get_coin_data()
148 except Exception as e:
149 print("[" + CRED + "!" + CEND + "] Error retrieving second time; waiting 2m50s then running again")
150 time.sleep(150)
151 continue
152
153 try:
154 balance = coin_data[2] * print_stats[5]
155 os.system('clear')
156 print("MINER1 STATS as of {}\n".format(stattime))
157 print("[" + CYELLOW + "i" + CEND + "] " + "Hashrate: " + CGREEN + f'{print_stats[6]}' + CEND)
158 print("[" + CYELLOW + "i" + CEND + "] " + "Uptime: " + CGREEN + f'{print_stats[7]}' + CEND)
159 print("[" + CYELLOW + "i" + CEND + "] " + "Daily Revenue: " + CGREEN + f'{print_stats[0]}' + CEND)
160 print("[" + CYELLOW + "i" + CEND + "] " + "Weekly Revenue: " + CGREEN + f'{print_stats[1]}' + CEND)
161 print("[" + CYELLOW + "i" + CEND + "] " + "Monthly Revenue: " + CGREEN + f'{print_stats[2]}' + CEND)
162 print("[" + CYELLOW + "i" + CEND + "] " + "Pending on Pool: " + CGREEN + f'{print_stats[3]}' + CEND)
163 print("[" + CYELLOW + "i" + CEND + "] " + "Wallet: " + CGREEN + f'{print_stats[4]}' + CEND)
164 print("[" + CYELLOW + "i" + CEND + "] " + "ETH: " + CGREEN + f'{coin_data[0]} ' + CEND + f'{coin_data[1]} (24h)')
165 print("[" + CYELLOW + "i" + CEND + "] " + "Balance: " + CGREEN + f'${balance:.2f} ' + CEND)
166 except Exception as e:
167 # Sometimes I'll get wierd out of bounds errors depending on wha the api's decide to return
168 print("[" + CRED + "!" + CEND + "] Error:", e)
169 continue
170
171 try: # This try block is only for Temp information from Raspberry Pi's and you can remove it.
172 tempC = float(bash("/usr/bin/vcgencmd measure_temp | egrep -o '[0-9]*\.[0-9]*'"))
173 tempF = tempC * 1.8 + 32
174 print("\n[" + CYELLOW + "i" + CEND + "] PROC_TEMP: " + CGREEN + f'{tempC:.2f}' + "\xB0C" + CEND + " | " + CGREEN + f'{tempF:.2f}' + "\xB0F" + CEND)
175 except Exception as e:
176 print("[" + CYELLOW + "i" + CEND + "] " + CYELLOW + "Can't get temp right now..." + CEND)
177 continue
178
179 for i in range(900,0,-1): # Live countdown timer to wait for the next update starts at 900 seconds.
180 sys.stdout.write("\r")
181 sys.stdout.write("[" + CYELLOW + "i" + CEND + "] {:2d} seconds until next refresh.".format(i))
182 sys.stdout.flush()
183 time.sleep(1)
184
185if __name__ == '__main__':
186 main()
187 sys.exit(0)
188