UpsInfoPlugin.pm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. package Foswiki::Plugins::UpsInfoPlugin;
  2. use Net::SNMP;
  3. use Net::Ping;
  4. # Always use strict to enforce variable scoping
  5. use strict;
  6. # $VERSION is referred to by Foswiki, and is the only global variable that
  7. # *must* exist in this package
  8. use vars qw( $VERSION $RELEASE $debug $pluginName );
  9. use Foswiki::Func (); # The plugins API
  10. use Foswiki::Plugins (); # For the API version
  11. # This should always be $Rev: 8713$ so that Foswiki can determine the checked-in
  12. # status of the plugin. It is used by the build automation tools, so
  13. # you should leave it alone.
  14. $VERSION = '$Rev: 8713$';
  15. # This is a free-form string you can use to "name" your own plugin version.
  16. # It is *not* used by the build automation tools, but is reported as part
  17. # of the version number in PLUGINDESCRIPTIONS.
  18. $RELEASE = '1.01';
  19. # Name of this Plugin, only used in this module
  20. $pluginName = 'UpsInfoPlugin';
  21. =pod
  22. ---++ initPlugin($topic, $web, $user, $installWeb) -> $boolean
  23. * =$topic= - the name of the topic in the current CGI query
  24. * =$web= - the name of the web in the current CGI query
  25. * =$user= - the login name of the user
  26. * =$installWeb= - the name of the web the plugin is installed in
  27. REQUIRED
  28. Called to initialise the plugin. If everything is OK, should return
  29. a non-zero value. On non-fatal failure, should write a message
  30. using Foswiki::Func::writeWarning and return 0. In this case
  31. %FAILEDPLUGINS% will indicate which plugins failed.
  32. In the case of a catastrophic failure that will prevent the whole
  33. installation from working safely, this handler may use 'die', which
  34. will be trapped and reported in the browser.
  35. You may also call =Foswiki::Func::registerTagHandler= here to register
  36. a function to handle tags that have standard Foswiki syntax - for example,
  37. =%MYTAG{"my param" myarg="My Arg"}%. You can also override internal
  38. Foswiki tag handling functions this way, though this practice is unsupported
  39. and highly dangerous!
  40. =cut
  41. sub initPlugin {
  42. my( $topic, $web, $user, $installWeb ) = @_;
  43. # check for Plugins.pm versions
  44. if( $Foswiki::Plugins::VERSION < 1.026 ) {
  45. Foswiki::Func::writeWarning( "Version mismatch between $pluginName and Plugins.pm" );
  46. return 0;
  47. }
  48. Foswiki::Func::registerTagHandler( 'UpsINFO', \&_UpsINFO );
  49. # Plugin correctly initialized
  50. return 1;
  51. }
  52. sub GetSNMPkeyValue {
  53. my $session = shift;
  54. my $key = shift;
  55. my $value;
  56. eval {
  57. my $ret = $session->get_request( -varbindlist => [$key] );
  58. if (!$ret) {
  59. #search in subtree
  60. $ret = $session->get_next_request( -varbindlist => [$key] );
  61. my $branch = $key.'.*';
  62. my @keys_next = keys %$ret;
  63. my $get_key = $keys_next[0];
  64. if ($get_key=~/^$branch$/) { $value = $ret->{$get_key}; }
  65. } else { $value = $ret->{$key}; }
  66. };
  67. return $value;
  68. };
  69. sub _UpsINFO {
  70. my($session, $params, $theTopic, $theWeb) = @_;
  71. # $session - a reference to the Foswiki session object (if you don't know
  72. # what this is, just ignore it)
  73. # $params= - a reference to a Foswiki::Attrs object containing parameters.
  74. # This can be used as a simple hash that maps parameter names
  75. # to values, with _DEFAULT being the name for the default
  76. # parameter.
  77. # $theTopic - name of the topic in the query
  78. # $theWeb - name of the web in the query
  79. # Return: the result of processing the tag
  80. # For example, %EXAMPLETAG{'hamburger' sideorder="onions"}%
  81. # $params->{_DEFAULT} will be 'hamburger'
  82. # $params->{sideorder} will be 'onions'
  83. my $OIDModel = '.1.3.6.1.2.1.33.1.1.1.0';
  84. my $SchneiderModel = '.1.3.6.1.2.1.1.1.0';
  85. # APC OIDs
  86. my $OIDAPC = '1.3.6.1.4.1.318.';
  87. my $OIDhardware = '1.3.6.1.4.1.318.1.1.';
  88. my $OIDups = '1.3.6.1.4.1.318.1.1.1.';
  89. my $OIDident = '1.3.6.1.4.1.318.1.1.1.1.';
  90. my $OIDidentBasic = '1.3.6.1.4.1.318.1.1.1.1.1.';
  91. my $OIDidentBasicModel = '1.3.6.1.4.1.318.1.1.1.1.1.1.0';
  92. my $OIDidentBasicName = '1.3.6.1.4.1.318.1.1.1.1.1.2.0';
  93. my $OIDidentAdv = '1.3.6.1.4.1.318.1.1.1.1.2.';
  94. my $OIDidentAdvFW = '1.3.6.1.4.1.318.1.1.1.1.2.1.0';
  95. my $OIDidentAdvManuf = '1.3.6.1.4.1.318.1.1.1.1.2.2.0';
  96. my $OIDidentAdvSerial = '1.3.6.1.4.1.318.1.1.1.1.2.3.0';
  97. my $OIDbattery = '1.3.6.1.4.1.318.1.1.1.2.';
  98. my $OIDbatteryBasic = '1.3.6.1.4.1.318.1.1.1.2.1.';
  99. my $OIDbatteryBasicStatus = '1.3.6.1.4.1.318.1.1.1.2.1.1.0';
  100. my $OIDbatteryBasicTime = '1.3.6.1.4.1.318.1.1.1.2.1.2.0';
  101. my $OIDbatteryBasicRepl = '1.3.6.1.4.1.318.1.1.1.2.1.3.0';
  102. my $OIDbatteryAdv = '1.3.6.1.4.1.318.1.1.1.2.2.';
  103. my $OIDbatteryAdvTemp = '1.3.6.1.4.1.318.1.1.1.2.2.2.0';
  104. my $OIDbatteryAdvRuntime = '1.3.6.1.4.1.318.1.1.1.2.2.3.0';
  105. my $OIDbatteryAdvReplace = '1.3.6.1.4.1.318.1.1.1.2.2.4.0';
  106. my $apcUpsAdvBatteryStatus ='1.3.6.1.4.1.318.1.1.1.4.1.1.0';
  107. my $apcUpsAdvBatteryCapacity ='1.3.6.1.4.1.318.1.1.1.2.2.1.0';
  108. my $apcUpsAdvBatteryTemperature ='1.3.6.1.4.1.318.1.1.1.2.2.2.0';
  109. my $apcUpsAdvBatteryRunTimeRemaining ='1.3.6.1.4.1.318.1.1.1.2.2.3.0';
  110. my $apcUpsAdvOutputVoltage ='1.3.6.1.4.1.318.1.1.1.4.2.1.0';
  111. my $apcUpsAdvOutputFrequency ='1.3.6.1.4.1.318.1.1.1.4.2.2.0';
  112. my $apcUpsAdvOutputLoad ='1.3.6.1.4.1.318.1.1.1.4.2.3.0';
  113. my $apcUpsAdvOutputCurrent ='1.3.6.1.4.1.318.1.1.1.4.2.4.0';
  114. my $apcUpsAdvInputLineVoltage ='1.3.6.1.4.1.318.1.1.1.3.2.1.0';
  115. my $apcUpsAdvInputFrequency ='1.3.6.1.4.1.318.1.1.1.3.2.4.0';
  116. my $BATTERYREPLACE = '2';
  117. my $defaultModel = '.1.3.6.1.2.1.33.1.1.2.0';
  118. my $defaultBatteryReplace;
  119. my $defaultBatteryStatus = '.1.3.6.1.2.1.33.1.2.1';
  120. my $defaultbatteryTemp = '.1.3.6.1.2.1.33.1.2.4';
  121. my $defaultInputAC = '.1.3.6.1.2.1.33.1.3.3.1.3.1';
  122. my $defaultInputHz = '.1.3.6.1.2.1.33.1.3.3.1.2';
  123. my $defaultOutputAC = '.1.3.6.1.2.1.33.1.4.4.1.2';
  124. my $defaultOutputCurrent = '.1.3.6.1.2.1.33.1.4.4.1.3';
  125. my $defaultOutputPower = '.1.3.6.1.2.1.33.1.4.4.1.4';
  126. my $defaultPercentLoad = '.1.3.6.1.2.1.33.1.4.4.1.5';
  127. my $defaultLiveTime = '.1.3.6.1.2.1.33.1.2.3';
  128. my $defaultUpsLoad = '.1.3.6.1.2.1.33.1.4.4.1.5.1';
  129. my $defaultUpsStatus = '.1.3.6.1.2.1.33.1.6.3.2';
  130. my $defaultOutputHz = '.1.3.6.1.2.1.33.1.4.2';
  131. my $TEMPCRIT = 55;
  132. my $TEMPWARN = 50;
  133. my $host = $params->{_DEFAULT} || $params->{host};
  134. ### check host alive
  135. my $p = Net::Ping->new("tcp",1,1);
  136. my $ok= $p->ping($host);
  137. $p->close();
  138. if (!$ok) { return "Ups $host is not available<BR>"; }
  139. undef($p);
  140. my $port = $params->{port} || 161;
  141. my $timeout = $params->{timeout} || 5;
  142. my $community = $params->{community};
  143. $community = 'public' if (!$community);
  144. my $snmp_session;
  145. my $error;
  146. ### open SNMP session
  147. eval {
  148. ($snmp_session, $error) = Net::SNMP->session( -hostname => $host, -community => $community );
  149. };
  150. return "Ups is not available<BR>" if (!defined($snmp_session));
  151. $snmp_session->translate([-timeticks]);
  152. my $vendor;
  153. my $vendor_string = GetSNMPkeyValue($snmp_session,$OIDModel);
  154. if (!$vendor_string) { $vendor_string = GetSNMPkeyValue($snmp_session,$SchneiderModel); $vendor = 'Schneider'; }
  155. return "Ups model unknown!<BR>" if (!defined($vendor_string));
  156. if (!$vendor and $vendor_string=~/Eaton/i) { $vendor='EATON'; }
  157. if (!$vendor and $vendor_string=~/APC/i) { $vendor='APC'; }
  158. my $upsModel = GetSNMPkeyValue($snmp_session,$defaultModel);
  159. my $ret = "UPS Model: ".$upsModel."\n\n";
  160. my $battery_status = GetSNMPkeyValue($snmp_session,$defaultBatteryStatus);
  161. my $input_voltage = GetSNMPkeyValue($snmp_session,$defaultInputAC);
  162. my $status = "%GREEN%ONLINE%ENDCOLOR%";
  163. $status = "%RED%AHEZ%ENDCOLOR%" if ($battery_status eq 1);
  164. $status = "%RED%ON BATTERY%ENDCOLOR%" if ($battery_status eq 3);
  165. $status = "%RED%On Smart Boost%ENDCOLOR%" if ($battery_status eq 4);
  166. $status = "%RED%Timed Sleeping%ENDCOLOR%" if ($battery_status eq 5);
  167. $status = "%RED%Software Bypass%ENDCOLOR%" if ($battery_status eq 6);
  168. $status = "%RED%OFF%ENDCOLOR%" if ($battery_status eq 7);
  169. $status = "%GREEn%REBOOTING%ENDCOLOR%" if ($battery_status eq 8);
  170. $status = "%RED%SWITCHED BYPASS%ENDCOLOR%" if ($battery_status eq 9);
  171. $status = "%RED%Hardware Failure Bypass%ENDCOLOR%" if ($battery_status eq 10);
  172. $status = "%RED%Sleeping until power return%ENDCOLOR%" if ($battery_status eq 11);
  173. $ret .= "| UPS Status | ".$status." |\n";
  174. if ($vendor eq 'APC') {
  175. my $batteryAdvReplace = $snmp_session->get_request(-varbindlist => [$OIDbatteryAdvReplace])->{$OIDbatteryAdvReplace};
  176. if ($batteryAdvReplace && ($batteryAdvReplace eq $BATTERYREPLACE)) { $ret .= "| Battery Status | %RED%Battery requires replacement!%ENDCOLOR%|\n"; };
  177. $ret .= "| Battery Capacity | ".$snmp_session->get_request(-varbindlist => [$apcUpsAdvBatteryCapacity])->{$apcUpsAdvBatteryCapacity}."% |\n";
  178. }
  179. my $inputHz = GetSNMPkeyValue($snmp_session,$defaultInputHz);
  180. if ($inputHz) { $inputHz = int($inputHz/10); }
  181. my $outputHz = GetSNMPkeyValue($snmp_session,$defaultOutputHz);
  182. if ($outputHz) { $outputHz = int($outputHz/10); }
  183. my $runtime;
  184. if ($vendor eq 'APC') {
  185. $runtime = GetSNMPkeyValue($snmp_session,$OIDbatteryAdvRuntime);
  186. $runtime=int($runtime/6000);
  187. } else {
  188. if ($vendor eq 'EATON') {
  189. $runtime = GetSNMPkeyValue($snmp_session,'.1.3.6.1.4.1.534.1.2.1');
  190. } else {
  191. $runtime = GetSNMPkeyValue($snmp_session,$defaultLiveTime);
  192. }
  193. }
  194. if ($vendor eq 'EATON') { $runtime=int($runtime/60); }
  195. my $outputCurrent = GetSNMPkeyValue($snmp_session,$defaultOutputCurrent);
  196. if ($outputCurrent) { $outputCurrent=$outputCurrent/10; }
  197. my $batTemp;
  198. if ($vendor eq 'APC') {
  199. $batTemp=GetSNMPkeyValue($snmp_session,$OIDbatteryAdvTemp);
  200. } else {
  201. if ($vendor eq 'EATON') {
  202. $batTemp=GetSNMPkeyValue($snmp_session,'.1.3.6.1.4.1.534.1.6.1.0');
  203. } else {
  204. $batTemp=GetSNMPkeyValue($snmp_session,$defaultbatteryTemp);
  205. }
  206. }
  207. $ret .= "| Runtime Remaining | ". $runtime." min. |\n";
  208. $ret .= "| Battery Temperature | ".$batTemp." C |\n";
  209. $ret .= "| Output Voltage | ".GetSNMPkeyValue($snmp_session,$defaultOutputAC)." |\n";
  210. $ret .= "| Output Frequency | ".$outputHz." Hz |\n";
  211. $ret .= "| Output Load | ".GetSNMPkeyValue($snmp_session,$defaultUpsLoad)." % |\n";
  212. $ret .= "| Output Current | ".$outputCurrent." A |\n";
  213. $ret .= "| Input Voltage | ".$input_voltage." V |\n";
  214. $ret .= "| Input Frequency | ".$inputHz." Hz |\n";
  215. $snmp_session->close;
  216. return $ret;
  217. }
  218. 1;