]> arthur.barton.de Git - netdata.git/blob - python.d/python_modules/lm_sensors.py
freeradius_plugin: python 2.6 compatibility fix2
[netdata.git] / python.d / python_modules / lm_sensors.py
1 """
2 @package sensors.py
3 Python Bindings for libsensors3
4
5 use the documentation of libsensors for the low level API.
6 see example.py for high level API usage.
7
8 @author: Pavel Rojtberg (http://www.rojtberg.net)
9 @see: https://github.com/paroj/sensors.py
10 @copyright: LGPLv2 (same as libsensors) <http://opensource.org/licenses/LGPL-2.1>
11 """
12
13 from ctypes import *
14 import ctypes.util
15
16 _libc = cdll.LoadLibrary(ctypes.util.find_library("c"))
17 # see https://github.com/paroj/sensors.py/issues/1
18 _libc.free.argtypes = [c_void_p]
19 _hdl = cdll.LoadLibrary(ctypes.util.find_library("sensors"))
20
21 version = c_char_p.in_dll(_hdl, "libsensors_version").value.decode("ascii")
22
23
24 class bus_id(Structure):
25     _fields_ = [("type", c_short),
26                 ("nr", c_short)]
27
28
29 class chip_name(Structure):
30     _fields_ = [("prefix", c_char_p),
31                 ("bus", bus_id),
32                 ("addr", c_int),
33                 ("path", c_char_p)]
34
35
36 class feature(Structure):
37     _fields_ = [("name", c_char_p),
38                 ("number", c_int),
39                 ("type", c_int)]
40
41     # sensors_feature_type
42     IN = 0x00
43     FAN = 0x01
44     TEMP = 0x02
45     POWER = 0x03
46     ENERGY = 0x04
47     CURR = 0x05
48     HUMIDITY = 0x06
49     MAX_MAIN = 0x7
50     VID = 0x10
51     INTRUSION = 0x11
52     MAX_OTHER = 0x12
53     BEEP_ENABLE = 0x18
54
55
56 class subfeature(Structure):
57     _fields_ = [("name", c_char_p),
58                 ("number", c_int),
59                 ("type", c_int),
60                 ("mapping", c_int),
61                 ("flags", c_uint)]
62
63
64 _hdl.sensors_get_detected_chips.restype = POINTER(chip_name)
65 _hdl.sensors_get_features.restype = POINTER(feature)
66 _hdl.sensors_get_all_subfeatures.restype = POINTER(subfeature)
67 _hdl.sensors_get_label.restype = c_void_p  # return pointer instead of str so we can free it
68 _hdl.sensors_get_adapter_name.restype = c_char_p  # docs do not say whether to free this or not
69 _hdl.sensors_strerror.restype = c_char_p
70
71 ### RAW API ###
72 MODE_R = 1
73 MODE_W = 2
74 COMPUTE_MAPPING = 4
75
76
77 def init(cfg_file=None):
78     file = _libc.fopen(cfg_file.encode("utf-8"), "r") if cfg_file is not None else None
79
80     if _hdl.sensors_init(file) != 0:
81         raise Exception("sensors_init failed")
82
83     if file is not None:
84         _libc.fclose(file)
85
86
87 def cleanup():
88     _hdl.sensors_cleanup()
89
90
91 def parse_chip_name(orig_name):
92     ret = chip_name()
93     err = _hdl.sensors_parse_chip_name(orig_name.encode("utf-8"), byref(ret))
94
95     if err < 0:
96         raise Exception(strerror(err))
97
98     return ret
99
100
101 def strerror(errnum):
102     return _hdl.sensors_strerror(errnum).decode("utf-8")
103
104
105 def free_chip_name(chip):
106     _hdl.sensors_free_chip_name(byref(chip))
107
108
109 def get_detected_chips(match, nr):
110     """
111     @return: (chip, next nr to query)
112     """
113     _nr = c_int(nr)
114
115     if match is not None:
116         match = byref(match)
117
118     chip = _hdl.sensors_get_detected_chips(match, byref(_nr))
119     chip = chip.contents if bool(chip) else None
120     return chip, _nr.value
121
122
123 def chip_snprintf_name(chip, buffer_size=200):
124     """
125     @param buffer_size defaults to the size used in the sensors utility
126     """
127     ret = create_string_buffer(buffer_size)
128     err = _hdl.sensors_snprintf_chip_name(ret, buffer_size, byref(chip))
129
130     if err < 0:
131         raise Exception(strerror(err))
132
133     return ret.value.decode("utf-8")
134
135
136 def do_chip_sets(chip):
137     """
138     @attention this function was not tested
139     """
140     err = _hdl.sensors_do_chip_sets(byref(chip))
141     if err < 0:
142         raise Exception(strerror(err))
143
144
145 def get_adapter_name(bus):
146     return _hdl.sensors_get_adapter_name(byref(bus)).decode("utf-8")
147
148
149 def get_features(chip, nr):
150     """
151     @return: (feature, next nr to query)
152     """
153     _nr = c_int(nr)
154     feature = _hdl.sensors_get_features(byref(chip), byref(_nr))
155     feature = feature.contents if bool(feature) else None
156     return feature, _nr.value
157
158
159 def get_label(chip, feature):
160     ptr = _hdl.sensors_get_label(byref(chip), byref(feature))
161     val = cast(ptr, c_char_p).value.decode("utf-8")
162     _libc.free(ptr)
163     return val
164
165
166 def get_all_subfeatures(chip, feature, nr):
167     """
168     @return: (subfeature, next nr to query)
169     """
170     _nr = c_int(nr)
171     subfeature = _hdl.sensors_get_all_subfeatures(byref(chip), byref(feature), byref(_nr))
172     subfeature = subfeature.contents if bool(subfeature) else None
173     return subfeature, _nr.value
174
175
176 def get_value(chip, subfeature_nr):
177     val = c_double()
178     err = _hdl.sensors_get_value(byref(chip), subfeature_nr, byref(val))
179     if err < 0:
180         raise Exception(strerror(err))
181     return val.value
182
183
184 def set_value(chip, subfeature_nr, value):
185     """
186     @attention this function was not tested
187     """
188     val = c_double(value)
189     err = _hdl.sensors_set_value(byref(chip), subfeature_nr, byref(val))
190     if err < 0:
191         raise Exception(strerror(err))
192
193
194 ### Convenience API ###
195 class ChipIterator:
196     def __init__(self, match=None):
197         self.match = parse_chip_name(match) if match is not None else None
198         self.nr = 0
199
200     def __iter__(self):
201         return self
202
203     def __next__(self):
204         chip, self.nr = get_detected_chips(self.match, self.nr)
205
206         if chip is None:
207             raise StopIteration
208
209         return chip
210
211     def __del__(self):
212         if self.match is not None:
213             free_chip_name(self.match)
214
215     def next(self):  # python2 compability
216         return self.__next__()
217
218
219 class FeatureIterator:
220     def __init__(self, chip):
221         self.chip = chip
222         self.nr = 0
223
224     def __iter__(self):
225         return self
226
227     def __next__(self):
228         feature, self.nr = get_features(self.chip, self.nr)
229
230         if feature is None:
231             raise StopIteration
232
233         return feature
234
235     def next(self):  # python2 compability
236         return self.__next__()
237
238
239 class SubFeatureIterator:
240     def __init__(self, chip, feature):
241         self.chip = chip
242         self.feature = feature
243         self.nr = 0
244
245     def __iter__(self):
246         return self
247
248     def __next__(self):
249         subfeature, self.nr = get_all_subfeatures(self.chip, self.feature, self.nr)
250
251         if subfeature is None:
252             raise StopIteration
253
254         return subfeature
255
256     def next(self):  # python2 compability
257         return self.__next__()