mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
dcb4590d79
git-svn-id: https://svn.fhem.de/fhem/trunk@14440 2b470e98-0d58-463d-a4d8-8e2adae1ed80
768 lines
21 KiB
Perl
768 lines
21 KiB
Perl
################################################################
|
||
#
|
||
# Copyright notice
|
||
#
|
||
# (c) 2014 Alexander Schulz
|
||
#
|
||
# This script is free software; you can redistribute it and/or modify
|
||
# it under the terms of the GNU General Public License as published by
|
||
# the Free Software Foundation; either version 2 of the License, or
|
||
# (at your option) any later version.
|
||
#
|
||
# The GNU General Public License can be found at
|
||
# http://www.gnu.org/copyleft/gpl.html.
|
||
# A copy is found in the textfile GPL.txt and important notices to the license
|
||
# from the author is found in LICENSE.txt distributed with these scripts.
|
||
#
|
||
# This script is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
# GNU General Public License for more details.
|
||
#
|
||
# This copyright notice MUST APPEAR in all copies of the script!
|
||
#
|
||
################################################################
|
||
|
||
# $Id$
|
||
|
||
package main;
|
||
|
||
use strict;
|
||
use warnings;
|
||
use Data::Dumper;
|
||
|
||
my $VERSION = "0.9.5";
|
||
|
||
my $DEFAULT_INTERVAL = 60; # in minuten
|
||
|
||
sub SMARTMON_refreshReadings($);
|
||
sub SMARTMON_obtainParameters($);
|
||
sub SMARTMON_getSmartDataReadings($$);
|
||
sub SMARTMON_interpretKnownData($$$);
|
||
sub SMARTMON_readSmartData($;$);
|
||
sub SMARTMON_readDeviceData($%);
|
||
sub SMARTMON_sec2Dauer($);
|
||
sub SMARTMON_hour2Dauer($);
|
||
sub SMARTMON_execute($$);
|
||
|
||
|
||
sub SMARTMON_Initialize($)
|
||
{
|
||
my ($hash) = @_;
|
||
|
||
Log 5, "SMARTMON Initialize";
|
||
|
||
$hash->{DefFn} = "SMARTMON_Define";
|
||
$hash->{UndefFn} = "SMARTMON_Undefine";
|
||
$hash->{GetFn} = "SMARTMON_Get";
|
||
#$hash->{SetFn} = "SMARTMON_Set";
|
||
$hash->{AttrFn} = "SMARTMON_Attr";
|
||
$hash->{AttrList} = "show_raw:0,1,2 disable:0,1 include parameters ".$readingFnAttributes;
|
||
}
|
||
|
||
sub SMARTMON_Log($$$) {
|
||
my ( $hash, $loglevel, $text ) = @_;
|
||
my $xline = ( caller(0) )[2];
|
||
|
||
my $xsubroutine = ( caller(1) )[3];
|
||
my $sub = ( split( ':', $xsubroutine ) )[2];
|
||
$sub =~ s/SMARTMON_//;
|
||
|
||
my $instName = ( ref($hash) eq "HASH" ) ? $hash->{NAME} : $hash;
|
||
Log3 $hash, $loglevel, "SMARTMON $instName: $sub.$xline " . $text;
|
||
}
|
||
|
||
my $device;
|
||
|
||
sub SMARTMON_Define($$)
|
||
{
|
||
my ($hash, $def) = @_;
|
||
|
||
SMARTMON_Log($hash, 4, "Define $def");
|
||
|
||
my @a = split("[ \t][ \t]*", $def);
|
||
|
||
SMARTMON_Log($hash, 5, "Define: ".Dumper(@a));
|
||
|
||
return "Usage: define <name> SMARTMON <device> [M1]" if(@a < 3);
|
||
|
||
$hash->{DEVICE} = $a[2];
|
||
if(int(@a)>=4)
|
||
{
|
||
$hash->{INTERVAL} = $a[3]*60;
|
||
} else {
|
||
$hash->{INTERVAL} = $DEFAULT_INTERVAL*60;
|
||
}
|
||
|
||
$hash->{STATE} = "Initialized";
|
||
|
||
RemoveInternalTimer($hash);
|
||
# erstes update zeitversetzt starten
|
||
InternalTimer(gettimeofday()+10, "SMARTMON_Update", $hash, 0);
|
||
|
||
return undef;
|
||
}
|
||
|
||
sub SMARTMON_Undefine($$)
|
||
{
|
||
my ($hash, $arg) = @_;
|
||
|
||
SMARTMON_Log($hash, 4, "Undefine");
|
||
|
||
RemoveInternalTimer($hash);
|
||
return undef;
|
||
}
|
||
|
||
sub SMARTMON_Get($@)
|
||
{
|
||
# http://www.linux-community.de/Internal/Artikel/Print-Artikel/LinuxUser/2004/10/Die-Zuverlaessigkeit-von-Festplatten-ueberwachen-mit-smartmontools
|
||
my ($hash, @a) = @_;
|
||
|
||
my $name = $a[0];
|
||
|
||
if(@a < 2)
|
||
{
|
||
return "$name: get needs at least one parameter";
|
||
}
|
||
|
||
my $cmd= $a[1];
|
||
|
||
SMARTMON_Log($hash, 5, "Get: ".Dumper(@a));
|
||
|
||
if($cmd eq "update")
|
||
{
|
||
SMARTMON_refreshReadings($hash);
|
||
return undef;
|
||
}
|
||
|
||
my $param="";
|
||
if($hash->{PARAMETERS}) {$param=" ".$hash->{PARAMETERS};}
|
||
|
||
if($cmd eq "list")
|
||
{
|
||
if(@a<3) {return "$name: get list needs at least one parameter"; }
|
||
my $subcmd=$a[2];
|
||
my @t;
|
||
my $r;
|
||
if($subcmd eq "info") {
|
||
my $tdev = $hash->{DEVICE};
|
||
if(@a>3) {$tdev=$a[3];}
|
||
($r, @t) = SMARTMON_execute($hash, "sudo smartctl -i".$param." ".$tdev);
|
||
}
|
||
if($subcmd eq "data") {
|
||
my $tdev = $hash->{DEVICE};
|
||
if(@a>3) {$tdev=$a[3];}
|
||
($r, @t) = SMARTMON_execute($hash, "sudo smartctl -A".$param." ".$tdev);
|
||
}
|
||
if($subcmd eq "health") {
|
||
my $tdev = $hash->{DEVICE};
|
||
if(@a>3) {$tdev=$a[3];}
|
||
($r, @t) = SMARTMON_execute($hash, "sudo smartctl -H".$param." ".$tdev);
|
||
}
|
||
if($subcmd eq "devices") {
|
||
($r, @t) = SMARTMON_execute($hash, "sudo smartctl --scan");
|
||
}
|
||
|
||
my $tt;
|
||
if(defined($t[0])) {
|
||
if(scalar(@t)>0) {
|
||
$tt = join('',@t);
|
||
}
|
||
}
|
||
if(!$tt) {return "unknown parameter";}
|
||
return $tt."\nreturn code: ".$r;
|
||
}
|
||
|
||
if($cmd eq "version")
|
||
{
|
||
return $VERSION;
|
||
}
|
||
|
||
return "Unknown argument $cmd, choose one of update:noArg version:noArg list:devices,info,data,health";
|
||
}
|
||
|
||
sub SMARTMON_Attr($$$) {
|
||
my ($cmd, $name, $attrName, $attrVal) = @_;
|
||
|
||
$attrVal= "" unless defined($attrVal);
|
||
|
||
Log 5, "SMARTMON Attr: $cmd $name $attrName $attrVal";
|
||
|
||
my $hash = $main::defs{$name};
|
||
|
||
my $orig = AttrVal($name, $attrName, "");
|
||
|
||
if( $cmd eq "set" ) {# set, del
|
||
if( $orig ne $attrVal ) {
|
||
|
||
$attr{$name}{$attrName} = $attrVal;
|
||
|
||
if($attrName eq "disable") {
|
||
# NOP
|
||
}
|
||
|
||
if($attrName eq "parameters") {
|
||
$hash->{PARAMETERS}=$attrVal;
|
||
}
|
||
|
||
if($attrName eq "show_raw") {
|
||
SMARTMON_refreshReadings($hash);
|
||
}
|
||
|
||
if($attrName eq "include") {
|
||
SMARTMON_refreshReadings($hash);
|
||
}
|
||
|
||
#return $attrName ." set to ". $attrVal;
|
||
return undef;
|
||
}
|
||
}
|
||
|
||
if( $cmd eq "del" ) {# set,
|
||
if($attrName eq "show_raw") {
|
||
delete $attr{$name}{$attrName};
|
||
SMARTMON_refreshReadings($hash);
|
||
}
|
||
|
||
if($attrName eq "include") {
|
||
delete $attr{$name}{$attrName};
|
||
SMARTMON_refreshReadings($hash);
|
||
}
|
||
|
||
if($attrName eq "parameters") {
|
||
delete $hash->{PARAMETERS};
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
sub SMARTMON_Update($)
|
||
{
|
||
my ($hash) = @_;
|
||
|
||
SMARTMON_Log($hash, 5, "Update");
|
||
|
||
my $name = $hash->{NAME};
|
||
|
||
RemoveInternalTimer($hash);
|
||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "SMARTMON_Update", $hash, 1);
|
||
|
||
SMARTMON_refreshReadings($hash);
|
||
}
|
||
|
||
# Alle Readings neuerstellen
|
||
sub SMARTMON_refreshReadings($) {
|
||
my ($hash) = @_;
|
||
|
||
SMARTMON_Log($hash, 5, "Refresh readings");
|
||
|
||
my $name = $hash->{NAME};
|
||
|
||
readingsBeginUpdate($hash);
|
||
|
||
if( AttrVal($name, "disable", "") eq "1" ) {
|
||
SMARTMON_Log($hash, 5, "Update disabled");
|
||
$hash->{STATE} = "Inactive";
|
||
} else {
|
||
# Parameter holen
|
||
my $map = SMARTMON_obtainParameters($hash);
|
||
|
||
$hash->{STATE} = "Active";
|
||
|
||
foreach my $aName (keys %{$map}) {
|
||
my $value = $map->{$aName};
|
||
#SMARTMON_Log($hash, 5, "Update: ".$value);
|
||
# Nur aktualisieren, wenn ein gueltiges Value vorliegt
|
||
if(defined $value) {
|
||
readingsBulkUpdate($hash,$aName,$value);
|
||
}
|
||
|
||
}
|
||
|
||
# Alle anderen Readings entfernen
|
||
foreach my $rName (sort keys %{$hash->{READINGS}}) {
|
||
if(!defined($map->{$rName})) {
|
||
delete $hash->{READINGS}->{$rName};
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
readingsEndUpdate($hash,1);
|
||
}
|
||
|
||
# Alle Readings erstellen
|
||
sub SMARTMON_obtainParameters($) {
|
||
my ($hash) = @_;
|
||
SMARTMON_Log($hash, 5, "Obtain parameters");
|
||
my $map;
|
||
|
||
# /usr/sbin/smartctl in /etc/sudoers aufnehmen
|
||
# fhem ALL=(ALL) NOPASSWD: [...,] /usr/sbin/smartctl
|
||
# Natuerlich muss der user auch der Gruppe "sudo" angeh<65>ren.
|
||
|
||
# Health
|
||
my $param="";
|
||
if($hash->{PARAMETERS}) {$param=" ".$hash->{PARAMETERS};}
|
||
my ($rcode, @adev_health) = SMARTMON_execute($hash, "sudo smartctl -H".$param." ".$hash->{DEVICE}." | grep 'test result:'");
|
||
my $dev_health;
|
||
my $tt;
|
||
if(defined($adev_health[0])) {
|
||
if(scalar(@adev_health)>0) {
|
||
$dev_health = join('',@adev_health);
|
||
}
|
||
}
|
||
|
||
delete $map->{"overall_health_test"};
|
||
if(defined($dev_health)) {
|
||
SMARTMON_Log($hash, 5, "health: $dev_health");
|
||
if($dev_health=~m/test\s+result:\s+(\S+).*/) {
|
||
$map->{"overall_health_test"} = $1;
|
||
}
|
||
}
|
||
|
||
$map = SMARTMON_getSmartDataReadings($hash, $map);
|
||
|
||
return $map;
|
||
}
|
||
|
||
# Readings zu gelesenen RAW-Daten
|
||
sub SMARTMON_getSmartDataReadings($$) {
|
||
my ($hash, $map) = @_;
|
||
|
||
my $name = $hash->{NAME};
|
||
|
||
# Attribut lesen, splitten, als Keys eines Hashes setzen
|
||
my $t_include = AttrVal($name, "include", undef);
|
||
my %h_include;
|
||
if(defined($t_include)) {
|
||
my @a_include = split(/,\s*/, trim($t_include));
|
||
%h_include = map { int($_) => 1 } @a_include; # 1 oder 001 soll gleichwertig sein
|
||
}
|
||
|
||
# S.M.A.R.T. RAW-Daten auslesen
|
||
my $dmap = SMARTMON_readSmartData($hash, defined($t_include)?\%h_include:undef);
|
||
#$dmap->{1}->{failed}="FAILING_NOW";
|
||
# Bekannte Werte einspielen
|
||
# per Referenz uebergeben!
|
||
my $done_map = SMARTMON_interpretKnownData($hash, \%{$dmap}, \%{$map});
|
||
|
||
my $cnt_oldage=0;
|
||
my $cnt_prefail=0;
|
||
my $sr = AttrVal($name, "show_raw", "0");
|
||
foreach my $id (sort keys %{$dmap}) {
|
||
if($id eq "RC") {next}
|
||
# warnings zaehlen
|
||
if($dmap->{$id}->{failed} ne "-") {
|
||
if($dmap->{$id}->{type} eq "Pre-fail") {$cnt_prefail++;}
|
||
if($dmap->{$id}->{type} eq "Old_age") {$cnt_oldage++;}
|
||
}
|
||
# restlichen RAW-Werte ggf. einspielen, per Attribut (show_raw) abschaltbar
|
||
if( $sr eq "1" || $sr eq "2" ) {
|
||
# nur wenn noch nicht frueher interpretiert werden,
|
||
# oder wenn explizit erwuenscht (Attribut show_raw)
|
||
if(!defined($done_map->{$id}) || $sr eq "2") {
|
||
my $m = $dmap->{$id};
|
||
my $rName = $m->{name};
|
||
#my $raw = $dmap->{$id}->{raw};
|
||
$map->{sprintf("%03d_%s",$id,$rName)} =
|
||
sprintf("Flag: %s Val: %s Worst: %s Thresh: %s ".
|
||
"Type: %s Updated: %s When_Failed: %s Raw: %s",
|
||
$m->{flag},$m->{value},$m->{worst},$m->{thresh},$m->{type},
|
||
$m->{updated},$m->{failed},$m->{raw});
|
||
}
|
||
}
|
||
}
|
||
|
||
$map->{warnings}="Pre-fail: $cnt_prefail Old_age: $cnt_oldage";
|
||
|
||
SMARTMON_readDeviceData($hash, \%{$map});
|
||
|
||
return $map;
|
||
}
|
||
|
||
sub SMARTMON_readDeviceData($%) {
|
||
my ($hash, $map) = @_;
|
||
|
||
my $param="";
|
||
if($hash->{PARAMETERS}) {$param=" ".$hash->{PARAMETERS};}
|
||
my ($r, @dev_data) = SMARTMON_execute($hash, "sudo smartctl -i".$param." ".$hash->{DEVICE});
|
||
SMARTMON_Log($hash, 5, "device data: ".Dumper(@dev_data));
|
||
if(defined($dev_data[0])) {
|
||
while(scalar(@dev_data)>0) {
|
||
my $line = $dev_data[0];
|
||
shift @dev_data;
|
||
my($k,$v) = split(/:\s*/,$line);
|
||
if($k eq "Device Model") {
|
||
$hash->{DEVICE_MODEL}=$v;
|
||
}
|
||
if($k eq "Serial Number") {
|
||
$hash->{DEVICE_SERIAL}=$v;
|
||
}
|
||
if($k eq "Firmware Version") {
|
||
$hash->{DEVICE_FIRMARE}=$v;
|
||
}
|
||
if($k eq "User Capacity") {
|
||
$hash->{DEVICE_CAPACITY}=$v;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
# Readings zu bekannten Werten erstellen
|
||
sub SMARTMON_interpretKnownData($$$) {
|
||
my ($hash, $dmap, $map) = @_;
|
||
my $known;
|
||
#$map->{TEST}="TestX";
|
||
|
||
# smartctl 5.41 2011-06-09 r3365 [armv7l-linux-3.4.98-sun7i+] (local build)
|
||
# Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net
|
||
#
|
||
# === START OF READ SMART DATA SECTION ===
|
||
# SMART Attributes Data Structure revision number: 16
|
||
# Vendor Specific SMART Attributes with Thresholds:
|
||
# ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
|
||
# 1 Raw_Read_Error_Rate 0x002f 200 200 051 Pre-fail Always - 0
|
||
# 3 Spin_Up_Time 0x0027 184 183 021 Pre-fail Always - 1800
|
||
# 4 Start_Stop_Count 0x0032 100 100 000 Old_age Always - 28
|
||
# 5 Reallocated_Sector_Ct 0x0033 200 200 140 Pre-fail Always - 0
|
||
# 7 Seek_Error_Rate 0x002e 200 200 000 Old_age Always - 0
|
||
# 9 Power_On_Hours 0x0032 096 096 000 Old_age Always - 3444
|
||
# 10 Spin_Retry_Count 0x0032 100 253 000 Old_age Always - 0
|
||
# 11 Calibration_Retry_Count 0x0032 100 253 000 Old_age Always - 0
|
||
# 12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 28
|
||
# 192 Power-Off_Retract_Count 0x0032 200 200 000 Old_age Always - 20
|
||
# 193 Load_Cycle_Count 0x0032 200 200 000 Old_age Always - 7
|
||
# 194 Temperature_Celsius 0x0022 103 097 000 Old_age Always - 44
|
||
# 196 Reallocated_Event_Count 0x0032 200 200 000 Old_age Always - 0
|
||
# 197 Current_Pending_Sector 0x0032 200 200 000 Old_age Always - 0
|
||
# 198 Offline_Uncorrectable 0x0030 100 253 000 Old_age Offline - 0
|
||
# 199 UDMA_CRC_Error_Count 0x0032 200 200 000 Old_age Always - 0
|
||
# 200 Multi_Zone_Error_Rate 0x0008 100 253 000 Old_age Offline - 0
|
||
|
||
|
||
if($dmap->{3}) {
|
||
$map->{spin_up_time} = $dmap->{3}->{raw};
|
||
$known->{3}=1;
|
||
}
|
||
if($dmap->{4}) {
|
||
$map->{start_stop_count} = $dmap->{4}->{raw};
|
||
$known->{4}=1;
|
||
}
|
||
if($dmap->{5}) {
|
||
$map->{reallocated_sector_count} = $dmap->{5}->{raw};
|
||
$known->{5}=1;
|
||
}
|
||
if($dmap->{9}) {
|
||
$map->{power_on_hours} = $dmap->{9}->{raw};
|
||
$map->{power_on_text} = SMARTMON_hour2Dauer($dmap->{9}->{raw});
|
||
$known->{9}=1;
|
||
}
|
||
if($dmap->{10}) {
|
||
$map->{spin_retry_count} = $dmap->{10}->{raw};
|
||
$known->{10}=1;
|
||
}
|
||
if($dmap->{12}) {
|
||
$map->{power_cycle_count} = $dmap->{12}->{raw};
|
||
$known->{12}=1;
|
||
}
|
||
|
||
if($dmap->{190}) {
|
||
$map->{airflow_temperature} = $dmap->{190}->{raw};
|
||
$known->{190}=1;
|
||
}
|
||
if($dmap->{194}) {
|
||
$map->{temperature} = $dmap->{194}->{raw};
|
||
$known->{194}=1;
|
||
}
|
||
|
||
# TODO
|
||
|
||
if($dmap->{"RC"}) {
|
||
$map->{last_exit_code} = $dmap->{"RC"}->{raw};
|
||
$known->{"RC"}=1;
|
||
}
|
||
|
||
return $known;
|
||
}
|
||
|
||
# Ausrechnet aus der Zahl der Sekunden Anzeige in Tagen:Stunden:Minuten:Sekunden.
|
||
sub SMARTMON_sec2Dauer($){
|
||
my ($t) = @_;
|
||
my $d = int($t/86400);
|
||
my $r = $t-($d*86400);
|
||
my $h = int($r/3600);
|
||
$r = $r - ($h*3600);
|
||
my $m = int($r/60);
|
||
my $s = $r - $m*60;
|
||
return sprintf("%02d Tage %02d Std. %02d Min. %02d Sec.",$d,$h,$m,$s);
|
||
}
|
||
|
||
# Ausrechnet aus der Zahl der Stunden Anzeige in Tagen:Stunden:Minuten:Sekunden.
|
||
sub SMARTMON_hour2Dauer($){
|
||
my ($t) = @_;
|
||
#return SMARTMON_sec2Dauer($t*3600);
|
||
$t =~ /([0-9]*)/;
|
||
my $d=int($1/24);
|
||
$t = $1-($d*24);
|
||
#my $d=int($t/24);
|
||
#$t = $t-($d*24);
|
||
my $y=int($d/365);
|
||
$d = $d-($y*365);
|
||
return sprintf("%d Jahre %d Tage %d Std.",$y,$d,$t);
|
||
}
|
||
|
||
# liest RAW-Daten
|
||
# Params:
|
||
# HASH: Device-HASH
|
||
# Include-HASH: Wenn definiert,werden nur die ID zurueckgegeben, die in
|
||
# diesem HASH enthalten sind.
|
||
sub SMARTMON_readSmartData($;$) {
|
||
my ($hash, $include) = @_;
|
||
my $map;
|
||
|
||
my $param="";
|
||
if($hash->{PARAMETERS}) {$param=" ".$hash->{PARAMETERS};}
|
||
my ($r, @dev_data) = SMARTMON_execute($hash, "sudo smartctl -A".$param." ".$hash->{DEVICE});
|
||
SMARTMON_Log($hash, 5, "device SMART data: ".Dumper(@dev_data));
|
||
if(defined($r)) {$map->{"RC"}->{raw} = $r;}
|
||
if(defined($dev_data[0])) {
|
||
while(scalar(@dev_data)>0) {
|
||
shift @dev_data;
|
||
if(scalar(@dev_data)>0 && $dev_data[0]=~m/ID#.*/) {
|
||
shift @dev_data;
|
||
while(scalar(@dev_data)>0) {
|
||
my ($d_id, $d_attr_name, $d_flag, $d_value, $d_worst, $d_thresh,
|
||
$d_type, $d_updated, $d_when_failed, $d_raw_value)
|
||
= split(/\s+/, trim($dev_data[0]));
|
||
shift @dev_data;
|
||
|
||
if(!defined($include) || defined($include->{$d_id})) {
|
||
if(defined($d_attr_name)) {
|
||
#$map->{$d_attr_name} = "Value: $d_value, Worst: $d_worst, Type: $d_type, Raw: $d_raw_value";
|
||
$map->{$d_id}->{name} = $d_attr_name;
|
||
$map->{$d_id}->{flag} = $d_flag;
|
||
$map->{$d_id}->{value} = $d_value;
|
||
$map->{$d_id}->{worst} = $d_worst;
|
||
$map->{$d_id}->{thresh} = $d_thresh;
|
||
$map->{$d_id}->{type} = $d_type;
|
||
$map->{$d_id}->{updated} = $d_updated;
|
||
$map->{$d_id}->{failed} = $d_when_failed;
|
||
$map->{$d_id}->{raw} = $d_raw_value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $map;
|
||
}
|
||
|
||
# BS-Befehl ausfuehren
|
||
sub SMARTMON_execute($$) {
|
||
my ($hash, $cmd) = @_;
|
||
|
||
SMARTMON_Log($hash, 5, "Execute: $cmd");
|
||
|
||
local $SIG{'CHLD'}='DEFAULT';
|
||
my @ret = qx($cmd);
|
||
my $rcode = $?>>8;
|
||
SMARTMON_Log($hash, 5, "Returncode: ".$rcode);
|
||
return ($rcode,@ret);
|
||
}
|
||
|
||
1;
|
||
|
||
=pod
|
||
=item device
|
||
=item summary provides some statistics about the S.M.A.R.T. capable drive
|
||
=item summary_DE liefert einige Statistiken ueber S.M.A.R.T. kompatible Ger<65>te
|
||
=begin html
|
||
|
||
<!-- ================================ -->
|
||
<a name="SMARTMON"></a>
|
||
<h3>SMARTMON</h3>
|
||
<ul>
|
||
This module is a FHEM frontend to the Linux tool smartctl.
|
||
It provides various information on the SMART System of the hard drive.
|
||
<br><br>
|
||
<b>Define</b>
|
||
<br><br>
|
||
<code>define <name> SMARTMON <device> [<Interval>]</code><br>
|
||
<br>
|
||
This statement creates a new SMARTMON instance.
|
||
The parameters specify a device to be monitored and the update interval in minutes.<br>
|
||
<br>
|
||
|
||
Example: <code>define sm SMARTMON /dev/sda 60</code>
|
||
<br>
|
||
<br>
|
||
|
||
<b>Readings:</b>
|
||
<br><br>
|
||
<ul>
|
||
<li>last_exit_code<br>
|
||
Exit code of smartctl.
|
||
</li>
|
||
<li>overall_health_test<br>
|
||
Specifies the general condition of the HDD (PASSED or FAILED).
|
||
</li>
|
||
<br>
|
||
<li>warnings<br>
|
||
Specifies the number of stored alerts.
|
||
</li>
|
||
<br>
|
||
Furthermore, the available SMART parameters can be displayed as Readings (RAW and / or (partially) interpreted).
|
||
</ul>
|
||
<br>
|
||
|
||
<b>Get:</b><br><br>
|
||
<ul>
|
||
<li>version<br>
|
||
Displays the module version.
|
||
</li>
|
||
<br>
|
||
<li>update<br>
|
||
Updates all readings.
|
||
</li>
|
||
<br>
|
||
<li>list<br>
|
||
Displays various information:
|
||
<ul>
|
||
<li>devices:<br>List of available devices in the system.</li>
|
||
</ul><br>
|
||
<ul>
|
||
<li>info:<br>Information about the current device.</li>
|
||
</ul><br>
|
||
<ul>
|
||
<li>data:<br>List of SMART parameters for the current device.</li>
|
||
</ul><br>
|
||
<ul>
|
||
<li>health:<br>Information about overall health status for the device.</li>
|
||
</ul><br>
|
||
For the Last 3 commands can also be another Device specified (as an additional parameter).
|
||
</li>
|
||
<br>
|
||
</ul><br>
|
||
|
||
<b>Attributes:</b><br><br>
|
||
<ul>
|
||
<li>show_raw<br>
|
||
Valid values: 0: no RAW Readings (default), 1: show all, are not included in interpreted Readings, 2: show all.
|
||
</li>
|
||
<br>
|
||
<li>include<br>
|
||
Comma separated list of IDs for desired SMART parameters. If nothing passed, all available values are displayed.
|
||
</li>
|
||
<br>
|
||
<li>disable<br>
|
||
Valid values: 0: Module active (default), 1: module is disabled (no updates).
|
||
</li>
|
||
<br>
|
||
<li>parameters<br>
|
||
Additional values for smartctl.
|
||
</li>
|
||
<br>
|
||
</ul><br>
|
||
For more information see cmartctrl documentation.
|
||
</ul>
|
||
<!-- ================================ -->
|
||
|
||
=end html
|
||
=begin html_DE
|
||
|
||
<a name="SMARTMON"></a>
|
||
<h3>SMARTMON</h3>
|
||
<ul>
|
||
Dieses Modul ist ein FHEM-Frontend zu dem Linux-Tool smartctl.
|
||
Es liefert diverse Informationen zu dem S.M.A.R.T. System einer Festplatte.
|
||
<br><br>
|
||
<b>Define</b>
|
||
<br><br>
|
||
<code>define <name> SMARTMON <device> [<Interval>]</code><br>
|
||
<br>
|
||
Diese Anweisung erstellt eine neue SMARTMON-Instanz.
|
||
Die Parameter geben ein zu überwachenden Gerät und den Aktualisierungsinterval in Minuten an.<br>
|
||
<br>
|
||
|
||
Beispiel: <code>define sm SMARTMON /dev/sda 60</code>
|
||
<br>
|
||
<br>
|
||
|
||
<b>Readings:</b>
|
||
<br><br>
|
||
<ul>
|
||
<li>last_exit_code<br>
|
||
Gibt den Exitcode bei der letzten Ausführung vom smartctl.
|
||
</li>
|
||
<br>
|
||
<li>overall_health_test<br>
|
||
Gibt den allgemeinen Zustand der Platte an. Kann PASSED oder FAILED sein.
|
||
</li>
|
||
<br>
|
||
<li>warnings<br>
|
||
Gibt die Anzahl der vermerkten Warnungen an.
|
||
</li>
|
||
<br>
|
||
Weiterhin können die verfügbaren SMART-Parameter als Readings angezeigt werden (RAW und/oder (teilweise) interpretiert).
|
||
</ul>
|
||
<br>
|
||
|
||
<b>Get:</b><br><br>
|
||
<ul>
|
||
<li>version<br>
|
||
Zeigt die verwendete Modul-Version an.
|
||
</li>
|
||
<br>
|
||
<li>update<br>
|
||
Veranlasst die Aktualisierung der gelesenen Parameter.
|
||
</li>
|
||
<br>
|
||
<li>list<br>
|
||
Zeigt verschiedenen Informationen an:
|
||
<ul>
|
||
<li>devices:<br>Liste der im System verfügbaren Geräten.</li>
|
||
</ul><br>
|
||
<ul>
|
||
<li>info:<br>Information zu dem aktuellen Gerät.</li>
|
||
</ul><br>
|
||
<ul>
|
||
<li>data:<br>Liste der SMART-Parameter zu dem aktuellen Gerät.</li>
|
||
</ul><br>
|
||
<ul>
|
||
<li>health:<br>Information zu dem allgemeinen Gesundheitsstatus für das verwendete Gerät.</li>
|
||
</ul><br>
|
||
Für letzten 3 Befehle kann auch noch ein anderes Gerät als zusätzliche Parameter mitgegeben werden.
|
||
</li>
|
||
<br>
|
||
</ul><br>
|
||
|
||
<b>Attributes:</b><br><br>
|
||
<ul>
|
||
<li>show_raw<br>
|
||
Gültige Werte: 0: keine RAW-Readings anzeigen (default), 1: alle anzeigen, die nicht in interpretierten Readings enthalten sind, 2: alle anzeigen.
|
||
</li>
|
||
<br>
|
||
<li>include<br>
|
||
Kommaseparierte Liste der IDs gewünschten SMART-Parameter. Wenn nichts angegeben, werden alle verfügbaren angezeigt.
|
||
</li>
|
||
<br>
|
||
<li>disable<br>
|
||
Gültige Werte: 0: Modul aktiv (default), 1: Modul deaktiviert (keine Aktualisierungen).
|
||
</li>
|
||
<br>
|
||
<li>parameters<br>
|
||
Zusatzparameter für den Aufruf von smartctl.
|
||
</li>
|
||
<br>
|
||
</ul><br>
|
||
Für weitere Informationen wird die cmartctrl-Dokumentation empfohlen.
|
||
|
||
</ul>
|
||
|
||
=end html_DE
|
||
=cut
|