Passed
Push — master ( aef48c...fd031d )
by Dave
01:07
created

domain.miningrules.RuleParameters.__init__()   A

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nop 7
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
'''Mining Rules'''
2
from domain.mining import Miner, MinerStatistics
3
4
class RuleParameters(object):
5
    '''configurable parameters for rules'''
6
    def __init__(self, minertype, hashlimit, controllertemplimit, boardtemplimit, restartaftersec, maxtempreset=None):
7
        self.minertype = minertype
8
        self.hashlimit = hashlimit
9
        self.controllertemplimit = controllertemplimit
10
        self.boardtemplimit = boardtemplimit
11
        self.restartaftersec = restartaftersec
12
        self.maxtempreset = maxtempreset
13
14
class BrokenRule(object):
15
    '''broken rules'''
16
    def __init__(self, miner, action, parameter):
17
        self.miner = miner
18
        self.action = action
19
        self.parameter = parameter
20
    def __str__(self):
21
        return 'broke {0}:{1} {2}'.format(self.miner.name, self.action, self.parameter)
22
23
class MinerStatisticsRule(object):
24
    '''Rule for evaluating miner statistics'''
25
26
    def __init__(self, miner: Miner, statistics: MinerStatistics, ruleparameters: RuleParameters):
27
        self.miner = miner
28
        self.statistics = statistics
29
        self.ruleparameters = ruleparameters
30
        self.brokenrules = []
31
32
    @classmethod
33
    def hasreading(cls, reading):
34
        '''True when the reading is not empty'''
35
        if reading is None:
36
            return False
37
        if reading:
38
            return False
39
        return True
40
41
    @classmethod
42
    def hasreading_num(cls, reading):
43
        '''True when the reading is numeric and not empty'''
44
        if reading is None:
45
            return False
46
        if reading == 0:
47
            return False
48
        if isinstance(reading, int):
49
            return True
50
        if isinstance(reading, float):
51
            return True
52
        return False
53
54
    def has_reboot_rule(self):
55
        return any(therule.action == 'restart' and therule.parameter == 'reboot' for therule in self.brokenrules)
56
57
    def addbrokenrule(self, rule):
58
        if rule.action == 'restart':
59
            if not self.has_reboot_rule():
60
                self.brokenrules = [therule for therule in self.brokenrules if therule.action != 'restart']
61
                self.brokenrules.append(rule)
62
        else:
63
            self.brokenrules.append(rule)
64
65
    def isbroken(self):
66
        '''true when the rule is broken'''
67
        self.brokenrules = []
68
        if self.miner.miner_type != self.ruleparameters.minertype:
69
            return False
70
71
        self.check_hash()
72
        self.check_temp_controller()
73
        self.check_temp_boards()
74
75
        return len(self.brokenrules) > 0
76
77
    def check_hash(self):
78
        if MinerStatisticsRule.hasreading_num(self.statistics.currenthash):
79
            if self.statistics.currenthash < self.ruleparameters.hashlimit:
80
                self.brokenrules.append(BrokenRule(self.miner, 'alert', 'on {0} low hash {1} below {2}'.format(self.miner.name, self.statistics.currenthash, self.ruleparameters.hashlimit)))
81
                if self.statistics.elapsed > self.ruleparameters.restartaftersec:
82
                    self.addbrokenrule(BrokenRule(self.miner, 'restart', 'restart'))
83
                    self.addbrokenrule(BrokenRule(self.miner, 'alert', 'restarting {0} '.format(self.miner.name)))
84
85
    def check_temp_controller(self):
86
        if MinerStatisticsRule.hasreading_num(self.statistics.controllertemp):
87
            if self.statistics.controllertemp and self.statistics.controllertemp > self.ruleparameters.controllertemplimit:
88
                self.addbrokenrule(BrokenRule(self.miner, 'alert', 'on {0} controller temp {1} exceeded {2}'.format(self.miner.name, self.statistics.controllertemp, self.ruleparameters.controllertemplimit)))
89
90
    def check_temp_boards(self):
91
        if MinerStatisticsRule.hasreading_num(self.statistics.tempboardmax()):
92
            if self.statistics.tempboardmax() > self.ruleparameters.boardtemplimit:
93
                self.addbrokenrule(BrokenRule(self.miner, 'alert', 'on {0} board temp {1} exceeded {2}'.format(self.miner.name, self.statistics.tempboardmax(), self.ruleparameters.boardtemplimit)))
94
            if self.ruleparameters.maxtempreset and self.statistics.tempboardmax() > self.ruleparameters.maxtempreset:
95
                if self.statistics.elapsed > self.ruleparameters.restartaftersec:
96
                    self.addbrokenrule(BrokenRule(self.miner, 'restart', 'reboot'))
97