2 # Discovery module for Liebert HVAC systems
4 # Copyright (C) 2008 Jon Nistor
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20 # $Id: Liebert.pm,v 1.1 2010-12-27 00:03:50 ivan Exp $
21 # Jon Nistor <nistor at snickers.org>
23 # NOTE: Options for this module
24 # Liebert::use-fahrenheit
25 # Liebert::disable-temperature
26 # Liebert::disable-humidity
27 # Liebert::disable-state
28 # Liebert::disable-stats
30 # NOTE: This module supports both Fahrenheit and Celcius, but for ease of
31 # module and cleanliness we will convert Celcius into Fahrenheit
32 # instead of polling for Fahrenheit directly.
35 # Liebert discovery module
36 package Torrus::DevDiscover::Liebert;
42 $Torrus::DevDiscover::registry{'Liebert'} = {
44 'checkdevtype' => \&checkdevtype,
45 'discover' => \&discover,
46 'buildConfig' => \&buildConfig
51 # LIEBERT-GP-REGISTRATION-MIB
52 'GlobalProducts' => '1.3.6.1.4.1.476.1.42',
54 # LIEBERT-GP-AGENT-MIB
55 'Manufacturer' => '1.3.6.1.4.1.476.1.42.2.1.1.0',
56 'Model' => '1.3.6.1.4.1.476.1.42.2.1.2.0',
57 'FirmwareVer' => '1.3.6.1.4.1.476.1.42.2.1.3.0',
58 'SerialNum' => '1.3.6.1.4.1.476.1.42.2.1.4.0',
59 'PartNum' => '1.3.6.1.4.1.476.1.42.2.1.5.0',
61 'TemperatureIdDegF' => '1.3.6.1.4.1.476.1.42.3.4.1.2.3.1.1',
62 'TemperatureIdDegC' => '1.3.6.1.4.1.476.1.42.3.4.1.3.3.1.1',
63 'HumidityIdRel' => '1.3.6.1.4.1.476.1.42.3.4.2.2.3.1.1',
65 'lgpEnvState' => '1.3.6.1.4.1.476.1.42.3.4.3',
66 'lgpEnvStateCoolingCapacity' => '1.3.6.1.4.1.476.1.42.3.4.3.9.0',
67 'lgpEnvStatistics' => '1.3.6.1.4.1.476.1.42.3.4.6',
74 my $devdetails = shift;
76 if( not $dd->oidBaseMatch ( 'GlobalProducts',
77 $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
82 $devdetails->setCap('interfaceIndexingPersistent');
91 my $devdetails = shift;
93 my $session = $dd->session();
94 my $data = $devdetails->data();
96 # PROG: Grab versions, serials and type of chassis.
97 my $Info = $dd->retrieveSnmpOIDs ( 'Manufacturer', 'Model',
98 'FirmwareVer', 'SerialNum', 'PartNum' );
100 # SNMP: System comment
101 $data->{'param'}{'comment'} =
102 $Info->{'Manufacturer'} . " " . $Info->{'Model'} . ", Version: " .
103 $Info->{'FirmwareVer'} . ", Serial: " . $Info->{'SerialNum'};
105 # The Liebert HVAC snmp implementation requires a lower number
106 # of pdu's to be sent to it.
107 $data->{'param'}{'snmp-oids-per-pdu'} = 10;
110 if( $devdetails->param('Liebert::disable-temperature') ne 'yes' )
112 $devdetails->setCap('env-temperature');
114 if( $devdetails->param('Liebert::use-fahrenheit') ne 'yes' )
116 # ENV: Temperature in Celcius
117 my $idTable = $session->get_table(
118 -baseoid => $dd->oiddef('TemperatureIdDegC') );
119 $devdetails->storeSnmpVars( $idTable );
121 if( defined( $idTable ) )
123 $devdetails->setCap('env-temperature-celcius');
125 foreach my $index ( $devdetails->getSnmpIndices(
126 $dd->oiddef('TemperatureIdDegC') ) )
128 Debug("Liebert: Temp (degC) index: $index");
129 $data->{'liebert'}{'tempidx'}{$index} = "celcius";
133 # ENV: Temperature in Fahrenheit
134 my $idTable = $session->get_table(
135 -baseoid => $dd->oiddef('TemperatureIdDegF') );
136 $devdetails->storeSnmpVars( $idTable );
138 if( defined( $idTable ) )
140 $devdetails->setCap('env-temperature-fahrenheit');
142 foreach my $index ( $devdetails->getSnmpIndices(
143 $dd->oiddef('TemperatureIdDegF') ) )
145 Debug("Liebert: Temp (degF) index: $index");
146 $data->{'liebert'}{'tempidx'}{$index} = "fahrenheit";
153 if( $devdetails->param('Liebert::disable-humidity') ne 'yes' )
155 my $idTable = $session->get_table(
156 -baseoid => $dd->oiddef('HumidityIdRel') );
157 $devdetails->storeSnmpVars( $idTable );
159 if( defined( $idTable ) )
161 $devdetails->setCap('env-humidity');
162 foreach my $index ( $devdetails->getSnmpIndices(
163 $dd->oiddef('HumidityIdRel') ) )
165 Debug("Liebert: humidity index: $index");
166 $data->{'liebert'}{'humididx'}{$index} = "humidity";
172 if( $devdetails->param('Liebert::disable-state') ne 'yes' )
174 my $stateTable = $session->get_table(
175 -baseoid => $dd->oiddef('lgpEnvState') );
176 $devdetails->storeSnmpVars( $stateTable );
178 if( defined( $stateTable ) )
180 $devdetails->setCap('env-state');
182 # PROG: Check to see if Firmware is new enough for Capacity
183 if( $dd->checkSnmpOID('lgpEnvStateCoolingCapacity') )
185 $devdetails->setCap('env-state-capacity');
191 if( $devdetails->param('Liebert::disable-stats') ne 'yes' )
193 my $statsTable = $session->get_table(
194 -baseoid => $dd->oiddef('lgpEnvStatistics') );
195 $devdetails->storeSnmpVars( $statsTable );
197 if( defined( $statsTable ) )
199 $devdetails->setCap('env-stats');
209 my $devdetails = shift;
212 my $data = $devdetails->data();
214 if( $devdetails->hasCap('env-temperature') )
216 # All place-setting variables default to Celcius
218 my $dataFile = "%system-id%_temperature.rrd";
222 my $tempScale = "Celcius";
226 if( $devdetails->hasCap('env-temperature-fahrenheit') )
228 $dataFile = "%system-id%_temperature_f.rrd";
232 $tempScale = "Fahrenheit";
233 $tempLowLim = $tempLowLim * 1.8 + 32;
234 $tempUppLim = $tempUppLim * 1.8 + 32;
235 push(@template, "Liebert::temperature-sensor-fahrenheit");
237 push(@template, "Liebert::temperature-sensor");
241 'data-file' => $dataFile,
242 'temp-idx' => $snmpVar,
243 'temp-lower' => $tempLowLim,
244 'temp-scale' => $tempUnit,
245 'temp-upper' => $tempUppLim,
246 'vertical-label' => "degrees $tempScale"
248 my $nodeTemp = $cb->addSubtree( $devNode, 'Temperature', $paramSubTree,
249 [ 'Liebert::temperature-subtree' ] );
251 # ----------------------------------------------------------------
252 # PROG: Figure out how many indexes we have
253 foreach my $index ( keys %{$data->{'liebert'}{'tempidx'}} )
255 my $dataFile = "%system-id%_sensor_$index" .
256 ($fahrenheit ? '_fahrenheit':'') . ".rrd";
257 Debug("Liebert: Temperature idx: $index : $tempScale");
259 'comment' => "Sensor: $index",
260 'data-file' => $dataFile,
261 'sensor-idx' => $index
264 $cb->addSubtree( $nodeTemp, 'sensor_' . $index, $param,
266 } # END: foreach my $index
267 } # END: env-temperature
271 if( $devdetails->hasCap('env-humidity') )
273 my $nodeHumidity = $cb->addSubtree( $devNode, "Humidity", undef,
274 [ 'Liebert::humidity-subtree' ] );
276 # PROG: Figure out how many sensors we have
277 foreach my $index ( keys %{$data->{'liebert'}{'humididx'}} )
279 Debug("Liebert: Humidity idx: $index");
282 'comment' => "Sensor: " . $index,
283 'humid-idx' => $index
286 $cb->addSubtree( $nodeHumidity, 'sensor_' . $index, $param,
287 [ 'Liebert::humidity-sensor' ] );
293 # State of the system
294 if( $devdetails->hasCap('env-state') )
296 my $nodeState = $cb->addSubtree( $devNode, 'State', undef,
297 [ 'Liebert::state-subtree' ] );
299 if( $devdetails->hasCap('env-state-capacity') )
301 $cb->addSubtree( $devNode, 'State', undef,
302 [ 'Liebert::state-capacity' ] );
311 # indent-tabs-mode: nil
312 # perl-indent-level: 4