import torrus 1.0.9
[freeside.git] / torrus / perllib / Torrus / DevDiscover / Liebert.pm
1 #
2 #  Discovery module for Liebert HVAC systems
3 #
4 #  Copyright (C) 2008 Jon Nistor
5 #
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.
10 #
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.
15 #
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.
19
20 # $Id: Liebert.pm,v 1.1 2010-12-27 00:03:50 ivan Exp $
21 # Jon Nistor <nistor at snickers.org>
22 #
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
29 #
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.
33 #
34
35 # Liebert discovery module
36 package Torrus::DevDiscover::Liebert;
37
38 use strict;
39 use Torrus::Log;
40
41
42 $Torrus::DevDiscover::registry{'Liebert'} = {
43     'sequence'     => 500,
44     'checkdevtype' => \&checkdevtype,
45     'discover'     => \&discover,
46     'buildConfig'  => \&buildConfig
47     };
48
49 our %oiddef =
50     (
51      # LIEBERT-GP-REGISTRATION-MIB
52      'GlobalProducts'     => '1.3.6.1.4.1.476.1.42',
53
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',
60
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',
64
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',
68
69      );
70
71 sub checkdevtype
72 {
73     my $dd = shift;
74     my $devdetails = shift;
75
76     if( not $dd->oidBaseMatch ( 'GlobalProducts',
77             $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
78     {
79         return 0;
80     }
81    
82     $devdetails->setCap('interfaceIndexingPersistent');
83
84     return 1;
85 }
86
87
88 sub discover
89 {
90     my $dd = shift;
91     my $devdetails = shift;
92
93     my $session = $dd->session();
94     my $data = $devdetails->data();
95
96     # PROG: Grab versions, serials and type of chassis.
97     my $Info = $dd->retrieveSnmpOIDs ( 'Manufacturer', 'Model',
98                         'FirmwareVer', 'SerialNum', 'PartNum' );
99
100     # SNMP: System comment
101     $data->{'param'}{'comment'} =
102             $Info->{'Manufacturer'} . " " . $Info->{'Model'} . ", Version: " .
103             $Info->{'FirmwareVer'} . ", Serial: " . $Info->{'SerialNum'};
104
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;
108
109     # Temperature
110     if( $devdetails->param('Liebert::disable-temperature') ne 'yes' ) 
111     {
112         $devdetails->setCap('env-temperature');
113
114         if( $devdetails->param('Liebert::use-fahrenheit') ne 'yes' )
115         {
116             # ENV: Temperature in Celcius
117             my $idTable = $session->get_table(
118                  -baseoid => $dd->oiddef('TemperatureIdDegC') );
119             $devdetails->storeSnmpVars( $idTable );
120
121             if( defined( $idTable ) )
122             {
123                 $devdetails->setCap('env-temperature-celcius');
124
125                 foreach my $index ( $devdetails->getSnmpIndices(
126                                     $dd->oiddef('TemperatureIdDegC') ) )
127                 {
128                     Debug("Liebert: Temp (degC) index: $index");
129                     $data->{'liebert'}{'tempidx'}{$index} = "celcius";
130                 }
131             }
132         } else {
133             # ENV: Temperature in Fahrenheit
134             my $idTable = $session->get_table(
135                  -baseoid => $dd->oiddef('TemperatureIdDegF') );
136             $devdetails->storeSnmpVars( $idTable );
137
138             if( defined( $idTable ) )
139             {
140                 $devdetails->setCap('env-temperature-fahrenheit');
141
142                 foreach my $index ( $devdetails->getSnmpIndices(
143                                     $dd->oiddef('TemperatureIdDegF') ) )
144                 {
145                     Debug("Liebert: Temp (degF) index: $index");
146                     $data->{'liebert'}{'tempidx'}{$index} = "fahrenheit";
147                 }
148             }
149         }
150     }
151
152     # ENV: Humidity
153     if( $devdetails->param('Liebert::disable-humidity') ne 'yes' )
154     {
155         my $idTable = $session->get_table(
156                  -baseoid => $dd->oiddef('HumidityIdRel') );
157         $devdetails->storeSnmpVars( $idTable );
158
159         if( defined( $idTable ) )
160         {
161             $devdetails->setCap('env-humidity');
162             foreach my $index ( $devdetails->getSnmpIndices(
163                                 $dd->oiddef('HumidityIdRel') ) )
164             {
165                 Debug("Liebert: humidity index: $index");
166                 $data->{'liebert'}{'humididx'}{$index} = "humidity";
167             }
168         }
169     }
170
171     # ENV: State
172     if( $devdetails->param('Liebert::disable-state') ne 'yes' )
173     {
174         my $stateTable = $session->get_table(
175                  -baseoid => $dd->oiddef('lgpEnvState') );
176         $devdetails->storeSnmpVars( $stateTable );
177
178         if( defined( $stateTable ) )
179         {
180             $devdetails->setCap('env-state');
181
182             # PROG: Check to see if Firmware is new enough for Capacity
183             if( $dd->checkSnmpOID('lgpEnvStateCoolingCapacity') )
184             {
185                 $devdetails->setCap('env-state-capacity');
186             }
187         }
188     }
189
190     # Statistics
191     if( $devdetails->param('Liebert::disable-stats') ne 'yes' )
192     {
193         my $statsTable = $session->get_table(
194                  -baseoid => $dd->oiddef('lgpEnvStatistics') );
195         $devdetails->storeSnmpVars( $statsTable );
196
197         if( defined( $statsTable ) )
198         {
199             $devdetails->setCap('env-stats');
200         }
201     }
202
203     return 1;
204 }
205
206
207 sub buildConfig
208 {
209     my $devdetails = shift;
210     my $cb = shift;
211     my $devNode = shift;
212     my $data = $devdetails->data();
213
214     if( $devdetails->hasCap('env-temperature') )
215     {
216         # All place-setting variables default to Celcius
217         my @template;
218         my $dataFile   = "%system-id%_temperature.rrd";
219         my $fahrenheit = 0;
220         my $snmpVar    = 3;
221         my $tempUnit   = "C";
222         my $tempScale  = "Celcius";
223         my $tempLowLim = 15;
224         my $tempUppLim = 70;
225
226         if( $devdetails->hasCap('env-temperature-fahrenheit') )
227         {
228             $dataFile   = "%system-id%_temperature_f.rrd";
229             $fahrenheit = 1;
230             $snmpVar    = 2;
231             $tempUnit   = "F";
232             $tempScale  = "Fahrenheit";
233             $tempLowLim = $tempLowLim * 1.8 + 32;
234             $tempUppLim = $tempUppLim * 1.8 + 32;
235             push(@template, "Liebert::temperature-sensor-fahrenheit");
236         } else {
237             push(@template, "Liebert::temperature-sensor");
238         }
239
240         my $paramSubTree = {
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"
247         };
248         my $nodeTemp = $cb->addSubtree( $devNode, 'Temperature', $paramSubTree,
249                                       [ 'Liebert::temperature-subtree' ] );
250
251         # ----------------------------------------------------------------
252         # PROG: Figure out how many indexes we have
253         foreach my $index ( keys %{$data->{'liebert'}{'tempidx'}} )
254         {
255             my $dataFile = "%system-id%_sensor_$index" . 
256                            ($fahrenheit ? '_fahrenheit':'') . ".rrd";
257             Debug("Liebert: Temperature idx: $index : $tempScale");
258             my $param = {
259                 'comment'    => "Sensor: $index",
260                 'data-file'  => $dataFile,
261                 'sensor-idx' => $index
262             };
263
264             $cb->addSubtree( $nodeTemp, 'sensor_' . $index, $param,
265                         [ @template ] );
266         } # END: foreach my $index
267     } # END: env-temperature
268
269
270     # Humidity
271     if( $devdetails->hasCap('env-humidity') )
272     {
273         my $nodeHumidity = $cb->addSubtree( $devNode, "Humidity", undef,
274                                           [ 'Liebert::humidity-subtree' ] );
275
276         # PROG: Figure out how many sensors we have
277         foreach my $index ( keys %{$data->{'liebert'}{'humididx'}} )
278         {
279             Debug("Liebert: Humidity idx: $index");
280
281             my $param = {
282                 'comment'   => "Sensor: " . $index,
283                 'humid-idx' => $index
284             };
285
286             $cb->addSubtree( $nodeHumidity, 'sensor_' . $index, $param,
287                            [ 'Liebert::humidity-sensor' ] );
288         }
289
290     } # END of hasCap
291
292
293     # State of the system
294     if( $devdetails->hasCap('env-state') )
295     {
296         my $nodeState = $cb->addSubtree( $devNode, 'State', undef,
297                                        [ 'Liebert::state-subtree' ] );
298
299         if( $devdetails->hasCap('env-state-capacity') )
300         {
301             $cb->addSubtree( $devNode, 'State', undef,
302                            [ 'Liebert::state-capacity' ] );
303         }
304     }
305 }
306
307 1;
308
309 # Local Variables:
310 # mode: perl
311 # indent-tabs-mode: nil
312 # perl-indent-level: 4
313 # End: