xref: /openbmc/phosphor-mrw-tools/gen_presence_yaml.pl (revision 902c85375105db9f73353f510b4a6e2651d65c9e)
1*902c8537SMatt Spinler#!/usr/bin/env perl
2*902c8537SMatt Spinler
3*902c8537SMatt Spinler#This script generates YAML that defines the presence detects used
4*902c8537SMatt Spinler#for FRUs.  Its output is used by code that determines which FRUs
5*902c8537SMatt Spinler#are present in a system.
6*902c8537SMatt Spinler
7*902c8537SMatt Spinleruse strict;
8*902c8537SMatt Spinleruse warnings;
9*902c8537SMatt Spinler
10*902c8537SMatt Spinleruse Getopt::Long;
11*902c8537SMatt Spinleruse mrw::Inventory;
12*902c8537SMatt Spinleruse mrw::Targets;
13*902c8537SMatt Spinleruse mrw::Util;
14*902c8537SMatt Spinler
15*902c8537SMatt Spinlermy $serverwizFile;
16*902c8537SMatt Spinlermy $outputFile;
17*902c8537SMatt SpinlerGetOptions("i=s" => \$serverwizFile,
18*902c8537SMatt Spinler           "o=s" => \$outputFile) or printUsage();
19*902c8537SMatt Spinler
20*902c8537SMatt Spinlerif ((not defined $serverwizFile) ||
21*902c8537SMatt Spinler    (not defined $outputFile))
22*902c8537SMatt Spinler{
23*902c8537SMatt Spinler    printUsage();
24*902c8537SMatt Spinler}
25*902c8537SMatt Spinler
26*902c8537SMatt Spinlermy $targets = Targets->new;
27*902c8537SMatt Spinler$targets->loadXML($serverwizFile);
28*902c8537SMatt Spinler
29*902c8537SMatt Spinlermy @inventory = Inventory::getInventory($targets);
30*902c8537SMatt Spinlermy %presence;
31*902c8537SMatt Spinler
32*902c8537SMatt SpinlerfindTachBasedPresenceDetects(\%presence);
33*902c8537SMatt Spinler
34*902c8537SMatt Spinler#Future: Find other sorts of presence detects
35*902c8537SMatt Spinler
36*902c8537SMatt SpinlerprintYAML(\%presence, $outputFile);
37*902c8537SMatt Spinler
38*902c8537SMatt Spinlerexit 0;
39*902c8537SMatt Spinler
40*902c8537SMatt Spinler
41*902c8537SMatt Spinler#Finds FRUs and their Presence detects where a tach reading
42*902c8537SMatt Spinler#is used as the presence detect, such as when a nonzero fan RPM
43*902c8537SMatt Spinler#tach reading can be used to tell that a particular fan is present.
44*902c8537SMatt Spinlersub findTachBasedPresenceDetects
45*902c8537SMatt Spinler{
46*902c8537SMatt Spinler    my ($presence) = @_;
47*902c8537SMatt Spinler    my %tachs;
48*902c8537SMatt Spinler
49*902c8537SMatt Spinler    for my $target (keys %{$targets->getAllTargets()})
50*902c8537SMatt Spinler    {
51*902c8537SMatt Spinler        my $connections = $targets->findConnections($target, "TACH");
52*902c8537SMatt Spinler        next if ($connections eq "");
53*902c8537SMatt Spinler
54*902c8537SMatt Spinler        for my $tach (sort @{$connections->{CONN}})
55*902c8537SMatt Spinler        {
56*902c8537SMatt Spinler            #Because findConnections is recursive, we can hit this same
57*902c8537SMatt Spinler            #connection multiple times so only use it once.
58*902c8537SMatt Spinler            next if (exists $tachs{$tach->{SOURCE}}{$tach->{DEST}});
59*902c8537SMatt Spinler            $tachs{$tach->{SOURCE}}{$tach->{DEST}} = 1;
60*902c8537SMatt Spinler
61*902c8537SMatt Spinler            my $fru = Util::getEnclosingFru($targets, $tach->{SOURCE});
62*902c8537SMatt Spinler            my $name = Util::getObmcName(\@inventory, $fru);
63*902c8537SMatt Spinler            if (not defined $name)
64*902c8537SMatt Spinler            {
65*902c8537SMatt Spinler                die "$target was not found in the inventory\n";
66*902c8537SMatt Spinler            }
67*902c8537SMatt Spinler
68*902c8537SMatt Spinler            my $sensor = getSensor($tach->{DEST});
69*902c8537SMatt Spinler
70*902c8537SMatt Spinler            #For now, assuming only fans use tachs
71*902c8537SMatt Spinler            $$presence{Tach}{$name}{type} = 'Fan';
72*902c8537SMatt Spinler
73*902c8537SMatt Spinler            #Multi-rotor fans will have > 1 sensors per FRU
74*902c8537SMatt Spinler            push @{$$presence{Tach}{$name}{sensors}}, $sensor;
75*902c8537SMatt Spinler        }
76*902c8537SMatt Spinler    }
77*902c8537SMatt Spinler}
78*902c8537SMatt Spinler
79*902c8537SMatt Spinler
80*902c8537SMatt Spinler#Creates the YAML representation of the data
81*902c8537SMatt Spinlersub printYAML
82*902c8537SMatt Spinler{
83*902c8537SMatt Spinler    my ($presence, $outputFile) = @_;
84*902c8537SMatt Spinler    open (F, ">$outputFile") or die "Could not open $outputFile\n";
85*902c8537SMatt Spinler
86*902c8537SMatt Spinler    while (my ($method, $FRUs) = each(%{$presence}))
87*902c8537SMatt Spinler    {
88*902c8537SMatt Spinler        print F "- $method:\n";
89*902c8537SMatt Spinler        while (my ($name, $data) = each(%{$FRUs}))
90*902c8537SMatt Spinler        {
91*902c8537SMatt Spinler            my ($prettyName) = $name =~ /\b(\w+)$/;
92*902c8537SMatt Spinler
93*902c8537SMatt Spinler            print F "  - PrettyName: $prettyName\n";
94*902c8537SMatt Spinler            print F "    Inventory: $name\n";
95*902c8537SMatt Spinler            print F "    Description:\n"; #purposely leaving blank.
96*902c8537SMatt Spinler            print F "    Sensors:\n";
97*902c8537SMatt Spinler            for my $s (@{$data->{sensors}})
98*902c8537SMatt Spinler            {
99*902c8537SMatt Spinler                print F "      - $s\n";
100*902c8537SMatt Spinler            }
101*902c8537SMatt Spinler        }
102*902c8537SMatt Spinler    }
103*902c8537SMatt Spinler
104*902c8537SMatt Spinler    close F;
105*902c8537SMatt Spinler}
106*902c8537SMatt Spinler
107*902c8537SMatt Spinler
108*902c8537SMatt Spinler#Find what hwmon will call this unit's reading by looking in
109*902c8537SMatt Spinler#the child unit-hwmon-feature unit.
110*902c8537SMatt Spinlersub getSensor
111*902c8537SMatt Spinler{
112*902c8537SMatt Spinler    my ($unit) = @_;
113*902c8537SMatt Spinler
114*902c8537SMatt Spinler    my @hwmons = Util::getChildUnitsWithTargetType($targets,
115*902c8537SMatt Spinler                                                   "unit-hwmon-feature",
116*902c8537SMatt Spinler                                                   $unit);
117*902c8537SMatt Spinler    die "No HWMON children found for $unit\n" unless (scalar @hwmons != 0);
118*902c8537SMatt Spinler
119*902c8537SMatt Spinler    my $name = $targets->getAttributeField($hwmons[0],
120*902c8537SMatt Spinler                                           "HWMON_FEATURE",
121*902c8537SMatt Spinler                                           "DESCRIPTIVE_NAME");
122*902c8537SMatt Spinler    die "No HWMON name for hwmon unit $hwmons[0]\n" if ($name eq "");
123*902c8537SMatt Spinler
124*902c8537SMatt Spinler    return $name;
125*902c8537SMatt Spinler}
126*902c8537SMatt Spinler
127*902c8537SMatt Spinler
128*902c8537SMatt Spinlersub printUsage
129*902c8537SMatt Spinler{
130*902c8537SMatt Spinler    print "$0 -i [XML filename] -o [output YAML filename]\n";
131*902c8537SMatt Spinler    exit(1);
132*902c8537SMatt Spinler}
133