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

Should we provide composite classes for more devices? #522

Open
bennuttall opened this issue Jan 9, 2017 · 7 comments
Open

Should we provide composite classes for more devices? #522

bennuttall opened this issue Jan 9, 2017 · 7 comments
Projects

Comments

@bennuttall
Copy link
Member

bennuttall commented Jan 9, 2017

We have LEDBoard and ButtonBoard. But what about MotionSensorBoard? It sounds silly, but I just created an example where I wanted an LED for each Motion Sensor, and I can either create a LEDBoard and a list of MotionSensors (inconsistent):

from gpiozero import LEDBoard, MotionSensor

leds = LEDBoard(2, 3, 4)
sensors = [MotionSensor(pin) for pin in (5, 6, 7)]

or I can just use lists for consistency (not making use of LEDBoard):

from gpiozero import LED, MotionSensor

leds = [LED(pin) for pin in (2, 3, 4)]
sensors = [MotionSensor(pin) for pin in (5, 6, 7)]

Would it be worth creating more composite devices for single devices like this? When would it be worth it / not worth it? LightSensor? Energenie? MCP3008? I can imagine uses for them all. What's special about LED and Button?

@bennuttall
Copy link
Member Author

Related/unrelated: I guess "board" is really the wrong word for this anyway... LEDBoard was intended for commonality between add-on boards like pi-liter, but used more generally for a collection of LEDs.

@lurch
Copy link
Contributor

lurch commented Jan 22, 2017

CompositeDevices are actually really easy to create, so if the CompositeDevice / CompositeOutputDevice were better documented, it'd be trivial to create them 'on the fly' in user code, without any need to bloat the GpioZero API ;-)

@bennuttall bennuttall added this to Triage in Triage Feb 8, 2019
@bennuttall bennuttall moved this from Triage to Questions in Triage Feb 9, 2019
@bennuttall bennuttall moved this from Questions to Pending suggestions in Triage Feb 9, 2019
@bennuttall
Copy link
Member Author

@lurch I've Been thinking more about composite devices today. Looking at the ButtonBoard implementation, it:

  • extends HoldMixin which extends EventsMixin giving it when_activated etc.
  • takes an arbitrary number of pins
  • adds when_changed and fire_events

the value property is simply an n-tuple as per CompositeDevice.

However, as I suggested in #628, I see scenarios where you want to have a single value for the device.

Imagine a composite motion sensor where the value was the average value of the sensors:

class CompositeMotionSensor(CompositeDevice):
    def __init__(self, *pins):
        sensors = (MotionSensor(pin) for pin in pins)
        super(CompositeMotionSensor, self).__init__(*sensors)

    @property
    def value(self): 
        return sum(d.value for d in self) / len(self)

>>> pirs = CompositeMotionSensor(4, 5)
>>> pirs.value
0.0  # both inactive
>>> pirs.value
0.5  # one active
>>> pirs.value
1.0  # both active

Rather than the value (0, 1) telling you which one is active, you get 0.5 telling you one of them is (half of them are) active.

Also you can pass this value into, say, an LEDBarGraph:

graph.source = pirs

It occurs to me that the "2 buttons AND gate LED" recipe I refer to a lot could be solved with composite device too:

class AndGate(CompositeDevice):
    def __init__(self, pin1, pin2):
        super(AndGate, self).__init__(Button(pin1), Button(pin2))

    @property
    def value(self): 
        return all(btn.value for btn in self)

>>> led = LED(2)
>>> and_gate = AndGate(3, 4)
>>> led.source = and_gate

As an alternative to using the all_values source tool.

Just putting some thoughts down. Need to revisit later.

@lurch
Copy link
Contributor

lurch commented Mar 25, 2019

Imagine a composite motion sensor where the value was the average value of the sensors

Just out of curiosity, could you provide a practical example of where that'd be useful?

@bennuttall
Copy link
Member Author

If you had a number of motion sensors and wanted and an identical number of LEDs you could (currently) pair each sensor with an LED to indicate motion per sensor.

If you had a number of motion sensors and, say, one buzzer, and you wanted the buzzer to go off if any of the sensors were triggered, you could do this with multiple sensors with the same when_motion event, but you'd have to use a source tool to convert it if you. Maybe that's ok. I'm thinking aloud. But it doesn't give you an event threshold, so there's that too.

Also see #760 (comment)

@karwenzman

This comment has been minimized.

@lurch

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Triage
  
Pending suggestions
Development

No branches or pull requests

3 participants