Issues (48)

plugins/sensors/sensor/glances_batpercent.py (1 issue)

1
#
2
# This file is part of Glances.
3
#
4
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <[email protected]>
5
#
6
# SPDX-License-Identifier: LGPL-3.0-only
7
#
8
9
"""Battery plugin."""
10
11
import psutil
12
13
from glances.globals import LINUX
14
from glances.logger import logger
15
from glances.plugins.plugin.model import GlancesPluginModel
16
17
# Batinfo library (optional; Linux-only)
18
if LINUX:
19
    batinfo_tag = True
20
    try:
21
        import batinfo
22
    except ImportError:
23
        logger.debug("batinfo library not found. Fallback to psutil.")
24
        batinfo_tag = False
25
else:
26
    batinfo_tag = False
27
28
# PsUtil Sensors_battery available on Linux, Windows, FreeBSD, macOS
29
psutil_tag = True
30
try:
31
    psutil.sensors_battery()
32
except Exception as e:
33
    logger.error(f"Cannot grab battery status {e}.")
34
    psutil_tag = False
35
36
37
class PluginModel(GlancesPluginModel):
38
    """Glances battery capacity plugin.
39
40
    stats is a list
41
    """
42
43
    def __init__(self, args=None, config=None):
44
        """Init the plugin."""
45
        super().__init__(args=args, config=config, stats_init_value=[])
46
47
        # Init the sensor class
48
        try:
49
            self.glances_grab_bat = GlancesGrabBat()
50
        except Exception as e:
51
            logger.error(f"Can not init battery class ({e})")
52
            global batinfo_tag
53
            global psutil_tag
54
            batinfo_tag = False
55
            psutil_tag = False
56
57
        # We do not want to display the stat in a dedicated area
58
        # The HDD temp is displayed within the sensors plugin
59
        self.display_curse = False
60
61
    # @GlancesPluginModel._check_decorator
62
    @GlancesPluginModel._log_result_decorator
63
    def update(self):
64
        """Update battery capacity stats using the input method."""
65
        # Init new stats
66
        stats = self.get_init_value()
67
68
        if self.input_method == 'local':
69
            # Update stats
70
            self.glances_grab_bat.update()
71
            stats = self.glances_grab_bat.get()
72
73
        elif self.input_method == 'snmp':
74
            # Update stats using SNMP
75
            # Not available
76
            pass
77
78
        # Update the stats
79
        self.stats = stats
80
81
        return self.stats
82
83
84
class GlancesGrabBat:
85
    """Get batteries stats using the batinfo library."""
86
87
    def __init__(self):
88
        """Init batteries stats."""
89
        self.bat_list = []
90
91
        if batinfo_tag:
92
            self.bat = batinfo.batteries()
0 ignored issues
show
The variable batinfo does not seem to be defined for all execution paths.
Loading history...
93
        elif psutil_tag:
94
            self.bat = psutil
95
        else:
96
            self.bat = None
97
98
    def update(self):
99
        """Update the stats."""
100
        self.bat_list = []
101
        if batinfo_tag:
102
            # Use the batinfo lib to grab the stats
103
            # Compatible with multiple batteries
104
            self.bat.update()
105
            # Batinfo support multiple batteries
106
            # ... so take it into account (see #1920)
107
            # self.bat_list = [{
108
            #     'label': 'Battery',
109
            #     'value': self.battery_percent,
110
            #     'unit': '%'}]
111
            for b in self.bat.stat:
112
                self.bat_list.append(
113
                    {
114
                        'label': 'BAT {}'.format(b.path.split('/')[-1]),
115
                        'value': b.capacity,
116
                        'unit': '%',
117
                        'status': b.status,
118
                    }
119
                )
120
        elif psutil_tag and hasattr(self.bat.sensors_battery(), 'percent'):
121
            # Use psutil to grab the stats
122
            # Give directly the battery percent
123
            self.bat_list = [
124
                {
125
                    'label': 'Battery',
126
                    'value': int(self.bat.sensors_battery().percent),
127
                    'unit': '%',
128
                    'status': 'Charging' if self.bat.sensors_battery().power_plugged else 'Discharging',
129
                }
130
            ]
131
132
    def get(self):
133
        """Get the stats."""
134
        return self.bat_list
135
136
    @property
137
    def battery_percent(self):
138
        """Get batteries capacity percent."""
139
        if not batinfo_tag or not self.bat.stat:
140
            return []
141
142
        # Init the b_sum (sum of percent)
143
        # and Loop over batteries (yes a computer could have more than 1 battery)
144
        b_sum = 0
145
        for b in self.bat.stat:
146
            try:
147
                b_sum += int(b.capacity)
148
            except ValueError:
149
                return []
150
151
        # Return the global percent
152
        return int(b_sum / len(self.bat.stat))
153