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