def build_zones(self):
        self.zones = []
        counter = 0
        for name, data in list(self.fsc_config["zones"].items()):
            filename = data["expr_file"]
            with open(os.path.join(self.zone_config, filename), "r") as exf:
                source = exf.read()
                Logger.info("Compiling FSC expression for zone:")
                Logger.info(source)
                (expr, inf) = fsc_expr.make_eval_tree(source, self.profiles)
                for name in inf["ext_vars"]:
                    sdata = name.split(":")
                    board = sdata[0]
                    # sname never used. so comment out (avoid lint error)
                    # sname = sdata[1]
                    if board not in self.machine.frus:
                        self.machine.nums[board] = []
                    self.machine.frus.add(board)
                    if len(sdata) == 3:
                        self.machine.nums[board].append(sdata[2])

                zone = Zone(
                    data["pwm_output"],
                    expr,
                    inf,
                    self.transitional,
                    counter,
                    self.boost,
                    self.sensor_fail,
                    self.sensor_valid_check,
                    self.fail_sensor_type,
                    self.ssd_progressive_algorithm,
                )
                counter += 1
                self.zones.append(zone)
Example #2
0
    def build_zones(self):
        self.zones = []
        counter = 0
        for name, data in self.fsc_config['zones'].items():
            filename = data['expr_file']
            with open(os.path.join(self.zone_config, filename), 'r') as exf:
                source = exf.read()
                Logger.info("Compiling FSC expression for zone:")
                Logger.info(source)
                (expr, inf) = fsc_expr.make_eval_tree(source, self.profiles)
                for name in inf['ext_vars']:
                    board, sname = name.split(':')
                    self.machine.frus.add(board)

                zone = Zone(data['pwm_output'], expr, inf, self.transitional,
                            counter, self.boost, self.fail_sensor_type,
                            self.ssd_progressive_algorithm)
                counter += 1
                self.zones.append(zone)
Example #3
0
def main():
    global transitional
    global boost
    global wdfile
    global ramp_rate
    syslog.openlog("fscd")
    info("starting")
    machine.set_all_pwm(transitional)
    configfile = "config.json"
    config = None
    zones = []
    if os.path.isfile(RAMFS_CONFIG):
        configfile = RAMFS_CONFIG
    info("Started, reading configuration from %s" % (configfile,))
    with open(configfile, 'r') as f:
        config = json.load(f)
    transitional = config['pwm_transition_value']
    boost = config['pwm_boost_value']
    watchdog = config['watchdog']
    if 'ramp_rate' in config:
        ramp_rate = config['ramp_rate']
    wdfile = None
    if watchdog:
        info("watchdog pinging enabled")
        wdfile = open('/dev/watchdog', 'w+')
        if not wdfile:
            error("couldn't open watchdog device")
        else:
            wdfile.write('V')
            wdfile.flush()

    machine.set_all_pwm(transitional)
    profile_constructors = {}
    for name, pdata in config['profiles'].items():
        profile_constructors[name] = profile_constructor(pdata)

    print("Available profiles: " + ", ".join(profile_constructors.keys()))

    for name, data in config['zones'].items():
        filename = data['expr_file']
        with open(os.path.join(CONFIG_DIR, filename), 'r') as exf:
            source = exf.read()
            print("Compiling FSC expression for zone:")
            print(source)
            (expr, inf) = fsc_expr.make_eval_tree(source, profile_constructors)
            for name in inf['ext_vars']:
                board, sname = name.split(':')
                machine.frus.add(board)
            zone = Zone(data['pwm_output'], expr, inf)
            zones.append(zone)
    info("Read %d zones" % (len(zones),))
    info("Including sensors from: " + ", ".join(machine.frus))
    interval = config['sample_interval_ms'] / 1000.0

    last = time.time()
    dead_fans = set()
    while True:
        last_dead_fans = dead_fans.copy()
        if wdfile:
            wdfile.write('V')
            wdfile.flush()

        time.sleep(interval)
        sensors = machine.read_sensors()
        speeds = machine.read_speed()
        fan_fail = False
        now = time.time()
        dt = now - last
        last = now
        print("\x1b[2J\x1b[H")
        sys.stdout.flush()
        for fan, rpms in speeds.items():
            print("Fan %d speed: %d RPM" % (fan, rpms))
            if rpms < config['min_rpm']:
                dead_fans.add(fan)
            else:
                dead_fans.discard(fan)
        recovered_fans = last_dead_fans - dead_fans
        newly_dead_fans = dead_fans - last_dead_fans
        if len(newly_dead_fans) > 0:
            crit("%d fans failed" % (len(dead_fans),))
        for fan in recovered_fans:
            crit("Fan %d has recovered" % (fan,))
        for zone in zones:
            print("PWM: %s" % (json.dumps(zone.pwm_output)))
            pwmval = zone.run(sensors, dt)
            if abs(zone.last_pwm - pwmval) > ramp_rate:
                if pwmval < zone.last_pwm:
                    pwmval = zone.last_pwm - ramp_rate
                else:
                    pwmval = zone.last_pwm + ramp_rate
            zone.last_pwm = pwmval
            if dead_fans:
                print("Failed fans: %s" %
                      (', '.join([str(i) for i in dead_fans],)))
                pwmval = boost
            if hasattr(zone.pwm_output, '__iter__'):
                for output in zone.pwm_output:
                    machine.set_pwm(output, pwmval)
            else:
                machine.set_pwm(zone.pwm_output, pwmval)
