1 | # -*- coding: utf-8 -*- |
||
2 | # |
||
3 | # This file is part of Glances. |
||
4 | # |
||
5 | # Copyright (C) 2015 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 | """HDD temperature plugin.""" |
||
21 | |||
22 | import os |
||
23 | import socket |
||
24 | import numbers |
||
25 | |||
26 | from glances.compat import nativestr, range |
||
27 | from glances.logger import logger |
||
28 | from glances.plugins.glances_plugin import GlancesPlugin |
||
29 | |||
30 | |||
31 | View Code Duplication | class Plugin(GlancesPlugin): |
|
0 ignored issues
–
show
Duplication
introduced
by
Loading history...
|
|||
32 | |||
33 | """Glances HDD temperature sensors plugin. |
||
34 | |||
35 | stats is a list |
||
36 | """ |
||
37 | |||
38 | def __init__(self, args=None): |
||
39 | """Init the plugin.""" |
||
40 | super(Plugin, self).__init__(args=args) |
||
41 | |||
42 | # Init the sensor class |
||
43 | self.glancesgrabhddtemp = GlancesGrabHDDTemp(args=args) |
||
44 | |||
45 | # We do not want to display the stat in a dedicated area |
||
46 | # The HDD temp is displayed within the sensors plugin |
||
47 | self.display_curse = False |
||
48 | |||
49 | # Init stats |
||
50 | self.reset() |
||
51 | |||
52 | def reset(self): |
||
53 | """Reset/init the stats.""" |
||
54 | self.stats = [] |
||
55 | |||
56 | def update(self): |
||
57 | """Update HDD stats using the input method.""" |
||
58 | # Reset stats |
||
59 | self.reset() |
||
60 | |||
61 | if self.input_method == 'local': |
||
62 | # Update stats using the standard system lib |
||
63 | self.stats = self.glancesgrabhddtemp.get() |
||
64 | |||
65 | else: |
||
66 | # Update stats using SNMP |
||
67 | # Not available for the moment |
||
68 | pass |
||
69 | |||
70 | return self.stats |
||
71 | |||
72 | |||
73 | class GlancesGrabHDDTemp(object): |
||
74 | |||
75 | """Get hddtemp stats using a socket connection.""" |
||
76 | |||
77 | def __init__(self, host='127.0.0.1', port=7634, args=None): |
||
78 | """Init hddtemp stats.""" |
||
79 | self.args = args |
||
80 | self.host = host |
||
81 | self.port = port |
||
82 | self.cache = "" |
||
83 | self.reset() |
||
84 | |||
85 | def reset(self): |
||
86 | """Reset/init the stats.""" |
||
87 | self.hddtemp_list = [] |
||
88 | |||
89 | def __update__(self): |
||
90 | """Update the stats.""" |
||
91 | # Reset the list |
||
92 | self.reset() |
||
93 | |||
94 | # Only update if --disable-hddtemp is not set |
||
95 | if self.args is None or self.args.disable_hddtemp: |
||
96 | return |
||
97 | |||
98 | # Fetch the data |
||
99 | data = self.fetch() |
||
100 | |||
101 | # Exit if no data |
||
102 | if data == "": |
||
103 | return |
||
104 | |||
105 | # Safety check to avoid malformed data |
||
106 | # Considering the size of "|/dev/sda||0||" as the minimum |
||
107 | if len(data) < 14: |
||
108 | data = self.cache if len(self.cache) > 0 else self.fetch() |
||
109 | self.cache = data |
||
110 | |||
111 | try: |
||
112 | fields = data.split(b'|') |
||
113 | except TypeError: |
||
114 | fields = "" |
||
115 | devices = (len(fields) - 1) // 5 |
||
116 | for item in range(devices): |
||
117 | offset = item * 5 |
||
118 | hddtemp_current = {} |
||
119 | device = os.path.basename(nativestr(fields[offset + 1])) |
||
120 | temperature = fields[offset + 3] |
||
121 | unit = nativestr(fields[offset + 4]) |
||
122 | hddtemp_current['label'] = device |
||
123 | # Temperature could be 'ERR' or 'SLP' (see issue#824) |
||
124 | hddtemp_current['value'] = float(temperature) if isinstance(temperature, numbers.Number) else temperature |
||
125 | hddtemp_current['unit'] = unit |
||
126 | self.hddtemp_list.append(hddtemp_current) |
||
127 | |||
128 | def fetch(self): |
||
129 | """Fetch the data from hddtemp daemon.""" |
||
130 | # Taking care of sudden deaths/stops of hddtemp daemon |
||
131 | try: |
||
132 | sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
||
133 | sck.connect((self.host, self.port)) |
||
134 | data = sck.recv(4096) |
||
135 | except socket.error as e: |
||
136 | logger.warning("Can not connect to an HDDtemp server ({0}:{1} => {2})".format(self.host, self.port, e)) |
||
137 | logger.debug("Disable the HDDtemp module. Use the --disable-hddtemp to hide the previous message.") |
||
138 | self.args.disable_hddtemp = True |
||
139 | data = "" |
||
140 | finally: |
||
141 | sck.close() |
||
142 | |||
143 | return data |
||
144 | |||
145 | def get(self): |
||
146 | """Get HDDs list.""" |
||
147 | self.__update__() |
||
148 | return self.hddtemp_list |
||
149 |