예제 #1
0
 def add_if_supported(ip, model_id):
     # check if the miner is supported by the software
     try:
         supported_miner = [id for id in MODELS.keys() if id == model_id][0]
         add_miner(ip, supported_miner, "")
         return True
     except IndexError as i:
         return False
    def poll(self):
        miner_stats = get_stats(self.ip)
        # if miner not accessible
        if miner_stats['STATUS'][0]['STATUS'] == 'error':
            self.is_inactive = True
            self.errors.append(miner_stats['STATUS'][0]['description'])
        else:
            try:
                # Get worker name
                miner_pools = get_pools(self.ip)
                active_pool = [
                    pool for pool in miner_pools['POOLS']
                    if pool['Stratum Active']
                ]
            except Exception as k:
                active_pool = []
            try:
                self.worker = active_pool[0]['User']
            except Exception as e:
                self.worker = ""

            # 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]
            C = [str(x).count('C') for x in asic_chains]
            B = [str(x).count('B') for x in asic_chains]
            Xs = sum(X)
            Bs = sum(B)
            Cs = sum(C)
            # 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(MODELS.get(self.model_id).get('chips')).split(',')
            ]
            total_chips = sum(chips_list)

            self.chips.update({
                'Os': Os,
                'Xs': Xs,
                '-': _dash_chips,
                'total': total_chips
            })

            # Get the temperatures of the miner according to miner's model
            self.temperatures = [
                int(miner_stats['STATS'][1][temp])
                for temp in sorted(miner_stats['STATS'][1].keys(),
                                   key=lambda x: str(x))
                if re.search(
                    MODELS.get(self.model_id).get('temp_keys') + '[0-9]', temp)
                if miner_stats['STATS'][1][temp] != 0
            ]

            # Get fan speeds
            self.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
            try:
                self.hash_rate_ghs5s = float(
                    str(miner_stats['STATS'][1]['GHS 5s']))
            except Exception as e:
                miner_summary = get_summary(self.ip)
                self.hash_rate_ghs5s = float(
                    str(miner_summary['SUMMARY'][0]['GHS 5s']))

            # Normalize hashrate
            new_value, new_unit = update_unit_and_value(
                self.hash_rate_ghs5s, MODELS[self.model_id]['unit'])
            self.normalized_hash_rate = "{:3.2f} {}".format(
                new_value, new_unit)

            # Get HW Errors
            try:
                # Probably the miner is an Antminer E3 or S17
                miner_summary = get_summary(self.ip)
                self.hw_error_rate = miner_summary['SUMMARY'][0][
                    'Device Hardware%']
            except Exception as e:
                # self.hw_error_rate = miner_stats['STATS'][1]['Device Hardware%']
                # this seems to work
                self.hw_error_rate = 0

            # Get uptime
            self.uptime = str(
                timedelta(seconds=miner_stats['STATS'][1]['Elapsed']))

            # Flash error messages
            if Xs > 0:
                error_message = ("[WARNING] '{}' chips are defective on "
                                 "miner '{}'.").format(Xs, self.ip)
                # current_app.logger.warning(error_message)
                # flash(error_message, "warning")
                self.warnings.append(error_message)
            if Os + Xs < total_chips:
                error_message = (
                    "[ERROR] ASIC chips are missing from miner "
                    "'{}'. Your Antminer '{}' has '{}/{} chips'.").format(
                        self.ip, self.model_id, Os + Xs, total_chips)
                # current_app.logger.error(error_message)
                # flash(error_message, "error")
                self.errors.append(error_message)
            if Bs > 0:
                # flash an info message. Probably the E3 is still warming up
                # error_message = (
                #    "[INFO] Miner '{}' is still warming up").format(self.ip)
                # current_app.logger.error(error_message)
                # flash(error_message, "info")
                pass
            if Cs > 0:
                # flask an info message. Probably the E3 is still warming up
                # error_message = (
                #    "[INFO] Miner '{}' is still warming up").format(self.ip)
                # current_app.logger.error(error_message)
                # flash(error_message, "info")
                pass

            if not self.temperatures:
                error_message = ("[ERROR] Could not retrieve temperatures "
                                 "from miner '{}'.").format(self.ip)
                # current_app.logger.warning(error_message)
                # flash(error_message, "error")
                self.errors.append(error_message)
            else:
                if max(self.temperatures) >= 80:
                    error_message = ("[WARNING] High temperatures on "
                                     "miner '{}'.").format(self.ip)
                    # current_app.logger.warning(error_message)
                    # flash(error_message, "warning")
                    self.warnings.append(error_message)
