#!/usr/bin/env python3

r"""
Provide useful ipmi functions.
"""

import re
import gen_print as gp
import gen_misc as gm
import gen_cmd as gc
import gen_robot_keyword as grk
import gen_robot_utils as gru
import bmc_ssh_utils as bsu
import var_funcs as vf
import ipmi_client as ic
import tempfile
import json
from robot.libraries.BuiltIn import BuiltIn

gru.my_import_resource("ipmi_client.robot")


def get_sol_info():
    r"""
    Get all SOL info and return it as a dictionary.

    Example use:

    Robot code:
    ${sol_info}=  get_sol_info
    Rpvars  sol_info

    Output:
    sol_info:
      sol_info[Info]:                                SOL parameter 'Payload Channel (7)'
                                                     not supported - defaulting to 0x0e
      sol_info[Character Send Threshold]:            1
      sol_info[Force Authentication]:                true
      sol_info[Privilege Level]:                     USER
      sol_info[Set in progress]:                     set-complete
      sol_info[Retry Interval (ms)]:                 100
      sol_info[Non-Volatile Bit Rate (kbps)]:        IPMI-Over-Serial-Setting
      sol_info[Character Accumulate Level (ms)]:     100
      sol_info[Enabled]:                             true
      sol_info[Volatile Bit Rate (kbps)]:            IPMI-Over-Serial-Setting
      sol_info[Payload Channel]:                     14 (0x0e)
      sol_info[Payload Port]:                        623
      sol_info[Force Encryption]:                    true
      sol_info[Retry Count]:                         7
    """

    status, ret_values = grk.run_key_u("Run IPMI Standard Command  sol info")

    # Create temp file path.
    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name

    # Write sol info to temp file path.
    text_file = open(temp_file_path, "w")
    text_file.write(ret_values)
    text_file.close()

    # Use my_parm_file to interpret data.
    sol_info = gm.my_parm_file(temp_file_path)

    return sol_info


def set_sol_setting(setting_name, setting_value):
    r"""
    Set SOL setting with given value.

    # Description of argument(s):
    # setting_name                  SOL setting which needs to be set (e.g.
    #                               "retry-count").
    # setting_value                 Value which needs to be set (e.g. "7").
    """

    status, ret_values = grk.run_key_u("Run IPMI Standard Command  sol set "
                                       + setting_name + " " + setting_value)

    return status


def execute_ipmi_cmd(cmd_string,
                     ipmi_cmd_type='inband',
                     print_output=1,
                     ignore_err=0,
                     **options):
    r"""
    Run the given command string as an IPMI command and return the stdout,
    stderr and the return code.

    Description of argument(s):
    cmd_string                      The command string to be run as an IPMI
                                    command.
    ipmi_cmd_type                   'inband' or 'external'.
    print_output                    If this is set, this function will print
                                    the stdout/stderr generated by
                                    the IPMI command.
    ignore_err                      Ignore error means that a failure
                                    encountered by running the command
                                    string will not be raised as a python
                                    exception.
    options                         These are passed directly to the
                                    create_ipmi_ext_command_string function.
                                    See that function's prolog for details.
    """

    if ipmi_cmd_type == 'inband':
        IPMI_INBAND_CMD = BuiltIn().get_variable_value("${IPMI_INBAND_CMD}")
        cmd_buf = IPMI_INBAND_CMD + " " + cmd_string
        return bsu.os_execute_command(cmd_buf,
                                      print_out=print_output,
                                      ignore_err=ignore_err)

    if ipmi_cmd_type == 'external':
        cmd_buf = ic.create_ipmi_ext_command_string(cmd_string, **options)
        rc, stdout, stderr = gc.shell_cmd(cmd_buf,
                                          print_output=print_output,
                                          ignore_err=ignore_err,
                                          return_stderr=1)
        return stdout, stderr, rc


