Example #1
0
class Daemon:
    def __init__(self, loop_self):

        driver = Driver()
        driver.load_default_device()
        self._controller = Controller(driver)

        computer = self._controller.get_computer()

        if computer is None:
            exit(1)

        self._computer = computer

        self._COMPUTER_BLOCKS_TO_SAVE = (
            (True, self._computer.BLOCK_LOAD_ON_BOOT),
            #(True, self._computer.BLOCK_STANDBY),
            #(True, self._computer.BLOCK_AC_POWER),
            #(#True, self._computer.BLOCK_CHARGING),
            #(True, self._computer.BLOCK_BATT_SLEEPING),
            #(True, self._computer.BLOCK_BAT_POWER),
            #(True, self._computer.BLOCK_BATT_CRITICAL),
            (False, self._computer.BLOCK_LOAD_ON_BOOT))

        self.loop_self = loop_self

        # Initialize the daemon
        #
        self._user = '******'
        self._paths = Paths()
        self._paths = Paths(self._user)
        self._ccp = CCParser(self._paths._configuration_file,
                             'GUI Configuration')
        self._indicator_pyro = False

        self.reload_configurations(self._user)
        self._lights_state = False

    def _iluminate_keyboard(self):

        # Find the last theme that has been used
        #
        os.utime(self._theme.path, None)

        # Iluminate the computer lights
        #

        self._controller.erase_config()

        for save, block in self._COMPUTER_BLOCKS_TO_SAVE:

            self._controller.add_block_line(save=save, block=block)
            self._controller.add_reset_line(self._computer.RESET_ALL_LIGHTS_ON)
            self._controller.add_speed_line(self._theme.get_speed())

            for area in self._theme.get_areas():
                for zone in area.get_zones():
                    self._controller.add_color_line(zone.get_hex_id(),
                                                    zone.get_mode(),
                                                    zone.get_left_color(),
                                                    zone.get_right_color())

                self._controller.end_colors_line()

            self._controller.end_block_line()

        self._controller.apply_config()

        # Update the Indicator
        #
        if self._indicator_pyro:
            self._indicator_send_code(100)
            try:
                self._indicator_pyro.load_profiles(
                    theme_factory._AVAILABLE_THEMES.keys(), self._theme.name,
                    self._lights_state)
            except Exception:
                print_error(format_exc())

        # Update the Daemon variables
        #
        self._lights_state = True

    def _indicator_send_code(self, val):
        if self._indicator_pyro:
            try:
                self._indicator_pyro.set_code(val)
            except Exception:
                print_error(format_exc())

    """
        General Bindings
    """

    @Pyro4.expose
    def ping(self):
        pass

    @Pyro4.expose
    def reload_configurations(self, user, indicator=True, set_default=True):

        if user != self._user:
            self._user = user
            self._paths = Paths(user)
            self._ccp.set_configuration_path(self._paths._configuration_file)

        theme_factory.LOAD_profiles(self._computer, self._paths._profiles_dir)

        if set_default:
            _, profile_name = theme_factory.GET_last_configuration()
            self._theme = theme_factory.get_theme_by_name(profile_name)

        if self._indicator_pyro and indicator:
            try:
                self._indicator_pyro.load_profiles(
                    theme_factory._AVAILABLE_THEMES.keys(), self._theme.name,
                    self._lights_state)
            except Exception:
                print_error(format_exc())

    """
        Bindings for the users
    """

    @Pyro4.expose
    def set_profile(self, user, profile):
        """
            Set a profile from the existing profiles.

            + 'profile' is the profile name
        """
        if user != self._user:
            self._user = user
            self._paths = Paths(user)

        self.reload_configurations(user, False, False)

        if profile in theme_factory._AVAILABLE_THEMES.keys():
            self._theme = theme_factory._AVAILABLE_THEMES[profile]
            self._iluminate_keyboard()

    @Pyro4.expose
    def switch_lights(self, user):
        """
            If the lights are on, put them off
            or if the lights are off put them on
        """
        if self._lights_state:
            self.set_lights(user, False)
        else:
            self.set_lights(user, True)

    @Pyro4.expose
    def set_lights(self, user_name, state):
        """
            Turn the lights on or off, 'state' can be a boolean or a string.
        """
        if user_name != self._user:
            self.reload_configurations(user_name)

        if state in (False, 'False', 'false'):

            areas_to_keep_on = self._ccp.get_str_defval('areas_to_keep_on', '')

            print_warning("AREAS TO KEEP ON")
            print_warning(areas_to_keep_on)

            if areas_to_keep_on == '':

                self._controller.erase_config()

                for save, block in self._COMPUTER_BLOCKS_TO_SAVE:
                    self._controller.add_block_line(save, block)
                    self._controller.add_reset_line(
                        self._computer.RESET_ALL_LIGHTS_OFF)

                self._controller.apply_config()
            else:
                """
                    To turn off the lights but let some areas on, instead of sending the command "all the lights off",
                    some areas are set to black color.
                """

                areas_to_keep_on = areas_to_keep_on.split('|')

                print_warning(areas_to_keep_on)

                self._controller.erase_config()
                for save, block in self._COMPUTER_BLOCKS_TO_SAVE:

                    self._controller.add_block_line(save, block)
                    self._controller.add_reset_line(
                        self._computer.RESET_ALL_LIGHTS_ON)
                    self._controller.add_speed_line(1)

                    for area in self._theme.get_areas():
                        if not area.name in areas_to_keep_on:
                            for zone in area.get_zones():
                                self._controller.add_color_line(
                                    zone.get_hex_id(), 'fixed', '#000000',
                                    '#000000')
                            self._controller.end_colors_line()
                    self._controller.end_block_line()
                self._controller.apply_config()

            self._lights_state = False
            self._indicator_send_code(150)
        else:
            self._iluminate_keyboard()

    @Pyro4.expose
    def set_colors(self, mode, speed, left_colors, right_colors=None):
        """
            Change the colors and the mode of the keyboard.

            + The available modes are: 'fixed', 'morph', 'blink'
                'fixed' and 'blink' only takes left_colors

            + Speed must be an integer. 1 =< speed =< 256

            + left_colors and right_colors can be a single hex color or a list of hex_colors.
              If both arguments are used, they must have the same number of items.
        """

        if mode not in ('fixed', 'morph', 'blink'):
            print_warning("Wrong mode" + str(mode))
            return
        elif not isinstance(speed, int):
            print_warning("The speed argument must be an integer.")
            return
        elif speed > 255:
            print_warning("The speed argument exeeds the limit > 255.")
            return
        elif speed < 1:
            print_warning("The speed argument must be >= 1.")
            return

        if not isinstance(left_colors, list) and not isinstance(
                left_colors, tuple):
            left_colors = [left_colors]

        if right_colors is None:
            right_colors = left_colors

        elif not isinstance(right_colors, list) and not isinstance(
                right_colors, tuple):
            right_colors = [right_colors]

        if len(left_colors) != len(right_colors):
            print_warning("The colors lists must have the same lenght.")
            return

        for color_list in (left_colors, right_colors):
            for color in color_list:
                if not string_is_hex_color(color):
                    print_warning(
                        "The colors argument must only contain hex colors. The color={} is not valid."
                        .format(color))
                    return

        self._controller.erase_config()

        for save, block in self._COMPUTER_BLOCKS_TO_SAVE:

            self._controller.add_block_line(save, block)
            self._controller.add_reset_line(self._computer.RESET_ALL_LIGHTS_ON)
            self._controller.add_speed_line(speed)

            for region in self._computer.get_regions():
                for i, (left_color, right_color) in enumerate(
                        zip(left_colors, right_colors)):

                    if i + 1 > region.max_commands:
                        print_warning(
                            "The number of maximum commands for the region={} have been exeed. The loop was stopped at {}."
                            .format(region.name, i + 1))
                        break

                    if mode == 'blink':
                        if region.can_blink:
                            self._controller.add_color_line(
                                region.hex_id, 'blink', left_color,
                                right_color)
                        else:
                            self._controller.add_color_line(
                                region.hex_id, 'fixed', left_color)
                            print_warning(
                                "The mode=blink is not supported for the region={}, the mode=fixed will be used instead."
                                .format(region.name))

                    elif mode == 'morph':
                        if region.can_morph:
                            self._controller.add_color_line(
                                region.hex_id, 'morph', left_color,
                                right_color)
                        else:
                            self._controller.add_color_line(
                                region.hex_id, 'fixed', left_color)
                            print_warning(
                                "The mode=morph is not supported for the region={}, the mode=fixed will be used instead."
                                .format(region.name))

                    else:
                        self._controller.add_color_line(
                            region.hex_id, 'fixed', left_color)

                self._controller.end_colors_line()

            self._controller.end_block_line()

        self._controller.apply_config()

        self._lights_state = True

    """
        Bindings for the graphical interphase
    """

    @Pyro4.expose
    def get_computer_name(self):
        return self._computer.NAME

    @Pyro4.expose
    def get_computer_info(self):
        return (self._computer.NAME, self._computer.VENDOR_ID,
                self._computer.PRODUCT_ID,
                self._controller.get_device_information())

    @Pyro4.expose
    def modify_lights_state(self, value):
        """
            This method does not changes the lights of the keyboard,
            it only updates the daemon and the indicator
        """
        if value in (False, 'False', 'false'):
            self._lights_state = False
            self._indicator_send_code(150)
        else:
            self._lights_stae = True
            self._indicator_send_code(100)

    """
        Indicator Bindings
    """

    @Pyro4.expose
    def indicator_get_state(self):
        if self._lights_state:
            self._indicator_send_code(100)
        else:
            self._indicator_send_code(150)

    @Pyro4.expose
    def indicator_init(self, uri):
        try:
            self._indicator_pyro = Pyro4.Proxy(str(uri))
            self.reload_configurations(self._user)
        except Exception:
            print_warning("Failed initialization")
            print(format_exc())
            self._indicator_pyro = False

    @Pyro4.expose
    def indicator_kill(self):
        self._indicator_pyro = False
