summaryrefslogtreecommitdiffstats
path: root/gen_presence_yaml.pl
blob: 96e323db27b1de3a2f4b95650a3684b8f8faddfc (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
#!/usr/bin/env perl

#This script generates YAML that defines the presence detects used
#for FRUs.  Its output is used by code that determines which FRUs
#are present in a system.

use strict;
use warnings;

use Getopt::Long;
use mrw::Inventory;
use mrw::Targets;
use mrw::Util;

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 %presence;

findTachBasedPresenceDetects(\%presence);

#Future: Find other sorts of presence detects

printYAML(\%presence, $outputFile);

exit 0;


#Finds FRUs and their Presence detects where a tach reading
#is used as the presence detect, such as when a nonzero fan RPM
#tach reading can be used to tell that a particular fan is present.
sub findTachBasedPresenceDetects
{
    my ($presence) = @_;
    my %tachs;

    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;

            my $fru = Util::getEnclosingFru($targets, $tach->{SOURCE});
            my $name = Util::getObmcName(\@inventory, $fru);
            if (not defined $name)
            {
                die "$target was not found in the inventory\n";
            }

            my $sensor = getSensor($tach->{DEST});

            #For now, assuming only fans use tachs
            $$presence{Tach}{$name}{type} = 'Fan';

            #Multi-rotor fans will have > 1 sensors per FRU
            push @{$$presence{Tach}{$name}{sensors}}, $sensor;
        }
    }
}


#Creates the YAML representation of the data
sub printYAML
{
    my ($presence, $outputFile) = @_;
    open (F, ">$outputFile") or die "Could not open $outputFile\n";

    while (my ($method, $FRUs) = each(%{$presence}))
    {
        print F "- $method:\n";
        while (my ($name, $data) = each(%{$FRUs}))
        {
            my ($prettyName) = $name =~ /\b(\w+)$/;

            print F "  - PrettyName: $prettyName\n";
            print F "    Inventory: $name\n";
            print F "    Description:\n"; #purposely leaving blank.
            print F "    Sensors:\n";
            for my $s (@{$data->{sensors}})
            {
                print F "      - $s\n";
            }
        }
    }

    close F;
}


#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;
}


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