UnknownOutputPin
last analyzed

Complexity

Total Complexity 0

Size/Duplication

Total Lines 1
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
c 0
b 0
f 0
wmc 0
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 importlib
9
10
import doorpi
11
from doorpi.keyboard.AbstractBaseClass import KeyboardAbstractBaseClass
12
13
class KeyboardImportError(ImportError): pass
14
class UnknownOutputPin(Exception): pass
15
16
def load_keyboard():
17
    config_keyboards = doorpi.DoorPi().config.get_keys(section = 'keyboards')
18
    if len(config_keyboards) > 0:
19
        logger.info("using multi-keyboard mode (keyboards: %s)", ', '.join(config_keyboards))
20
        return KeyboardHandler(config_keyboards)
21
    else:
22
        logger.info("using multi-keyboard mode with dummy keyboard")
23
        return KeyboardHandler(['dummy'])
24
25
def load_single_keyboard(keyboard_name):
26
    conf_pre = keyboard_name+'_'
27
    conf_post = ''
28
29
    keyboard_type = doorpi.DoorPi().config.get('keyboards', keyboard_name, 'dummy').lower()
30
    store_if_not_exists = False if keyboard_type == "dummy" else True
31
32
    section_name = conf_pre+'keyboard'+conf_post
33
    input_pins = doorpi.DoorPi().config.get_keys(conf_pre+'InputPins'+conf_post)
34
    output_pins = doorpi.DoorPi().config.get_keys(conf_pre+'OutputPins'+conf_post)
35
    bouncetime = doorpi.DoorPi().config.get_float(section_name, 'bouncetime', 2000,
36
                                                  store_if_not_exists=store_if_not_exists)
37
    polarity = doorpi.DoorPi().config.get_int(section_name, 'polarity', 0,
38
                                              store_if_not_exists=store_if_not_exists)
39
    pressed_on_key_down = doorpi.DoorPi().config.get_bool(section_name, 'pressed_on_keydown',
40
                                                          True, store_if_not_exists=store_if_not_exists)
41
    try:
42
        keyboard = importlib.import_module('doorpi.keyboard.from_'+keyboard_type).get(
43
            input_pins=input_pins,
44
            output_pins=output_pins,
45
            bouncetime=bouncetime,
46
            polarity=polarity,
47
            keyboard_name=keyboard_name,
48
            keyboard_type=keyboard_type,
49
            conf_pre=conf_pre,
50
            conf_post=conf_post,
51
            pressed_on_key_down=pressed_on_key_down
52
        )
53
    except ImportError as exp:
54
        logger.exception('keyboard %s not found @ keyboard.from_%s (msg: %s)', keyboard_name, keyboard_type, exp)
55
        return None
56
57
    return keyboard
58
59
60
class KeyboardHandler(KeyboardAbstractBaseClass):
61
    @property
62
    def name(self):
63
        keyboard_names = []
64
        for Keyboard in self.__keyboards:
65
            keyboard_names.append(Keyboard)
66
        return 'KeyboardHandler (with %s)' % ', '.join(keyboard_names)
67
68
    @property
69
    def input_pins(self):
70
        return_list = []
71
        for Keyboard in self.__keyboards:
72
            for input_pin in self.__keyboards[Keyboard].input_pins:
73
                return_list.append(Keyboard+'.'+str(input_pin))
74
        return return_list
75
76
    @property
77
    def output_pins(self):
78
        return_list = []
79
        for Keyboard in self.__keyboards:
80
            for pin in self.__keyboards[Keyboard].output_pins:
81
                return_list.append(Keyboard+'.'+str(pin))
82
        return return_list
83
84
    @property
85
    def output_status(self):
86
        return_dict = {}
87
        for Keyboard in self.__keyboards:
88
            for pin in self.__keyboards[Keyboard].output_pins:
89
                return_dict[Keyboard+'.'+str(pin)] = self.__keyboards[Keyboard].status_output(pin)
90
        return return_dict
91
92
    @property
93
    def loaded_keyboards(self):
94
        return_dict = {}
95
        for keyboard in self.__keyboards:
96
            return_dict[keyboard] = self.__keyboards[keyboard].keyboard_typ
97
        return return_dict
98
99
    def __init__(self, config_keyboards):
100
        self.__OutputMappingTable = {}
101
        self.__keyboards = {}
102
        for keyboard_name in config_keyboards:
103
            logger.info("trying to add keyboard '%s' to handler", keyboard_name)
104
            self.__keyboards[keyboard_name] = load_single_keyboard(keyboard_name)
105
            if self.__keyboards[keyboard_name] is None:
106
                logger.error("couldn't load keyboard %s", keyboard_name)
107
                del self.__keyboards[keyboard_name]
108
                continue
109
110
            output_pins = doorpi.DoorPi().config.get_keys(keyboard_name+'_OutputPins')
111
            for output_pin in output_pins:
112
                output_pin_name = doorpi.DoorPi().config.get(keyboard_name+'_OutputPins', output_pin)
113
                if output_pin_name in self.__OutputMappingTable:
114
                    logger.warning('overwriting existing name of outputpin "%s" (exists in %s and %s)',
115
                        output_pin_name,
116
                        self.__OutputMappingTable[output_pin_name],
117
                        keyboard_name
118
                    )
119
                self.__OutputMappingTable[output_pin_name] = keyboard_name
120
121
        if len(self.__keyboards) is 0:
122
            logger.error('No Keyboards loaded - load dummy!')
123
            self.__keyboards['dummy'] = load_single_keyboard('dummy')
124
125
    def destroy(self):
126
        try:
127
            for Keyboard in self.__keyboards:
128
                self.__keyboards[Keyboard].destroy()
129
        except: pass
130
131
    def set_output(self, pin, value, log_output = True):
132
        if pin not in self.__OutputMappingTable:
133
            raise UnknownOutputPin('outputpin with name %s is unknown %s' % (pin, self.__OutputMappingTable))
134
        self.__keyboards[self.__OutputMappingTable[pin]].set_output(pin, value, log_output)
135
136
    def status_input(self, pin):
137
        for keyboard in self.__keyboards:
138
            if pin.startswith(keyboard+'.'):
139
                return self.__keyboards[keyboard].status_input(pin[len(keyboard+'.'):])
140
        return None
141
142
    def status_output(self, pin):
143
        for keyboard in self.__keyboards:
144
            if pin.startswith(keyboard+'.'):
145
                return self.__keyboards[keyboard].status_output(pin[len(keyboard+'.'):])
146
        return None
147
148
    __del__ = destroy