Example #1
0
    def clear_hw_rule(self, switch: Switch):
        """Clear all rules for switch and this driver.

        Args:
            switch: Switch to clear on this driver.
        """
        self.platform.clear_hw_rule(switch.get_configured_switch(), self.get_configured_driver())
Example #2
0
    def is_state(self, switch: Switch, state, ms=0.0):
        """Check if switch is in state.

        Query whether a switch is in a given state and (optionally)
        whether it has been in that state for the specified number of ms.

        Args:
            switch: Switch object to check.
            state: Bool of the state to check. True is active and False is
                inactive.
            ms: Milliseconds that the switch has been in that state. If this
                is non-zero, then this method will only return True if the
                switch has been in that state for at least the number of ms
                specified.

        Returns: True if the switch_name has been in the state for the given
            number of ms. If ms is not specified, returns True if the switch
            is in the state regardless of how long it's been in that state.
        """
        if not self._initialised:
            raise AssertionError(
                "Cannot read switch state before init_phase_3")
        if not ms:
            ms = 0.0

        if ms:
            return switch.state == state and ms <= switch.get_ms_since_last_change(
            )

        return switch.state == state
Example #3
0
    def set_pulse_on_hit_and_enable_and_release_and_disable_rule(self, enable_switch: Switch, disable_switch: Switch):
        """Add pulse on hit and enable and release and disable rule to driver.

        Pulse and then enable driver. Cancel pulse and enable when switch is released or a disable switch is hit.

        Args:
            enable_switch: Switch which triggers the rule.
            disable_switch: Switch which disables the rule.
        """
        self._check_platform(enable_switch)
        self._check_platform(disable_switch)

        self.platform.set_pulse_on_hit_and_enable_and_release_and_disable_rule(
            enable_switch.get_configured_switch(),
            disable_switch.get_configured_switch(),
            self.get_configured_driver()
        )
Example #4
0
    def set_pulse_on_hit_rule(self, enable_switch: Switch):
        """Add pulse on hit rule to driver.

        Alway do the full pulse. Even when the switch is released.

        Args:
            enable_switch: Switch which triggers the rule.
        """
        self._check_platform(enable_switch)

        self.platform.set_pulse_on_hit_rule(enable_switch.get_configured_switch(), self.get_configured_driver())
Example #5
0
    def set_pulse_on_hit_and_enable_and_release_rule(self, enable_switch: Switch):
        """Add pulse on hit and enable and relase rule to driver.

        Pulse and enable a driver. Cancel pulse and enable if switch is released.

        Args:
            enable_switch: Switch which triggers the rule.
        """
        self._check_platform(enable_switch)

        self.platform.set_pulse_on_hit_and_enable_and_release_rule(enable_switch.get_configured_switch(),
                                                                   self.get_configured_driver())