def get_lan_print_dict(channel_number='', ipmi_cmd_type='external'):
    r"""
    Get IPMI 'lan print' output and return it as a dictionary.

    Here is an example of the IPMI lan print output:

    Set in Progress         : Set Complete
    Auth Type Support       : MD5
    Auth Type Enable        : Callback : MD5
                            : User     : MD5
                            : Operator : MD5
                            : Admin    : MD5
                            : OEM      : MD5
    IP Address Source       : Static Address
    IP Address              : x.x.x.x
    Subnet Mask             : x.x.x.x
    MAC Address             : xx:xx:xx:xx:xx:xx
    Default Gateway IP      : x.x.x.x
    802.1q VLAN ID          : Disabled
    Cipher Suite Priv Max   : Not Available
    Bad Password Threshold  : Not Available

    Given that data, this function will return the following dictionary.

    lan_print_dict:
      [Set in Progress]:                              Set Complete
      [Auth Type Support]:                            MD5
      [Auth Type Enable]:
        [Callback]:                                   MD5
        [User]:                                       MD5
        [Operator]:                                   MD5
        [Admin]:                                      MD5
        [OEM]:                                        MD5
      [IP Address Source]:                            Static Address
      [IP Address]:                                   x.x.x.x
      [Subnet Mask]:                                  x.x.x.x
      [MAC Address]:                                  xx:xx:xx:xx:xx:xx
      [Default Gateway IP]:                           x.x.x.x
      [802.1q VLAN ID]:                               Disabled
      [Cipher Suite Priv Max]:                        Not Available
      [Bad Password Threshold]:                       Not Available

    Description of argument(s):
    ipmi_cmd_type                   The type of ipmi command to use (e.g.
                                    'inband', 'external').
    """

    channel_number = str(channel_number)
    # Notice in the example of data above that 'Auth Type Enable' needs some
    # special processing.  We essentially want to isolate its data and remove
    # the 'Auth Type Enable' string so that key_value_outbuf_to_dict can
    # process it as a sub-dictionary.
    cmd_buf = "lan print " + channel_number + " | grep -E '^(Auth Type Enable)" +\
        "?[ ]+: ' | sed -re 's/^(Auth Type Enable)?[ ]+: //g'"
    stdout1, stderr, rc = execute_ipmi_cmd(cmd_buf, ipmi_cmd_type,
                                           print_output=0)

    # Now get the remainder of the data and exclude the lines with no field
    # names (i.e. the 'Auth Type Enable' sub-fields).
    cmd_buf = "lan print " + channel_number + " | grep -E -v '^[ ]+: '"
    stdout2, stderr, rc = execute_ipmi_cmd(cmd_buf, ipmi_cmd_type,
                                           print_output=0)

    # Make auth_type_enable_dict sub-dictionary...
    auth_type_enable_dict = vf.key_value_outbuf_to_dict(stdout1, to_lower=0,
                                                        underscores=0)

    # Create the lan_print_dict...
    lan_print_dict = vf.key_value_outbuf_to_dict(stdout2, to_lower=0,
                                                 underscores=0)
    # Re-assign 'Auth Type Enable' to contain the auth_type_enable_dict.
    lan_print_dict['Auth Type Enable'] = auth_type_enable_dict

    return lan_print_dict


def get_ipmi_power_reading(strip_watts=1):
    r"""
    Get IPMI power reading data and return it as a dictionary.

    The data is obtained by issuing the IPMI "power reading" command.  An
    example is shown below:

    Instantaneous power reading:                   234 Watts
    Minimum during sampling period:                234 Watts
    Maximum during sampling period:                234 Watts
    Average power reading over sample period:      234 Watts
    IPMI timestamp:                           Thu Jan  1 00:00:00 1970
    Sampling period:                          00000000 Seconds.
    Power reading state is:                   deactivated

    For the data shown above, the following dictionary will be returned.

    result:
      [instantaneous_power_reading]:              238 Watts
      [minimum_during_sampling_period]:           238 Watts
      [maximum_during_sampling_period]:           238 Watts
      [average_power_reading_over_sample_period]: 238 Watts
      [ipmi_timestamp]:                           Thu Jan  1 00:00:00 1970
      [sampling_period]:                          00000000 Seconds.
      [power_reading_state_is]:                   deactivated

    Description of argument(s):
    strip_watts                     Strip all dictionary values of the
                                    trailing " Watts" substring.
    """

    status, ret_values = \
        grk.run_key_u("Run IPMI Standard Command  dcmi power reading")
    result = vf.key_value_outbuf_to_dict(ret_values)

    if strip_watts:
        result.update((k, re.sub(' Watts$', '', v)) for k, v in result.items())

    return result


