コード例 #1
0
    def set_lighting(self, values: list = None, mode=0x18, speed=0x00) -> None:
        """
        for the sake of performance this will assume the data your passing in is correct.
        if it isnt the worst that will happen (i guess) is the lights wont show up as
        expected.
        :param values: [r,g,b...]
        :param mode: lighting mode(hex)
        :param speed: light update speed(hex)
        """

        ## Reading https://github.com/MoshiMoshi0/ttrgbplusapi/blob/master/controllers/riing-trio.md
        ## It says the data sent to the controller for colors is:
        ## "For Riing Trio fans the COLORS (30 colors, 3 zones, 12+12+6) list is split in 2 chunks (19+11)"
        ## "CHUNK_ID indicates the chunk number starting from 1"
        ## Thus I need to send two lists, the first with 19 numbers, the second with 11.
        ##                                                                       v Chunk 1
        first_chunk = [
            PROTOCOL_SET, PROTOCOL_LIGHT, self.port, mode + speed, 3, 1, 0
        ]
        ##                                                                        v Chunk 2
        second_chunk = [
            PROTOCOL_SET, PROTOCOL_LIGHT, self.port, mode + speed, 3, 2, 0
        ]
        ## It is worth noting that I am still using the mode as defined in the riing plus, not the riing trio.
        ## This is probably wrong, but it is very late and I will poke at this after some soonze.
        ## Also, this actually seems to work.
        first_chunk.extend(values)
        second_chunk.extend(values)
        LOGGER.debug('{} set lighting: raw hex: {}'.format(
            self.__class__.__name__, first_chunk))
        self.controller.driver.write_out(first_chunk)
        LOGGER.debug('{} set lighting: raw hex: {}'.format(
            self.__class__.__name__, second_chunk))
        self.controller.driver.write_out(second_chunk)
コード例 #2
0
    def __init__(self, config):
        self.points = config.get('points')
        self.sensor_name = config.get('sensor_name')
        LOGGER.debug(f'curve fan points: {self.points}')
        # ensure the curve starts at 0, 0
        has_zero = False
        for point in self.points:
            if point[0] == 0:
                has_zero = True

        if not has_zero:
            self.points.insert(0, [0, 0])

        self.points.sort(key=lambda s: s[0])

        temps = []
        speeds = []
        for set_ in self.points:
            temps.append(set_[0])
            speeds.append(set_[1])

        self._array = []

        # this involved alot of stack overflow and admittedly im not 100% sure how it works
        # basically given a set of points it extrapolates that into a line consisting of one
        # point per degree.
        x = np.asarray(temps)
        y = np.asarray(speeds)
        pch = pchip(x, y)
        xx = np.linspace(x[0], x[-1], x[-1])
        line2d = pyplot.plot(xx, pch(xx), 'g-')
        self.temps = line2d[0].get_xdata()
        self.speeds = line2d[0].get_ydata()
コード例 #3
0
 def stop(self):
     self._continue = False
     self.lighting_manager.stop()
     self.fan_manager.stop()
     self._thread.join()
     LOGGER.debug('saving controller profiles')
     for controller in self.controllers.values():
         controller.save_profile()
コード例 #4
0
    def register_attached_device(self, unit, port, dev=None):
        if isinstance(dev, devices.ThermaltakeFanDevice):
            LOGGER.debug('  registering %s with fan manager', dev.model)
            self.fan_manager.attach_device(dev)
        if isinstance(dev, devices.ThermaltakeRGBDevice):
            LOGGER.debug('  registering %s with lighting manager', dev.model)
            self.lighting_manager.attach_device(dev)

        self.attached_devices[f'{unit}:{port}'] = dev
コード例 #5
0
 def write_out(self, data: list, length: int = 64) -> list:
     output = list(data)
     try:
         ##output = self.endpoint_out.write(self._populate_partial_data_array(data, length))
         output = self.endpoint_out.write(
             self._populate_partial_data_array(data, length))
         LOGGER.debug('write_out returned: {}'.format(output))
         return output
     except OverflowError:
         return output
コード例 #6
0
 def factory(cls, unit_type, unit_identifier=None):
     subclass_dict = {clazz.model: clazz for clazz in cls.inheritors()}
     try:
         # TODO: remove copy pasta
         if unit_identifier is not None:
             return subclass_dict.get(unit_type.lower())(unit=unit_identifier)
         else:
             return subclass_dict.get(unit_type.lower())()
     except KeyError as e:
         LOGGER.warn('%s not a valid controller type', e)
コード例 #7
0
    def start(self):
        values = []
        try:
            g, r, b = self._config['g'], self._config['r'], self._config['b']
            for i in range(12):
                values.extend([g, r, b])
        except KeyError as e:
            LOGGER.warn('%s not found in config item: lighting_controller', e)

        for device in self._devices:
            device.set_lighting(mode=RGB.Mode.FULL, speed=0x00, values=values)
コード例 #8
0
    def main(self):
        temp = self._get_temp()
        speed = (((temp - self.target) * self.multiplier) + self.last_speed) / 2

        if speed < 0:
            speed = 0
        elif speed > 100:
            speed = 100

        LOGGER.debug(f'Temperature is {temp}°C, setting fan speed to {speed}%')
        return speed
コード例 #9
0
    def start(self):
        try:
            g, r, b = self._config['g'], self._config['r'], self._config['b']
        except KeyError as e:
            LOGGER.warn('%s not found in config item: lighting_controller', e)
            return

        for device in self._devices:
            device.set_lighting(mode=RGB.Mode.RIPPLE,
                                speed=self._speed,
                                values=[g, r, b])
コード例 #10
0
 def factory(cls, model, controller=None, port=None):
     subclass_dict = {
         clazz.model.lower(): clazz
         for clazz in cls.inheritors() if clazz.model is not None
     }
     try:
         dev = subclass_dict[model.lower()](controller, port)
         LOGGER.debug('created {} device'.format(dev.__class__.__name__))
         return dev
     except KeyError:
         LOGGER.warn(
             f'model {model} not found. controller: {controller} port: {port}'
         )
コード例 #11
0
    def load_config(self):
        with open('{}/{}'.format(self.config_dir,
                                 self.config_file_name)) as cfg:
            cfg_str = cfg.readlines()
        cfg_lines = []
        for s in cfg_str:
            # remove comments and blank lines
            if not s.strip().startswith('#') and len(s) > 1:
                cfg_lines.append(s)

        cfg = ''.join(cfg_lines)
        LOGGER.debug('raw config file\n** start **\n\n%s\n** end **\n', cfg)
        return yaml.load(cfg)
コード例 #12
0
    def start(self):
        try:
            g, r, b = self._config['g'], self._config['r'], self._config['b']
        except KeyError as e:
            LOGGER.warn('%s not found in config item: lighting_controller', e)
            return

        for device in self._devices:
            values = []
            for i in range(12):
                values.extend([g, r, b])
            device.set_lighting(mode=RGB.Mode.PULSE,
                                speed=self._speed,
                                values=values)
コード例 #13
0
 def set_lighting(self, values: list = None, mode=0x18, speed=0x00) -> None:
     """
     for the sake of performance this will assume the data your passing in is correct.
     if it isnt the worst that will happen (i guess) is the lights wont show up as
     expected.
     :param values: [r,g,b...]
     :param mode: lighting mode(hex)
     :param speed: light update speed(hex)
     """
     data = [PROTOCOL_SET, PROTOCOL_LIGHT, self.port, mode + speed]
     if values:
         data.extend(values)
     LOGGER.debug(data)
     self.controller.driver.write_out(data)
コード例 #14
0
 def stop(self):
     LOGGER.debug('recieved exit command')
     self._continue = False
     LOGGER.debug('stopping lighting manager')
     self.lighting_manager.stop()
     LOGGER.debug('stopping fan manager')
     self.fan_manager.stop()
     LOGGER.debug('saving controller profiles')
     for controller in self.controllers.values():
         controller.save_profile()