Example #4
0
def main():
    global transitional
    global boost
    global boost_type
    global wdfile
    global ramp_rate
    syslog.openlog("fscd")
    info("starting")
    machine.set_all_pwm(transitional)
    configfile = "config.json"
    config = None
    zones = []
    if os.path.isfile(RAMFS_CONFIG):
        configfile = RAMFS_CONFIG
    info("Started, reading configuration from %s" % (configfile, ))
    with open(configfile, 'r') as f:
        config = json.load(f)
    transitional = config['pwm_transition_value']
    boost = config['pwm_boost_value']
    if 'boost' in config and 'progressive' in config['boost']:
        if config['boost']['progressive']:
            boost_type = 'progressive'
    watchdog = config['watchdog']
    if 'chassis_intrusion' in config:
        chassis_intrusion = config['chassis_intrusion']
    else:
        chassis_intrusion = False
    if 'ramp_rate' in config:
        ramp_rate = config['ramp_rate']
    wdfile = None
    if watchdog:
        info("watchdog pinging enabled")
        wdfile = open('/dev/watchdog', 'w+')
        if not wdfile:
            error("couldn't open watchdog device")
        else:
            wdfile.write('V')
            wdfile.flush()
    machine.set_all_pwm(transitional)
    profile_constructors = {}
    for name, pdata in config['profiles'].items():
        profile_constructors[name] = profile_constructor(pdata)

    print("Available profiles: " + ", ".join(profile_constructors.keys()))

    for name, data in config['zones'].items():
        filename = data['expr_file']
        with open(os.path.join(CONFIG_DIR, filename), 'r') as exf:
            source = exf.read()
            print("Compiling FSC expression for zone:")
            print(source)
            (expr, inf) = fsc_expr.make_eval_tree(source, profile_constructors)
            for name in inf['ext_vars']:
                board, sname = name.split(':')
                machine.frus.add(board)
            zone = Zone(data['pwm_output'], expr, inf)
            zones.append(zone)
    info("Read %d zones" % (len(zones), ))
    info("Including sensors from: " + ", ".join(machine.frus))
    interval = config['sample_interval_ms'] / 1000.0

    last = time.time()
    dead_fans = set()
    while True:
        last_dead_fans = dead_fans.copy()
        if wdfile:
            wdfile.write('V')
            wdfile.flush()
        time.sleep(interval)
        sensors = machine.read_sensors()
        speeds = machine.read_speed()
        fan_fail = False
        now = time.time()
        dt = now - last
        last = now
        print("\x1b[2J\x1b[H")
        sys.stdout.flush()
        for fan, rpms in speeds.items():
            print("Fan %d speed: %d RPM" % (fan, rpms))
            if rpms < config['min_rpm']:
                dead_fans.add(fan)
                pal_fan_dead_handle(fan)
            else:
                dead_fans.discard(fan)
        recovered_fans = last_dead_fans - dead_fans
        newly_dead_fans = dead_fans - last_dead_fans
        if len(newly_dead_fans) > 0:
            crit("%d fans failed" % (len(dead_fans), ))
            for dead_fan_num in dead_fans:
                crit("Fan %d dead, %d RPM" %
                     (dead_fan_num, speeds[dead_fan_num]))
        for fan in recovered_fans:
            crit("Fan %d has recovered" % (fan, ))
            pal_fan_recovered_handle(fan)
        for zone in zones:
            print("PWM: %s" % (json.dumps(zone.pwm_output)))

            chassis_intrusion_boost_flag = 0
            if chassis_intrusion:
                self_tray_pull_out = pal_fan_chassis_intrusion_handle()
                if self_tray_pull_out == 1:
                    chassis_intrusion_boost_flag = 1

            if chassis_intrusion_boost_flag == 0:
                pwmval = zone.run(sensors, dt)
            else:
                pwmval = boost

            if boost_type == 'progressive':
                dead = len(dead_fans)
                if dead > 0:
                    print("Failed fans: %s" %
                          (', '.join([str(i) for i in dead_fans], )))
                    if dead < 3:
                        pwmval = clamp(pwmval + (10 * dead), 0, 100)
                        print("Boosted PWM to %d" % pwmval)
                    else:
                        pwmval = boost
            else:
                if dead_fans:
                    print("Failed fans: %s" %
                          (', '.join([str(i) for i in dead_fans], )))
                    pwmval = boost

            if abs(zone.last_pwm - pwmval) > ramp_rate:
                if pwmval < zone.last_pwm:
                    pwmval = zone.last_pwm - ramp_rate
                else:
                    pwmval = zone.last_pwm + ramp_rate
            zone.last_pwm = pwmval

            if hasattr(zone.pwm_output, '__iter__'):
                for output in zone.pwm_output:
                    machine.set_pwm(output, pwmval)
            else:
                machine.set_pwm(zone.pwm_output, pwmval)