import torrus 1.0.9
[freeside.git] / torrus / perllib / Torrus / DevDiscover / Liebert.pm
diff --git a/torrus/perllib/Torrus/DevDiscover/Liebert.pm b/torrus/perllib/Torrus/DevDiscover/Liebert.pm
new file mode 100644 (file)
index 0000000..c8aa3d2
--- /dev/null
@@ -0,0 +1,313 @@
+#
+#  Discovery module for Liebert HVAC systems
+#
+#  Copyright (C) 2008 Jon Nistor
+#
+#  This program 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.
+#
+#  This program 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.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+# $Id: Liebert.pm,v 1.1 2010-12-27 00:03:50 ivan Exp $
+# Jon Nistor <nistor at snickers.org>
+#
+# NOTE: Options for this module
+#       Liebert::use-fahrenheit
+#      Liebert::disable-temperature
+#      Liebert::disable-humidity
+#      Liebert::disable-state
+#      Liebert::disable-stats
+#
+# NOTE: This module supports both Fahrenheit and Celcius, but for ease of
+#       module and cleanliness we will convert Celcius into Fahrenheit
+#       instead of polling for Fahrenheit directly.
+#
+
+# Liebert discovery module
+package Torrus::DevDiscover::Liebert;
+
+use strict;
+use Torrus::Log;
+
+
+$Torrus::DevDiscover::registry{'Liebert'} = {
+    'sequence'     => 500,
+    'checkdevtype' => \&checkdevtype,
+    'discover'     => \&discover,
+    'buildConfig'  => \&buildConfig
+    };
+
+our %oiddef =
+    (
+     # LIEBERT-GP-REGISTRATION-MIB
+     'GlobalProducts'    => '1.3.6.1.4.1.476.1.42',
+
+     # LIEBERT-GP-AGENT-MIB
+     'Manufacturer'       => '1.3.6.1.4.1.476.1.42.2.1.1.0',
+     'Model'              => '1.3.6.1.4.1.476.1.42.2.1.2.0',
+     'FirmwareVer'        => '1.3.6.1.4.1.476.1.42.2.1.3.0',
+     'SerialNum'          => '1.3.6.1.4.1.476.1.42.2.1.4.0',
+     'PartNum'            => '1.3.6.1.4.1.476.1.42.2.1.5.0',
+
+     'TemperatureIdDegF'  => '1.3.6.1.4.1.476.1.42.3.4.1.2.3.1.1',
+     'TemperatureIdDegC'  => '1.3.6.1.4.1.476.1.42.3.4.1.3.3.1.1',
+     'HumidityIdRel'      => '1.3.6.1.4.1.476.1.42.3.4.2.2.3.1.1',
+
+     'lgpEnvState'                => '1.3.6.1.4.1.476.1.42.3.4.3',
+     'lgpEnvStateCoolingCapacity' => '1.3.6.1.4.1.476.1.42.3.4.3.9.0',
+     'lgpEnvStatistics'           => '1.3.6.1.4.1.476.1.42.3.4.6',
+
+     );
+
+sub checkdevtype
+{
+    my $dd = shift;
+    my $devdetails = shift;
+
+    if( not $dd->oidBaseMatch ( 'GlobalProducts',
+            $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
+    {
+        return 0;
+    }
+   
+    $devdetails->setCap('interfaceIndexingPersistent');
+
+    return 1;
+}
+
+
+sub discover
+{
+    my $dd = shift;
+    my $devdetails = shift;
+
+    my $session = $dd->session();
+    my $data = $devdetails->data();
+
+    # PROG: Grab versions, serials and type of chassis.
+    my $Info = $dd->retrieveSnmpOIDs ( 'Manufacturer', 'Model',
+                        'FirmwareVer', 'SerialNum', 'PartNum' );
+
+    # SNMP: System comment
+    $data->{'param'}{'comment'} =
+            $Info->{'Manufacturer'} . " " . $Info->{'Model'} . ", Version: " .
+            $Info->{'FirmwareVer'} . ", Serial: " . $Info->{'SerialNum'};
+
+    # The Liebert HVAC snmp implementation requires a lower number
+    # of pdu's to be sent to it.
+    $data->{'param'}{'snmp-oids-per-pdu'} = 10;
+
+    # Temperature
+    if( $devdetails->param('Liebert::disable-temperature') ne 'yes' ) 
+    {
+        $devdetails->setCap('env-temperature');
+
+        if( $devdetails->param('Liebert::use-fahrenheit') ne 'yes' )
+        {
+            # ENV: Temperature in Celcius
+            my $idTable = $session->get_table(
+                 -baseoid => $dd->oiddef('TemperatureIdDegC') );
+            $devdetails->storeSnmpVars( $idTable );
+
+            if( defined( $idTable ) )
+            {
+                $devdetails->setCap('env-temperature-celcius');
+
+                foreach my $index ( $devdetails->getSnmpIndices(
+                                    $dd->oiddef('TemperatureIdDegC') ) )
+                {
+                    Debug("Liebert: Temp (degC) index: $index");
+                    $data->{'liebert'}{'tempidx'}{$index} = "celcius";
+                }
+            }
+        } else {
+            # ENV: Temperature in Fahrenheit
+            my $idTable = $session->get_table(
+                 -baseoid => $dd->oiddef('TemperatureIdDegF') );
+            $devdetails->storeSnmpVars( $idTable );
+
+            if( defined( $idTable ) )
+            {
+                $devdetails->setCap('env-temperature-fahrenheit');
+
+                foreach my $index ( $devdetails->getSnmpIndices(
+                                    $dd->oiddef('TemperatureIdDegF') ) )
+                {
+                    Debug("Liebert: Temp (degF) index: $index");
+                    $data->{'liebert'}{'tempidx'}{$index} = "fahrenheit";
+                }
+            }
+        }
+    }
+
+    # ENV: Humidity
+    if( $devdetails->param('Liebert::disable-humidity') ne 'yes' )
+    {
+        my $idTable = $session->get_table(
+                 -baseoid => $dd->oiddef('HumidityIdRel') );
+        $devdetails->storeSnmpVars( $idTable );
+
+        if( defined( $idTable ) )
+        {
+            $devdetails->setCap('env-humidity');
+            foreach my $index ( $devdetails->getSnmpIndices(
+                                $dd->oiddef('HumidityIdRel') ) )
+            {
+                Debug("Liebert: humidity index: $index");
+                $data->{'liebert'}{'humididx'}{$index} = "humidity";
+            }
+        }
+    }
+
+    # ENV: State
+    if( $devdetails->param('Liebert::disable-state') ne 'yes' )
+    {
+        my $stateTable = $session->get_table(
+                 -baseoid => $dd->oiddef('lgpEnvState') );
+        $devdetails->storeSnmpVars( $stateTable );
+
+        if( defined( $stateTable ) )
+        {
+            $devdetails->setCap('env-state');
+
+            # PROG: Check to see if Firmware is new enough for Capacity
+            if( $dd->checkSnmpOID('lgpEnvStateCoolingCapacity') )
+            {
+                $devdetails->setCap('env-state-capacity');
+            }
+        }
+    }
+
+    # Statistics
+    if( $devdetails->param('Liebert::disable-stats') ne 'yes' )
+    {
+        my $statsTable = $session->get_table(
+                 -baseoid => $dd->oiddef('lgpEnvStatistics') );
+        $devdetails->storeSnmpVars( $statsTable );
+
+        if( defined( $statsTable ) )
+        {
+            $devdetails->setCap('env-stats');
+        }
+    }
+
+    return 1;
+}
+
+
+sub buildConfig
+{
+    my $devdetails = shift;
+    my $cb = shift;
+    my $devNode = shift;
+    my $data = $devdetails->data();
+
+    if( $devdetails->hasCap('env-temperature') )
+    {
+        # All place-setting variables default to Celcius
+        my @template;
+        my $dataFile   = "%system-id%_temperature.rrd";
+        my $fahrenheit = 0;
+        my $snmpVar    = 3;
+        my $tempUnit   = "C";
+        my $tempScale  = "Celcius";
+        my $tempLowLim = 15;
+        my $tempUppLim = 70;
+
+        if( $devdetails->hasCap('env-temperature-fahrenheit') )
+        {
+            $dataFile   = "%system-id%_temperature_f.rrd";
+            $fahrenheit        = 1;
+            $snmpVar    = 2;
+            $tempUnit   = "F";
+            $tempScale  = "Fahrenheit";
+            $tempLowLim = $tempLowLim * 1.8 + 32;
+            $tempUppLim = $tempUppLim * 1.8 + 32;
+            push(@template, "Liebert::temperature-sensor-fahrenheit");
+        } else {
+            push(@template, "Liebert::temperature-sensor");
+        }
+
+        my $paramSubTree = {
+            'data-file'      => $dataFile,
+            'temp-idx'       => $snmpVar,
+            'temp-lower'     => $tempLowLim,
+            'temp-scale'     => $tempUnit,
+            'temp-upper'     => $tempUppLim,
+            'vertical-label' => "degrees $tempScale"
+        };
+        my $nodeTemp = $cb->addSubtree( $devNode, 'Temperature', $paramSubTree,
+                                      [ 'Liebert::temperature-subtree' ] );
+
+       # ----------------------------------------------------------------
+        # PROG: Figure out how many indexes we have
+        foreach my $index ( keys %{$data->{'liebert'}{'tempidx'}} )
+        {
+            my $dataFile = "%system-id%_sensor_$index" . 
+                           ($fahrenheit ? '_fahrenheit':'') . ".rrd";
+            Debug("Liebert: Temperature idx: $index : $tempScale");
+            my $param = {
+                'comment'    => "Sensor: $index",
+                'data-file'  => $dataFile,
+                'sensor-idx' => $index
+            };
+
+            $cb->addSubtree( $nodeTemp, 'sensor_' . $index, $param,
+                        [ @template ] );
+        } # END: foreach my $index
+    } # END: env-temperature
+
+
+    # Humidity
+    if( $devdetails->hasCap('env-humidity') )
+    {
+        my $nodeHumidity = $cb->addSubtree( $devNode, "Humidity", undef,
+                                          [ 'Liebert::humidity-subtree' ] );
+
+        # PROG: Figure out how many sensors we have
+        foreach my $index ( keys %{$data->{'liebert'}{'humididx'}} )
+        {
+            Debug("Liebert: Humidity idx: $index");
+
+            my $param = {
+                'comment'   => "Sensor: " . $index,
+                'humid-idx' => $index
+            };
+
+            $cb->addSubtree( $nodeHumidity, 'sensor_' . $index, $param,
+                           [ 'Liebert::humidity-sensor' ] );
+        }
+
+    } # END of hasCap
+
+
+    # State of the system
+    if( $devdetails->hasCap('env-state') )
+    {
+        my $nodeState = $cb->addSubtree( $devNode, 'State', undef,
+                                       [ 'Liebert::state-subtree' ] );
+
+        if( $devdetails->hasCap('env-state-capacity') )
+        {
+            $cb->addSubtree( $devNode, 'State', undef,
+                           [ 'Liebert::state-capacity' ] );
+        }
+    }
+}
+
+1;
+
+# Local Variables:
+# mode: perl
+# indent-tabs-mode: nil
+# perl-indent-level: 4
+# End: