def manage_fans()

in platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_pddf_monitor.py [0:0]


    def manage_fans(self):
        global fan_policy_state
        global fan_policy_alarm
        global send_yellow_alarm
        global send_red_alarm
        global fan_fail
        global count_check
        global test_temp
        global test_temp_list
        global temp_test_data
        global test_temp_revert
        global platform_chassis

        CHECK_TIMES = 3

        LEVEL_FAN_INIT = 0
        LEVEL_FAN_MIN = 1
        LEVEL_FAN_MID = 2
        LEVEL_FAN_MAX = 3  # LEVEL_FAN_DEF
        LEVEL_FAN_YELLOW_ALARM = 4
        LEVEL_FAN_RED_ALARM = 5
        LEVEL_FAN_SHUTDOWN = 6
        THERMAL_NUM_MAX = 7

        FAN_NUM = 2
        FAN_TRAY_NUM = 6

        fan_policy_f2b = {  # AFO
            LEVEL_FAN_MIN: [50,  0x7],
            LEVEL_FAN_MID: [75,  0xb],
            LEVEL_FAN_MAX: [100, 0xf]
        }
        fan_policy_b2f = {  # AFI
            LEVEL_FAN_MID: [75,  0xb],
            LEVEL_FAN_MAX: [100, 0xf]
        }

        afi_thermal_spec = {
            "mid_to_max_temp": [61500, 51500, 49400, 49400, 45100, 46750, 48000, 38500],
            "max_to_mid_temp": [57000, 47300, 45000, 45100, 40750, 42100, 44000, 35000]
        }
        afo_thermal_spec = {
            "min_to_mid_temp": [70000, 66000, 68000, 62000, 62000, 67000, 77000, 50000],
            "mid_to_max_temp": [67000, 62000, 65000, 59000, 58500, 63000, 69000, 49000],
            "max_to_mid_temp": [59000, 53500, 55300, 50300, 50000, 52500, 59000, 41100],
            "mid_to_min_temp": [55800, 50500, 51100, 47600, 45750, 50100, 57000, 36600],
            "max_to_yellow_alarm":   [68000, 64000, 65000, 61000, 60000, 64000, 70000, 68000],
            "yellow_to_red_alarm":   [72000, 68000, 69000, 65000, 64000, 68000, 74000, 72000],
            "red_alarm_to_shutdown": [77000, 73000, 74000, 70000, 69000, 73000, 79000, 77000]
        }

        thermal_val = [0, 0, 0, 0, 0, 0, 0, 0]
        max_to_mid = 0
        mid_to_min = 0

        if fan_policy_state == LEVEL_FAN_INIT:
            fan_policy_state = LEVEL_FAN_MAX  # This is default state
            logging.debug("fan_policy_state=LEVEL_FAN_MAX")
            return

        count_check = count_check+1
        if count_check < CHECK_TIMES:
            return
        else:
            count_check = 0

        fan_dir = platform_chassis.get_fan(1).get_direction()

        if fan_dir == "INTAKE":  # AFI
            fan_thermal_spec = afi_thermal_spec
            fan_policy = fan_policy_b2f
        elif fan_dir == "EXHAUST":          # AFO
            fan_thermal_spec = afo_thermal_spec
            fan_policy = fan_policy_f2b
        else:
            logging.debug("NULL case, not meet with fan_dir=0 or 1")

        ori_duty_cycle = platform_chassis.get_fan(0).get_speed()
        new_duty_cycle = 0

        if test_temp_revert == 0:
            temp_test_data = temp_test_data+2000
        else:
            temp_test_data = temp_test_data-2000

        if test_temp == 0:
            for i in range(THERMAL_NUM_MAX):
                thermal_val[i] = platform_chassis.get_thermal(i).get_temperature()*1000
        else:
            for i in range(THERMAL_NUM_MAX):
                thermal_val[i] = test_temp_list[i]
                thermal_val[i] = thermal_val[i] + temp_test_data

            fan_fail = 0

        ori_state = fan_policy_state
        current_state = fan_policy_state

        if fan_dir == "INTAKE":  # AFI
            for i in range(THERMAL_NUM_MAX):
                if ori_state == LEVEL_FAN_MID:
                    if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]:
                        current_state = LEVEL_FAN_MAX
                        logging.debug("current_state=LEVEL_FAN_MAX")
                        break
                else:
                    if (thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i]):
                        max_to_mid = max_to_mid+1
            if max_to_mid == THERMAL_NUM_MAX and fan_policy_state == LEVEL_FAN_MAX:
                if fan_fail == 0:
                    current_state = LEVEL_FAN_MID
                    logging.debug("current_state=LEVEL_FAN_MID")
        else:  # AFO
            psu_full_load = check_psu_loading()
            for i in range(THERMAL_NUM_MAX):
                if ori_state == LEVEL_FAN_MID:
                    if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]:
                        current_state = LEVEL_FAN_MAX
                        break
                    else:
                        if psu_full_load != True and thermal_val[i] <= fan_thermal_spec["mid_to_min_temp"][i]:
                            mid_to_min = mid_to_min+1

                elif ori_state == LEVEL_FAN_MIN:
                    if psu_full_load == True and fan_fail == 0:
                        current_state = LEVEL_FAN_MID
                        logging.warning("psu_full_load, set current_state=LEVEL_FAN_MID")
                        logging.debug("current_state=LEVEL_FAN_MID")
                    if thermal_val[i] >= fan_thermal_spec["min_to_mid_temp"][i] and fan_fail == 0:
                        current_state = LEVEL_FAN_MID
                        logging.debug("current_state=LEVEL_FAN_MID")

                else:
                    if thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i]:
                        max_to_mid = max_to_mid+1
                    if fan_policy_alarm == 0:
                        if thermal_val[i] >= fan_thermal_spec["max_to_yellow_alarm"][i]:
                            if send_yellow_alarm == 0:
                                logging.warning('Alarm-Yellow for temperature high is detected')
                                fan_policy_alarm = LEVEL_FAN_YELLOW_ALARM
                                send_yellow_alarm = 1
                    elif fan_policy_alarm == LEVEL_FAN_YELLOW_ALARM:
                        if thermal_val[i] >= fan_thermal_spec["yellow_to_red_alarm"][i]:
                            if send_red_alarm == 0:
                                logging.warning('Alarm-Red for temperature high is detected')
                                logging.warning('Alarm for temperature high is detected ')
                                fan_policy_alarm = LEVEL_FAN_RED_ALARM
                                send_red_alarm = 1
                    elif fan_policy_alarm == LEVEL_FAN_RED_ALARM:
                        if thermal_val[i] >= fan_thermal_spec["red_alarm_to_shutdown"][i]:
                            logging.critical('Alarm-Critical for temperature high is detected, shutdown DUT')
                            logging.critical('Alarm for temperature critical is detected ')
                            fan_policy_alarm = LEVEL_FAN_SHUTDOWN
                            time.sleep(2)
                            power_off_dut()

            if max_to_mid == THERMAL_NUM_MAX and ori_state == LEVEL_FAN_MAX:
                if fan_fail == 0:
                    current_state = LEVEL_FAN_MID
                    logging.debug("current_state=LEVEL_FAN_MID")
                    logging.debug("current_state=LEVEL_FAN_MID")
                if fan_policy_alarm != 0:
                    logging.warning('Alarm for temperature high is cleared')
                    fan_policy_alarm = 0
                    send_yellow_alarm = 0
                    send_red_alarm = 0
                    test_temp_revert = 0

            if mid_to_min == THERMAL_NUM_MAX and ori_state == LEVEL_FAN_MID:
                if psu_full_load == 0:
                    current_state = LEVEL_FAN_MIN
                    logging.debug("current_state=LEVEL_FAN_MIN")

        # Check Fan status
        for i in range(FAN_TRAY_NUM * FAN_NUM):
            if not platform_chassis.get_fan(i).get_status() or not platform_chassis.get_fan(i).get_speed_rpm():
                new_duty_cycle = 100
                logging.warning('fan_%d fail, set duty_cycle to 100', i+1)
                if test_temp == 0:
                    fan_fail = 1
                    # 1.When insert/remove fan, fan speed/log still according to thermal policy.
                    # 2.If thermal policy state is bigger than LEVEL_FAN_MAX:
                    #  Do not change back to LEVEL_FAN_MAX, beacuse still need to deal with LOG or shutdown case.
                    # 3.If thermal policy state is smaller than LEVEL_FAN_MAX, set state=MAX.
                    # When remove and insert back fan test, policy check temp and set to correct fan_speed.
                    #
                    if current_state < LEVEL_FAN_MAX:
                        current_state = LEVEL_FAN_MAX
                        logging.debug('fan_%d fail, current_state=LEVEL_FAN_MAX', i+1)

                    as9716_32d_set_fan_speed(new_duty_cycle)

                    break
            else:
                fan_fail = 0

        if current_state != ori_state:
            fan_policy_state = current_state
            new_duty_cycle = fan_policy[current_state][0]
            logging.debug("fan_policy_state=%d, new_duty_cycle=%d", fan_policy_state, new_duty_cycle)
            if new_duty_cycle != ori_duty_cycle and fan_fail == 0:
                as9716_32d_set_fan_speed(new_duty_cycle)
                return True
            if new_duty_cycle == 0 and fan_fail == 0:
                as9716_32d_set_fan_speed(FAN_DUTY_CYCLE_MAX)

        return True