def get_mc_info():
    r"""
    Get IPMI mc info data and return it as a dictionary.

    The data is obtained by issuing the IPMI "mc info" command.  An
    example is shown below:

    Device ID                 : 0
    Device Revision           : 0
    Firmware Revision         : 2.01
    IPMI Version              : 2.0
    Manufacturer ID           : 42817
    Manufacturer Name         : Unknown (0xA741)
    Product ID                : 16975 (0x424f)
    Product Name              : Unknown (0x424F)
    Device Available          : yes
    Provides Device SDRs      : yes
    Additional Device Support :
        Sensor Device
        SEL Device
        FRU Inventory Device
        Chassis Device
    Aux Firmware Rev Info     :
        0x00
        0x00
        0x00
        0x00

    For the data shown above, the following dictionary will be returned.
    mc_info:
      [device_id]:                       0
      [device_revision]:                 0
      [firmware_revision]:               2.01
      [ipmi_version]:                    2.0
      [manufacturer_id]:                 42817
      [manufacturer_name]:               Unknown (0xA741)
      [product_id]:                      16975 (0x424f)
      [product_name]:                    Unknown (0x424F)
      [device_available]:                yes
      [provides_device_sdrs]:            yes
      [additional_device_support]:
        [additional_device_support][0]:  Sensor Device
        [additional_device_support][1]:  SEL Device
        [additional_device_support][2]:  FRU Inventory Device
        [additional_device_support][3]:  Chassis Device
      [aux_firmware_rev_info]:
        [aux_firmware_rev_info][0]:      0x00
        [aux_firmware_rev_info][1]:      0x00
        [aux_firmware_rev_info][2]:      0x00
        [aux_firmware_rev_info][3]:      0x00
    """

    status, ret_values = \
        grk.run_key_u("Run IPMI Standard Command  mc info")
    result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1)

    return result


def get_sdr_info():
    r"""
    Get IPMI sdr info data and return it as a dictionary.

    The data is obtained by issuing the IPMI "sdr info" command.  An
    example is shown below:

    SDR Version                         : 0x51
    Record Count                        : 216
    Free Space                          : unspecified
    Most recent Addition                :
    Most recent Erase                   :
    SDR overflow                        : no
    SDR Repository Update Support       : unspecified
    Delete SDR supported                : no
    Partial Add SDR supported           : no
    Reserve SDR repository supported    : no
    SDR Repository Alloc info supported : no

    For the data shown above, the following dictionary will be returned.
    mc_info:

      [sdr_version]:                         0x51
      [record_Count]:                        216
      [free_space]:                          unspecified
      [most_recent_addition]:
      [most_recent_erase]:
      [sdr_overflow]:                        no
      [sdr_repository_update_support]:       unspecified
      [delete_sdr_supported]:                no
      [partial_add_sdr_supported]:           no
      [reserve_sdr_repository_supported]:    no
      [sdr_repository_alloc_info_supported]: no
    """

    status, ret_values = \
        grk.run_key_u("Run IPMI Standard Command  sdr info")
    result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1)

    return result


def get_aux_version(version_id):
    r"""
    Get IPMI Aux version info data and return it.

    Description of argument(s):
    version_id                      The data is obtained by from BMC
                                    /etc/os-release
                                    (e.g. "xxx-v2.1-438-g0030304-r3-gfea8585").

    In the prior example, the 3rd field is "438" is the commit version and
    the 5th field is "r3" and value "3" is the release version.

    Aux version return from this function 4380003.
    """

    # Commit version.
    count = re.findall("-(\\d{1,4})-", version_id)

    # Release version.
    release = re.findall("-r(\\d{1,4})", version_id)
    if release:
        aux_version = count[0] + "{0:0>4}".format(release[0])
    else:
        aux_version = count[0] + "0000"

    return aux_version


