summaryrefslogtreecommitdiffstats
path: root/gen_fan_zone_yaml.pl
blob: 68e31f5f3de3142197c07d830366e733535a8ce6 (plain)
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
146
147
148
149
150
151
152
153
154
#!/usr/bin/env perl

#This script generates fan definitions from the MRW
#and outputs them in a YAML file.

use strict;
use warnings;

use Getopt::Long;
use mrw::Inventory;
use mrw::Targets;
use mrw::Util;
use Scalar::Util qw(looks_like_number);

my $serverwizFile;
my $outputFile;
GetOptions("i=s" => \$serverwizFile,
           "o=s" => \$outputFile) or printUsage();

if ((not defined $serverwizFile) ||
    (not defined $outputFile))
{
    printUsage();
}

my $targets = Targets->new;
$targets->loadXML($serverwizFile);

my @inventory = Inventory::getInventory($targets);

my %fans = findFans();

printFanYAML(\%fans, $outputFile);


#This function returns a hash representing the fans in the system.
#The hash looks like:
#  $fans{<name>}{<zone>}
#  $fans{<name>}{<profile>}
#  @fans{<name>}{sensors}
#
#  Where:
#    <name> = inventory name
#    <zone> = cooling zone number
#    <profile> = cooling zone profile, such as air, water, or all
#    <sensors> = an array of the hwmon sensors for the fan's tachs
sub findFans
{
    my %tachs;
    my %fans;

    #Find fans by looking at the TACH connections.  We could also find
    #parts of type FAN, but we need the tach connection anyway to
    #lookup the sensors on the other end...
    for my $target (keys %{$targets->getAllTargets()})
    {
        my $connections = $targets->findConnections($target, "TACH");
        next if ($connections eq "");

        for my $tach (sort @{$connections->{CONN}})
        {
            #Because findConnections is recursive, we can hit this same
            #connection multiple times, so only use it once.
            next if (exists $tachs{$tach->{SOURCE}}{$tach->{DEST}});
            $tachs{$tach->{SOURCE}}{$tach->{DEST}} = 1;

            #Note: SOURCE = tach unit on fan, DEST = tach unit on fan ctlr

            my $fru = Util::getEnclosingFru($targets, $tach->{SOURCE});
            my $name = Util::getObmcName(\@inventory, $fru);

            my $sensor = getSensor($tach->{DEST});
            push @{$fans{$name}{sensors}}, $sensor;

            #Get the cooling zone and profile from the fan controller part
            my $part = $targets->getTargetParent($tach->{SOURCE});
            my $zone = $targets->getAttribute($part, "COOLING_ZONE");
            if (!looks_like_number($zone))
            {
                die "Cooling zone '$zone' on $part is not a number\n";
            }

            #If the profile isn't set, just set it to be 'all'.
            my $profile = "";
            if (!$targets->isBadAttribute($part, "COOLING_ZONE_PROFILE"))
            {
                $profile = $targets->getAttribute($part,
                                                  "COOLING_ZONE_PROFILE");
            }

            if ($profile eq "")
            {
                $profile = "all";
            }

            $fans{$name}{profile} = lc $profile;
            $fans{$name}{zone} = $zone;
        }
    }

    return %fans;
}


#Find what hwmon will call this unit's reading by looking in
#the child unit-hwmon-feature unit.
sub getSensor
{
    my ($unit) = @_;

    my @hwmons = Util::getChildUnitsWithTargetType($targets,
                                                   "unit-hwmon-feature",
                                                   $unit);
    die "No HWMON children found for $unit\n" unless (scalar @hwmons != 0);

    my $name = $targets->getAttributeField($hwmons[0],
                                           "HWMON_FEATURE",
                                           "DESCRIPTIVE_NAME");
    die "No HWMON name for hwmon unit $hwmons[0]\n" if ($name eq "");

    return $name;
}


#Creates the YAML representation of the data
sub printFanYAML
{
    my ($fans, $file) = @_;

    open (F, ">$file") or die "Could not open $file\n";

    print F "fans:\n";

    while (my ($fan, $data) = each(%{$fans}))
    {
        print F "  - inventory: $fan\n";
        print F "    cooling_zone: $data->{zone}\n";
        print F "    cooling_profile: $data->{profile}\n";
        print F "    sensors:\n";
        for my $s (@{$data->{sensors}})
        {
            print F "      - $s\n";
        }
    }

    close F;
}


sub printUsage
{
    print "$0 -i [XML filename] -o [output YAML filename]\n";
    exit(1);
}
OpenPOWER on IntegriCloud