Example #2
0
class BlockTesting(Gtk.Window):

    def __init__(self):

        self._paths = Paths()

        """
            Glade
        """
        builder = Gtk.Builder()
        builder.add_from_file(self._paths._block_testing_glade_file)
        builder.connect_signals(self)

        glade_object_names = (
            'window_block_testing',
                'combobox_block_modes',
                'colorbutton_1_block',
                'colorbutton_2_block',
                'config_box',
                'textbuffer_device_info',
                'combobox_default_blocks',
                'textbuffer_block_testing',
                'entry_block_testing',
                'entry_id_vendor',
                'entry_id_product',
                'togglebutton_find_device',
                'box_block_testing',
                'spinbutton_block_speed',
                'viewport_common_block',
                'button_update_common_blocks',
                'button_block_make_test',
                'checkbutton_auto_turn_off',
                'checkbutton_hex_format_when_finding',
        )


        # load the glade objects
        for glade_object in glade_object_names:
            setattr(self, glade_object, builder.get_object(glade_object))

        # get the computer info
        computer_device_info = get_alienware_device_info()
        
        # Fill the computer data
        self.textbuffer_device_info.set_text(computer_device_info)

        # Fill the idProduct and idVendor entries if possible
        if 'idVendor' in computer_device_info and 'idProduct' in computer_device_info:
            for line in computer_device_info.split('\n'):
                if 'idVendor' in line:
                    self.entry_id_vendor.set_text(line.split()[1])
                elif 'idProduct' in line:
                    self.entry_id_product.set_text(line.split()[1])
        
        # Display the window
        self.window_block_testing.show_all()

    def on_entry_block_testing_changed(self, entry, data=None):
        text = entry.get_text()
        try:
            value = int(text)

            if value < 0:
                self.button_block_make_test.set_sensitive(False)
            else:
                self.button_block_make_test.set_sensitive(True)

        except:
            self.button_block_make_test.set_sensitive(False)

    def on_togglebutton_find_device_clicked(self, button, data=None):

        # try to load the driver
        if self.checkbutton_hex_format_when_finding.get_active():
            vendor = int(self.entry_id_vendor.get_text(), 16)
            product = int(self.entry_id_product.get_text(), 16)
        else:
            vendor = int(self.entry_id_vendor.get_text())
            product = int(self.entry_id_product.get_text())

        self._testing_driver = Driver()
        self._testing_driver.load_device(id_vendor=vendor, id_product=product, empty_computer=True)

        # try to load the controller
        if self._testing_driver.has_device():
            
            self._testing_controller = Controller(self._testing_driver)
            
            self._computer = self._testing_driver.computer
            
            self._COMPUTER_BLOCKS_TO_SAVE = (#(True, self._computer.BLOCK_LOAD_ON_BOOT),
                                                #(True, self._computer.BLOCK_STANDBY),
                                                #(True, self._computer.BLOCK_AC_POWER),
                                                #(#True, self._computer.BLOCK_CHARGING),
                                                #(True, self._computer.BLOCK_BATT_SLEEPING),
                                                #(True, self._computer.BLOCK_BAT_POWER),
                                                #(True, self._computer.BLOCK_BATT_CRITICAL),
                                                (False, self._computer.BLOCK_LOAD_ON_BOOT),)
            
            # Add the general computer variables
            for attr_name, attr_value in sorted(vars(self._computer).items()):
                if not attr_name.startswith("_") and isinstance(attr_value, int):
                    
                    widget_box = Gtk.Box()
                    
                    widget_label = Gtk.Label(attr_name)
                    
                    widget_entry = Gtk.Entry()
                    widget_entry.set_text(str(attr_value))
                    widget_entry.connect("changed", self.on_dynamic_entry_general_properties_changed, attr_name)
                    
                    
                    widget_box.pack_start(widget_label, expand=False, fill=True, padding=5)
                    widget_box.pack_start(widget_entry, expand=False, fill=False, padding=5)
                    
                    self.config_box.pack_start(widget_box, expand=False, fill=False, padding=1)


            self.config_box.show_all()


            # activate the window
            
            self.box_block_testing.set_sensitive(True)
            self.entry_id_vendor.set_sensitive(False)
            self.entry_id_product.set_sensitive(False)
            gtk_append_text_to_buffer(self.textbuffer_block_testing, TEXT_DEVICE_FOUND.format(vendor,product))

            self.combobox_default_blocks.set_active(0)

        else:
            self.box_block_testing.set_sensitive(False)
            self.togglebutton_find_device.set_active(False)
            self.entry_id_vendor.set_sensitive(True)
            self.entry_id_product.set_sensitive(True)
            gtk_append_text_to_buffer(self.textbuffer_block_testing,TEXT_DEVICE_NOT_FOUND.format(vendor,product))

    def on_button_block_make_test_clicked(self, button, data=None):
        
        if self.checkbutton_auto_turn_off.get_active():
            self.on_button_block_testing_lights_off_clicked(button)
            
        try:
            zone_left_color = self.colorbutton_1_block.get_color()
            zone_left_color = rgb_to_hex([zone_left_color.red/65535.0, 
                                          zone_left_color.green/65535.0, 
                                          zone_left_color.blue/65535.0])

            zone_right_color = self.colorbutton_2_block.get_color()
            zone_right_color = rgb_to_hex([zone_right_color.red/65535.0, 
                                           zone_right_color.green/65535.0, 
                                           zone_right_color.blue/65535.0])

            zone_block = int(self.entry_block_testing.get_text())
            speed = self.spinbutton_block_speed.get_value_as_int()

            index = self.combobox_block_modes.get_active()
            model = self.combobox_block_modes.get_model()
            zone_mode = model[index][0]
            zone_mode = zone_mode.lower()

            # Log the test
            #
            gtk_append_text_to_buffer(self.textbuffer_block_testing, TEXT_BLOCK_TEST.format(zone_block,
                                                                                            zone_mode,
                                                                                            speed,
                                                                                            zone_left_color,
                                                                                            zone_right_color))

            #   Test
            #
            self._testing_controller.erase_config()
            
            for save, block in self._COMPUTER_BLOCKS_TO_SAVE:
                    
                self._testing_controller.add_block_line(save=save, block=block)
                self._testing_controller.add_reset_line(self._computer.RESET_ALL_LIGHTS_ON)
                self._testing_controller.add_speed_line(speed)
                self._testing_controller.add_color_line(zone_block, zone_mode, zone_left_color, zone_right_color)
                self._testing_controller.end_colors_line()
                self._testing_controller.end_block_line()
                
            self._testing_controller.apply_config()
     
 
        except Exception:
            gtk_append_text_to_buffer(self.textbuffer_block_testing, '\n' + format_exc() + '\n')

    def on_button_block_testing_lights_off_clicked(self, button, data=None):
        try:

            self._testing_controller.erase_config()
            
            for save, block in self._COMPUTER_BLOCKS_TO_SAVE:
                self._testing_controller.add_block_line(save, block)
                self._testing_controller.add_reset_line(self._computer.RESET_ALL_LIGHTS_OFF)
                
            self._testing_controller.apply_config()

            gtk_append_text_to_buffer(self.textbuffer_block_testing, '\n' + TEXT_BLOCK_LIGHTS_OFF + '\n')
            
        except Exception:
            gtk_append_text_to_buffer(self.textbuffer_block_testing, '\n' + format_exc())

    def on_checkbutton_protect_common_blocks_clicked(self, checkbutton, data=None):
        if checkbutton.get_active():
            self.viewport_common_block.set_sensitive(False)
        else:
            self.viewport_common_block.set_sensitive(True)

    def on_combobox_default_blocks_changed(self, combobox, data=None):
        index = combobox.get_active()
        model = combobox.get_model()
        value = model[index][0]

        if value == -1:
            self.entry_block_testing.set_sensitive(True)
        else:
            self.entry_block_testing.set_sensitive(False)
            self.entry_block_testing.set_text(str(value))

    def on_dynamic_entry_general_properties_changed(self, entry, variable_name):
        
        try:
            entry_value = int(entry.get_text())
        except:
            gtk_append_text_to_buffer(self.textbuffer_block_testing, "\n {} must be an integer.".format(variable_name, entry_value))
            return
            
        setattr(self._testing_driver.computer, variable_name, entry_value)
        gtk_append_text_to_buffer(self.textbuffer_block_testing, "\n {} = {}".format(variable_name, entry_value))
        

    

    def on_window_block_testing_destroy(self, data=None):
        Gtk.main_quit()