def get_fru_info():
    r"""
    Get fru info and return it as a list of dictionaries.

    The data is obtained by issuing the IPMI "fru print -N 50" command.  An
    example is shown below:

    FRU Device Description : Builtin FRU Device (ID 0)
     Device not present (Unspecified error)

    FRU Device Description : cpu0 (ID 1)
     Board Mfg Date        : Sun Dec 31 18:00:00 1995
     Board Mfg             : <Manufacturer Name>
     Board Product         : PROCESSOR MODULE
     Board Serial          : YA1934315964
     Board Part Number     : 02CY209

    FRU Device Description : cpu1 (ID 2)
     Board Mfg Date        : Sun Dec 31 18:00:00 1995
     Board Mfg             : <Manufacturer Name>
     Board Product         : PROCESSOR MODULE
     Board Serial          : YA1934315965
     Board Part Number     : 02CY209

    For the data shown above, the following list of dictionaries will be
    returned.

    fru_obj:
      fru_obj[0]:
        [fru_device_description]:  Builtin FRU Device (ID 0)
        [state]:                   Device not present (Unspecified error)
      fru_obj[1]:
        [fru_device_description]:  cpu0 (ID 1)
        [board_mfg_date]:          Sun Dec 31 18:00:00 1995
        [board_mfg]:               <Manufacturer Name>
        [board_product]:           PROCESSOR MODULE
        [board_serial]:            YA1934315964
        [board_part_number]:       02CY209
      fru_obj[2]:
        [fru_device_description]:  cpu1 (ID 2)
        [board_mfg_date]:          Sun Dec 31 18:00:00 1995
        [board_mfg]:               <Manufacturer Name>
        [board_product]:           PROCESSOR MODULE
        [board_serial]:            YA1934315965
        [board_part_number]:       02CY209
    """

    status, ret_values = \
        grk.run_key_u("Run IPMI Standard Command  fru print -N 50")

    # Manipulate the "Device not present" line to create a "state" key.
    ret_values = re.sub("Device not present", "state : Device not present",
                        ret_values)

    return [vf.key_value_outbuf_to_dict(x) for x in re.split("\n\n",
                                                             ret_values)]


def get_component_fru_info(component='cpu',
                           fru_objs=None):
    r"""
    Get fru info for the given component and return it as a list of
    dictionaries.

    This function calls upon get_fru_info and then filters out the unwanted
    entries.  See get_fru_info's prolog for a layout of the data.

    Description of argument(s):
    component                       The component (e.g. "cpu", "dimm", etc.).
    fru_objs                        A fru_objs list such as the one returned
                                    by get_fru_info.  If this is None, then
                                    this function will call get_fru_info to
                                    obtain such a list.
                                    Supplying this argument may improve
                                    performance if this function is to be
                                    called multiple times.
    """

    if fru_objs is None:
        fru_objs = get_fru_info()
    return\
        [x for x in fru_objs
         if re.match(component + '([0-9]+)? ', x['fru_device_description'])]


def get_user_info(userid, channel_number=1):
    r"""
    Get user info using channel command and return it as a dictionary.

    Description of argument(s):
    userid          The userid (e.g. "1", "2", etc.).
    channel_number  The user's channel number (e.g. "1").

    Note: If userid is blank, this function will return a list of dictionaries.  Each list entry represents
    one userid record.

    The data is obtained by issuing the IPMI "channel getaccess" command.  An
    example is shown below for user id 1 and channel number 1.

    Maximum User IDs     : 15
    Enabled User IDs     : 1
    User ID              : 1
    User Name            : root
    Fixed Name           : No
    Access Available     : callback
    Link Authentication  : enabled
    IPMI Messaging       : enabled
    Privilege Level      : ADMINISTRATOR
    Enable Status        : enabled

    For the data shown above, the following dictionary will be returned.

    user_info:
      [maximum_userids]:     15
      [enabled_userids:      1
      [userid]               1
      [user_name]            root
      [fixed_name]           No
      [access_available]     callback
      [link_authentication]  enabled
      [ipmi_messaging]       enabled
      [privilege_level]      ADMINISTRATOR
      [enable_status]        enabled
    """

    status, ret_values = grk.run_key_u("Run IPMI Standard Command  channel getaccess "
                                       + str(channel_number) + " " + str(userid))

    if userid == "":
        return vf.key_value_outbuf_to_dicts(ret_values, process_indent=1)
    else:
        return vf.key_value_outbuf_to_dict(ret_values, process_indent=1)


