Thread If / elsif / else Block weigert sich zu tun was er soll (7 answers)
Opened by Errorsmith at 2012-07-21 15:18

Gast Errorsmith
 2012-07-21 15:18
#160110 #160110
Hi!

Ich schreibe ein Skript das Statistiken aus meinem DSL Modem auslesen und (später dann) via rrd-tool speichern soll.
Zur Zeit schreibe ich den zentralen Block, der auf Anfrage hin die Parameter zurückgibt. Als Argument bekommt die Subroutine den gewünschten Parameter, ermittelt die Daten vom Modem (oder bentutzt bereits gespeicherte Werte) und gibt sie zurück.

Irgendwie haut die Auswahl der Parameter jedoch nicht hin.

Mein Code dafür sieht so aus:

more (6.6kb):
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# global variables
our $dsl_cache_basicstats_time=0; # last time we got real data from device
our $dsl_cache_basicstats_cache=10; # cache time, data older than this
# is considered outdated (300 seconds)

our @dsl_cache_basicstats_data=( # our array of basic stats
0, # time (last retrieved basic stats)
0, # snr_dn - signal noise margin
0, # snr_up
0, # att_dn - attenuation
0, # att_up
0, # pwr_dn - power (dBm)
0, # pwr_up
0, # capa_dn - line capacity
0, # capa_up
0, # rate_dn - actual rate
0, # rate_dn
0, # perc_dn
0, # perc_up
);