コード例 #15
0
    def _initialize_device(self):
        self.device = usb.core.find(idVendor=self.vendor_id,
                                    idProduct=self.product_id)
        # fail safe incase last device usage was dirty
        self.device.reset()

        if self.device is None:
            raise ValueError('Device not found')

        # Linux kernel sets up a device driver for USB device, which you have
        # to detach. Otherwise trying to interact with the device gives a
        # 'Resource Busy' error.
        try:
            self.device.detach_kernel_driver(0)
        except Exception:
            LOGGER.warning('kernel driver already detached')

        self.device.set_configuration()

        # claim the device
        try:
            usb.util.claim_interface(self.device, 0)
        except usb.core.USBError as e:
            LOGGER.error('{} while claiming interface for device'.format(e))
            raise e

        self.cfg = self.device.get_active_configuration()
        self.interface = self.cfg[(0, 0)]
        self.endpoint_out = usb.util.find_descriptor(
            self.interface,
            custom_match=lambda e: usb.util.endpoint_direction(
                e.bEndpointAddress) == usb.util.ENDPOINT_OUT)
        assert self.endpoint_out is not None

        self.endpoint_in = usb.util.find_descriptor(
            self.interface,
            custom_match=lambda e: usb.util.endpoint_direction(
                e.bEndpointAddress) == usb.util.ENDPOINT_IN)
        assert self.endpoint_in is not None

        # initialize/reset the device
        self.init_controller()
コード例 #16
0
 def parse_config(self, config):
     self.controllers = config.get('controllers')
     LOGGER.debug(config.get('controllers'))
     # self.devices = config.get('devices')
     LOGGER.debug(config.get('fan_manager'))
     self.fan_manager = config.get('fan_manager')
     LOGGER.debug(config.get('lighting_manager'))
     self.lighting_manager = config.get('lighting_manager')
コード例 #17
0
    def __init__(self, config):
        self.points = np.array(config.get('points'))
        self.temps = self.points[:, 0]
        self.speeds = self.points[:, 1]
        self.sensor_name = config.get('sensor_name')
        LOGGER.debug(f'curve fan points: {self.points}')

        if np.min(self.speeds) < 0:
            raise ValueError(
                f'Fan curve contains negative speeds, speed should be in [0,100]'
            )
        if np.max(self.speeds) > 100:
            raise ValueError(
                f'Fan curve contains speeds greater than 100, speed should be in [0,100]'
            )
        if np.any(np.diff(self.temps) <= 0):
            raise ValueError(
                f'Fan curve points should be strictly monotonically increasing, configuration error ?'
            )
        if np.any(np.diff(self.speeds) < 0):
            raise ValueError(
                f'Curve fan speeds should be monotonically increasing, configuration error ?'
            )
コード例 #18
0
 def _main_loop(self):
     LOGGER.debug(f'entering {self.__class__.__name__} main loop')
     while self._continue:
         speed = self._model.main()
         LOGGER.debug(f'new fan speed {speed}')
         for dev in self._devices:
             dev.set_fan_speed(speed)
         time.sleep(1)
     LOGGER.debug(f'exiting {self.__class__.__name__} main loop')
コード例 #19
0
    def test_basic_startup(self, init_dev):
        LOGGER.setLevel(logging.DEBUG)
        stream = StringIO()
        stream_handler = logging.StreamHandler(stream)
        # stream_handler = logging.StreamHandler(sys.stdout)

        LOGGER.addHandler(stream_handler)
        try:
            daemon = ThermaltakeDaemon()
        finally:
            stream_handler.flush()
            LOGGER.removeHandler(stream_handler)
        self.assertIsNotNone(daemon)
        self.assertIsNotNone(daemon.config.controllers)
        self.assertTrue(init_dev.called)

        logging_output = stream.getvalue()
        print(logging_output)
        for keyword in ('** start **', '** end **'):
            self.assertIn(keyword, logging_output)
コード例 #20
0
    def __init__(self):
        # if we have config in /etc, use it, otherwise try and use repository config file
        if os.path.isdir(self.abs_config_dir):
            if os.path.isfile(
                    os.path.join(self.abs_config_dir, self.config_file_name)):
                self.config_dir = self.abs_config_dir
        elif os.path.isdir(self.rel_config_dir):
            if os.path.isfile(
                    os.path.join(self.rel_config_dir, self.config_file_name)):
                self.config_dir = self.rel_config_dir

        with open('{}/{}'.format(self.config_dir,
                                 self.config_file_name)) as cfg:
            config = yaml.load(cfg)
            self.controllers = config.get('controllers')
            LOGGER.debug(config.get('controllers'))
            # self.devices = config.get('devices')
            LOGGER.debug(config.get('fan_manager'))
            self.fan_manager = config.get('fan_manager')
            LOGGER.debug(config.get('lighting_manager'))
            self.lighting_manager = config.get('lighting_manager')