def channel_getciphers_ipmi():

    r"""
    Run 'channel getciphers ipmi' command and return the result as a list of dictionaries.

    Example robot code:
    ${ipmi_channel_ciphers}=  Channel Getciphers IPMI
    Rprint Vars  ipmi_channel_ciphers

    Example output:
    ipmi_channel_ciphers:
      [0]:
        [id]:                                         3
        [iana]:                                       N/A
        [auth_alg]:                                   hmac_sha1
        [integrity_alg]:                              hmac_sha1_96
        [confidentiality_alg]:                        aes_cbc_128
      [1]:
        [id]:                                         17
        [iana]:                                       N/A
        [auth_alg]:                                   hmac_sha256
        [integrity_alg]:                              sha256_128
        [confidentiality_alg]:                        aes_cbc_128
    """

    cmd_buf = "channel getciphers ipmi | sed -re 's/ Alg/_Alg/g'"
    stdout, stderr, rc = execute_ipmi_cmd(cmd_buf, "external", print_output=0)
    return vf.outbuf_to_report(stdout)


def get_device_id_config():
    r"""
    Get the device id config data and return as a dictionary.

    Example:

    dev_id_config =  get_device_id_config()
    print_vars(dev_id_config)

    dev_id_config:
        [manuf_id]:            7244
        [addn_dev_support]:     141
        [prod_id]:            16976
        [aux]:                    0
        [id]:                    32
        [revision]:             129
        [device_revision]:        1
    """
    stdout, stderr, rc = bsu.bmc_execute_command("cat /usr/share/ipmi-providers/dev_id.json")

    result = json.loads(stdout)

    # Create device revision field for the user.
    # Reference IPMI specification v2.0 "Get Device ID Command"
    # [7]   1 = device provides Device SDRs
    #       0 = device does not provide Device SDRs
    # [6:4] reserved. Return as 0.
    # [3:0] Device Revision, binary encoded.

    result['device_revision'] = result['revision'] & 0x0F

    return result


def get_chassis_status():
    r"""
    Get IPMI chassis status data and return it as a dictionary.

    The data is obtained by issuing the IPMI "chassis status" command. An
    example is shown below:

    System Power              : off
    Power Overload            : false
    Power Interlock           : inactive
    Main Power Fault          : false
    Power Control Fault       : false
    Power Restore Policy      : previous
    Last Power Event          :
    Chassis Intrusion         : inactive
    Front-Panel Lockout       : inactive
    Drive Fault               : false
    Cooling/Fan Fault         : false
    Sleep Button Disable      : not allowed
    Diag Button Disable       : not allowed
    Reset Button Disable      : not allowed
    Power Button Disable      : allowed
    Sleep Button Disabled     : false
    Diag Button Disabled      : false
    Reset Button Disabled     : false
    Power Button Disabled     : false

    For the data shown above, the following dictionary will be returned.

    chassis_status:
      [system_power]:                        off
      [power_overload]:                      false
      [power_interlock]:                     inactive
      [main_power_fault]:                    false
      [power_control_fault]:                 false
      [power_restore_policy]:                previous
      [last_power_event]:
      [chassis_intrusion]:                   inactive
      [front-panel_lockout]:                 inactive
      [drive_fault]:                         false
      [cooling/fan_fault]:                   false
      [sleep_button_disable]:                not allowed
      [diag_button_disable]:                 not allowed
      [reset_button_disable]:                not allowed
      [power_button_disable]:                allowed
      [sleep_button_disabled]:               false
      [diag_button_disabled]:                false
      [reset_button_disabled]:               false
      [power_button_disabled]:               false
    """

    status, ret_values = \
        grk.run_key_u("Run IPMI Standard Command  chassis status")
    result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1)

    return result


def get_channel_info(channel_number=1):
    r"""
    Get the channel info and return as a dictionary.
    Example:

    channel_info:
      [channel_0x2_info]:
        [channel_medium_type]:                        802.3 LAN
        [channel_protocol_type]:                      IPMB-1.0
        [session_support]:                            multi-session
        [active_session_count]:                       0
        [protocol_vendor_id]:                         7154
      [volatile(active)_settings]:
        [alerting]:                                   enabled
        [per-message_auth]:                           enabled
        [user_level_auth]:                            enabled
        [access_mode]:                                always available
      [non-volatile_settings]:
        [alerting]:                                   enabled
        [per-message_auth]:                           enabled
        [user_level_auth]:                            enabled
        [access_mode]:                                always available
    """

    status, ret_values = \
        grk.run_key_u("Run IPMI Standard Command  channel info " + str(channel_number))
    key_var_list = list(filter(None, ret_values.split("\n")))
    # To match the dict format, add a colon after 'Volatile(active) Settings' and 'Non-Volatile Settings'
    # respectively.
    key_var_list[6] = 'Volatile(active) Settings:'
    key_var_list[11] = 'Non-Volatile Settings:'
    result = vf.key_value_list_to_dict(key_var_list, process_indent=1)
    return result


