Fox
Explorer
- Joined
- Mar 22, 2014
- Messages
- 66
I have a python script that parses the SmartCtl output and essentially tokenizes its output (select fields) and prints all your drives and their drive temps automatically. I currently use it on FreeNAS and on my Windows box to have it automatically list all my drives and temps on demand. The intent was to store the data in a SQLite database and then graph them so i can monitor drive temps over time, but I never got that far. In fact, it could be used to also track other Smartctl data points as well.
In any case, if anyone wants it, I'm posting it below. It's python and really "simple" code to read. I should note that it was not tested on any other drives than my own, but should work out of the box. It works either from Windows (run it from a mapped or physical drive) and on FreeNAS command line.
Just didn't want the work to go to waste in case someone can use it. Note that it is based on a specific version of SmartCtl, so if SmartCtl is updated (majorly) and the output is changed, this script may not work. Currently, it is working on SmartCtl 6.2 (on my Windows Box).. Given the way SmartCtl was coded, I expect only a major redesign to change the output format.
In any case, if anyone wants it, I'm posting it below. It's python and really "simple" code to read. I should note that it was not tested on any other drives than my own, but should work out of the box. It works either from Windows (run it from a mapped or physical drive) and on FreeNAS command line.
Just didn't want the work to go to waste in case someone can use it. Note that it is based on a specific version of SmartCtl, so if SmartCtl is updated (majorly) and the output is changed, this script may not work. Currently, it is working on SmartCtl 6.2 (on my Windows Box).. Given the way SmartCtl was coded, I expect only a major redesign to change the output format.
Code:
import os,string
def Run_SmartCtl(strArgs):
cmdstring = "smartctl " + strArgs
the_output = os.popen(cmdstring).read()
lines =str.splitlines(the_output)
#lines = ["/dev/sda"]
return lines
def Get_Device_Ids():
lines = Run_SmartCtl("--scan")
Device_List = []
for line in lines:
device_id = string.split(line," ",1)[0]
Device_List.append(device_id)
return Device_List
def Get_Device_Info(device_id):
dev = DeviceRecord()
dev_info_lines = Run_SmartCtl("-i " + device_id )
bEnteredInfoSection = False
dev.device_id = device_id
for line2 in dev_info_lines:
if ( not bEnteredInfoSection ):
TheFirstField = string.split(line2," ",2)
#if (TheFirstField[0].lower() == 'smartctl' ):
# print "SmartCtl Version is: " + TheFirstField[1]
if ( line2.lower() == "=== start of information section ===" ) :
bEnteredInfoSection = True
else:
field = string.split(line2,":",1)
if (field[0].lower() == "model family" ):
dev.family = field[1].strip()
elif (field[0].lower() == "device model" ):
dev.model = field[1].strip()
elif (field[0].lower() == "serial number" ):
dev.serial = field[1].strip()
elif (field[0].lower() == "firmware version" ):
dev.firmware_version = field[1].strip()
elif (field[0].lower() == "user capacity" ):
dev.capacity = field[1].strip()
elif (field[0].lower() == "sector sizes" ):
dev.sector_sizes = field[1].strip()
elif (field[0].lower() == "rotation rate" ):
dev.rotation_rate = field[1].strip()
elif (field[0].lower() == "device is" ):
dev.device_is = field[1].strip()
elif (field[0].lower() == "ata version is" ):
dev.ata_version = field[1].strip()
elif (field[0].lower() == "sata version is" ):
dev.sata_version = field[1].strip()
elif (field[0].lower() == "smart support is" ):
temp = string.split(field[1].strip()," ",1)
#temp = string.split(field[1]," ",1)
strTemp = temp[0].strip().lower()
if (strTemp == "available" ):
dev.smart_support_available = True
elif (strTemp == "unavailable" ):
dev.smart_support_available = False
dev.smart_support_enabled = False
elif (strTemp == "enabled" ) :
dev.smart_support_enabled = True
elif (strTemp == "disabled" ) :
dev.smart_support_enabled = False
return dev
def Get_Temp_Data(device_id):
dev_info_lines = Run_SmartCtl("-l scttemp " + device_id )
for line2 in dev_info_lines:
TheFirstField = string.split(line2," ",2)
field = string.split(line2,":",1)
if (field[0].lower() == "current temperature" ):
current_temp = field[1].strip()
#elif (field[0].lower() == "device model" ):
# dev.model = field[1].strip()
#elif (field[0].lower() == "serial number" ):
# dev.serial = field[1].strip()
return current_temp
class DeviceRecord:
device_id = ""
family = ""
model = ""
serial = ""
firmware_version = ""
capacity = ""
sector_sizes = ""
rotation_rate = ""
device_is = ""
ata_version = ""
sata_version = ""
smart_support_available = False
smart_support_enabled = False
def RemoveDupes(devices):
newlist = []
for device in devices:
currentSerial = device.serial
present = False
for item in newlist:
if (item.serial == currentSerial):
present = True
if ( not present ) :
newlist.append(device)
return newlist
def RemoveDisabledUnsupported(devices):
newlist = []
for device in devices:
if ( device.smart_support_available == True and device.smart_support_enabled == True ):
newlist.append(device)
return newlist
###################################################################################################
device_list = Get_Device_Ids()
if ( [] == device_list ) : print "No devices found."
list_of_records = []
for strDevice in device_list:
device = Get_Device_Info(strDevice)
#print device.family, device.model, device.serial, device.smart_support_available,device.smart_support_enabled
list_of_records.append(device)
newlist = RemoveDupes(list_of_records)
devices_new = RemoveDisabledUnsupported(newlist)
for x in devices_new:
print "{0:40}{1:30}{2:15}".format(x.family, x.model,Get_Temp_Data(x.device_id))
raw_input("Press Enter to continue...")