-
Notifications
You must be signed in to change notification settings - Fork 0
/
RebootServer.py
255 lines (218 loc) · 7.25 KB
/
RebootServer.py
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/usr/bin/env python3
import RPi.GPIO as GPIO
from time import sleep
import requests
import arrow
import os
import sys
import json
import re
# Try loading the config file and die if not found
try:
os.stat("config.json")
except Exception:
print ("Config file missing!!!", flush=True)
sys.exit(1)
else:
with open('config.json', 'r') as infile:
config = json.load(infile)
# End with
# End try/except block
# Listing of all GPIO pins we can use, 17 total
GPIO_pins = [7, 11, 12, 13, 15, 16, 18, 22, 29, 31, 32, 33, 35, 36, 37, 38, 40]
# Global list to hold our miner objects
miners = []
class miner:
def __init__ (self, name, earl, port, io_out_num, io_in_num):
self.io_in_num = io_in_num
self.io_out_num = io_out_num
self.earl = earl
self.name = name
self.port = port
# End def
def healthCheck (self):
# Returns True/False based on a good or bad health check.
line_regex = r'^<font color="#55FFFF">GPUs: (.*)$'
gpu_regex = r'(\d+\.\d+)'
try:
r = requests.get("%s:%s" % (self.earl, self.port), timeout=10)
except (requests.exceptions.Timeout, requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError) as e:
# Timeout means we can reach the host, but the service isn't running
# ConnectTimeout or ConnectionError means we can't reach the host at all.
return False
else:
if r.status_code == 200:
try:
filtered_text = []
for line in r.text.split("\n"):
if re.match(line_regex, line):
filtered_text.append(line)
# End if
# End for
test_str = filtered_text[-1]
speeds = [float(f) for f in re.findall(gpu_regex, test_str)]
for speed in speeds:
if speed <= 0.0:
return False
# End if
# End for
return True
except Exception as e:
print(e)
return True
# End try/except block
else:
return False
# End if/else block
# End try/except/else block
# End def
def change (self):
# Simulate a power button press
GPIO.output(self.io_out_num, GPIO.LOW)
sleep(1)
GPIO.output(self.io_out_num, GPIO.HIGH)
# End def
def reboot (self):
# Force the PC to shutoff
GPIO.output(self.io_out_num, GPIO.LOW)
sleep(10)
GPIO.output(self.io_out_num, GPIO.HIGH)
# Wait a second between operations
sleep(1)
# Turn the PC back on
self.change()
# End def
def status (self, q=None):
# 0: Miner turned off
# 1: Miner up
# 2: Miner frozen, or not mining
power = not GPIO.input(self.io_in_num)
if power:
program = self.healthCheck()
if program:
if q: q.put((self.name, 1))
#print ("%s, %s" % (self.name, "1"), flush=True)
return(1)
else:
if q: q.put((self.name, 2))
#print ("%s, %s" % (self.name, "2"), flush=True)
return(2)
# End if/else block
else:
if q: q.put((self.name, 0))
#print ("%s, %s" % (self.name, "0"), flush=True)
return(0)
# End if/else block
# End def
def url_status (self, q=None):
# 1: Miner up
# 2: Miner frozen, or not mining
if self.healthCheck():
if q: q.put((self.name, 1))
#print ("%s, %s" % (self.name, "1"), flush=True)
return(1)
else:
if q: q.put((self.name, 2))
#print ("%s, %s" % (self.name, "2"), flush=True)
return(2)
# End if/else block
# End def
# End class
def connection_check():
#Creates r, varaible for google.com URL
r = requests.get('https://google.com')
#Checks if HTTP code is 200(ok)
if r.status_code ==200:
return True
else:
return False
# End if/else block
# End def
def Setup(config):
# Set the GPIO pins to use the board numbering scheme
GPIO.setmode(GPIO.BOARD)
# Disable warnings
GPIO.setwarnings(False)
# Create the miner objects
miners = getMiners()
# Setup all GPIO pins as either input or output devices
for miner in miners.keys():
GPIO.setup(miners[miner].io_out_num, GPIO.OUT, initial=GPIO.HIGH)
GPIO.setup(miners[miner].io_in_num, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# End for
# Return the created miner object list
return miners
# End def
def Cleanup():
# Release all listed GPIO pins
GPIO.cleanup(GPIO_pins)
# End def
def RunServer(miners):
# First, we want to make sure all the miners are at least turned on
for miner in miners.keys():
if miners[miner].url_status() != 1:
#print("Miner %s is fubar!" % (miners[miner].name), flush=True)
pass
else:
#print("Miner %s already running!" % (miners[miner].name), flush=True)
pass
# End if/else block
try:
while True:
print("Sleeping for 300 seconds...", flush=True)
sleep(300)
print("Starting regular checks at %s..." % getTime(), flush=True)
if connection_check():
for miner in miners.keys():
if not miners[miner].healthCheck():
print("Miner %s wasn't responding, so we're rebooting it!" % miners[miner].name, flush=True)
miners[miner].reboot()
else:
print("Miner %s's health check passed!" % miners[miner].name, flush=True)
pass
# End if/else block
#End for block
else:
print("Connection to Google not found. Internet may be down.", flush=True)
# End if/else block
# End while
except KeyboardInterrupt:
return
# End try/except block
# End def
def getTime():
return arrow.now().format('YYYY-MM-DD HH:MM:SS')
# End def
def getMiners():
ret = {}
for item in config['hosts']:
if item['io_out_pin'] not in GPIO_pins or item['io_in_pin'] not in GPIO_pins:
print("One of the pins configured for miner %s is not a valid GPIO pin!" % item['name'])
# End if
ret[item['name']] = (
miner(name=item['name'],
earl=item['url'],
port=item['port'],
io_out_num=item['io_out_pin'],
io_in_num=item['io_in_pin'])
)
# End for
return ret
# End def
def main():
try:
#print ("Setting up the miner objects...", flush=True)
miners = Setup(config)
#print ("Running the miner server...", flush=True)
RunServer(miners)
except Exception as e:
print ("{}" % e, flush=True)
Cleanup()
finally:
sys.exit(0)
# End try/except block
# End def
if __name__ == "__main__":
#print ("Running main...", flush=True)
main()
# End if