def get_user_access_ipmi(channel_number=1):

    r"""
    Run 'user list [<channel number>]' command and return the result as a list of dictionaries.

    Example robot code:
    ${users_access}=  user list 1
    Rprint Vars  users_access

    Example output:
    users:
      [0]:
        [id]:                                         1
        [name]:                                       root
        [callin]:                                     false
        [link]:                                       true
        [auth]:                                       true
        [ipmi]:                                       ADMINISTRATOR
      [1]:
        [id]:                                         2
        [name]:                                       axzIDwnz
        [callin]:                                     true
        [link]:                                       false
        [auth]:                                       true
        [ipmi]:                                       ADMINISTRATOR
    """

    cmd_buf = "user list " + str(channel_number)
    stdout, stderr, rc = execute_ipmi_cmd(cmd_buf, "external", print_output=0)
    return vf.outbuf_to_report(stdout)


def get_channel_auth_capabilities(channel_number=1, privilege_level=4):
    r"""
    Get the channel authentication capabilities and return as a dictionary.

    Example:

    channel_auth_cap:
        [channel_number]:                               2
        [ipmi_v1.5__auth_types]:
        [kg_status]:                                    default (all zeroes)
        [per_message_authentication]:                   enabled
        [user_level_authentication]:                    enabled
        [non-null_user_names_exist]:                    yes
        [null_user_names_exist]:                        no
        [anonymous_login_enabled]:                      no
        [channel_supports_ipmi_v1.5]:                   no
        [channel_supports_ipmi_v2.0]:                   yes
    """

    status, ret_values = \
        grk.run_key_u("Run IPMI Standard Command  channel authcap " + str(channel_number) + " "
                      + str(privilege_level))
    result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1)

    return result


def fetch_date(date):
    r"""
    Removes prefix 0 in a date in given date

    Example : 08/12/2021 then returns 8/12/2021
    """

    date = date.lstrip("0")
    return date


def fetch_added_sel_date(entry):
    r"""
    Split sel entry string with with | and join only the date with space

    Example : If entry given is, "a | 02/14/2020 | 01:16:58 | Sensor_type #0x17 |  | Asserted"
    Then the result will be "02/14/2020 01:16:58"
    """

    temp = entry.split(" | ")
    date = temp[1] + " " + temp[2]
    print(date)
    return date


def prefix_bytes(listx):
    r"""
    prefixes byte strings in list

    Example:
    ${listx} = ['01', '02', '03']
    ${listx}=  Prefix Bytes  ${listx}
    then,
    ${listx}= ['0x01', '0x02', '0x03']

    """

    listy = []
    for item in listx:
        item = "0x" + item
        listy.append(item)
    return listy


def modify_and_fetch_threshold(old_threshold, threshold_list):
    r"""
    Description of argument(s):

        old_threshold              List of threshold values of sensor,
        threshold_list             List of higher and lower of critical and non-critical values.
                                   i,e [ "lcr", "lnc", "unc", "ucr" ]

    Gets old threshold values from sensor and threshold levels,
    then returns the list of new threshold and the dict of threshold levels

    For example :
    1. If old_threshold list is [ 1, 2, 3, 4] then the newthreshold_list will be [ 101, 102, 103, 104 ].
       If old_threshold has 'na' the same will be appended to new list, eg: [ 101, 102, 103, 104, 'na'].

    2. The newthreshold_list will be zipped to dictionary with threshold_list levels,
       Example : threshold_dict = { 'lcr': 101, 'lnc': 102, 'unc': 103, 'ucr': 104 }

    """

    # Adding the difference of 100 as less than this value,
    # may not have greater impact as the sensor considered is a fan sensor.
    # The set threshold may round off for certain values below 100.
    n = 100
    newthreshold_list = []
    for th in old_threshold:
        th = th.strip()
        if th == 'na':
            newthreshold_list.append('na')
        else:
            x = int(float(th)) + n
            newthreshold_list.append(x)
            n = n + 100
    threshold_dict = dict(zip(threshold_list, newthreshold_list))
    return newthreshold_list, threshold_dict
