Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parts Swich (or PushButton?) without polling task #107

Open
s-celles opened this issue Jan 20, 2016 · 6 comments
Open

Parts Swich (or PushButton?) without polling task #107

s-celles opened this issue Jan 20, 2016 · 6 comments

Comments

@s-celles
Copy link
Contributor

Hello,

In a project, we are using push button and Pingo.

Unfortunately Swich class only provides a class with a polling mechanism.

What is your opinion about adding to Switch class some methods that could be used in a non threading context ?

We could have for example attributes such as pressed or released which would return True or False.

I also noticed that it's odd to have such a class named Switch in a file named button.py

CC @lwalter86

I also wonder how this could behave if passed pin at init could come from a GhostBoard.

For unit test, it will be very convenient to add also methods to simulate that a button is being pressed or released.

but.press()
do_something()
but.release()

Kind regards

@s-celles
Copy link
Contributor Author

I noticed in https://github.com/pingo-io/pingo-py/blob/master/pingo/parts/test/test_switch.py

class FakeDigitalPin(object):
    def __init__(self):
        self.mode = 'IN'
        self.state = 'LOW'

Maybe this class shouldn't be there (in a test) but should be merged with DigitalPin
https://github.com/pingo-io/pingo-py/blob/master/pingo/board.py

@s-celles
Copy link
Contributor Author

When but is initialized with a pin (a DigitalPin) from a GhostBoard, press and release method should change internal state of this pin but when but is initialized with a pin (a DigitalPin) from a "real" board it should raise an exception.

@s-celles
Copy link
Contributor Author

Here is a possible implementation

import pingo
import time

class PushButton(object):
    """A single Push button"""
    def __init__(self, pin, pressed_state=pingo.LOW):
        """Set pressed_state to pingo.LOW when button is pressed
        :param pin: A instance of DigitalPin
        :param pressed_state: use pingo.LOW for pull-up, pingo.HIGH for pull-down
        """
        pin.mode = pingo.IN
        self.pin = pin
        self._pressed_state = pressed_state
        d = {
            pingo.LOW: pingo.HIGH,
            pingo.HIGH: pingo.LOW,
        }
        self._released_state = d[pressed_state]

    def _test_pin_instance(self):
        if not isinstance(self.pin.board, pingo.ghost.ghost.GhostBoard):
            raise(NotImplementedError('pin from a GhostBoard is required'))
        elif not isinstance(self.pin, pingo.board.DigitalPin):
            raise(NotImplementedError('DigitalPin is required'))                

    def press(self):
        self._test_pin_instance()
        board = self.pin.board
        pin = self.pin
        board._set_pin_state(pin, self._pressed_state)

    def release(self):
        self._test_pin_instance()
        board = self.pin.board
        pin = self.pin
        board._set_pin_state(pin, self._released_state)

    @property
    def pressed(self):
        return True if self.pin.state == self._pressed_state else False

    @property
    def released(self):
        return True if self.pin.state == self._released_state else False

@s-celles
Copy link
Contributor Author

@Vido
Copy link
Contributor

Vido commented Feb 19, 2016

Hallo @scls19fr ,

I guess I don't get it. Do you need a 'mock-up' Button-object for testing?

Let me list the features you proposed:

  • methods press(self) and release(self), properties pressed(self) and released(self)
  • This class will be enable to switch on and off a DigitalPin

So it would behave like a virtual Button, which can set a state via software.

There is something that's not clear:
On the example you posted, pin.mode is set to pingo.IN. In fact, you should not (or perhaps, can not) change a state when pingo.IN is set (when working with a real hardware).

Given you are using GhostBoard, I believe what you are looking for is a way to simulate a "input device". Am I right?

The Question: What is the main purpose of this feature?
(testing, using GhostBoard or Something else?)


About FakeDigitalPin, it is used for testing. It is not exposed on the API.

@s-celles
Copy link
Contributor Author

The goal of such a virtual part is to run unit tests for a app with a virtual push button.
I use it in https://github.com/RaspberryPi-Samples/py-my-key see https://github.com/RaspberryPi-Samples/py-my-key/blob/master/tests/test_py_my_key.py

you can see

my_app.hw.black_btn.press()
...
my_app.hw.black_btn.release()

and in https://github.com/RaspberryPi-Samples/py-my-key/blob/master/py_my_key/cli_rpi_access.py#L97

you can also see

if self.hw.black_btn.pressed and self.hw.red_btn.released:
    ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants