Пример #1
0
class MacControl():

    def __init__(self, config_file):
        self.config_file = config_file
        self.coretemp = None
        self.applesmc = None
        if not self.__find_sys_dirs():
            if self.applesmc is None:
                logger.error('Unable to find applesmc directory in /sys')
                exit()
            if self.coretemp is None:
                logger.warn('Unable to find coretemp directory in /sys, falling back on applesmc temps')

        self.fc = FanControl(self.applesmc)
        self.kb = BackLightControl(self.applesmc)

        self.sensors = {}
        self.__load_coretemp()
        self.__load_applesmc()
        self.load_config(config_file)

        self.light_log = []

    def load_config(self, config_file=None):
        errors = False
        if config_file is None:
            config_file = self.config_file

        cfg = config.FanConfig(config_file)
        if cfg is None:
            logger.error('Unable to parse config file "%s" ' % config_file)
            return False

        sensors = cfg.get_required_sensors()
        # Make sure all the required sensors exist before starting
        for sensor in sensors:
            if self.sensors.get(sensor, None) is None:
                logger.error('Unable to find sensor data for sensor : "%s" ' % sensor)
                errors = True

        fans = cfg.get_required_fans()

        for fan in fans:
            if not self.fc.has_fan(fan):
                logger.error('Unable to find fan data for fan : "%d" ' % fan)
                errors = True

        if errors:
            self.cfg = None
            return False

        self.cfg = cfg

    def run_sensors(self):
        sensors = self.cfg.get_required_sensors()

        for sensor in sensors:
            s = self.sensors.get(sensor)
            if s.get('current_log', None) is None:
                s['current_log'] = []

            s['current_log'].append(int(self.__read_temp(s)) / 1000)

            while len(s['current_log']) > self.cfg.sliding_window:
                s['current_log'].pop(0)

            s['current'] = sum(s['current_log']) / len(s['current_log'])

        fans = self.cfg.get_fan_speed(self.sensors)

        for fan in fans:
            self.fc.set_speed(fan, fans[fan])

    def run_light(self):
        light = self.kb.get_light()

        self.light_log.append(light)
        while len(self.light_log) > self.cfg.sliding_window:
            self.light_log.pop(0)

        light_avg = sum(self.light_log) / len(self.light_log)

        brightness = self.cfg.get_keyboard_brightness(light_avg)
        self.kb.set_brightness(brightness)

    def run(self):
        while 1:
            if self.cfg is None:
                break

            # Check lighting and adjust keyboard backlight
            self.run_light()

            # Check the CPU temp and adjust fan speed
            self.run_sensors()

            time.sleep(self.cfg.sleep_time)

    def __find_sys_dirs(self):
        base_dir = '/sys/devices'

        for root, dirnames, filenames in os.walk(base_dir):
            for dirname in fnmatch.filter(dirnames, 'applesmc*'):
                self.applesmc = os.path.join(root, dirname)
                logger.debug('found applesmc in "%s"' % self.applesmc)

            for dirname in fnmatch.filter(dirnames, 'coretemp.*'):
                self.coretemp = os.path.join(root, dirname)
                logger.debug('found coretemp in "%s"' % self.coretemp)

            if not self.coretemp is None and not self.applesmc is None:
                return True

        return False

    def __load_coretemp(self):

        if self.coretemp is None:
            return
        names = []
        for temp in glob.glob(os.path.join(self.coretemp, 'temp*_label')):
            temp_id = os.path.basename(temp)[4:]
            temp_id = int(temp_id[:temp_id.find('_')])

            temp_info = {'id': temp_id}
            temp_info['label'] = self.__read_file(temp)
            temp_info['path'] = os.path.join(self.coretemp, 'temp%d_input' % temp_id)

            self.sensors[temp_info['label']] = temp_info
            names.append(temp_info['label'])

        logger.info('Found %d coretemp sensors %s' % (len(names), ', '.join(names)))

    def __load_applesmc(self):
        names = []
        for label in glob.glob(os.path.join(self.applesmc, 'temp*_label')):
            sensor = {}
            sensor_id = os.path.basename(label)[4:]
            sensor_id = int(sensor_id[:sensor_id.find('_')])

            sensor['id'] = sensor_id
            sensor['path'] = os.path.join(self.applesmc, 'temp%d_input' % sensor_id)
            sensor['label'] = self.__read_file(label)

            self.sensors[sensor['label']] = sensor
            names.append(sensor['label'])

        logger.info('Found %d applesmc sensors %s' % (len(names), ', '.join(names)))

        self.light = os.path.join(self.applesmc, 'light')
        if not os.path.isfile(self.light):
            self.light = None

    def __read_temp(self, sensor):
        return self.__read_file(sensor['path'])

    def __read_file(self, filename):

        try:
            with open(filename, 'r') as f:
                return f.read().strip()
        except IOError, e:
            logger.error('Unable to read property from %s because %s' % (filename, e))
            return 0