def detect_model(ip): stats = get_stats(ip) # Check for connectivity error. if stats['STATUS'][0]['STATUS'] == 'error': flash( "[ERROR] Error while connecting to miner at ip address '{}'.". format(ip), "error") return None # Try identifying the device. model_name = None if 'Type' in stats['STATS'][0]: models = re.findall(r'Antminer (\w*\+?)', stats['STATS'][0]['Type']) if len(models) == 1: model_name = models[0] elif 'ID' in stats['STATS'][0]: # ID are used for devices like Avalon. model_name = stats['STATS'][0]['ID'] if not model_name is None: model = MinerModel.query.filter_by(model=model_name).first() if not model is None: return model else: model_name = "Unknown" flash( "[ERROR] Miner type '{}' at ip address '{}' is not supported.".format( model_name, ip), "error") return None
def get_miner_status(miner): # if miner not accessible miner_stats = get_stats(miner.ip) if miner_stats['STATUS'][0]['STATUS'] == 'error': return None status = MinersStatus() if miner.model.model == ModelType.Avalon741.value or miner.model.model == ModelType.Avalon821.value: make_miner_instance_avalon7or8(status, miner, miner_stats, get_pools(miner.ip)) elif miner.model.model == ModelType.GekkoScience.value: make_miner_instance_gekkoscience(status, miner, miner_stats, get_pools(miner.ip), get_summary(miner.ip)) elif miner.model.model == ModelType.AntRouterR1LTC.value: make_miner_instance_r1_ltc(status, miner, miner_stats, get_pools(miner.ip), get_summary(miner.ip)) else: make_miner_instance_bitmain(status, miner, miner_stats, get_pools(miner.ip)) # Check if the count. if status.miner_instance_list and miner.count > len( status.miner_instance_list): status.errors.add("Expected {} miners in ip {}. Found {}".format( miner.count, miner.ip, len(status.miner_instance_list))) return status
def temperature(): # Init variables start = time.clock() miners = Miner.query.all() models = MinerModel.query.all() active_miners = [] inactive_miners = [] temperatures = {} uptimes = {} for miner in miners: miner_stats = get_stats(miner.ip) # if miner not accessible if miner_stats['STATUS'][0]['STATUS'] == 'error': inactive_miners.append(miner) else: # Get the temperatures of the miner according to miner's model temps = [ int(miner_stats['STATS'][1][temp]) for temp in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search(miner.model.temp_keys + '[0-9]', temp) if miner_stats['STATS'][1][temp] != 0 ] # Get uptime uptime = timedelta(seconds=miner_stats['STATS'][1]['Elapsed']) temperatures.update({miner.ip: temps}) uptimes.update({miner.ip: uptime}) active_miners.append(miner) # Flash error messages if max(temps) >= 80: error_message = "[WARNING] High temperatures on miner '{}'.".format( miner.ip) logger.warning(error_message) flash(error_message, "warning") end = time.clock() loading_time = end - start return render_template('readonly_temperature.html', version=__version__, models=models, active_miners=active_miners, inactive_miners=inactive_miners, temperatures=temperatures, uptimes=uptimes, loading_time=loading_time)
def detect_model(ip): stats = get_stats(ip) # Check for connectivity error. if stats['STATUS'][0]['STATUS'] == 'error': raise Exception( "[ERROR] Error while connecting to miner at ip address '{}'.". format(ip)) # Try identifying the device. model_name = None if 'Type' in stats['STATS'][0]: models = re.findall(r'Antminer (\w*\+?)', stats['STATS'][0]['Type']) if len(models) == 1: model_name = models[0] elif 'ID' in stats['STATS'][0]: # ID are used for devices like Avalon. model_name = stats['STATS'][0]['ID'] if model_name == "AV70": model_name = ModelType.Avalon741.value elif model_name == "AV80": model_name = ModelType.Avalon821.value elif model_name == "GSD0": model_name = ModelType.GekkoScience.value elif model_name == "ANTR10": model_name = ModelType.AntRouterR1LTC.value if not model_name is None: model = MinerModel.query.filter_by(model=model_name).first() if not model is None: return model else: model_name = "Unknown" raise Exception( "[ERROR] Miner type '{}' at ip address '{}' is not supported.".format( model_name, ip))
def details(): if __show_temperature_only__: return redirect(url_for('temperature')) # Init variables start = time.clock() miners = Miner.query.all() models = MinerModel.query.all() active_miners = [] inactive_miners = [] workers = {} miner_chips = {} temperatures = {} fans = {} hash_rates = {} hw_error_rates = {} uptimes = {} total_hash_rate_per_model = { "L3+": { "value": 0, "unit": "MH/s" }, "S7": { "value": 0, "unit": "GH/s" }, "S9": { "value": 0, "unit": "GH/s" }, "D3": { "value": 0, "unit": "MH/s" }, "T9": { "value": 0, "unit": "TH/s" }, "A3": { "value": 0, "unit": "GH/s" }, "L3": { "value": 0, "unit": "MH/s" }, } errors = False miner_errors = {} for miner in miners: miner_stats = get_stats(miner.ip) # if miner not accessible if miner_stats['STATUS'][0]['STATUS'] == 'error': errors = True inactive_miners.append(miner) else: # Get worker name miner_pools = get_pools(miner.ip) worker = miner_pools['POOLS'][0]['User'] # Get miner's ASIC chips asic_chains = [ miner_stats['STATS'][1][chain] for chain in miner_stats['STATS'][1].keys() if "chain_acs" in chain ] # count number of working chips O = [str(o).count('o') for o in asic_chains] Os = sum(O) # count number of defective chips X = [str(x).count('x') for x in asic_chains] Xs = sum(X) # get number of in-active chips _dash_chips = [str(x).count('-') for x in asic_chains] _dash_chips = sum(_dash_chips) # Get total number of chips according to miner's model # convert miner.model.chips to int list and sum chips_list = [int(y) for y in str(miner.model.chips).split(',')] total_chips = sum(chips_list) # Get the temperatures of the miner according to miner's model temps = [ int(miner_stats['STATS'][1][temp]) for temp in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search(miner.model.temp_keys + '[0-9]', temp) if miner_stats['STATS'][1][temp] != 0 ] # Get fan speeds fan_speeds = [ miner_stats['STATS'][1][fan] for fan in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search("fan" + '[0-9]', fan) if miner_stats['STATS'][1][fan] != 0 ] # Get GH/S 5s ghs5s = float(str(miner_stats['STATS'][1]['GHS 5s'])) # Get HW Errors hw_error_rate = miner_stats['STATS'][1]['Device Hardware%'] # Get uptime uptime = timedelta(seconds=miner_stats['STATS'][1]['Elapsed']) # workers.update({miner.ip: worker}) miner_chips.update({ miner.ip: { 'status': { 'Os': Os, 'Xs': Xs, '-': _dash_chips }, 'total': total_chips, } }) temperatures.update({miner.ip: temps}) fans.update({miner.ip: {"speeds": fan_speeds}}) value, unit = update_unit_and_value( ghs5s, total_hash_rate_per_model[miner.model.model]['unit']) hash_rates.update({miner.ip: "{:3.2f} {}".format(value, unit)}) hw_error_rates.update({miner.ip: hw_error_rate}) uptimes.update({miner.ip: uptime}) total_hash_rate_per_model[miner.model.model]["value"] += ghs5s active_miners.append(miner) # Flash error messages if Xs > 0: error_message = "[WARNING] '{}' chips are defective on miner '{}'.".format( Xs, miner.ip) logger.warning(error_message) flash(error_message, "warning") errors = True miner_errors.update({miner.ip: error_message}) if Os + Xs < total_chips: error_message = "[ERROR] ASIC chips are missing from miner '{}'. Your Antminer '{}' has '{}/{} chips'." \ .format(miner.ip, miner.model.model, Os + Xs, total_chips) logger.error(error_message) flash(error_message, "error") errors = True miner_errors.update({miner.ip: error_message}) if max(temps) >= 80: error_message = "[WARNING] High temperatures on miner '{}'.".format( miner.ip) logger.warning(error_message) flash(error_message, "warning") # Flash success/info message if not miners: error_message = "[INFO] No miners added yet. Please add miners using the above form." logger.info(error_message) flash(error_message, "info") elif not errors: error_message = "[INFO] All miners are operating normal. No errors found." logger.info(error_message) flash(error_message, "info") # flash("INFO !!! Check chips on your miner", "info") # flash("SUCCESS !!! Miner added successfully", "success") # flash("WARNING !!! Check temperatures on your miner", "warning") # flash("ERROR !!!Check board(s) on your miner", "error") # Convert the total_hash_rate_per_model into a data structure that the template can # consume. total_hash_rate_per_model_temp = {} for key in total_hash_rate_per_model: value, unit = update_unit_and_value( total_hash_rate_per_model[key]["value"], total_hash_rate_per_model[key]["unit"]) if value > 0: total_hash_rate_per_model_temp[key] = "{:3.2f} {}".format( value, unit) end = time.clock() loading_time = end - start return render_template( 'myminers.html', version=__version__, models=models, active_miners=active_miners, inactive_miners=inactive_miners, workers=workers, miner_chips=miner_chips, temperatures=temperatures, fans=fans, hash_rates=hash_rates, hw_error_rates=hw_error_rates, uptimes=uptimes, total_hash_rate_per_model=total_hash_rate_per_model_temp, loading_time=loading_time, miner_errors=miner_errors, )
def getAndUpdate(miner): active_miners = [] errors = False rec_ip = {} rec_worker = {} rec_model_id = {} rec_remarks = {} rec_chipsOs = {} rec_chipsXs = {} rec_chipsl = {} rec_tem = {} rec_fan = {} rec_hash = {} rec_hwerorr = {} rec_status = {} rec_uptime = {} rec_online = {} total_hash_rate_per_model = { "L3+": { "value": 0, "unit": "MH/s" }, "S7": { "value": 0, "unit": "GH/s" }, "S9": { "value": 0, "unit": "GH/s" }, "D3": { "value": 0, "unit": "MH/s" }, "T9": { "value": 0, "unit": "TH/s" }, "A3": { "value": 0, "unit": "GH/s" }, "L3": { "value": 0, "unit": "MH/s" }, } # if Miner.query.filter_by(ip=miner.ip).first() is not None: try: miner_stats = get_stats(miner.ip) # print(miner_stats) rec_last = str(datetime.now().strftime('%H:%M:%S %d/%m/%Y')) if miner_stats['STATUS'][0]['STATUS'] == 'error': errors = True rec_ip = miner.ip rec_worker = '0' rec_model_id = miner.model_id rec_remarks = miner.remarks rec_chipsOs = '0' rec_chipsXs = '0' rec_chipsl = '0' rec_tem = '0' rec_fan = '0' rec_hash = '0' rec_hwerorr = '0' rec_status = 'offline' rec_uptime = '0' rec_online = '0' else: rec_ip = miner.ip rec_online = '1' miner_pools = get_pools(miner.ip) try: rec_worker = miner_pools['POOLS'][0]['User'] except: rec_worker = '0' rec_model_id = miner.model_id rec_remarks = miner.remarks asic_chains = [ miner_stats['STATS'][1][chain] for chain in miner_stats['STATS'][1].keys() if "chain_acs" in chain ] O = [str(o).count('o') for o in asic_chains] rec_chipsOs = sum(O) X = [str(x).count('x') for x in asic_chains] rec_chipsXs = sum(X) _dash_chips = [str(x).count('-') for x in asic_chains] rec_chipsl = sum(_dash_chips) rec_tem = [ int(miner_stats['STATS'][1][temp]) for temp in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search(miner.model.temp_keys + '[0-9]', temp) if miner_stats['STATS'][1][temp] != 0 ] rec_fan = [ miner_stats['STATS'][1][fan] for fan in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search("fan" + '[0-9]', fan) if miner_stats['STATS'][1][fan] != 0 ] ghs5s = float(str(miner_stats['STATS'][1]['GHS 5s'])) value, unit = update_unit_and_value( ghs5s, total_hash_rate_per_model[miner.model.model]['unit']) rec_hash = "{:3.2f} {}".format(value, unit) rec_hwerorr = miner_stats['STATS'][1]['Device Hardware%'] rec_status = 'OK' rec_uptime = timedelta(seconds=miner_stats['STATS'][1]['Elapsed']) try: # if Miner.query.filter_by(ip=miner.ip).first() is None: # record = Temp(ip=rec_ip, \ # worker=str(rec_worker), \ # model_id= rec_model_id, \ # remarks=str(rec_remarks), \ # chipsOs=str(rec_chipsOs), \ # chipsXs=str(rec_chipsXs), \ # chipsl=str(rec_chipsl), \ # tem=str(rec_tem), \ # fan=str(rec_fan), \ # hash=str(rec_hash), \ # hwerorr=str(rec_hwerorr), \ # uptime=str(rec_uptime), \ # online=str(rec_online), \ # last=str(rec_last)) # db.session.add(record) # db.session.commit() # else: record = Miner.query.filter_by(ip=rec_ip).first() record.worker = str(rec_worker) record.model_id = rec_model_id record.remarks = str(rec_remarks) record.chipsOs = str(rec_chipsOs) record.chipsXs = str(rec_chipsXs) record.chipsl = str(rec_chipsl) record.tem = str(rec_tem) record.fan = str(rec_fan) record.hash = str(rec_hash) record.hwerorr = str(rec_hwerorr) record.status = str(rec_status) record.uptime = str(rec_uptime) record.online = str(rec_online) record.last = str(rec_last) db.session.commit() error_message = "IP Address {} updated".format(rec_ip) # flash(error_message, "alert-success") logger.info(error_message) except: db.session.rollback() error_message = "[ERROR] Some shit happen!" logger.info(error_message) # flash(error_message, "alert-danger") except: pass
def getAndUpdateHistory(miner): """Add record in History Table (check miner and add it)""" rec_ip = {} rec_worker = {} rec_model_id = {} rec_remarks = {} rec_chipsOs = {} rec_chipsXs = {} rec_chipsl = {} rec_tem = {} rec_fan = {} rec_hash = {} rec_hwerorr = {} rec_status = {} rec_uptime = {} rec_online = {} total_hash_rate_per_model = { "L3+": { "value": 0, "unit": "MH/s" }, "S7": { "value": 0, "unit": "GH/s" }, "S9": { "value": 0, "unit": "GH/s" }, "D3": { "value": 0, "unit": "MH/s" }, "T9": { "value": 0, "unit": "TH/s" }, "A3": { "value": 0, "unit": "GH/s" }, "L3": { "value": 0, "unit": "MH/s" }, } miner_stats = get_stats(miner.ip) rec_last = str(datetime.now().strftime('%H:%M:%S %d/%m/%Y')) if miner_stats['STATUS'][0]['STATUS'] == 'error': rec_ip = miner.ip rec_worker = '0' rec_model_id = miner.model_id rec_remarks = miner.remarks rec_chipsOs = '0' rec_chipsXs = '0' rec_chipsl = '0' rec_tem = '0' rec_fan = '0' rec_hash = '0' rec_hwerorr = '0' rec_status = 'offline' rec_uptime = '0' rec_online = '0' else: rec_ip = miner.ip rec_online = '1' miner_pools = get_pools(miner.ip) try: rec_worker = miner_pools['POOLS'][0]['User'] except: rec_worker = '0' rec_model_id = miner.model_id rec_remarks = miner.remarks asic_chains = [ miner_stats['STATS'][1][chain] for chain in miner_stats['STATS'][1].keys() if "chain_acs" in chain ] O = [str(o).count('o') for o in asic_chains] rec_chipsOs = sum(O) X = [str(x).count('x') for x in asic_chains] rec_chipsXs = sum(X) _dash_chips = [str(x).count('-') for x in asic_chains] rec_chipsl = sum(_dash_chips) rec_tem = [ int(miner_stats['STATS'][1][temp]) for temp in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search(miner.model.temp_keys + '[0-9]', temp) if miner_stats['STATS'][1][temp] != 0 ] rec_fan = [ miner_stats['STATS'][1][fan] for fan in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search("fan" + '[0-9]', fan) if miner_stats['STATS'][1][fan] != 0 ] ghs5s = float(str(miner_stats['STATS'][1]['GHS 5s'])) value, unit = update_unit_and_value( ghs5s, total_hash_rate_per_model[miner.model.model]['unit']) rec_hash = "{:3.2f} {}".format(value, unit) rec_hwerorr = miner_stats['STATS'][1]['Device Hardware%'] rec_status = 'OK' rec_uptime = timedelta(seconds=miner_stats['STATS'][1]['Elapsed']) record = History(ip=rec_ip, \ worker=str(rec_worker), \ model_id= rec_model_id, \ remarks=str(rec_remarks), \ chipsOs=str(rec_chipsOs), \ chipsXs=str(rec_chipsXs), \ chipsl=str(rec_chipsl), \ tem=str(rec_tem), \ fan=str(rec_fan), \ hash=str(rec_hash), \ hwerorr=str(rec_hwerorr), \ status=str(rec_status), \ uptime=str(rec_uptime), \ online=str(rec_online), \ last=str(rec_last)) miner_rec = History.query.filter_by(ip=str(miner.ip)).order_by( History.last.desc()).first() if miner_rec is not None: datetime_object = datetime.strptime(miner_rec.last, '%H:%M:%S %d/%m/%Y') datetime_object = datetime.now() - datetime_object if datetime_object.total_seconds() > 600: db.session.add(record) db.session.commit() else: db.session.add(record) db.session.commit()
def miners(): # Init variables start = time.clock() miners = Miner.query.all() models = MinerModel.query.all() active_miners = [] inactive_miners = [] workers = {} miner_chips = {} temperatures = {} fans = {} hash_rates = {} hw_error_rates = {} uptimes = {} total_hash_rate_per_model = {"L3+": {"value": 0, "unit": "MH/s" }, "S7": {"value": 0, "unit": "GH/s" }, "S9": {"value": 0, "unit": "GH/s" }, "D3": {"value": 0, "unit": "MH/s" }} errors = False miner_errors = {} for miner in miners: miner_stats = get_stats(miner.ip) # if miner not accessible if miner_stats['STATUS'][0]['STATUS'] == 'error': errors = True inactive_miners.append(miner) else: # Get worker name miner_pools = get_pools(miner.ip) worker = miner_pools['POOLS'][0]['User'] # Get miner's ASIC chips asic_chains = [miner_stats['STATS'][1][chain] for chain in miner_stats['STATS'][1].keys() if "chain_acs" in chain] # count number of working chips O = [str(o).count('o') for o in asic_chains] Os = sum(O) # count number of defective chips X = [str(x).count('x') for x in asic_chains] Xs = sum(X) # get number of in-active chips _dash_chips = [str(x).count('-') for x in asic_chains] _dash_chips = sum(_dash_chips) # Get total number of chips according to miner's model # convert miner.model.chips to int list and sum chips_list = [int(y) for y in str(miner.model.chips).split(',')] total_chips = sum(chips_list) # Get the temperatures of the miner according to miner's model temps = [int(miner_stats['STATS'][1][temp]) for temp in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search(miner.model.temp_keys + '[0-9]', temp) if miner_stats['STATS'][1][temp] != 0] # Get fan speeds fan_speeds = [miner_stats['STATS'][1][fan] for fan in sorted(miner_stats['STATS'][1].keys(), key=lambda x: str(x)) if re.search("fan" + '[0-9]', fan) if miner_stats['STATS'][1][fan] != 0] # Get GH/S 5s ghs5s = float(str(miner_stats['STATS'][1]['GHS 5s'])) # Get HW Errors hw_error_rate = miner_stats['STATS'][1]['Device Hardware%'] # Get uptime uptime = timedelta(seconds=miner_stats['STATS'][1]['Elapsed']) # workers.update({miner.ip: worker}) miner_chips.update({miner.ip: {'status': {'Os': Os, 'Xs': Xs, '-': _dash_chips}, 'total': total_chips, } }) temperatures.update({miner.ip: temps}) fans.update({miner.ip: {"speeds": fan_speeds}}) value, unit = update_unit_and_value(ghs5s, total_hash_rate_per_model[miner.model.model]['unit']) hash_rates.update({miner.ip: "{:3.2f} {}".format(value, unit)}) hw_error_rates.update({miner.ip: hw_error_rate}) uptimes.update({miner.ip: uptime}) total_hash_rate_per_model[miner.model.model]["value"] += ghs5s active_miners.append(miner) # Flash error messages if Xs > 0: error_message = "[WARNING] '{}' chips are defective on miner '{}'.".format(Xs, miner.ip) logger.warning(error_message) flash(error_message, "warning") errors = True miner_errors.update({miner.ip: error_message}) if Os + Xs < total_chips: error_message = "[ERROR] ASIC chips are missing from miner '{}'. Your Antminer '{}' has '{}/{} chips'." \ .format(miner.ip, miner.model.model, Os + Xs, total_chips) logger.error(error_message) flash(error_message, "error") errors = True miner_errors.update({miner.ip: error_message}) if max(temps) >= 80: error_message = "[WARNING] High temperatures on miner '{}'.".format(miner.ip) logger.warning(error_message) flash(error_message, "warning") # Flash success/info message if not miners: error_message = "[INFO] No miners added yet. Please add miners using the above form." logger.info(error_message) flash(error_message, "info") elif not errors: error_message = "[INFO] All miners are operating normal. No errors found." logger.info(error_message) flash(error_message, "info") # flash("INFO !!! Check chips on your miner", "info") # flash("SUCCESS !!! Miner added successfully", "success") # flash("WARNING !!! Check temperatures on your miner", "warning") # flash("ERROR !!!Check board(s) on your miner", "error") # Convert the total_hash_rate_per_model into a data structure that the template can # consume. total_hash_rate_per_model_temp = {} for key in total_hash_rate_per_model: value, unit = update_unit_and_value(total_hash_rate_per_model[key]["value"], total_hash_rate_per_model[key]["unit"]) if value > 0: total_hash_rate_per_model_temp[key] = "{:3.2f} {}".format(value, unit) end = time.clock() loading_time = end - start return render_template('myminers.html', version=__version__, models=models, active_miners=active_miners, inactive_miners=inactive_miners, workers=workers, miner_chips=miner_chips, temperatures=temperatures, fans=fans, hash_rates=hash_rates, hw_error_rates=hw_error_rates, uptimes=uptimes, total_hash_rate_per_model=total_hash_rate_per_model_temp, loading_time=loading_time, miner_errors=miner_errors, )
def stats(ip): output = get_stats(ip) return jsonify(output)