コード例 #21
0
 def factory(cls, config):
     subclass_dict = {clazz.model: clazz for clazz in cls.inheritors()}
     try:
         return subclass_dict.get(config.pop('model').lower())(config)
     except KeyError as e:
         LOGGER.warn('%s not found in config item', e)
コード例 #22
0
 def __init__(self, config):
     self._config = config
     self._devices = []
     LOGGER.info(f'initializing {self.__class__.__name__} light controller')
コード例 #23
0
 def start(self):
     LOGGER.info(f'Starting fan manager ({self._model})...')
     self._continue = True
     self._thread.start()
コード例 #24
0
 def start(self):
     LOGGER.info(f'Starting lighting manager ({self._controller})...')
     self._continue = True
     self._thread.start()
コード例 #25
0
 def main(self):
     LOGGER.debug(f'Setting fan speed to {self.speed}%')
     return self.speed
コード例 #26
0
 def run(self):
     self._continue = True
     LOGGER.debug('starting lighting manager')
     self.lighting_manager.start()
     LOGGER.debug('starting fan manager')
     self.fan_manager.start()
コード例 #27
0
 def stop(self):
     LOGGER.info(f'Stopping lighting manager...')
     self._continue = False
     self._thread.join()
コード例 #28
0
    def __init__(self):
        LOGGER.info('initializing thermaltake rgb daemon')

        LOGGER.debug('loading config')
        self.config = Config()

        LOGGER.debug('creating fan manager')
        fan_model = FanModel.factory(self.config.fan_manager)
        self.fan_manager = FanManager(fan_model)

        LOGGER.debug('creating lighting manager')
        self.lighting_manager = LightingEffect.factory(
            self.config.lighting_manager)

        self.attached_devices = {}
        self.controllers = {}

        LOGGER.debug('configuring controllers')
        for controller in self.config.controllers:
            self.controllers[
                controller['unit']] = ThermaltakeController.factory(
                    controller['type'], controller.get('unit'))
            for id, model in controller['devices'].items():
                LOGGER.debug(' configuring devices for controller %s: %s',
                             controller['type'], controller.get('unit'))
                dev = ThermaltakeDevice.factory(
                    model, self.controllers[controller['unit']], id)
                self.controllers[controller['unit']].attach_device(id, dev)
                self.register_attached_device(controller['unit'], id, dev)

        self._continue = False
コード例 #29
0
ファイル: off_daemon.py プロジェクト: ccraddock/ttrgbplusapi
from linux_thermaltake_rgb.globals import RGB
import time

logging.basicConfig(stream=sys.stdout,
                    level=logging.DEBUG,
                    format='%(message)s')

self_config = Config()
self_lighting_manager = LightingEffect.factory(self_config.lighting_manager)
self_fan_manager = None

self_attached_devices = {}
self_controllers = {}

self_attached_devices = {}
LOGGER.debug('configuring controllers')
for controller in self_config.controllers:
    self_controllers[controller['unit']] = ThermaltakeController.factory(
        controller['type'], controller.get('unit'))
    for id, model in controller['devices'].items():
        dev = ThermaltakeDevice.factory(model,
                                        self_controllers[controller['unit']],
                                        id)
        self_controllers[controller['unit']].attach_device(id, dev)

        if isinstance(dev, devices.ThermaltakeFanDevice) and self_fan_manager:
            LOGGER.debug('  registering %s with fan manager', dev.model)
            self_fan_manager.attach_device(dev)
        if isinstance(dev,
                      devices.ThermaltakeRGBDevice) and self_lighting_manager:
            LOGGER.debug('  registering %s with lighting manager', dev.model)
コード例 #30
0
 def factory(cls, model, controller, port):
     subclass_dict = {clazz.model.lower(): clazz for clazz in cls.inheritors() if clazz.model is not None}
     try:
         return subclass_dict[model.lower()](controller, port)
     except KeyError:
         LOGGER.warn(f'model {model} not found. controller: {controller} port: {port}')