Completed
Push — master ( 0bc61b...16fc24 )
by Thomas
8s
created

doorpi.keyboard.GPIO.set_output()   B

Complexity

Conditions 5

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 5
dl 0
loc 19
rs 8.5454
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
import logging
5
logger = logging.getLogger(__name__)
6
logger.debug("%s loaded", __name__)
7
8
import RPi.GPIO as RPiGPIO # basic for GPIO control
9
from doorpi.keyboard.AbstractBaseClass import KeyboardAbstractBaseClass, HIGH_LEVEL, LOW_LEVEL
10
import doorpi
11
12
13
def get(**kwargs): return GPIO(**kwargs)
14
15
16
class GPIO(KeyboardAbstractBaseClass):
17
    name = 'GPIO Keyboard'
18
19
    def __init__(self, input_pins, output_pins, conf_pre, conf_post, keyboard_name,
0 ignored issues
show
Unused Code introduced by
The argument kwargs seems to be unused.
Loading history...
Unused Code introduced by
The argument args seems to be unused.
Loading history...
20
                 bouncetime=200, polarity=0, pressed_on_key_down=True, *args, **kwargs):
21
        logger.debug("__init__(input_pins = %s, output_pins = %s, bouncetime = %s, polarity = %s)",
22
                     input_pins, output_pins, bouncetime, polarity)
23
        self.keyboard_name = keyboard_name
24
        self._polarity = polarity
25
        self._InputPins = map(int, input_pins)
26
        self._OutputPins = map(int, output_pins)
27
        self._pressed_on_key_down = pressed_on_key_down
28
29
        RPiGPIO.setwarnings(False)
30
31
        section_name = conf_pre+'keyboard'+conf_post
32
        if doorpi.DoorPi().config.get(section_name, 'mode', "BOARD").upper() == "BOARD":
33
            RPiGPIO.setmode(RPiGPIO.BOARD)
34
        else:
35
            RPiGPIO.setmode(RPiGPIO.BCM)
36
37
        # issue 134
38
        pull_up_down = doorpi.DoorPi().config.get(section_name, 'pull_up_down', "PUD_OFF").upper()
39
        if pull_up_down == "PUD_DOWN":
40
            pull_up_down = RPiGPIO.PUD_DOWN
41
        elif pull_up_down == "PUD_UP":
42
            pull_up_down = RPiGPIO.PUD_UP
43
        else:
44
            pull_up_down = RPiGPIO.PUD_OFF
45
46
        # issue #133
47
        try:
48
            RPiGPIO.setup(self._InputPins, RPiGPIO.IN, pull_up_down=pull_up_down)
49
        except TypeError:
50
            logger.warning('you use an old version of GPIO library - fallback to single-register of input pins')
51
            for input_pin in self._InputPins:
52
                RPiGPIO.setup(input_pin, RPiGPIO.IN, pull_up_down=pull_up_down)
53
54
        for input_pin in self._InputPins:
55
            RPiGPIO.add_event_detect(
56
                input_pin,
57
                RPiGPIO.BOTH,
58
                callback=self.event_detect,
59
                bouncetime=int(bouncetime)
60
            )
61
            self._register_EVENTS_for_pin(input_pin, __name__)
62
63
        # issue #133
64
        try:
65
            RPiGPIO.setup(self._OutputPins, RPiGPIO.OUT)
66
        except TypeError:
67
            logger.warning('you use an old version of GPIO library - fallback to single-register of input pins')
68
            for output_pin in self._OutputPins:
69
                RPiGPIO.setup(output_pin, RPiGPIO.OUT)
70
71
        # use set_output to register status @ dict self._OutputStatus
72
        for output_pin in self._OutputPins:
73
            self.set_output(output_pin, 0, False)
74
75
        self.register_destroy_action()
76
77
    def destroy(self):
78
        if self.is_destroyed:
79
            return
80
81
        logger.debug("destroy")
82
        # shutdown all output-pins
83
        for output_pin in self._OutputPins:
84
            self.set_output(output_pin, 0, False)
85
        RPiGPIO.cleanup()
86
        doorpi.DoorPi().event_handler.unregister_source(__name__, True)
87
        self.__destroyed = True
88
89
    def event_detect(self, pin):
90
        if self.status_input(pin):
91
            self._fire_OnKeyDown(pin, __name__)
92
            if self._pressed_on_key_down:  # issue 134
93
                self._fire_OnKeyPressed(pin, __name__)
94
        else:
95
            self._fire_OnKeyUp(pin, __name__)
96
            if not self._pressed_on_key_down:  # issue 134
97
                self._fire_OnKeyPressed(pin, __name__)
98
99
    def status_input(self, pin):
100
        if self._polarity is 0:
101
            return str(RPiGPIO.input(int(pin))).lower() in HIGH_LEVEL
102
        else:
103
            return str(RPiGPIO.input(int(pin))).lower() in LOW_LEVEL
104
105
    def set_output(self, pin, value, log_output=True):
106
        parsed_pin = doorpi.DoorPi().parse_string("!"+str(pin)+"!")
107
        if parsed_pin != "!"+str(pin)+"!":
108
            pin = parsed_pin
109
110
        pin = int(pin)
111
        value = str(value).lower() in HIGH_LEVEL
112
        if self._polarity is 1:
113
            value = not value
114
        log_output = str(log_output).lower() in HIGH_LEVEL
115
116
        if pin not in self._OutputPins:
117
            return False
118
        if log_output:
119
            logger.debug("out(pin = %s, value = %s, log_output = %s)", pin, value, log_output)
120
121
        RPiGPIO.output(pin, value)
122
        self._OutputStatus[pin] = value
123
        return True
124