Completed
Push — master ( 1806d1...053f07 )
by Nicolas
01:42
created

glances/plugins/glances_hddtemp.py (1 issue)

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
This code seems to be duplicated in your project.
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