def update_zones(self, dead_fans, time_difference): """ TODO: Need to change logic here. # Platforms with chassis_intrusion mode enabled if chassis_intrusion: set the chassis_intrusion_boost_flag to 0 and then do necessary checks to set flag to 1 if chassis_intrusion_boost_flag: run boost mode else: run normal mode else # Platforms WITHOUT chassis_intrusion mode run normal mode """ sensors_tuples = self.machine.read_sensors(self.sensors) self.fsc_safe_guards(sensors_tuples) for zone in self.zones: Logger.info("PWM: %s" % (json.dumps(zone.pwm_output))) chassis_intrusion_boost_flag = 0 if self.chassis_intrusion: self_tray_pull_out = board_callout( callout='chassis_intrusion') if self_tray_pull_out == 1: chassis_intrusion_boost_flag = 1 if chassis_intrusion_boost_flag == 0: pwmval = zone.run(sensors=sensors_tuples, dt=time_difference) else: pwmval = self.boost if self.fan_fail: if self.boost_type == 'progressive' and self.fan_dead_boost: # Cases where we want to progressively bump PWMs dead = len(dead_fans) if dead > 0: Logger.info("Progressive mode: Failed fans: %s" % (', '.join([str(i.label) for i in dead_fans],))) for fan_count, rate in self.fan_dead_boost["data"]: if dead <= fan_count: pwmval = clamp(pwmval + (dead * rate), 0, 100) break else: pwmval = self.boost else: if dead_fans: # If not progressive ,when there is 1 fan failed, boost all fans Logger.info("Failed fans: %s" % ( ', '.join([str(i.label) for i in dead_fans],))) pwmval = self.boost if self.fan_dead_boost: # If all the fans failed take action after a few cycles if len(dead_fans) == len(self.fans): self.all_fan_fail_counter = self.all_fan_fail_counter + 1 Logger.warn("Currently all fans failed for {} cycles".format(self.all_fan_fail_counter)) if self.fan_dead_boost["threshold"] and self.fan_dead_boost["action"]: if self.all_fan_fail_counter >= self.fan_dead_boost["threshold"]: self.fsc_host_action( action=self.fan_dead_boost["action"], cause="All fans are bad for more than " + str(self.fan_dead_boost["threshold"]) + " cycles" ) else: # If atleast 1 fan is working reset the counter self.all_fan_fail_counter = 0 if abs(zone.last_pwm - pwmval) > self.ramp_rate: if pwmval < zone.last_pwm: pwmval = zone.last_pwm - self.ramp_rate else: pwmval = zone.last_pwm + self.ramp_rate zone.last_pwm = pwmval if hasattr(zone.pwm_output, '__iter__'): for output in zone.pwm_output: self.machine.set_pwm(self.fans.get( str(output)), pwmval) else: self.machine.set_pwm(self.fans[zone.pwm_output], pwmval)
def run(self, sensors, dt): ctx = {'dt': dt} outmin = 0 fail_ssd_count = 0 sensor_index = 0 for v in self.expr_meta['ext_vars']: sensor_valid_flag = 1 board, sname = v.split(":") if self.sensor_valid_check != None: for check_name in self.sensor_valid_check: if re.match(check_name, sname, re.IGNORECASE) != None: self.sensor_valid_cur[sensor_index] = fsc_board.sensor_valid_check(board, sname, check_name, self.sensor_valid_check[check_name]["attribute"]) #If current or previous sensor valid status is 0, ignore this sensor reading. #Only when both are 1, goes to sensor check process if (self.sensor_valid_cur[sensor_index] == 0) or (self.sensor_valid_pre[sensor_index] == 0): sensor_valid_flag = 0 self.missing_sensor_assert_retry[sensor_index] = 0 break if sensor_valid_flag == 1: if sname in sensors[board]: self.missing_sensor_assert_retry[sensor_index] = 0 if self.missing_sensor_assert_flag[sensor_index]: Logger.crit('DEASSERT: Zone%d Missing sensors: %s' % (self.counter, v)) self.missing_sensor_assert_flag[sensor_index] = False sensor = sensors[board][sname] ctx[v] = sensor.value if sensor.status in ['ucr']: Logger.warn('Sensor %s reporting status %s' % (sensor.name, sensor.status)) outmin = max(outmin, self.transitional) else: if self.sensor_fail == True: if (sensor.status in ['na']) and (self.sensor_valid_cur[sensor_index] != -1): if re.match(r'.+_C[2-4]_[0-3]_NVME_.+', sensor.name) != None: Logger.warn("%s Fail" % v) outmin = max(outmin, self.boost) elif re.match(r'SSD', sensor.name) != None or re.match(r'(.*)nvme(.*)', sname) != None: fail_ssd_count = fail_ssd_count + 1 else: Logger.warn("%s Fail" % v) outmin = max(outmin, self.boost) else: if (not self.missing_sensor_assert_flag[sensor_index]) and (self.missing_sensor_assert_retry[sensor_index] >= 2): Logger.crit('ASSERT: Zone%d Missing sensors: %s' % (self.counter, v)) self.missing_sensor_assert_flag[sensor_index] = True if (self.missing_sensor_assert_retry[sensor_index] < 2): self.missing_sensor_assert_retry[sensor_index] += 1 # evaluation tries to ignore the effects of None values # (e.g. acts as 0 in max/+) ctx[v] = None self.sensor_valid_pre[sensor_index] = self.sensor_valid_cur[sensor_index] sensor_index += 1 if verbose: (exprout, dxstr) = self.expr.dbgeval(ctx) Logger.info(dxstr + " = " + str(exprout)) else: exprout = self.expr.eval(ctx) Logger.info(self.expr_str + " = " + str(exprout)) # If *all* sensors in the top level max() report None, the # expression will report None if (not exprout) and (outmin == 0): if not self.transitional_assert_flag: Logger.crit('ASSERT: Zone%d No sane fan speed could be \ calculated! Using transitional speed.' % (self.counter)) exprout = self.transitional self.transitional_assert_flag = True else: if self.transitional_assert_flag: Logger.crit('DEASSERT: Zone%d No sane fan speed could be \ calculated! Using transitional speed.' % (self.counter)) self.transitional_assert_flag = False if self.fail_sensor_type != None: if 'SSD_sensor_fail' in list(self.fail_sensor_type.keys()): if self.fail_sensor_type['SSD_sensor_fail'] == True: if fail_ssd_count != 0: if self.ssd_progressive_algorithm != None: if 'offset_algorithm' in list(self.ssd_progressive_algorithm.keys()): list_index = 0 for i in self.ssd_progressive_algorithm['offset_algorithm']: list_index = list_index + 1 if fail_ssd_count <= i[0]: exprout = exprout + i[1] break else: if list_index == len(self.ssd_progressive_algorithm['offset_algorithm']): outmin = max(outmin, self.boost) if not exprout: exprout = 0 if exprout < outmin: exprout = outmin exprout = clamp(exprout, 0, 100) return exprout
def run(self, sensors, dt): ctx = {'dt': dt} outmin = 0 fail_ssd_count = 0 missing = set() for v in self.expr_meta['ext_vars']: board, sname = v.split(":") if sname in sensors[board]: sensor = sensors[board][sname] ctx[v] = sensor.value if sensor.status in ['ucr']: Logger.warn('Sensor %s reporting status %s' % (sensor.name, sensor.status)) outmin = self.transitional if self.fail_sensor_type != None: if 'standby_sensor_fail' in self.fail_sensor_type.keys(): if self.fail_sensor_type[ 'standby_sensor_fail'] == True: if sensor.status in ['na']: if re.match(r'SOC', sensor.name) != None: if 'server_sensor_fail' in self.fail_sensor_type.keys( ): if self.fail_sensor_type[ 'server_sensor_fail'] == True: ret = fsc_board.get_power_status( board) if ret: Logger.debug( "Server Sensor Fail") outmin = self.boost break elif re.match(r'SSD', sensor.name) != None: if 'SSD_sensor_fail' in self.fail_sensor_type.keys( ): if self.fail_sensor_type[ 'SSD_sensor_fail'] == True: fail_ssd_count = fail_ssd_count + 1 else: Logger.debug("Standby Sensor Fail") outmin = self.boost break else: missing.add(v) # evaluation tries to ignore the effects of None values # (e.g. acts as 0 in max/+) ctx[v] = None if missing: Logger.warn('Missing sensors: %s' % (', '.join(missing), )) if verbose: (exprout, dxstr) = self.expr.dbgeval(ctx) Logger.info(dxstr + " = " + str(exprout)) else: exprout = self.expr.eval(ctx) Logger.info(self.expr_str + " = " + str(exprout)) # If *all* sensors in the top level max() report None, the # expression will report None if not exprout: if not self.transitional_assert_flag: Logger.crit('ASSERT: Zone%d No sane fan speed could be \ calculated! Using transitional speed.' % (self.counter)) exprout = self.transitional self.transitional_assert_flag = True else: if self.transitional_assert_flag: Logger.crit('DEASSERT: Zone%d No sane fan speed could be \ calculated! Using transitional speed.' % (self.counter)) self.transitional_assert_flag = False if self.fail_sensor_type != None: if 'SSD_sensor_fail' in self.fail_sensor_type.keys(): if self.fail_sensor_type['SSD_sensor_fail'] == True: if fail_ssd_count != 0: if self.ssd_progressive_algorithm != None: if 'offset_algorithm' in self.ssd_progressive_algorithm.keys( ): list_index = 0 for i in self.ssd_progressive_algorithm[ 'offset_algorithm']: list_index = list_index + 1 if fail_ssd_count <= i[0]: exprout = exprout + i[1] break else: if list_index == len( self.ssd_progressive_algorithm[ 'offset_algorithm']): outmin = self.boost if exprout < outmin: exprout = outmin exprout = clamp(exprout, 0, 100) return exprout
def run(self, sensors, dt): ctx = {"dt": dt} outmin = 0 fail_ssd_count = 0 sensor_index = 0 cause_boost_count = 0 no_sane_flag = 0 mode = 0 for v in self.expr_meta["ext_vars"]: sensor_valid_flag = 1 sdata = v.split(":") board = sdata[0] sname = sdata[1] if self.sensor_valid_check != None: for check_name in self.sensor_valid_check: if re.match(check_name, sname, re.IGNORECASE) != None: self.sensor_valid_cur[ sensor_index] = fsc_board.sensor_valid_check( board, sname, check_name, self.sensor_valid_check[check_name] ["attribute"], ) # If current or previous sensor valid status is 0, ignore this sensor reading. # Only when both are 1, goes to sensor check process if (self.sensor_valid_cur[sensor_index] == 0) or (self.sensor_valid_pre[sensor_index] == 0): sensor_valid_flag = 0 self.missing_sensor_assert_retry[sensor_index] = 0 break if sensor_valid_flag == 1: if sname in sensors[board]: self.missing_sensor_assert_retry[sensor_index] = 0 if self.missing_sensor_assert_flag[sensor_index]: Logger.crit("DEASSERT: Zone%d Missing sensors: %s" % (self.counter, v)) self.missing_sensor_assert_flag[sensor_index] = False sensor = sensors[board][sname] ctx[v] = sensor.value if sensor.status in ["ucr"]: Logger.warn("Sensor %s reporting status %s" % (sensor.name, sensor.status)) outmin = max(outmin, self.transitional) if outmin == self.transitional: mode = fan_mode["trans_mode"] else: if self.sensor_fail == True: sensor_fail_record_path = SENSOR_FAIL_RECORD_DIR + v if not os.path.isdir(SENSOR_FAIL_RECORD_DIR): os.mkdir(SENSOR_FAIL_RECORD_DIR) if (sensor.status in [ "na" ]) and (self.sensor_valid_cur[sensor_index] != -1): if re.match(r"SSD", sensor.name) != None: fail_ssd_count = fail_ssd_count + 1 else: Logger.warn("%s Fail" % v) outmin = max(outmin, self.boost) cause_boost_count += 1 if not os.path.isfile(sensor_fail_record_path): sensor_fail_record = open( sensor_fail_record_path, "w") sensor_fail_record.close() if outmin == self.boost: mode = fan_mode["boost_mode"] else: if os.path.isfile(sensor_fail_record_path): os.remove(sensor_fail_record_path) else: if (not self.missing_sensor_assert_flag[sensor_index] ) and (self.missing_sensor_assert_retry[sensor_index] >= 2): Logger.crit("ASSERT: Zone%d Missing sensors: %s" % (self.counter, v)) self.missing_sensor_assert_flag[sensor_index] = True if self.missing_sensor_assert_retry[sensor_index] < 2: self.missing_sensor_assert_retry[sensor_index] += 1 # evaluation tries to ignore the effects of None values # (e.g. acts as 0 in max/+) ctx[v] = None self.sensor_valid_pre[sensor_index] = self.sensor_valid_cur[ sensor_index] sensor_index += 1 if verbose: (exprout, dxstr) = self.expr.dbgeval(ctx) Logger.info(dxstr + " = " + str(exprout)) else: exprout = self.expr.eval(ctx) Logger.info(self.expr_str + " = " + str(exprout)) # If *all* sensors in the top level max() report None, the # expression will report None if (not exprout) and (outmin == 0): if not self.transitional_assert_flag: Logger.crit("ASSERT: Zone%d No sane fan speed could be \ calculated! Using transitional speed." % (self.counter)) exprout = self.transitional mode = fan_mode["trans_mode"] no_sane_flag = 1 self.transitional_assert_flag = True else: if self.transitional_assert_flag: Logger.crit("DEASSERT: Zone%d No sane fan speed could be \ calculated! Using transitional speed." % (self.counter)) self.transitional_assert_flag = False if self.fail_sensor_type != None: if "SSD_sensor_fail" in list(self.fail_sensor_type.keys()): if self.fail_sensor_type["SSD_sensor_fail"] == True: if fail_ssd_count != 0: if self.ssd_progressive_algorithm != None: if "offset_algorithm" in list( self.ssd_progressive_algorithm.keys()): list_index = 0 for i in self.ssd_progressive_algorithm[ "offset_algorithm"]: list_index = list_index + 1 if fail_ssd_count <= i[0]: exprout = exprout + i[1] no_sane_flag = 0 break else: if list_index == len( self.ssd_progressive_algorithm[ "offset_algorithm"]): outmin = max(outmin, self.boost) cause_boost_count += 1 if outmin == self.boost: mode = fan_mode["boost_mode"] boost_record_path = RECORD_DIR + "sensor_fail_boost" if cause_boost_count != 0: if not os.path.isfile(boost_record_path): sensor_fail_boost_record = open(boost_record_path, "w") sensor_fail_boost_record.close() else: if os.path.isfile(boost_record_path): os.remove(boost_record_path) if not exprout: exprout = 0 if exprout < outmin: exprout = outmin else: if no_sane_flag != 1: mode = fan_mode["normal_mode"] self.get_set_fan_mode(mode, action="write") exprout = clamp(exprout, 0, 100) return exprout
def update_zones(self, dead_fans, time_difference): """ TODO: Need to change logic here. # Platforms with chassis_intrusion mode enabled if chassis_intrusion: set the chassis_intrusion_boost_flag to 0 and then do necessary checks to set flag to 1 if chassis_intrusion_boost_flag: run boost mode else: run normal mode else # Platforms WITHOUT chassis_intrusion mode run normal mode # Platforms with enable_fsc_sensor_check mode enabled if enable_fsc_sensor_check: set the sensor_violated_flag to 0 and then do necessary checks to set flag to 1 if sensor_violated_flag: run boost mode else: run normal mode else # Platforms WITHOUT enable_fsc_sensor_check mode run normal mode """ ctx = {} if not self.sensor_filter_all: sensors_tuples = self.machine.read_sensors(self.sensors, None) self.fsc_safe_guards(sensors_tuples) for zone in self.zones: if self.sensor_filter_all: sensors_tuples = self.machine.read_sensors( self.sensors, zone.expr_meta) self.fsc_safe_guards(sensors_tuples) Logger.info("PWM: %s" % (json.dumps(zone.pwm_output))) mode = 0 chassis_intrusion_boost_flag = 0 sensor_violated_flag = 0 if self.chassis_intrusion: self_tray_pull_out = board_callout(callout="chassis_intrusion") if self_tray_pull_out == 1: chassis_intrusion_boost_flag = 1 if self.enable_fsc_sensor_check: Logger.info("enable_fsc_sensor_check") if self.fsc_sensor_check(sensors_tuples) != 0: sensor_violated_flag = 1 Logger.debug(" dead_fans(%d) " % len(dead_fans)) Logger.debug("Calculate") if chassis_intrusion_boost_flag == 0 and sensor_violated_flag == 0: ctx["dt"] = time_difference ctx["dead_fans"] = dead_fans ctx["last_pwm"] = zone.last_pwm ignore_fan_mode = False if self.non_fanfail_limited_boost and dead_fans: ignore_fan_mode = True pwmval = zone.run(sensors=sensors_tuples, ctx=ctx, ignore_mode=ignore_fan_mode) mode = zone.get_set_fan_mode(mode, action="read") # if we set pwm_sensor_boost_value option, assign it to pwmval if self.pwm_sensor_boost_value != None and \ int(mode) == fan_mode["boost_mode"]: if pwmval == self.boost: pwmval = self.pwm_sensor_boost_value else: pwmval = self.boost mode = fan_mode["boost_mode"] if self.fan_fail: boost_record_path = RECORD_DIR + "fan_fail_boost" if self.boost_type == "progressive" and self.fan_dead_boost: # Cases where we want to progressively bump PWMs dead = len(dead_fans) if dead > 0: Logger.info( "Progressive mode: Failed fans: %s" % (", ".join([str(i.label) for i in dead_fans]))) for fan_count, rate in self.fan_dead_boost["data"]: if dead <= fan_count: pwmval = clamp(pwmval + (dead * rate), 0, 100) mode = fan_mode["normal_mode"] if os.path.isfile(boost_record_path): os.remove(boost_record_path) break else: pwmval = self.boost mode = fan_mode["boost_mode"] if not os.path.isfile(boost_record_path): fan_fail_boost_record = open( boost_record_path, "w") fan_fail_boost_record.close() else: if os.path.isfile(boost_record_path): os.remove(boost_record_path) else: if dead_fans: # If not progressive ,when there is 1 fan failed, boost all fans Logger.info( "Failed fans: %s" % (", ".join([str(i.label) for i in dead_fans]))) # choose the higher PWM if self.output_max_boost_pwm: pwmval = self.boost if pwmval < self.boost else pwmval else: pwmval = self.boost mode = fan_mode["boost_mode"] if not os.path.isfile(boost_record_path): fan_fail_boost_record = open( boost_record_path, "w") fan_fail_boost_record.close() else: if os.path.isfile(boost_record_path): os.remove(boost_record_path) if self.fan_dead_boost: # If all the fans failed take action after a few cycles if len(dead_fans) == len(self.fans): self.all_fan_fail_counter = self.all_fan_fail_counter + 1 Logger.warn( "Currently all fans failed for {} cycles". format(self.all_fan_fail_counter)) if (self.fan_dead_boost["threshold"] and self.fan_dead_boost["action"]): if (self.all_fan_fail_counter >= self.fan_dead_boost["threshold"]): self.fsc_host_action( action=self.fan_dead_boost["action"], cause="All fans are bad for more than " + str(self.fan_dead_boost["threshold"]) + " cycles", ) else: # If atleast 1 fan is working reset the counter self.all_fan_fail_counter = 0 if self.fan_limit_upper_pwm: if pwmval > self.fan_limit_upper_pwm: pwmval = self.fan_limit_upper_pwm if self.fan_limit_lower_pwm: if pwmval < self.fan_limit_lower_pwm: pwmval = self.fan_limit_lower_pwm # if no fan fail, the max of pwm is non_fanfail_limited_boost pwm: if self.non_fanfail_limited_boost and not dead_fans: pwmval = clamp(pwmval, 0, self.non_fanfail_limited_boost) if abs(zone.last_pwm - pwmval) > self.ramp_rate: if pwmval < zone.last_pwm: pwmval = zone.last_pwm - self.ramp_rate else: pwmval = zone.last_pwm + self.ramp_rate zone.last_pwm = pwmval if hasattr(zone.pwm_output, "__iter__"): for output in zone.pwm_output: self.machine.set_pwm(self.fans.get(str(output)), pwmval) else: self.machine.set_pwm(self.fans[zone.pwm_output], pwmval) zone.get_set_fan_mode(mode, action="write")
def run(self, sensors, ctx, ignore_mode): outmin = 0 fail_ssd_count = 0 valid_m2_count = 0 sensor_index = 0 cause_boost_count = 0 no_sane_flag = 0 display_progressive_flag = 0 mode = 0 for v in self.expr_meta["ext_vars"]: sensor_valid_flag = 1 sdata = v.split(":") board = sdata[0] sname = sdata[1] if self.sensor_valid_check != None: for check_name in self.sensor_valid_check: if re.match(check_name, sname, re.IGNORECASE) != None: self.sensor_valid_cur[ sensor_index] = fsc_board.sensor_valid_check( board, sname, check_name, self.sensor_valid_check[check_name] ["attribute"], ) # If current or previous sensor valid status is 0, ignore this sensor reading. # Only when both are 1, goes to sensor check process if (self.sensor_valid_cur[sensor_index] == 0) or (self.sensor_valid_pre[sensor_index] == 0): sensor_valid_flag = 0 self.missing_sensor_assert_retry[sensor_index] = 0 break if sensor_valid_flag == 1: if sname in sensors[board]: self.missing_sensor_assert_retry[sensor_index] = 0 if self.missing_sensor_assert_flag[sensor_index]: Logger.crit("DEASSERT: Zone%d Missing sensors: %s" % (self.counter, v)) self.missing_sensor_assert_flag[sensor_index] = False sensor = sensors[board][sname] ctx[v] = sensor.value if re.match(r".*temp_dev", sname) != None: valid_m2_count = valid_m2_count + 1 if sensor.status in ["ucr"]: Logger.warn("Sensor %s reporting status %s" % (sensor.name, sensor.status)) outmin = max(outmin, self.transitional) if outmin == self.transitional: mode = fan_mode["trans_mode"] else: if self.sensor_fail == True: sensor_fail_record_path = SENSOR_FAIL_RECORD_DIR + v if not os.path.isdir(SENSOR_FAIL_RECORD_DIR): os.mkdir(SENSOR_FAIL_RECORD_DIR) if (sensor.status in [ "na" ]) and (self.sensor_valid_cur[sensor_index] != -1): if (re.match(r"SSD", sensor.name) != None) or (re.match( r".*temp_dev", sname) != None): fail_ssd_count = fail_ssd_count + 1 Logger.warn("M.2 Device %s Fail" % v) else: Logger.warn("%s Fail" % v) outmin = max(outmin, self.boost) cause_boost_count += 1 if not os.path.isfile(sensor_fail_record_path): sensor_fail_record = open( sensor_fail_record_path, "w") sensor_fail_record.close() if outmin == self.boost: mode = fan_mode["boost_mode"] else: if os.path.isfile(sensor_fail_record_path): os.remove(sensor_fail_record_path) else: if (not self.missing_sensor_assert_flag[sensor_index] ) and (self.missing_sensor_assert_retry[sensor_index] >= 2): Logger.crit("ASSERT: Zone%d Missing sensors: %s" % (self.counter, v)) self.missing_sensor_assert_flag[sensor_index] = True if self.missing_sensor_assert_retry[sensor_index] < 2: self.missing_sensor_assert_retry[sensor_index] += 1 # evaluation tries to ignore the effects of None values # (e.g. acts as 0 in max/+) ctx[v] = None else: if sname in sensors[board]: if self.sensor_fail == True: sensor_fail_record_path = SENSOR_FAIL_RECORD_DIR + v if os.path.isfile(sensor_fail_record_path): os.remove(sensor_fail_record_path) self.sensor_valid_pre[sensor_index] = self.sensor_valid_cur[ sensor_index] sensor_index += 1 if verbose: (exprout, dxstr) = self.expr.dbgeval(ctx) Logger.info(dxstr + " = " + str(exprout)) else: exprout = self.expr.eval_driver(ctx) Logger.info(self.expr_str + " = " + str(exprout)) # If *all* sensors in the top level max() report None, the # expression will report None if (not exprout) and (outmin == 0): if not self.transitional_assert_flag: Logger.crit( "ASSERT: Zone%d No sane fan speed could be calculated! Using transitional speed." % (self.counter)) exprout = self.transitional mode = fan_mode["trans_mode"] no_sane_flag = 1 self.transitional_assert_flag = True else: if self.transitional_assert_flag: Logger.crit( "DEASSERT: Zone%d No sane fan speed could be calculated! Using transitional speed." % (self.counter)) self.transitional_assert_flag = False if self.fail_sensor_type != None: progressive_mode = True if ("M2_sensor_fail" in list(self.fail_sensor_type.keys())) and ( "M2_sensor_count" in list(self.fail_sensor_type.keys())): if (self.fail_sensor_type["M2_sensor_fail"] == True) and ( self.fail_sensor_type["M2_sensor_count"] > 0): if valid_m2_count == 0: if fsc_board.all_slots_power_off() == False: # Missing all module (no M.2 device) outmin = max(outmin, self.boost) cause_boost_count += 1 mode = fan_mode["boost_mode"] progressive_mode = False else: # All slots power off, do not boost up progressive_mode = False elif valid_m2_count != self.fail_sensor_type[ "M2_sensor_count"]: # Missing some module (M.2 devices partially populated) progressive_mode = False cause_boost_count += 1 else: # M.2 devices fully populated if cause_boost_count != 0: # other boost reasons: e.g. other sensors (not M.2 devices' sensors) fail to read sensors progressive_mode = False else: if fail_ssd_count != 0: # M.2 devices progressive_mode # handle M.2 devices/SSD fail to read case cause_boost_count += 1 # show out sensor fail record display_progressive_flag = ( 1) # do not override by normal mode mode = fan_mode["progressive_mode"] else: # M.2 devices noraml mode progressive_mode = False if progressive_mode and ("SSD_sensor_fail" in list( self.fail_sensor_type.keys())): if self.fail_sensor_type["SSD_sensor_fail"] == True: if fail_ssd_count != 0: if self.ssd_progressive_algorithm != None: if "offset_algorithm" in list( self.ssd_progressive_algorithm.keys()): list_index = 0 for i in self.ssd_progressive_algorithm[ "offset_algorithm"]: list_index = list_index + 1 if fail_ssd_count <= i[0]: exprout = exprout + i[1] no_sane_flag = 0 break else: if list_index == len( self.ssd_progressive_algorithm[ "offset_algorithm"]): outmin = max(outmin, self.boost) cause_boost_count += 1 if outmin == self.boost: mode = fan_mode["boost_mode"] boost_record_path = RECORD_DIR + "sensor_fail_boost" if cause_boost_count != 0: if not os.path.isfile(boost_record_path): sensor_fail_boost_record = open(boost_record_path, "w") sensor_fail_boost_record.close() else: if os.path.isfile(boost_record_path): os.remove(boost_record_path) if not exprout: exprout = 0 if exprout < outmin: exprout = outmin else: if (no_sane_flag != 1) and (display_progressive_flag != 1): mode = fan_mode["normal_mode"] if not ignore_mode: self.get_set_fan_mode(mode, action="write") exprout = clamp(exprout, 0, 100) return exprout