sub dsl_cache_basicstats ($)
{
# making a new telnet connection each time a value is requested is a waste
# of ressources and puts a significant load onto the device.
# we retrieve all of the basic data at once, cache them and return
# cached values instead of the real data if cached data is not older than
# five minutes
debug("dsl basicstats cache controller\n");

$current_time=time();
debug("current time: $current_time\n");

if ( ($dsl_cache_basicstats_time + $dsl_cache_basicstats_cache) > $current_time )
{
debug("basic stats are not outdated - returning cached data\n");
}
else
{
debug("basic stats are quite old - refreshing now...\n");
$comm=open_telnet();
if ( $commstatus == 9 )
{
debug ("retrieving data from device\n");
@output=$comm->cmd("adsl info --stats");
if ( $commstatus == 9 )
{
close_telnet($comm);
$snr_dn=rwhite(substr(substr(@output[12],16),0,-5));
$snr_up=rwhite(substr(@output[12],25));
$att_dn=rwhite(substr(substr(@output[13],16),0,-5));
$att_up=rwhite(substr(@output[13],25));
$pwr_dn=rwhite(substr(substr(@output[14],16),0,-5));
$pwr_up=rwhite(substr(@output[14],25));
$capa_dn=rwhite(substr(substr(@output[15],16),0,-5));
$capa_up=rwhite(substr(@output[15],25));
$rate_dn=rwhite(substr(substr(@output[16],16),0,-5));
$rate_up=rwhite(substr(@output[16],25));
$perc_dn=100 * $rate_dn / $capa_dn;
$perc_up=100 * $rate_up / $capa_up;
our @dsl_cache_basicstats_data=( # our array of basic stats
time(), # time
$snr_dn, # snr_dn
$snr_up, # snr_up
$att_dn, # att_dn
$att_up, # att_up
$pwr_dn, # pwr_dn
$pwr_up, # pwr_up
$capa_dn, # capa_dn
$capa_up, # capa_up
$rate_dn, # rate_dn
$rate_up, # rate_dn
$perc_dn, # perc_dn
$perc_up, # perc_up
);
$dsl_cache_basicstats_time=time();
debug (@dsl_cache_basicstats_data."\n");
debug ("
$dsl_cache_basicstats_data[0]
$dsl_cache_basicstats_data[1]
$dsl_cache_basicstats_data[2]
$dsl_cache_basicstats_data[3]
$dsl_cache_basicstats_data[4]
$dsl_cache_basicstats_data[5]
$dsl_cache_basicstats_data[6]
$dsl_cache_basicstats_data[7]
$dsl_cache_basicstats_data[8]
$dsl_cache_basicstats_data[9]
$dsl_cache_basicstats_data[10]
$dsl_cache_basicstats_data[11]
$dsl_cache_basicstats_data[12]\n");
}
else
{
debug ("eeek! while retrieving data from device:\n");
debug ("connection problem. can't refresh, failing back to cached data\n");
}
}
else
{
debug ("eeek! while connecting to device:\n");
debug ("eeek! connection problem. can't refresh, failing back to cached data\n");
}
}
debug ("begin request processing\n");
$request=shift;
debug ("request as given in argument 1: $request\n");
if ( $request == "snr" )
{
debug("reqest: snr/$request\n");
my ($retval1,$retval2) = ($dsl_cache_basicstats_data[1],$dsl_cache_basicstats_data[2]);
}
elsif ( $request == "att" )
{
debug("reqest: att/$request\n");
my ($retval1,$retval2) = ($dsl_cache_basicstats_data[3],$dsl_cache_basicstats_data[4]);
}
elsif ( $request == "pwr" )
{
debug("reqest: pwr/$request\n");
my ($retval1,$retval2) = ($dsl_cache_basicstats_data[5],$dsl_cache_basicstats_data[6]);
}
elsif ( $request == "capa" )
{
debug("reqest: capa/$request\n");
my ($retval1,$retval2) = ($dsl_cache_basicstats_data[7],$dsl_cache_basicstats_data[8]);
}
elsif ( $request == "rate" )
{
debug("reqest: rate/$request\n");
my ($retval1,$retval2) = ($dsl_cache_basicstats_data[9],$dsl_cache_basicstats_data[10]);
}
elsif ( $request == "perc" )
{
debug("reqest: perc/$request\n");
my ($retval1,$retval2) = ($dsl_cache_basicstats_data[11],$dsl_cache_basicstats_data[12]);
}
else
{
debug ("fall through... oh my dear\n");
my ($retval1,$retval2) = ("error","unspecified request: $request");
}
debug ("end request processing\n");
return ($retval1,$retval2);
}



Der Aufruf im Programm erfolgt so:
Code: (dl )
1
2
3
4
5
6
7
8
my ($snr_dn,$snr_up) = dsl_cache_basicstats("snr");
my ($att_dn,$att_up) = dsl_cache_basicstats("att");
my ($pwr_dn,$pwr_up) = dsl_cache_basicstats("pwr");
print "DSL Werte:
SNR: $snr_dn / $snr_up
ATT: $att_dn / $att_up
PWR: $pwr_dn / $pwr_up
";


Dinge die ich nicht mit hier im Post habe:
sub "debug" - prüft ob globale Variable "debug == 1" und gibt ggf ihre Argumente mit "print" aus
sub "comm_open" - baut eine Verbindung zum DSL Modem auf und gibt ein Handle zurück (nutzt Net::Telnet)
sub "comm_close" - beendet die Telnet Verbindung wieder
subs rwhite, lwhite - entfernen leerzeichen aus strings
globale Variable $commstatus bedeutet: 0->Keine Verbindung, 1-> Verbindung offen, 2->login, 3-> authientifizierung, 9->Verbindung steht und ist für Befehle bereit

Leider gibt das meine Routine nur die Werte für SNR zurück, egal mit welchem Argument ich sie aufrufe. Selbst mit unsinnigem Parameter - bei denen ich die entsprechende Meldung erhalten muesste, liefert mir die Routine nur die snr Werte zurueck, er landet auch jedesmal beim Auswahlverfahren bei "snr".

Ich benutze strict und warnings und bin sicher das das irgendwas dummes, einfaches ist, aber ich komm einfach nicht drauf...

Ich würde mich über einen Stupser in die richtige Richtung freuen, da sitz ich nun schon seit gestern dran und komm nicht weiter...

Grüße,
Errorsmith

modedit Editiert von pq: more-tag um script hinzugefügt
Last edited: 2012-07-21 16:22:27 +0200 (CEST)

View full thread If / elsif / else Block weigert sich zu tun was er soll