New openbmctool_utils functions:

get_fru_status
get_fru_print
get_fru_list
get_sensors_print
get_sensors_list
get_openbmctool_version

Change-Id: Ieca9a56bf1d4a985c7924a81ae4eeb8f9044764d
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/lib/openbmctool_utils.py b/lib/openbmctool_utils.py
index eb6aacd..ba12274 100755
--- a/lib/openbmctool_utils.py
+++ b/lib/openbmctool_utils.py
@@ -5,8 +5,11 @@
 openbmctool_execute_command.
 """
 
+import gen_print as gp
 import gen_cmd as gc
 import gen_valid as gv
+import gen_misc as gm
+import var_funcs as vf
 from robot.libraries.BuiltIn import BuiltIn
 import re
 
@@ -77,8 +80,287 @@
     pipeline.insert(1, "tail -n +1 | egrep -v 'Attempting login|User [^ ]+ has"
                     " been logged out'")
 
-    command_string = "set -o pipefail ; openbmctool.py -H " + openbmc_host\
+    command_string = "set -o pipefail ; python3 openbmctool.py -H " + openbmc_host\
         + " -U " + openbmc_username + " -P " + openbmc_password + " "\
         + " | ".join(pipeline)
 
     return gc.shell_cmd(command_string, *args, **kwargs)
+
+
+def get_fru_status():
+    r"""
+    Get the fru status and return as a list of dictionaries.
+
+    Example robot code:
+
+    ${fru_status}=  Get Fru Status
+    Rprint Vars  1  fru_status
+
+    Example result (excerpt):
+
+    fru_status:
+      fru_status[0]:
+        [component]:             cpu0
+        [is_a]:                  Yes
+        [fru]:                   Yes
+        [present]:               Yes
+        [functional]:            No
+      fru_status[1]:
+        [component]:             cpu0-core0
+        [is_a]:                  No
+        [fru]:                   Yes
+        [present]:               Yes
+        [functional]:            No
+    ...
+    """
+    rc, output = openbmctool_execute_command("fru status", print_output=False,
+                                             ignore_err=False)
+    # Example value for output (partial):
+    # Component     | Is a FRU  | Present  | Functional  | Has Logs
+    # cpu0          | Yes       | Yes      | Yes         | No
+    # cpu0-core0    | No        | Yes      | Yes         | No
+    # ...
+
+    # Replace spaces with underscores in field names (e.g. "Is a FRU" becomes
+    # "Is_a_FRU").
+    output = re.sub("([^ \\|])[ ]([^ ])", "\\1_\\2", output)
+    output = re.sub("([^ \\|])[ ]([^ ])", "\\1_\\2", output)
+
+    return vf.outbuf_to_report(output, field_delim="|")
+
+
+def get_fru_print(parse_json=True):
+    r"""
+    Get the output of the fru print command and return it either as raw JSON
+    data or as a list of dictionaries.
+
+    Example robot code:
+
+    ${fru_print}=  Get Fru Print  parse_json=${False}
+    Log to Console  ${fru_print}
+
+    Example result (excerpt):
+
+    {
+      "data": {
+        "/xyz/openbmc_project/inventory/system": {
+          "AssetTag": "",
+          "BuildDate": "",
+          "Cached": false,
+          "FieldReplaceable": false,
+          "Manufacturer": "",
+          "Model": "xxxxxxxx",
+          "PartNumber": "",
+          "Present": true,
+          "PrettyName": "",
+          "SerialNumber": "13183FA"
+        },
+        "/xyz/openbmc_project/inventory/system/chassis": {
+          "AirCooled": true,
+          "WaterCooled": false
+        },
+    ...
+
+    Example robot code:
+
+    ${fru_print}=  Get Fru Print
+    Rprint Vars  1  fru_print
+
+    Example result (excerpt):
+
+    fru_print:
+      fru_print[0]:
+        [data]:
+          [/xyz/openbmc_project/inventory/system]:
+            [AssetTag]:          <blank>
+            [BuildDate]:         <blank>
+            [Cached]:            False
+            [FieldReplaceable]:  False
+            [Manufacturer]:      <blank>
+            [Model]:             xxxxxxxx
+            [PartNumber]:        <blank>
+            [Present]:           True
+            [PrettyName]:        <blank>
+            [SerialNumber]:      13183FA
+          [/xyz/openbmc_project/inventory/system/chassis]:
+            [AirCooled]:         True
+            [WaterCooled]:       False
+    ...
+
+    Description of argument(s):
+    parse_json                      Indicates that the raw JSON data should
+                                    parsed into a list of dictionaries.
+    """
+
+    rc, output = openbmctool_execute_command("fru print", print_output=False,
+                                             ignore_err=False)
+    if parse_json:
+        return gm.json_loads_multiple(output)
+    else:
+        return output
+
+
+def get_fru_list(parse_json=True):
+    r"""
+    Get the output of the fru list command and return it either as raw JSON
+    data or as a list of dictionaries.
+
+    Example robot code:
+
+    ${fru_list}=  Get Fru List  parse_json=${False}
+    Log to Console  ${fru_list}
+
+    Example result (excerpt):
+
+    {
+      "data": {
+        "/xyz/openbmc_project/inventory/system": {
+          "AssetTag": "",
+          "BuildDate": "",
+          "Cached": false,
+          "FieldReplaceable": false,
+          "Manufacturer": "",
+          "Model": "xxxxxxxx",
+          "PartNumber": "",
+          "Present": true,
+          "PrettyName": "",
+          "SerialNumber": "13183FA"
+        },
+        "/xyz/openbmc_project/inventory/system/chassis": {
+          "AirCooled": true,
+          "WaterCooled": false
+        },
+    ...
+
+    Example robot code:
+
+    ${fru_list}=  Get Fru List
+    Rprint Vars  1  fru_list
+
+    Example result (excerpt):
+
+    fru_list:
+      fru_list[0]:
+        [data]:
+          [/xyz/openbmc_project/inventory/system]:
+            [AssetTag]:          <blank>
+            [BuildDate]:         <blank>
+            [Cached]:            False
+            [FieldReplaceable]:  False
+            [Manufacturer]:      <blank>
+            [Model]:             xxxxxxxx
+            [PartNumber]:        <blank>
+            [Present]:           True
+            [PrettyName]:        <blank>
+            [SerialNumber]:      13183FA
+          [/xyz/openbmc_project/inventory/system/chassis]:
+            [AirCooled]:         True
+            [WaterCooled]:       False
+    ...
+
+    Description of argument(s):
+    parse_json                      Indicates that the raw JSON data should
+                                    parsed into a list of dictionaries.
+    """
+
+    rc, output = openbmctool_execute_command("fru list", print_output=False,
+                                             ignore_err=False)
+    if parse_json:
+        return gm.json_loads_multiple(output)
+    else:
+        return output
+
+
+def get_sensors_print():
+
+    r"""
+    Get the output of the sensors print command and return as a list of
+    dictionaries.
+
+    Example robot code:
+
+    ${sensors_print}=  Get Sensors Print
+    Rprint Vars  1  sensors_print
+
+    Example result (excerpt):
+
+    sensors_print:
+      sensors_print[0]:
+        [sensor]:                OCC0
+        [type]:                  Discrete
+        [units]:                 N/A
+        [value]:                 Active
+        [target]:                Active
+      sensors_print[1]:
+        [sensor]:                OCC1
+        [type]:                  Discrete
+        [units]:                 N/A
+        [value]:                 Active
+        [target]:                Active
+    ...
+    """
+    rc, output = openbmctool_execute_command("sensors print",
+                                             print_output=False,
+                                             ignore_err=False)
+    # Example value for output (partial):
+    # sensor                 | type         | units     | value    | target
+    # OCC0                   | Discrete     | N/A       | Active   | Active
+    # OCC1                   | Discrete     | N/A       | Active   | Active
+
+    return vf.outbuf_to_report(output, field_delim="|")
+
+
+def get_sensors_list():
+
+    r"""
+    Get the output of the sensors list command and return as a list of
+    dictionaries.
+
+    Example robot code:
+
+    ${sensors_list}=  Get Sensors List
+    Rprint Vars  1  sensors_list
+
+    Example result (excerpt):
+
+    sensors_list:
+      sensors_list[0]:
+        [sensor]:                OCC0
+        [type]:                  Discrete
+        [units]:                 N/A
+        [value]:                 Active
+        [target]:                Active
+      sensors_list[1]:
+        [sensor]:                OCC1
+        [type]:                  Discrete
+        [units]:                 N/A
+        [value]:                 Active
+        [target]:                Active
+    ...
+    """
+    rc, output = openbmctool_execute_command("sensors list",
+                                             print_output=False,
+                                             ignore_err=False)
+    # Example value for output (partial):
+    # sensor                 | type         | units     | value    | target
+    # OCC0                   | Discrete     | N/A       | Active   | Active
+    # OCC1                   | Discrete     | N/A       | Active   | Active
+
+    return vf.outbuf_to_report(output, field_delim="|")
+
+
+def get_openbmctool_version():
+    r"""
+    Get the openbmctool.py version and return it.
+
+    Example robot code:
+    ${openbmctool_version}=  Get Openbmctool Version
+    Rprint Vars  openbmctool_version
+
+    Example result (excerpt):
+    openbmctool_version:         1.06
+    """
+    rc, output = openbmctool_execute_command("-V | cut -f 2 -d ' '",
+                                             print_output=False,
+                                             ignore_err=False)
+    return output