Beispiel #1
0
    def parse_json(self, keycode_name, json_obj=None, parser_info=None):

        print_warnings = False

        if parser_info == None:
            assert (json_obj != None)
            print_warnings = True
            parser_info = KeyplusParserInfo("<EKCHoldKeycode Dict>",
                                            {keycode_name: json_obj})
        parser_info.enter(keycode_name)

        # Get the tap key field
        self.keycode = parser_info.try_get('keycode', field_type=str)
        assert_equal(self.keycode, 'kc_hold')

        # Get the hold key field
        self.hold_key = parser_info.try_get('hold_key', type=str)

        # Get the tap key field
        self.tap_key = parser_info.try_get('tap_key', type=str)

        # Get the delay key field
        self.delay = try_get('delay',
                             field_type=int,
                             default=EKCHoldKey.DEFAULT_DELAY)

        # Finish parsing `device_name`
        parser_info.exit()

        # If this is debug code, print the warnings
        if print_warnings:
            for warn in parser_info.warnings:
                print(warn, file=sys.stderr)
Beispiel #2
0
    def _from_file_common(self,
                          layout_file=None,
                          rf_file=None,
                          print_warnings=False,
                          load_method=yaml.load,
                          warnings=None):
        basename = os.path.basename(layout_file)
        if layout_file:
            with open(layout_file) as f:
                layout_json_obj = load_method(f.read())
            parser_info = KeyplusParserInfo(
                "<{}>".format(basename),
                layout_json_obj,
                print_warnings=print_warnings,
            )
        else:
            parser_info = None

        if rf_file:
            rf_basename = os.path.basename(rf_file)
            with open(rf_file) as f:
                rf_json_obj = load_method(f.read())
            rf_parser_info = KeyplusParserInfo(
                "<{}>".format(rf_basename),
                rf_json_obj,
                print_warnings=print_warnings,
            )
        else:
            rf_parser_info = None

        result = self.parse_json(
            parser_info=parser_info,
            rf_parser_info=rf_parser_info,
        )

        if warnings != None:
            # print(warnings, parser_info.warnings, rf_parser_info.warnings)
            if parser_info != None:
                warnings.extend(parser_info.warnings)
            if rf_parser_info != None:
                warnings.extend(rf_parser_info.warnings)

        return result
Beispiel #3
0
    def parse_json(self, json_obj=None, parser_info=None):

        print_warnings = False

        if parser_info == None:
            assert (json_obj != None)
            print_warnings = True
            parser_info = KeyplusParserInfo("<keycodes Dict>",
                                            {'keycodes': json_obj})

        parser_info.enter('keycodes')
        for kc_name in parser_info.iter_fields():
            self.add_keycode(kc_name=kc_name,
                             json_obj=parser_info.try_get(kc_name),
                             parser_info=parser_info)
        parser_info.exit()
Beispiel #4
0
    def parse_json(self, kc_name, json_obj=None, parser_info=None):

        print_warnings = False

        if parser_info == None:
            assert (json_obj != None)
            print_warnings = True
            parser_info = KeyplusParserInfo("<EKCMacroKey Dict>",
                                            {kc_name: json_obj})

        self._dirty = True
        self._kc_name = kc_name

        parser_info.enter(kc_name)

        # Get the tap key field
        self.keycode = parser_info.try_get('keycode', field_type=str)
        assert_equal(self.keycode, self.KEYCODE_TYPE)

        # Get movement thresholds for gestures
        self._commands_press = parser_info.try_get('commands',
                                                   field_type=list,
                                                   default=[])
        if self._commands_press == None:
            self._commands_press = []

        # Get movement thresholds for gestures
        self._commands_release = parser_info.try_get('commands_release',
                                                     field_type=list,
                                                     default=[])
        if self._commands_release == None:
            self._commands_release = []

        # Finish parsing `device_name`
        parser_info.exit()

        # If this is debug code, print the warnings
        if print_warnings:
            for warn in parser_info.warnings:
                print(warn, file=sys.stderr)
Beispiel #5
0
    def parse_json(self, layout_json=None, rf_json=None, parser_info=None, rf_parser_info=None):
        if parser_info == None:
            assert(layout_json != None)
            parser_info = KeyplusParserInfo(
                "<KeyplusLayout(layout)>",
                layout_json,
                print_warnings = True
            )
        if not rf_parser_info and rf_json:
            rf_parser_info = KeyplusParserInfo(
                "<KeyplusLayout(rf)>",
                rf_json,
                print_warnings = True
            )

        self.settings["name"] = parser_info.try_get(
            field = "name",
            field_type = str,
            default = "Keyplus Layout",
        )

        self.settings["version"] = parser_info.try_get(
            field = "version",
            field_type = [str, int],
            optional = True
        )

        self.settings["default_report_mode"] = parser_info.try_get(
            field = "default_report_mode",
            field_type = str,
            default = KEYBOARD_REPORT_MODE_AUTO,
            remap_table = REPORT_MODE_MAP,
        )

        self._parse_devices(parser_info)
        self._parse_layouts(parser_info)

        if rf_parser_info:
            self.rf_settings = LayoutRFSettings()
            self.rf_settings.parse_json(rf_json, rf_parser_info)

        if DEBUG.parsing_extra:
            for device in six.itervalues(self._devices):
                print("LayoutDevice({})".format(device.name))
                print(device.to_json())
                print()
            for layout in six.itervalues(self._layouts):
                print("LayoutKeyboard({}, {})".format(layout.layout_id, layout.name))
                print(layout.to_json())
                print()
            if self.rf_settings and rf_parser_info:
                print("LayoutRFSettings({})".format(rf_parser_info.current_field))
                print(self.rf_settings.to_json())
                print()
Beispiel #6
0
    def parse_json(self, layout_json=None, rf_json=None, parser_info=None, rf_parser_info=None):
        if parser_info == None:
            assert(layout_json != None)
            parser_info = KeyplusParserInfo(
                "<KeyplusLayout(layout)>",
                layout_json,
                print_warnings = True
            )
        if not rf_parser_info and rf_json:
            rf_parser_info = KeyplusParserInfo(
                "<KeyplusLayout(rf)>",
                rf_json,
                print_warnings = True
            )

        self.settings["name"] = parser_info.try_get(
            field = "name",
            field_type = str,
            default = "Keyplus Layout",
        )

        self.settings["version"] = parser_info.try_get(
            field = "version",
            field_type = [str, int],
            optional = True
        )

        self.settings["default_report_mode"] = parser_info.try_get(
            field = "default_report_mode",
            field_type = str,
            default = KEYBOARD_REPORT_MODE_AUTO,
            remap_table = REPORT_MODE_MAP,
        )

        self._parse_devices(parser_info)
        self._parse_keycodes(parser_info)
        self._parse_layouts(parser_info)

        for dev in six.itervalues(self._devices):
            if dev.scan_mode.mode == MATRIX_SCANNER_MODE_NO_MATRIX:
                continue

            layout = self.get_layout_by_name(dev.layout)
            dev_sizes = layout.layer_list[0].device_sizes

            if dev.split_device_num >= len(dev_sizes):
                raise KeyplusParseError(
                    "Layout doesn't have the given split device number. The "
                    "device \"{}\" maps to split device {}, but "
                    "the layout \"{}\" only has {} split devices."
                    .format(
                        dev.name,
                        dev.split_device_num,
                        layout.name,
                        len(dev_sizes),
                    )
                )
            layout_size = dev_sizes[dev.split_device_num]

            if dev.scan_mode.number_mapped_keys != layout_size:
                raise KeyplusParseError(
                    "Layout size doesn't match device matrix_map size. The "
                    "device \"{}\" has a matrix map of length {}, but "
                    "the layout \"{}\" has length {} for split device {}."
                    .format(
                        dev.name,
                        dev.scan_mode.number_mapped_keys,
                        layout.name,
                        layout_size,
                        dev.split_device_num
                    )
                )

        if rf_parser_info:
            self.rf_settings = LayoutRFSettings()
            self.rf_settings.parse_json(rf_json, rf_parser_info)

        if DEBUG.parsing_extra:
            for device in six.itervalues(self._devices):
                print("LayoutDevice({})".format(device.name))
                print(device.to_json())
                print()
            for layout in six.itervalues(self._layouts):
                print("LayoutKeyboard({}, {})".format(layout.layout_id, layout.name))
                print(layout.to_json())
                print()
            if self.rf_settings and rf_parser_info:
                print("LayoutRFSettings({})".format(rf_parser_info.current_field))
                print(self.rf_settings.to_json())
                print()
Beispiel #7
0
    def parse_json(self, device_name, json_obj=None, parser_info=None):
        if parser_info == None:
            assert(json_obj != None)
            parser_info = KeyplusParserInfo(
                "<LayoutDevice>",
                {device_name : json_obj},
                print_warnings = True,
            )

        parser_info.enter(device_name)
        self.name = device_name

        self.device_id = parser_info.try_get(
            "id",
            field_type = int,
            field_range = [0, MAX_NUMBER_DEVICES-1]
        )

        self.scan_mode = ScanMode()
        self.scan_mode.parse_json(parser_info=parser_info)

        if self.scan_mode.mode != keyplus.layout.scan_mode.NO_MATRIX:
            self.layout = parser_info.try_get(
                "layout",
                field_type = [str, int],
            )

            self.split_device_num = parser_info.try_get(
                "layout_offset",
                default = 0,
                field_type = int,
                field_range = [0, MAX_NUMBER_DEVICES-1]
            )


        # TODO: unifying naming of feature_ctrl variables
        # Load any of the feature settings, use defaults if they are not found
        self.feature_ctrl.nrf24_disabled = not parser_info.try_get(
            "wireless_split",
            default = not self.feature_ctrl.nrf24_disabled,
            field_type = bool,
        )
        self.feature_ctrl.unifying_disabled = not parser_info.try_get(
            "wireless_mouse",
            default = not self.feature_ctrl.unifying_disabled,
            field_type = bool,
        )
        self.feature_ctrl.i2c_disabled = not parser_info.try_get(
            "wired_split",
            default = not self.feature_ctrl.i2c_disabled,
            field_type = bool,
        )

        # Finish parsing `device_name`
        parser_info.exit()
Beispiel #8
0
    def parse_json(self, kc_name, json_obj=None, parser_info=None):

        print_warnings = False

        if parser_info == None:
            assert (json_obj != None)
            print_warnings = True
            parser_info = KeyplusParserInfo("<EKCMouseGestureKey Dict>",
                                            {kc_name: json_obj})

        parser_info.enter(kc_name)

        # Get the tap key field
        self.keycode = parser_info.try_get('keycode', field_type=str)
        assert_equal(self.keycode, 'mouse_gesture')

        # Get movement thresholds for gestures
        self.threshold = parser_info.try_get(
            'threshold',
            field_type=int,
            default=EKCMouseGestureKey.GESTURE_THRESHOLD)
        self.threshold_diag = parser_info.try_get(
            'threshold_diag',
            field_type=int,
            default=EKCMouseGestureKey.GESTURE_THRESHOLD_DIAG)
        self.threshold_tap = parser_info.try_get(
            'threshold_tap',
            field_type=int,
            default=EKCMouseGestureKey.GESTURE_THRESHOLD_TAP)

        # Get the keycodes for different directions field
        self.kc_left = parser_info.try_get('left', default='none')
        self.kc_right = parser_info.try_get('right', default='none')
        self.kc_up = parser_info.try_get('up', default='none')
        self.kc_down = parser_info.try_get('down', default='none')

        self.kc_up_left = parser_info.try_get('up_left', default='none')
        self.kc_up_right = parser_info.try_get('up_right', default='none')
        self.kc_down_left = parser_info.try_get('down_left', default='none')
        self.kc_down_right = parser_info.try_get('down_right', default='none')

        self.kc_tap = parser_info.try_get('tap', default='none')

        # Finish parsing `device_name`
        parser_info.exit()

        # If this is debug code, print the warnings
        if print_warnings:
            for warn in parser_info.warnings:
                print(warn, file=sys.stderr)
Beispiel #9
0
    def parse_json(self, json_obj=None, parser_info=None):
        if parser_info == None:
            assert (json_obj != None)
            parser_info = KeyplusParserInfo("<ScanMode>",
                                            {"scan_mode": json_obj},
                                            print_warnings=True)
        parser_info.enter("scan_mode")

        self.mode = parser_info.try_get(
            field="mode",
            field_type=str,
            remap_table=MODE_MAP,
        )

        if self.mode == NO_MATRIX:
            parser_info.exit()
            return
        elif self.mode in [ROW_COL, COL_ROW]:
            self.row_pins = parser_info.try_get("rows", field_type=[list, int])
            self.column_pins = parser_info.try_get("cols",
                                                   field_type=[list, int])
            parser_info.try_get(
                "matrix_map",
                field_type=list,
                remap_function=self.parse_matrix_map,
            )
        elif self.mode in [PIN_GND, PIN_VCC]:
            self.direct_wiring_pins = parser_info.try_get(
                "pins", field_type=[list, int])
        elif self.mode == VIRTUAL:

            def _parse_hex_u16(s):
                try:
                    v = int(s, 16)
                    if 0 < v > 0xffff:
                        raise Exception
                    return v
                except:
                    raise KeyplusParseError("bad VID/PID value")

            self.virtual_device["vid"] = parser_info.try_get(
                field="vid",
                field_type=[str],
                remap_function=_parse_hex_u16,
                default=0)

            self.virtual_device["pid"] = parser_info.try_get(
                field="pid",
                field_type=[str],
                remap_function=_parse_hex_u16,
                default=0)

            self.virtual_device["name"] = parser_info.try_get(
                field="name",
                field_type=[str],
                optional=True,
                ignore_case=False)

            self.virtual_device["serial"] = parser_info.try_get(
                field="serial",
                field_type=[str],
                optional=True,
                ignore_case=False)

            self.virtual_device["stats"] = parser_info.try_get(
                field="stats",
                field_type=[bool],
                default=True,
            )

            self.keys = parser_info.try_get("keys", field_type=[list])
        else:
            raise Exception("Internal error, unexpected value for scan_mode")

        if parser_info.has_field('debounce', field_type=str):
            debounce_profile = parser_info.try_get("debounce", field_type=str)
            self.set_debounce_profile(debounce_profile)
        elif parser_info.has_field('debounce', field_type=dict):

            parser_info.enter('debounce')

            self.set_debounce_profile('default')

            self.debounce_time_press = parser_info.try_get(
                "debounce_time_press",
                default=self.debounce_time_press,
                field_type=int,
                field_range=[0, 255])

            self.debounce_time_release = parser_info.try_get(
                "debounce_time_release",
                default=self.debounce_time_release,
                field_type=int,
                field_range=[0, 255])

            self.trigger_time_press = parser_info.try_get(
                "trigger_time_press",
                default=self.trigger_time_press,
                field_type=int,
                field_range=[0, 255])

            self.trigger_time_release = parser_info.try_get(
                "trigger_time_release",
                default=self.trigger_time_release,
                field_type=int,
                field_range=[0, 255])

            self.parasitic_discharge_delay_idle = parser_info.try_get(
                "parasitic_discharge_delay_idle",
                default=self.parasitic_discharge_delay_idle,
                field_type=[int, float],
                field_range=[0, 48.0])

            self.parasitic_discharge_delay_debouncing = parser_info.try_get(
                "parasitic_discharge_delay_debouncing",
                default=self.parasitic_discharge_delay_debouncing,
                field_type=[int, float],
                field_range=[0, 48.0])

            parser_info.exit()

        parser_info.exit()
