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