1#!/usr/bin/env python3 2 3r""" 4Provide useful ipmi functions. 5""" 6 7import re 8import gen_print as gp 9import gen_misc as gm 10import gen_cmd as gc 11import gen_robot_keyword as grk 12import gen_robot_utils as gru 13import bmc_ssh_utils as bsu 14import var_funcs as vf 15import ipmi_client as ic 16import tempfile 17import json 18from robot.libraries.BuiltIn import BuiltIn 19 20gru.my_import_resource("ipmi_client.robot") 21 22 23def get_sol_info(): 24 r""" 25 Get all SOL info and return it as a dictionary. 26 27 Example use: 28 29 Robot code: 30 ${sol_info}= get_sol_info 31 Rpvars sol_info 32 33 Output: 34 sol_info: 35 sol_info[Info]: SOL parameter 'Payload Channel (7)' 36 not supported - defaulting to 0x0e 37 sol_info[Character Send Threshold]: 1 38 sol_info[Force Authentication]: true 39 sol_info[Privilege Level]: USER 40 sol_info[Set in progress]: set-complete 41 sol_info[Retry Interval (ms)]: 100 42 sol_info[Non-Volatile Bit Rate (kbps)]: IPMI-Over-Serial-Setting 43 sol_info[Character Accumulate Level (ms)]: 100 44 sol_info[Enabled]: true 45 sol_info[Volatile Bit Rate (kbps)]: IPMI-Over-Serial-Setting 46 sol_info[Payload Channel]: 14 (0x0e) 47 sol_info[Payload Port]: 623 48 sol_info[Force Encryption]: true 49 sol_info[Retry Count]: 7 50 """ 51 52 status, ret_values = grk.run_key_u("Run IPMI Standard Command sol info") 53 54 # Create temp file path. 55 temp = tempfile.NamedTemporaryFile() 56 temp_file_path = temp.name 57 58 # Write sol info to temp file path. 59 text_file = open(temp_file_path, "w") 60 text_file.write(ret_values) 61 text_file.close() 62 63 # Use my_parm_file to interpret data. 64 sol_info = gm.my_parm_file(temp_file_path) 65 66 return sol_info 67 68 69def set_sol_setting(setting_name, setting_value): 70 r""" 71 Set SOL setting with given value. 72 73 # Description of argument(s): 74 # setting_name SOL setting which needs to be set (e.g. 75 # "retry-count"). 76 # setting_value Value which needs to be set (e.g. "7"). 77 """ 78 79 status, ret_values = grk.run_key_u("Run IPMI Standard Command sol set " 80 + setting_name + " " + setting_value) 81 82 return status 83 84 85def execute_ipmi_cmd(cmd_string, 86 ipmi_cmd_type='inband', 87 print_output=1, 88 ignore_err=0, 89 **options): 90 r""" 91 Run the given command string as an IPMI command and return the stdout, 92 stderr and the return code. 93 94 Description of argument(s): 95 cmd_string The command string to be run as an IPMI 96 command. 97 ipmi_cmd_type 'inband' or 'external'. 98 print_output If this is set, this function will print 99 the stdout/stderr generated by 100 the IPMI command. 101 ignore_err Ignore error means that a failure 102 encountered by running the command 103 string will not be raised as a python 104 exception. 105 options These are passed directly to the 106 create_ipmi_ext_command_string function. 107 See that function's prolog for details. 108 """ 109 110 if ipmi_cmd_type == 'inband': 111 IPMI_INBAND_CMD = BuiltIn().get_variable_value("${IPMI_INBAND_CMD}") 112 cmd_buf = IPMI_INBAND_CMD + " " + cmd_string 113 return bsu.os_execute_command(cmd_buf, 114 print_out=print_output, 115 ignore_err=ignore_err) 116 117 if ipmi_cmd_type == 'external': 118 cmd_buf = ic.create_ipmi_ext_command_string(cmd_string, **options) 119 rc, stdout, stderr = gc.shell_cmd(cmd_buf, 120 print_output=print_output, 121 ignore_err=ignore_err, 122 return_stderr=1) 123 return stdout, stderr, rc 124 125 126def get_lan_print_dict(channel_number='', ipmi_cmd_type='external'): 127 r""" 128 Get IPMI 'lan print' output and return it as a dictionary. 129 130 Here is an example of the IPMI lan print output: 131 132 Set in Progress : Set Complete 133 Auth Type Support : MD5 134 Auth Type Enable : Callback : MD5 135 : User : MD5 136 : Operator : MD5 137 : Admin : MD5 138 : OEM : MD5 139 IP Address Source : Static Address 140 IP Address : x.x.x.x 141 Subnet Mask : x.x.x.x 142 MAC Address : xx:xx:xx:xx:xx:xx 143 Default Gateway IP : x.x.x.x 144 802.1q VLAN ID : Disabled 145 Cipher Suite Priv Max : Not Available 146 Bad Password Threshold : Not Available 147 148 Given that data, this function will return the following dictionary. 149 150 lan_print_dict: 151 [Set in Progress]: Set Complete 152 [Auth Type Support]: MD5 153 [Auth Type Enable]: 154 [Callback]: MD5 155 [User]: MD5 156 [Operator]: MD5 157 [Admin]: MD5 158 [OEM]: MD5 159 [IP Address Source]: Static Address 160 [IP Address]: x.x.x.x 161 [Subnet Mask]: x.x.x.x 162 [MAC Address]: xx:xx:xx:xx:xx:xx 163 [Default Gateway IP]: x.x.x.x 164 [802.1q VLAN ID]: Disabled 165 [Cipher Suite Priv Max]: Not Available 166 [Bad Password Threshold]: Not Available 167 168 Description of argument(s): 169 ipmi_cmd_type The type of ipmi command to use (e.g. 170 'inband', 'external'). 171 """ 172 173 channel_number = str(channel_number) 174 # Notice in the example of data above that 'Auth Type Enable' needs some 175 # special processing. We essentially want to isolate its data and remove 176 # the 'Auth Type Enable' string so that key_value_outbuf_to_dict can 177 # process it as a sub-dictionary. 178 cmd_buf = "lan print " + channel_number + " | grep -E '^(Auth Type Enable)" +\ 179 "?[ ]+: ' | sed -re 's/^(Auth Type Enable)?[ ]+: //g'" 180 stdout1, stderr, rc = execute_ipmi_cmd(cmd_buf, ipmi_cmd_type, 181 print_output=0) 182 183 # Now get the remainder of the data and exclude the lines with no field 184 # names (i.e. the 'Auth Type Enable' sub-fields). 185 cmd_buf = "lan print " + channel_number + " | grep -E -v '^[ ]+: '" 186 stdout2, stderr, rc = execute_ipmi_cmd(cmd_buf, ipmi_cmd_type, 187 print_output=0) 188 189 # Make auth_type_enable_dict sub-dictionary... 190 auth_type_enable_dict = vf.key_value_outbuf_to_dict(stdout1, to_lower=0, 191 underscores=0) 192 193 # Create the lan_print_dict... 194 lan_print_dict = vf.key_value_outbuf_to_dict(stdout2, to_lower=0, 195 underscores=0) 196 # Re-assign 'Auth Type Enable' to contain the auth_type_enable_dict. 197 lan_print_dict['Auth Type Enable'] = auth_type_enable_dict 198 199 return lan_print_dict 200 201 202def get_ipmi_power_reading(strip_watts=1): 203 r""" 204 Get IPMI power reading data and return it as a dictionary. 205 206 The data is obtained by issuing the IPMI "power reading" command. An 207 example is shown below: 208 209 Instantaneous power reading: 234 Watts 210 Minimum during sampling period: 234 Watts 211 Maximum during sampling period: 234 Watts 212 Average power reading over sample period: 234 Watts 213 IPMI timestamp: Thu Jan 1 00:00:00 1970 214 Sampling period: 00000000 Seconds. 215 Power reading state is: deactivated 216 217 For the data shown above, the following dictionary will be returned. 218 219 result: 220 [instantaneous_power_reading]: 238 Watts 221 [minimum_during_sampling_period]: 238 Watts 222 [maximum_during_sampling_period]: 238 Watts 223 [average_power_reading_over_sample_period]: 238 Watts 224 [ipmi_timestamp]: Thu Jan 1 00:00:00 1970 225 [sampling_period]: 00000000 Seconds. 226 [power_reading_state_is]: deactivated 227 228 Description of argument(s): 229 strip_watts Strip all dictionary values of the 230 trailing " Watts" substring. 231 """ 232 233 status, ret_values = \ 234 grk.run_key_u("Run IPMI Standard Command dcmi power reading") 235 result = vf.key_value_outbuf_to_dict(ret_values) 236 237 if strip_watts: 238 result.update((k, re.sub(' Watts$', '', v)) for k, v in result.items()) 239 240 return result 241 242 243def get_mc_info(): 244 r""" 245 Get IPMI mc info data and return it as a dictionary. 246 247 The data is obtained by issuing the IPMI "mc info" command. An 248 example is shown below: 249 250 Device ID : 0 251 Device Revision : 0 252 Firmware Revision : 2.01 253 IPMI Version : 2.0 254 Manufacturer ID : 42817 255 Manufacturer Name : Unknown (0xA741) 256 Product ID : 16975 (0x424f) 257 Product Name : Unknown (0x424F) 258 Device Available : yes 259 Provides Device SDRs : yes 260 Additional Device Support : 261 Sensor Device 262 SEL Device 263 FRU Inventory Device 264 Chassis Device 265 Aux Firmware Rev Info : 266 0x00 267 0x00 268 0x00 269 0x00 270 271 For the data shown above, the following dictionary will be returned. 272 mc_info: 273 [device_id]: 0 274 [device_revision]: 0 275 [firmware_revision]: 2.01 276 [ipmi_version]: 2.0 277 [manufacturer_id]: 42817 278 [manufacturer_name]: Unknown (0xA741) 279 [product_id]: 16975 (0x424f) 280 [product_name]: Unknown (0x424F) 281 [device_available]: yes 282 [provides_device_sdrs]: yes 283 [additional_device_support]: 284 [additional_device_support][0]: Sensor Device 285 [additional_device_support][1]: SEL Device 286 [additional_device_support][2]: FRU Inventory Device 287 [additional_device_support][3]: Chassis Device 288 [aux_firmware_rev_info]: 289 [aux_firmware_rev_info][0]: 0x00 290 [aux_firmware_rev_info][1]: 0x00 291 [aux_firmware_rev_info][2]: 0x00 292 [aux_firmware_rev_info][3]: 0x00 293 """ 294 295 status, ret_values = \ 296 grk.run_key_u("Run IPMI Standard Command mc info") 297 result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) 298 299 return result 300 301 302def get_sdr_info(): 303 r""" 304 Get IPMI sdr info data and return it as a dictionary. 305 306 The data is obtained by issuing the IPMI "sdr info" command. An 307 example is shown below: 308 309 SDR Version : 0x51 310 Record Count : 216 311 Free Space : unspecified 312 Most recent Addition : 313 Most recent Erase : 314 SDR overflow : no 315 SDR Repository Update Support : unspecified 316 Delete SDR supported : no 317 Partial Add SDR supported : no 318 Reserve SDR repository supported : no 319 SDR Repository Alloc info supported : no 320 321 For the data shown above, the following dictionary will be returned. 322 mc_info: 323 324 [sdr_version]: 0x51 325 [record_Count]: 216 326 [free_space]: unspecified 327 [most_recent_addition]: 328 [most_recent_erase]: 329 [sdr_overflow]: no 330 [sdr_repository_update_support]: unspecified 331 [delete_sdr_supported]: no 332 [partial_add_sdr_supported]: no 333 [reserve_sdr_repository_supported]: no 334 [sdr_repository_alloc_info_supported]: no 335 """ 336 337 status, ret_values = \ 338 grk.run_key_u("Run IPMI Standard Command sdr info") 339 result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) 340 341 return result 342 343 344def get_aux_version(version_id): 345 r""" 346 Get IPMI Aux version info data and return it. 347 348 Description of argument(s): 349 version_id The data is obtained by from BMC 350 /etc/os-release 351 (e.g. "xxx-v2.1-438-g0030304-r3-gfea8585"). 352 353 In the prior example, the 3rd field is "438" is the commit version and 354 the 5th field is "r3" and value "3" is the release version. 355 356 Aux version return from this function 4380003. 357 """ 358 359 # Commit version. 360 count = re.findall("-(\\d{1,4})-", version_id) 361 362 # Release version. 363 release = re.findall("-r(\\d{1,4})", version_id) 364 if release: 365 aux_version = count[0] + "{0:0>4}".format(release[0]) 366 else: 367 aux_version = count[0] + "0000" 368 369 return aux_version 370 371 372def get_fru_info(): 373 r""" 374 Get fru info and return it as a list of dictionaries. 375 376 The data is obtained by issuing the IPMI "fru print -N 50" command. An 377 example is shown below: 378 379 FRU Device Description : Builtin FRU Device (ID 0) 380 Device not present (Unspecified error) 381 382 FRU Device Description : cpu0 (ID 1) 383 Board Mfg Date : Sun Dec 31 18:00:00 1995 384 Board Mfg : <Manufacturer Name> 385 Board Product : PROCESSOR MODULE 386 Board Serial : YA1934315964 387 Board Part Number : 02CY209 388 389 FRU Device Description : cpu1 (ID 2) 390 Board Mfg Date : Sun Dec 31 18:00:00 1995 391 Board Mfg : <Manufacturer Name> 392 Board Product : PROCESSOR MODULE 393 Board Serial : YA1934315965 394 Board Part Number : 02CY209 395 396 For the data shown above, the following list of dictionaries will be 397 returned. 398 399 fru_obj: 400 fru_obj[0]: 401 [fru_device_description]: Builtin FRU Device (ID 0) 402 [state]: Device not present (Unspecified error) 403 fru_obj[1]: 404 [fru_device_description]: cpu0 (ID 1) 405 [board_mfg_date]: Sun Dec 31 18:00:00 1995 406 [board_mfg]: <Manufacturer Name> 407 [board_product]: PROCESSOR MODULE 408 [board_serial]: YA1934315964 409 [board_part_number]: 02CY209 410 fru_obj[2]: 411 [fru_device_description]: cpu1 (ID 2) 412 [board_mfg_date]: Sun Dec 31 18:00:00 1995 413 [board_mfg]: <Manufacturer Name> 414 [board_product]: PROCESSOR MODULE 415 [board_serial]: YA1934315965 416 [board_part_number]: 02CY209 417 """ 418 419 status, ret_values = \ 420 grk.run_key_u("Run IPMI Standard Command fru print -N 50") 421 422 # Manipulate the "Device not present" line to create a "state" key. 423 ret_values = re.sub("Device not present", "state : Device not present", 424 ret_values) 425 426 return [vf.key_value_outbuf_to_dict(x) for x in re.split("\n\n", 427 ret_values)] 428 429 430def get_component_fru_info(component='cpu', 431 fru_objs=None): 432 r""" 433 Get fru info for the given component and return it as a list of 434 dictionaries. 435 436 This function calls upon get_fru_info and then filters out the unwanted 437 entries. See get_fru_info's prolog for a layout of the data. 438 439 Description of argument(s): 440 component The component (e.g. "cpu", "dimm", etc.). 441 fru_objs A fru_objs list such as the one returned 442 by get_fru_info. If this is None, then 443 this function will call get_fru_info to 444 obtain such a list. 445 Supplying this argument may improve 446 performance if this function is to be 447 called multiple times. 448 """ 449 450 if fru_objs is None: 451 fru_objs = get_fru_info() 452 return\ 453 [x for x in fru_objs 454 if re.match(component + '([0-9]+)? ', x['fru_device_description'])] 455 456 457def get_user_info(userid, channel_number=1): 458 r""" 459 Get user info using channel command and return it as a dictionary. 460 461 Description of argument(s): 462 userid The userid (e.g. "1", "2", etc.). 463 channel_number The user's channel number (e.g. "1"). 464 465 Note: If userid is blank, this function will return a list of dictionaries. Each list entry represents 466 one userid record. 467 468 The data is obtained by issuing the IPMI "channel getaccess" command. An 469 example is shown below for user id 1 and channel number 1. 470 471 Maximum User IDs : 15 472 Enabled User IDs : 1 473 User ID : 1 474 User Name : root 475 Fixed Name : No 476 Access Available : callback 477 Link Authentication : enabled 478 IPMI Messaging : enabled 479 Privilege Level : ADMINISTRATOR 480 Enable Status : enabled 481 482 For the data shown above, the following dictionary will be returned. 483 484 user_info: 485 [maximum_userids]: 15 486 [enabled_userids: 1 487 [userid] 1 488 [user_name] root 489 [fixed_name] No 490 [access_available] callback 491 [link_authentication] enabled 492 [ipmi_messaging] enabled 493 [privilege_level] ADMINISTRATOR 494 [enable_status] enabled 495 """ 496 497 status, ret_values = grk.run_key_u("Run IPMI Standard Command channel getaccess " 498 + str(channel_number) + " " + str(userid)) 499 500 if userid == "": 501 return vf.key_value_outbuf_to_dicts(ret_values, process_indent=1) 502 else: 503 return vf.key_value_outbuf_to_dict(ret_values, process_indent=1) 504 505 506def channel_getciphers_ipmi(): 507 508 r""" 509 Run 'channel getciphers ipmi' command and return the result as a list of dictionaries. 510 511 Example robot code: 512 ${ipmi_channel_ciphers}= Channel Getciphers IPMI 513 Rprint Vars ipmi_channel_ciphers 514 515 Example output: 516 ipmi_channel_ciphers: 517 [0]: 518 [id]: 3 519 [iana]: N/A 520 [auth_alg]: hmac_sha1 521 [integrity_alg]: hmac_sha1_96 522 [confidentiality_alg]: aes_cbc_128 523 [1]: 524 [id]: 17 525 [iana]: N/A 526 [auth_alg]: hmac_sha256 527 [integrity_alg]: sha256_128 528 [confidentiality_alg]: aes_cbc_128 529 """ 530 531 cmd_buf = "channel getciphers ipmi | sed -re 's/ Alg/_Alg/g'" 532 stdout, stderr, rc = execute_ipmi_cmd(cmd_buf, "external", print_output=0) 533 return vf.outbuf_to_report(stdout) 534 535 536def get_device_id_config(): 537 r""" 538 Get the device id config data and return as a dictionary. 539 540 Example: 541 542 dev_id_config = get_device_id_config() 543 print_vars(dev_id_config) 544 545 dev_id_config: 546 [manuf_id]: 7244 547 [addn_dev_support]: 141 548 [prod_id]: 16976 549 [aux]: 0 550 [id]: 32 551 [revision]: 129 552 [device_revision]: 1 553 """ 554 stdout, stderr, rc = bsu.bmc_execute_command("cat /usr/share/ipmi-providers/dev_id.json") 555 556 result = json.loads(stdout) 557 558 # Create device revision field for the user. 559 # Reference IPMI specification v2.0 "Get Device ID Command" 560 # [7] 1 = device provides Device SDRs 561 # 0 = device does not provide Device SDRs 562 # [6:4] reserved. Return as 0. 563 # [3:0] Device Revision, binary encoded. 564 565 result['device_revision'] = result['revision'] & 0x0F 566 567 return result 568 569 570def get_chassis_status(): 571 r""" 572 Get IPMI chassis status data and return it as a dictionary. 573 574 The data is obtained by issuing the IPMI "chassis status" command. An 575 example is shown below: 576 577 System Power : off 578 Power Overload : false 579 Power Interlock : inactive 580 Main Power Fault : false 581 Power Control Fault : false 582 Power Restore Policy : previous 583 Last Power Event : 584 Chassis Intrusion : inactive 585 Front-Panel Lockout : inactive 586 Drive Fault : false 587 Cooling/Fan Fault : false 588 Sleep Button Disable : not allowed 589 Diag Button Disable : not allowed 590 Reset Button Disable : not allowed 591 Power Button Disable : allowed 592 Sleep Button Disabled : false 593 Diag Button Disabled : false 594 Reset Button Disabled : false 595 Power Button Disabled : false 596 597 For the data shown above, the following dictionary will be returned. 598 599 chassis_status: 600 [system_power]: off 601 [power_overload]: false 602 [power_interlock]: inactive 603 [main_power_fault]: false 604 [power_control_fault]: false 605 [power_restore_policy]: previous 606 [last_power_event]: 607 [chassis_intrusion]: inactive 608 [front-panel_lockout]: inactive 609 [drive_fault]: false 610 [cooling/fan_fault]: false 611 [sleep_button_disable]: not allowed 612 [diag_button_disable]: not allowed 613 [reset_button_disable]: not allowed 614 [power_button_disable]: allowed 615 [sleep_button_disabled]: false 616 [diag_button_disabled]: false 617 [reset_button_disabled]: false 618 [power_button_disabled]: false 619 """ 620 621 status, ret_values = \ 622 grk.run_key_u("Run IPMI Standard Command chassis status") 623 result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) 624 625 return result 626 627 628def get_channel_info(channel_number=1): 629 r""" 630 Get the channel info and return as a dictionary. 631 Example: 632 633 channel_info: 634 [channel_0x2_info]: 635 [channel_medium_type]: 802.3 LAN 636 [channel_protocol_type]: IPMB-1.0 637 [session_support]: multi-session 638 [active_session_count]: 0 639 [protocol_vendor_id]: 7154 640 [volatile(active)_settings]: 641 [alerting]: enabled 642 [per-message_auth]: enabled 643 [user_level_auth]: enabled 644 [access_mode]: always available 645 [non-volatile_settings]: 646 [alerting]: enabled 647 [per-message_auth]: enabled 648 [user_level_auth]: enabled 649 [access_mode]: always available 650 """ 651 652 status, ret_values = \ 653 grk.run_key_u("Run IPMI Standard Command channel info " + str(channel_number)) 654 key_var_list = list(filter(None, ret_values.split("\n"))) 655 # To match the dict format, add a colon after 'Volatile(active) Settings' and 'Non-Volatile Settings' 656 # respectively. 657 key_var_list[6] = 'Volatile(active) Settings:' 658 key_var_list[11] = 'Non-Volatile Settings:' 659 result = vf.key_value_list_to_dict(key_var_list, process_indent=1) 660 return result 661 662 663def get_user_access_ipmi(channel_number=1): 664 665 r""" 666 Run 'user list [<channel number>]' command and return the result as a list of dictionaries. 667 668 Example robot code: 669 ${users_access}= user list 1 670 Rprint Vars users_access 671 672 Example output: 673 users: 674 [0]: 675 [id]: 1 676 [name]: root 677 [callin]: false 678 [link]: true 679 [auth]: true 680 [ipmi]: ADMINISTRATOR 681 [1]: 682 [id]: 2 683 [name]: axzIDwnz 684 [callin]: true 685 [link]: false 686 [auth]: true 687 [ipmi]: ADMINISTRATOR 688 """ 689 690 cmd_buf = "user list " + str(channel_number) 691 stdout, stderr, rc = execute_ipmi_cmd(cmd_buf, "external", print_output=0) 692 return vf.outbuf_to_report(stdout) 693 694 695def get_channel_auth_capabilities(channel_number=1, privilege_level=4): 696 r""" 697 Get the channel authentication capabilities and return as a dictionary. 698 699 Example: 700 701 channel_auth_cap: 702 [channel_number]: 2 703 [ipmi_v1.5__auth_types]: 704 [kg_status]: default (all zeroes) 705 [per_message_authentication]: enabled 706 [user_level_authentication]: enabled 707 [non-null_user_names_exist]: yes 708 [null_user_names_exist]: no 709 [anonymous_login_enabled]: no 710 [channel_supports_ipmi_v1.5]: no 711 [channel_supports_ipmi_v2.0]: yes 712 """ 713 714 status, ret_values = \ 715 grk.run_key_u("Run IPMI Standard Command channel authcap " + str(channel_number) + " " 716 + str(privilege_level)) 717 result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) 718 719 return result 720 721 722def fetch_date(date): 723 r""" 724 Removes prefix 0 in a date in given date 725 726 Example : 08/12/2021 then returns 8/12/2021 727 """ 728 729 date = date.lstrip("0") 730 return date 731 732 733def fetch_added_sel_date(entry): 734 r""" 735 Split sel entry string with with | and join only the date with space 736 737 Example : If entry given is, "a | 02/14/2020 | 01:16:58 | Sensor_type #0x17 | | Asserted" 738 Then the result will be "02/14/2020 01:16:58" 739 """ 740 741 temp = entry.split(" | ") 742 date = temp[1] + " " + temp[2] 743 print(date) 744 return date 745 746 747def prefix_bytes(listx): 748 r""" 749 prefixes byte strings in list 750 751 Example: 752 ${listx} = ['01', '02', '03'] 753 ${listx}= Prefix Bytes ${listx} 754 then, 755 ${listx}= ['0x01', '0x02', '0x03'] 756 757 """ 758 759 listy = [] 760 for item in listx: 761 item = "0x" + item 762 listy.append(item) 763 return listy 764 765 766def modify_and_fetch_threshold(old_threshold, threshold_list): 767 r""" 768 Description of argument(s): 769 770 old_threshold List of threshold values of sensor, 771 threshold_list List of higher and lower of critical and non-critical values. 772 i,e [ "lcr", "lnc", "unc", "ucr" ] 773 774 Gets old threshold values from sensor and threshold levels, 775 then returns the list of new threshold and the dict of threshold levels 776 777 For example : 778 1. If old_threshold list is [ 1, 2, 3, 4] then the newthreshold_list will be [ 101, 102, 103, 104 ]. 779 If old_threshold has 'na' the same will be appended to new list, eg: [ 101, 102, 103, 104, 'na']. 780 781 2. The newthreshold_list will be zipped to dictionary with threshold_list levels, 782 Example : threshold_dict = { 'lcr': 101, 'lnc': 102, 'unc': 103, 'ucr': 104 } 783 784 """ 785 786 # Adding the difference of 100 as less than this value, 787 # may not have greater impact as the sensor considered is a fan sensor. 788 # The set threshold may round off for certain values below 100. 789 n = 100 790 newthreshold_list = [] 791 for th in old_threshold: 792 th = th.strip() 793 if th == 'na': 794 newthreshold_list.append('na') 795 else: 796 x = int(float(th)) + n 797 newthreshold_list.append(x) 798 n = n + 100 799 threshold_dict = dict(zip(threshold_list, newthreshold_list)) 800 return newthreshold_list, threshold_dict 801