예제 #3
0
def miners():
    # Init variables
    start = time.clock()
    miners = Miner.query.all()
    active_miners = []
    inactive_miners = []
    warnings = []
    errors = []
    total_hash_rate_per_model = {}
    miner_objects = []

    # lookup table for total_hash_rate_per_model
    for id, miner in MODELS.items():
        total_hash_rate_per_model[id] = {"value": 0, "unit": miner.get('unit')}

    # create miner objects to pass to executor.map
    for miner in miners:
        module = MODELS[miner.model_id]['model_module']
        cls = MODELS[miner.model_id]['model_classname']
        obj = getattr(sys.modules[module], cls)(miner)
        miner_objects.append(obj)

    # pass this method to executor.map to poll the miner
    def poll(obj):
        obj.poll()
        return obj

    # run with ThreadPoolExecutor
    with concurrent.futures.ThreadPoolExecutor(
            max_workers=NUM_THREADS) as executor:
        results = executor.map(poll, miner_objects)
        for miner in results:
            if miner is not None:
                if miner.is_inactive:
                    inactive_miners.append(miner)
                else:
                    active_miners.append(miner)

                    for warning in miner.warnings:
                        warnings.append(warning)
                    for error in miner.errors:
                        errors.append(error)
                    total_hash_rate_per_model[
                        miner.model_id]["value"] += miner.hash_rate_ghs5s

    # Flash notifications
    if not miners:
        error_message = ("[INFO] No miners added yet. "
                         "Please add miners using the above form.")
        current_app.logger.info(error_message)
        flash(error_message, "info")
    elif not errors:
        error_message = ("[INFO] All miners are operating normal. "
                         "No errors found.")
        current_app.logger.info(error_message)
        flash(error_message, "info")

    for error in errors:
        current_app.logger.error(error)
        flash(error, "error")

    for warning in warnings:
        current_app.logger.error(warning)
        flash(warning, "warning")

    # 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(
        'asicminer/home.html',
        version=current_app.config['__VERSION__'],
        models=MODELS,
        errors=errors,
        warnings=warnings,
        active_miners=active_miners,
        inactive_miners=inactive_miners,
        loading_time=loading_time,
        total_hash_rate_per_model=total_hash_rate_per_model_temp)
예제 #4
0
def miners():
    # Init variables
    start = time.clock()
    miners = Miner.query.all()
    active_miners = []
    inactive_miners = []
    warnings = []
    errors = []

    total_hash_rate_per_model = {}

    for id, miner in MODELS.items():
        total_hash_rate_per_model[id] = {"value": 0, "unit": miner.get('unit')}

    # running single threaded
    for miner in miners:
        antminer = ASIC_ANTMINER(miner)

        if antminer.is_inactive:
            inactive_miners.append(antminer)
        else:
            active_miners.append(antminer)
            for warning in antminer.warnings:
                warnings.append(warning)
            for error in antminer.errors:
                errors.append(error)
            total_hash_rate_per_model[
                antminer.model_id]["value"] += antminer.hash_rate_ghs5s

    # Flash notifications
    if not miners:
        error_message = ("[INFO] No miners added yet. "
                         "Please add miners using the above form.")
        current_app.logger.info(error_message)
        flash(error_message, "info")
    elif not errors:
        error_message = ("[INFO] All miners are operating normal. "
                         "No errors found.")
        current_app.logger.info(error_message)
        flash(error_message, "info")

    for error in errors:
        current_app.logger.error(error)
        flash(error, "error")

    for warning in warnings:
        current_app.logger.error(warning)
        flash(warning, "warning")

    # 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(
        'asicminer/home.html',
        MODELS=MODELS,
        active_miners=active_miners,
        inactive_miners=inactive_miners,
        loading_time=loading_time,
        total_hash_rate_per_model=total_hash_rate_per_model_temp)