'''#what to do when miner is offline? #maybe send alert? #maybe disable the miner after a while? ''' from helpers.queuehelper import QueueName, QueueEntries from domain import mining from fcmapp import Component OFFLINE = Component('offline') def when_offline(channel, method, properties, body): '''when miner goes offline''' print("[{0}] Received miner offline message".format(OFFLINE.app.now())) try: entries = dooffline(OFFLINE.app.messagedecodeminer(body)) OFFLINE.app.enqueue(entries) except Exception as ex: OFFLINE.app.logexception(ex) def dooffline(miner: mining.Miner): '''notify user''' entries = QueueEntries() savedminer = OFFLINE.app.getminer(miner) if not savedminer.is_disabled(): if savedminer.is_send_offline_alert(): #update status to offline and alert savedminer.status = mining.MinerStatus.Offline alertmsg = OFFLINE.app.stamp( 'miner {0} is offline! since {1}'.format(
'''checks for web update''' import json import docker from helpers.queuehelper import QueueName from fcmapp import Component COMPONENTUPDATE = Component('fullcycle') def when_updateweb(channel, method, properties, body): '''event handler when updateweb event is raised''' try: print("[{0}] Received update web message".format( COMPONENTUPDATE.app.now())) doupdateweb(body.decode()) except Exception as ex: COMPONENTUPDATE.app.logexception(ex) def doupdateweb(msg): '''check if web app should be updated''' doupdate = False repository_name = COMPONENTUPDATE.app.configuration( 'update.fullcycleweb.name.repository') client = docker.client.APIClient() webstatus = client.pull(repository_name) print(webstatus) for line in webstatus.splitlines(): jline = json.loads(line) if 'status' in jline and jline['status'].startswith('Status'):
''' listens for pool switch command ''' import datetime from threading import Thread from queue import Queue from colorama import Fore #from pika.exceptions import ChannelClosed from helpers import antminerhelper from helpers.queuehelper import QueueName from domain.mining import MinerCommand, MinerAccessLevel from domain.logging import MinerLog from fcmapp import Component COMPONENTACTION = Component('action') def enthread(target, args): '''put a method on a queue to be run in background''' thread_queue = Queue() def wrapper(): thread_queue.put(target(*args)) thread = Thread(target=wrapper) thread.start() return thread_queue def when_switch(channel, method, properties, body): '''Handler for pool switching''' try: print("[{0}] Received switch command".format(COMPONENTACTION.app.now())) minermsg = COMPONENTACTION.app.messagedecodeminercommand(body)
'''what to do when miner becomes online enable, provision and start monitoring ''' from helpers.queuehelper import QueueName, QueueEntries from fcmapp import Component ONLINE = Component('online') def when_online(channel, method, properties, body): '''whan a miner is found to be online after being offline''' print("[{0}] Received miner online message".format(ONLINE.app.now())) try: miner = ONLINE.app.messagedecodeminer(body) entries = doonline(miner) ONLINE.app.enqueue(entries) except Exception as ex: ONLINE.app.logexception(ex) def doonline(miner): '''then provision the miner''' entries = QueueEntries() savedminer = ONLINE.app.getminer(miner) if savedminer is None: savedminer = miner #update status savedminer.online_now() ONLINE.app.putminer(savedminer) ONLINE.app.updateknownminer(savedminer) #just provision the miner and start to monitor
'''# use to provision miners with default pools # runs behind firewall # Listens for Discovered event ''' from threading import Thread from queue import Queue from colorama import Fore from helpers import antminerhelper from helpers.queuehelper import QueueName, QueueEntries from domain import services from domain.mining import MinerAccessLevel, MinerPool from fcmapp import Component PROVISION = Component('provision', option='') def enthread(target, args): '''put a method on a queue to be run in background''' thread_queue = Queue() def wrapper(): thread_queue.put(target(*args)) thread = Thread(target=wrapper) thread.start() return thread_queue def when_provision(channel, method, properties, body): '''when provision event raised''' try:
'''send email''' import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from helpers.queuehelper import QueueName from fcmapp import Component EMAIL = Component('email') def when_email(channel, method, properties, body): '''when email event is raised''' try: doemail(body) except Exception as ex: EMAIL.app.logexception(ex) def doemail(msg): '''sends the email''' melogin = EMAIL.app.readlogin('emaillogin.conf') sendtoemailfile = EMAIL.app.readlogin('emailsendto.conf') meuser = melogin.username you = sendtoemailfile.username msg = MIMEMultipart('alternative') msg['Subject'] = "Mining Summary" msg['From'] = meuser msg['To'] = you text = "Daily Summary\nLine2\n" html = """\ <html>
''' #will listen to poolconfigurationchanged event and provision all known miners #of a particular type ''' from colorama import Fore from helpers.antminerhelper import MinerMonitorException, stats from helpers.queuehelper import QueueName, QueueEntries from domain.mining import MinerAccessLevel from fcmapp import Component PROVISION_DISPATCH = Component('provision') def when_provisiondispatch(channel, method, properties, body): '''when provision event received''' print("[{0}] Received provision command".format( PROVISION_DISPATCH.app.now())) miner_type = body.decode("utf-8") try: entries = doprovisiondispatch(miner_type) PROVISION_DISPATCH.app.enqueue(entries) except Exception as ex: PROVISION_DISPATCH.app.logexception(ex) def doprovisiondispatch(miner_type=None): '''put all miners in provision worker queue''' entries = QueueEntries() miners = PROVISION_DISPATCH.app.allminers() print("{0} miners configured".format(len(miners))) for miner in miners:
'''# Scans network to see if there are new miners # Listens for Discover # Raises Discovered event # TODO: check if found miner is in miners.json and add it if not ''' from colorama import Fore from helpers.networkhelper import networkmap from helpers import antminerhelper from helpers.queuehelper import QueueName, QueueEntries from domain import mining from fcmapp import Component DISCOVER = Component('discover') MINERPORT = DISCOVER.app.configuration('discover.minerport') SSHPORT = DISCOVER.app.configuration('discover.sshport') DNS = DISCOVER.app.configuration('discover.dns') def findminers(hosts_list, knownminers): '''find miners on network''' entries = QueueEntries() minerstotal = 0 minersnew = 0 shownonminers = True hostsup = 0 print('Querying {0} hosts...'.format(len(hosts_list))) for host, status, macaddress in hosts_list: try: if status != 'down': hostsup += 1 if shownonminers: print("{0} {1} {2}".format(host, status, macaddress))
'''David Foderick, Skylake Software Inc. ''' #from helpers import antminerhelper from helpers.queuehelper import QueueName, QueueEntries from fcmapp import Component MONITOR = Component('monitor') def when_monitor(channel, method, properties, body): '''when its time to monitor all the machines on schedule''' try: print("[{0}] Received monitor command".format(MONITOR.app.now())) entries = domonitor() MONITOR.app.enqueue(entries) except Exception as ex: MONITOR.app.logexception(ex) def domonitor(): '''queue workers to run the individual miner monitoring''' entries = QueueEntries() try: miners = MONITOR.app.knownminers() print("{0} miners configured".format(len(miners))) for miner in miners: if not miner.is_manually_disabled(): entries.add(QueueName.Q_MONITORMINER, MONITOR.app.messageencode(miner)) print("waiting for next monitor event")
'''#discovered something that responds to cgminer api''' from helpers.queuehelper import QueueName, QueueEntries from domain.mining import Miner from fcmapp import Component COMPONENTDISCOVERED = Component(componentname='discover', option='') def when_discovered(channel, method, properties, body): '''when new miner is discovered on the network''' try: print("[{0}] Received discovered notice".format(COMPONENTDISCOVERED.app.now())) entries = dodiscovered(COMPONENTDISCOVERED.app.messagedecodeminer(body)) COMPONENTDISCOVERED.app.enqueue(entries) COMPONENTDISCOVERED.listeningqueue.acknowledge(method.delivery_tag) except Exception as ex: COMPONENTDISCOVERED.app.logexception(ex) COMPONENTDISCOVERED.listeningqueue.reject(method.delivery_tag) def dodiscovered(miner): '''then provision it''' entries = QueueEntries() entries.add(QueueName.Q_PROVISION, COMPONENTDISCOVERED.app.messageencode(miner)) cachedminer = COMPONENTDISCOVERED.app.getminer(miner) #knownminer should be None if cachedminer is not None: cachedminer.updatefrom(miner) COMPONENTDISCOVERED.app.putminer(cachedminer) knownminer = COMPONENTDISCOVERED.app.getknownminer(miner) if knownminer is None: COMPONENTDISCOVERED.app.addknownminer(miner)
'''shut down a miner''' from helpers.queuehelper import QueueName from helpers.antminerhelper import shutdown from fcmapp import Component SHUTDOWN = Component('shutdown') def when_shutdown(channel, method, properties, body): msg = SHUTDOWN.app.messagedecodeminer(body) miner = msg.miner minercommand = msg.command #sanity check if minercommand.command == 'shutdown': #here you implement specific logic to shutdown your miner shutdown(miner, SHUTDOWN.app.sshlogin()) def main(): SHUTDOWN.listeningqueue = SHUTDOWN.app.subscribe(QueueName.Q_SHUTDOWN, when_shutdown, no_acknowledge=True) SHUTDOWN.app.listen(SHUTDOWN.listeningqueue) if __name__ == "__main__": main()
'''what to do when an alert is triggered''' from helpers.queuehelper import QueueName from fcmapp import Component ALERT = Component('alert') def when_alert(channel, method, properties, body): '''when alert is fired''' try: print("[{0}] Received request to send telegram".format(ALERT.app.now())) doalert(body.decode()) except Exception as ex: ALERT.app.logexception(ex) def doalert(alertmsg): '''send the alert''' ALERT.app.sendtelegrammessage(alertmsg) print("Sent telegram {0}".format(alertmsg)) def main(): ALERT.listeningqueue = ALERT.app.subscribe_and_listen(QueueName.Q_ALERT, when_alert) if __name__ == "__main__": main()
'''#David Foderick, Skylake Software Inc. #Runs behind firewall ''' import time import datetime from threading import Thread from queue import Queue from colorama import Fore import pika from helpers.antminerhelper import MinerMonitorException, stats, pools from helpers.queuehelper import QueueName, QueueEntries from domain import mining from fcmapp import Component APPMONITOR = Component('monitorminer') MONITOR_PREFETCH = int(APPMONITOR.app.configuration("monitoring.queue.prefetch")) def enthread(target, args): '''put a method on a queue to be run in background''' thread_queue = Queue() def wrapper(): thread_queue.put(target(*args)) thread = Thread(target=wrapper) thread.start() return thread_queue def when_monitorminer(channel, method, properties, body): try: print("[{0}] Received monitorminer command".format(APPMONITOR.app.now())) APPMONITOR.app.queuestatus() minermsg = APPMONITOR.app.messagedecodeminer(body)
'''logs message to terminal. in future may log to database''' from helpers.queuehelper import QueueName from fcmapp import Component COMPONENTLOG = Component('log') def when_log(channel, method, properties, body): '''event handler when log event is raised''' try: print("[{0}] Received log message".format(COMPONENTLOG.app.now())) dolog(body.decode()) except Exception as ex: COMPONENTLOG.app.logexception(ex) def dolog(msg): print(msg) def main(): COMPONENTLOG.listeningqueue = COMPONENTLOG.app.listen_to_broadcast( QueueName.Q_LOG, when_log) if __name__ == "__main__": main()
'''save full cycle data''' from helpers.queuehelper import QueueName, QueueEntries from domain.mining import Pool, Miner from fcmapp import Component COMPONENTSAVE = Component('fullcycle') def when_save(channel, method, properties, body): '''event handler when log event is raised''' try: print("[{0}] Received save message".format(COMPONENTSAVE.app.now())) msg = COMPONENTSAVE.app.messagedecode_configuration(body) entries = dosave(msg) COMPONENTSAVE.app.enqueue(entries) except Exception as ex: COMPONENTSAVE.app.logexception(ex) def dosave(msg): entries = QueueEntries() if msg.entity == 'miner': #add or update miner minerid = name = ipaddress = port = None for pair in msg.values: if 'minerid' in pair: minerid = pair['minerid'] if 'name' in pair: name = pair['name'] if 'ipaddress' in pair:
'''what to do when a sensor reading is broadcast''' from helpers.queuehelper import QueueName from fcmapp import Component SENSOR = Component('fullcycle') def when_sensor(channel, method, properties, body): '''when there is a sensor reading''' try: print("[{0}] Received sensor reading".format(SENSOR.app.now())) message, sensorvalue = SENSOR.app.messagedecodesensor(body) dosensor(message, sensorvalue) except Exception as ex: SENSOR.app.logexception(ex) def dosensor(message, sensorvalue): '''put the sensor in cache''' SENSOR.app.addknownsensor(sensorvalue) def main(): SENSOR.listeningqueue = SENSOR.app.listen_to_broadcast(QueueName.Q_SENSOR, when_sensor) if __name__ == "__main__": main()