Example #6
0
    def process_switch_obj(self, obj: Switch, state, logical):
        """Process a new switch state change for a switch by name.

        Args:
            obj: The switch object.
            state: Boolean or int of state of the switch you're processing,
                True/1 is active, False/0 is inactive.
            logical: Boolean which specifies whether the 'state' argument
                represents the "physical" or "logical" state of the switch. If
                True, a 1 means this switch is active and a 0 means it's
                inactive, regardless of the NC/NO configuration of the switch.
                If False, then the state parameter passed will be inverted if
                the switch is configured to be an 'NC' type. Typically the
                hardware will send switch states in their raw (logical=False)
                states, but other interfaces like the keyboard and OSC will use
                logical=True.

        This is the method that is called by the platform driver whenever a
        switch changes state. It's also used by the "other" modules that
        activate switches, including the keyboard and OSC interfaces.

        State 0 means the switch changed from active to inactive, and 1 means
        it changed from inactive to active. (The hardware & platform code
        handles NC versus NO switches and translates them to 'active' versus
        'inactive'.)
        """
        # We need int, but this lets it come in as boolean also
        if state:
            state = 1
        else:
            state = 0

        # flip the logical & physical states for NC switches
        hw_state = state

        if obj.invert:
            if logical:  # NC + logical means hw_state is opposite of state
                hw_state ^= 1
            else:
                # NC w/o logical (i.e. hardware state was sent) means logical
                # state is the opposite
                state ^= 1

        # Update the hardware state since we always want this to match real hw
        obj.hw_state = hw_state

        # if the switch is active, check to see if it's recycle_time has passed
        if state and not self._check_recycle_time(obj, state):
            self.machine.clock.schedule_once(
                partial(self._recycle_passed, obj, state, logical,
                        obj.hw_state),
                timeout=obj.recycle_clear_time - self.machine.clock.get_time())
            return

        obj.state = state  # update the switch device

        if state:
            # update the switch's next recycle clear time
            obj.recycle_clear_time = (self.machine.clock.get_time() +
                                      obj.recycle_secs)

        # if the switch is already in this state, then abort
        if self.switches[obj.name].state == state:

            if not obj.recycle_secs:
                self.warning_log(
                    "Received duplicate switch state, which means this switch "
                    "had some non-debounced state changes. This could be "
                    "nothing, but if it happens a lot it could indicate noise "
                    "or interference on the line. Switch: %s", obj.name)
            return

        if state:
            self.info_log("<<<<<<< '{}' active >>>>>>>".format(obj.name))
        else:
            self.info_log("<<<<<<< '{}' inactive >>>>>>>".format(obj.name))

        # Update the switch controller's logical state for this switch
        self.set_state(obj.name, state)

        self._call_handlers(obj.name, state)

        self._cancel_timed_handlers(obj.name, state)

        for monitor in self.monitors:
            monitor(
                MonitoredSwitchChange(name=obj.name,
                                      label=obj.label,
                                      platform=obj.platform,
                                      num=obj.hw_switch.number,
                                      state=state))
Example #7
0
    def process_switch_obj(self, obj: Switch, state, logical):
        """Process a new switch state change for a switch by name.

        Args:
            obj: The switch object.
            state: Boolean or int of state of the switch you're processing,
                True/1 is active, False/0 is inactive.
            logical: Boolean which specifies whether the 'state' argument
                represents the "physical" or "logical" state of the switch. If
                True, a 1 means this switch is active and a 0 means it's
                inactive, regardless of the NC/NO configuration of the switch.
                If False, then the state parameter passed will be inverted if
                the switch is configured to be an 'NC' type. Typically the
                hardware will send switch states in their raw (logical=False)
                states, but other interfaces like the keyboard and OSC will use
                logical=True.

        This is the method that is called by the platform driver whenever a
        switch changes state. It's also used by the "other" modules that
        activate switches, including the keyboard and OSC interfaces.

        State 0 means the switch changed from active to inactive, and 1 means
        it changed from inactive to active. (The hardware & platform code
        handles NC versus NO switches and translates them to 'active' versus
        'inactive'.)
        """
        # We need int, but this lets it come in as boolean also
        if state:
            state = 1
        else:
            state = 0

        # flip the logical & physical states for NC switches
        hw_state = state

        if obj.invert:
            if logical:  # NC + logical means hw_state is opposite of state
                hw_state ^= 1
            else:
                # NC w/o logical (i.e. hardware state was sent) means logical
                # state is the opposite
                state ^= 1

        # if the switch is already in this state, then abort
        if obj.state == state:
            if not self.machine.options['production']:
                self.warning_log(
                    "Received duplicate switch state %s for switch %s from the platform interface.",
                    state,
                    obj.name,
                    error_no=1)
            return

        # Update the hardware state since we always want this to match real hw
        obj.hw_state = hw_state
        # update the switch device
        obj.state = state
        obj.last_change = self.machine.clock.get_time()

        if state:
            self.info_log("<<<<<<< '%s' active >>>>>>>", obj.name)
        else:
            self.info_log("<<<<<<< '%s' inactive >>>>>>>", obj.name)

        self._call_handlers(obj, state)

        self._cancel_timed_handlers(obj.name, state)

        for monitor in self.monitors:
            monitor(
                MonitoredSwitchChange(name=obj.name,
                                      label=obj.label,
                                      platform=obj.platform,
                                      num=obj.hw_switch.number,
                                      state=state))