Beispiel #10
0
    def parse_json(self, json_obj=None, parser_info=None):
        if parser_info == None:
            assert (json_obj != None)
            parser_info = KeyplusParserInfo("<ScanMode>",
                                            {"scan_mode": json_obj},
                                            print_warnings=True)
        parser_info.enter("scan_mode")

        self.mode = parser_info.try_get(
            field="mode",
            field_type=str,
            remap_table=MODE_MAP,
        )

        if self.mode == NO_MATRIX:
            parser_info.exit()
            return
        elif self.mode in [ROW_COL, COL_ROW]:
            self.row_pins = parser_info.try_get("rows", field_type=[list, int])
            self.column_pins = parser_info.try_get("cols",
                                                   field_type=[list, int])
            self.parse_matrix_map(
                parser_info.try_get("matrix_map", field_type=list))
        elif self.mode in [PIN_GND, PIN_VCC]:
            self.direct_wiring_pins = parser_info.try_get(
                "pins", field_type=[list, int])

        if parser_info.has_field('debounce', field_type=str):
            debounce_profile = parser_info.try_get("debounce", field_type=str)
            self.set_debounce_profile(debounce_profile)
        elif parser_info.has_field('debounce', field_type=dict):

            parser_info.enter('debounce')

            self.set_debounce_profile('default')

            self.debounce_time_press = parser_info.try_get(
                "debounce_time_press",
                default=self.debounce_time_press,
                field_type=int,
                field_range=[0, 255])

            self.debounce_time_release = parser_info.try_get(
                "debounce_time_release",
                default=self.debounce_time_release,
                field_type=int,
                field_range=[0, 255])

            self.trigger_time_press = parser_info.try_get(
                "trigger_time_press",
                default=self.trigger_time_press,
                field_type=int,
                field_range=[0, 255])

            self.trigger_time_release = parser_info.try_get(
                "trigger_time_release",
                default=self.trigger_time_release,
                field_type=int,
                field_range=[0, 255])

            self.parasitic_discharge_delay_idle = parser_info.try_get(
                "parasitic_discharge_delay_idle",
                default=self.parasitic_discharge_delay_idle,
                field_type=[int, float],
                field_range=[0, 48.0])

            self.parasitic_discharge_delay_debouncing = parser_info.try_get(
                "parasitic_discharge_delay_debouncing",
                default=self.parasitic_discharge_delay_debouncing,
                field_type=[int, float],
                field_range=[0, 48.0])

            parser_info.exit()

        parser_info.exit()
Beispiel #11
0
    def parse_json(self, json_obj=None, parser_info=None):
        print_warnings = False

        if parser_info == None:
            assert(json_obj != None)
            print_warnings = True
            parser_info = KeyplusParserInfo(
                "<LayoutRFSettings Dict>",
                {"rf_settings" : json_obj}
            )

        parser_info.enter("rf_settings")

        self.channel = parser_info.try_get(
            "rf_channel",
            field_type = int,
            field_range = [0, MAX_RF_CHANNEL]
        )

        self.encryption_key = parser_info.try_get(
            "aes_encryption_key",
            field_type = str,
            remap_function = string_to_bytearray,
        )

        for field in ['pipe0', 'pipe1']:
            setattr(self, field, parser_info.try_get(
                    field,
                    field_type = str,
                    remap_function = string_to_bytearray,
                )
            )
        for field in ['pipe2', 'pipe3', 'pipe4','pipe5']:
            setattr(self, field, parser_info.try_get(
                    field,
                    field_type = str,
                    remap_function = string_to_bytearray,
                )[0]
            )

        self.data_rate = parser_info.try_get(
            "data_rate",
            field_type = str,
            remap_table = RF_DATA_RATE_MAP
        )

        self.power = parser_info.try_get(
            "transmit_power",
            field_type = str,
            remap_table = RF_POWER_MAP,
        )

        self.auto_retransmit_count = parser_info.try_get(
            "auto_retransmit_count",
            field_type = int,
            field_range = [0, MAX_RF_CHANNEL]
        )

        # Finish parsing `rf_settings`
        parser_info.exit()

        # If this is debug code, print the warnings
        if print_warnings:
            for warn in parser_info.warnings:
                print(warn, file=sys.stderr)