Test Failed
Push — master ( 7e7379...128504 )
by Nicolas
03:31
created

Plugin.__init__()   A

Complexity

Conditions 2

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nop 3
dl 0
loc 17
rs 9.85
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2019 Nicolargo <[email protected]>
6
#
7
# Glances is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU Lesser General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Glances is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Lesser General Public License for more details.
16
#
17
# You should have received a copy of the GNU Lesser General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
"""Battery plugin."""
21
22
import psutil
23
24
from glances.logger import logger
25
from glances.plugins.glances_plugin import GlancesPlugin
26
27
# Batinfo library (optional; Linux-only)
28
batinfo_tag = True
29
try:
30
    import batinfo
31
except ImportError:
32
    logger.debug("batinfo library not found. Fallback to psutil.")
33
    batinfo_tag = False
34
35
# Availability:
36
# Linux, Windows, FreeBSD (psutil>=5.1.0)
37
# macOS (psutil>=5.4.2)
38
psutil_tag = True
39
try:
40
    psutil.sensors_battery()
41
except Exception as e:
42
    logger.error("Cannot grab battery status {}.".format(e))
43
    psutil_tag = False
44
45
46
class Plugin(GlancesPlugin):
47
    """Glances battery capacity plugin.
48
49
    stats is a list
50
    """
51
52
    def __init__(self, args=None, config=None):
53
        """Init the plugin."""
54
        super(Plugin, self).__init__(args=args, config=config, stats_init_value=[])
55
56
        # Init the sensor class
57
        try:
58
            self.glances_grab_bat = GlancesGrabBat()
59
        except Exception as e:
60
            logger.error("Can not init battery class ({})".format(e))
61
            global batinfo_tag
62
            global psutil_tag
63
            batinfo_tag = False
64
            psutil_tag = False
65
66
        # We do not want to display the stat in a dedicated area
67
        # The HDD temp is displayed within the sensors plugin
68
        self.display_curse = False
69
70
    # @GlancesPlugin._check_decorator
71
    @GlancesPlugin._log_result_decorator
72
    def update(self):
73
        """Update battery capacity stats using the input method."""
74
        # Init new stats
75
        stats = self.get_init_value()
76
77
        if self.input_method == 'local':
78
            # Update stats
79
            self.glances_grab_bat.update()
80
            stats = self.glances_grab_bat.get()
81
82
        elif self.input_method == 'snmp':
83
            # Update stats using SNMP
84
            # Not available
85
            pass
86
87
        # Update the stats
88
        self.stats = stats
89
90
        return self.stats
91
92
93
class GlancesGrabBat(object):
94
    """Get batteries stats using the batinfo library."""
95
96
    def __init__(self):
97
        """Init batteries stats."""
98
        self.bat_list = []
99
100
        if batinfo_tag:
101
            self.bat = batinfo.batteries()
102
        elif psutil_tag:
103
            self.bat = psutil
104
        else:
105
            self.bat = None
106
107
    def update(self):
108
        """Update the stats."""
109
        self.bat_list = []
110
        if batinfo_tag:
111
            # Use the batinfo lib to grab the stats
112
            # Compatible with multiple batteries
113
            self.bat.update()
114
            # Batinfo support multiple batteries
115
            # ... so take it into account (see #1920)
116
            # self.bat_list = [{
117
            #     'label': 'Battery',
118
            #     'value': self.battery_percent,
119
            #     'unit': '%'}]
120
            for b in self.bat.stat:
121
                self.bat_list.append(
122
                    {
123
                        'label': 'BAT {}'.format(b.path.split('/')[-1]),
124
                        'value': b.capacity,
125
                        'unit': '%',
126
                        'status': b.status,
127
                    }
128
                )
129
        elif psutil_tag and hasattr(self.bat.sensors_battery(), 'percent'):
130
            # Use psutil to grab the stats
131
            # Give directly the battery percent
132
            self.bat_list = [
133
                {
134
                    'label': 'Battery',
135
                    'value': int(self.bat.sensors_battery().percent),
136
                    'unit': '%',
137
                    'status': 'Charging' if self.bat.sensors_battery().power_plugged else 'Discharging',
138
                }
139
            ]
140
141
    def get(self):
142
        """Get the stats."""
143
        return self.bat_list
144
145
    @property
146
    def battery_percent(self):
147
        """Get batteries capacity percent."""
148
        if not batinfo_tag or not self.bat.stat:
149
            return []
150
151
        # Init the b_sum (sum of percent)
152
        # and Loop over batteries (yes a computer could have more than 1 battery)
153
        b_sum = 0
154
        for b in self.bat.stat:
155
            try:
156
                b_sum += int(b.capacity)
157
            except ValueError:
158
                return []
159
160
        # Return the global percent
161
        return int(b_sum / len(self.bat.stat))
162