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 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)
Beispiel #3
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 #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("<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 #5
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 #6
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 #7
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,
            )
        if not rf_parser_info and rf_json:
            rf_parser_info = KeyplusParserInfo(
                "<KeyplusLayout(rf)>",
                rf_json,
            )

        self.kc_mapper.attach_parser(parser_info)

        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["report_mode"] = parser_info.try_get(
            field="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)

        parser_info.exit()

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

            layout = self.get_layout_by_name(dev.layout)
            if layout == None:
                raise KeyplusParseError(
                    "Device '{}' references non-existent layout '{}'".format(
                        dev.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)
            rf_parser_info.exit()

        if DEBUG.parsing_extra:
            for device in self._devices.values():
                print("LayoutDevice({})".format(device.name))
                print(device.to_json())
                print()
            for layout in self._layouts.values():
                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 #8
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 #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])
            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()