简体   繁体   中英

Get hard disk temperature using Python

I would like to get the temperature of a hard disk using Python (under Linux). I'm currently calling hddtemp with subprocess.popen , but I call it often enough that it is a performance bottleneck in my script. I think it should be possible to do something similar to question 4193514 ?

You can run hddtemp as a daemon (the -d option), then use sockets to query it - defaults to port 7634.

Edit: see some code that does this .

Expanding on what @gnibbler suggested in his main comment, what about a cached approach? This is a stupidly simple example just to show the concept:

from collection import defaultdict

class CachedValue(object):
    def __init__(self):
        self.timestamp = -1
        self._value = None

    @property 
    def value(self):
        return self._value

    @value.setter 
    def value(self, val):
        self._value = val 
        self.timestamp = time.time()

    def isOld(self, seconds):
        return (time.time() - self.timestamp) >= seconds

>>> _cached = defaultdict(CachedValue)
>>> _cached['hddtemp'].isOld(10)
True
>>> _cached['hddtemp'].value = 'Foo'
>>> _cached['hddtemp'].isOld(10)
False
# (wait 10 seconds)
>>> _cached['hddtemp'].isOld(10)
True

And in your specific case:

def reportHDD(self):
    if self._cached['hddtemp'].isOld(10):
        self._cached['hddtemp'].value = self.getNewHDDValue()
    return self._cached['hddtemp'].value

This approach is really more of a general solution to caching an expensive operation. In larger applications, the CachedValue could easily be replaced with a simple memcached/redis lookup which maintains its own TTL value for you. But on a small scale, this is just a fancy way of organizing the local cached values.

I was googling around for a while and this hit kept coming up close to the top no matter how I formatted my search. I have smartmontools and at least python 2.7.6 installed on all of my hosts and I didn't want to install a new package to pipe hdd temp data to graphite/statsd so I made the following.

I am not a developer and I don't know python (as obvious) so this is my 1-2 day attempt at figuring it out. I am too embarrassed to post all of the code here but here is the main dealy::

enter code here
#!/usr/bin/env python
import os

import subprocess

import multiprocessing

def grab_hdd_temp(hdd, queue):
  for line in subprocess.Popen(['smartctl', '-a', str('/dev/' + hdd)], stdout=subprocess.PIPE).stdout.read().split('\n'):
    if ( 'Temperature_Celsius' in line.split() ) or ('Temperature_Internal' in line.split() ):
      queue.put([hdd, line.split()[9]])

def hddtmp_dict(hdds_list):
  procs = []
  queue = multiprocessing.Queue()
  hddict={}
  for hdd in hdds_list:
    p = multiprocessing.Process(target=grab_hdd_temp, args=(hdd, queue))
    procs.append(p)
    p.start()
  for _ in procs:
    val = queue.get()
    hddict[val[0]]=val[1]
    p.join()
  return hddict

if __name__ == '__main__':
  hdds_list = [ x for x in os.listdir('/sys/block/') if x.startswith('sd') ]
  hddict = hddtmp_dict(hdds_list)
  for k in hddict:
      print(k, hddict[k])

On my storage server this returned the complete list of 38 drives in 2 seconds vs 50 seconds to iterate through all of the disks serially. That said the load jumps up from around 1.08 to 3.50 on a 40 core box. So take it as you will. I am trying to find a way to use proc or possibly fcntl based on another stack overflow I found to pull the data instead of using subprocess.popen but eh.

it's 2:22am here and I need to start heading home. Once there I'll try and outline the snippet above and say what I think everything is doing but I hope it's somewhat self-explanatory.

Sorry for the kludge code. I think the buffer is the better way to go at this point but it was a cool exercise. If you don't want to install hddtemp and this I think a buffer + the above may be the best option. Still trying to figure that out as well as I don't understand how to do classes yet.

I hope this helps someone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM