diff --git a/apparatinterface.py b/apparatinterface.py index 4ed83ab..909ee32 100644 --- a/apparatinterface.py +++ b/apparatinterface.py @@ -5,149 +5,146 @@ import threading class FeApPinConfiguration(object): - def __init__(self, gpio_numbering, pin_nsa, pin_nsi, pin_gabelschalter, - pin_schauzeichen, pin_wecker_enable, pin_wecker_a, - pin_wecker_b, invert_gs): - if gpio_numbering == 'BOARD': - gpio_numbering = gpio.BOARD - elif gpio_numbering == 'BCM': - gpio_numbering = gpio.BCM - else: - raise ValueError('Illegal gpio numbering: %s' % (gpio_numbering)) + def __init__(self, gpio_numbering, pin_nsa, pin_nsi, pin_gabelschalter, + pin_schauzeichen, pin_wecker_enable, pin_wecker_a, + pin_wecker_b, invert_gs): + if gpio_numbering == 'BOARD': + gpio_numbering = gpio.BOARD + elif gpio_numbering == 'BCM': + gpio_numbering = gpio.BCM + else: + raise ValueError('Illegal gpio numbering: %s' % (gpio_numbering)) - self.gpio_numbering = gpio_numbering - self.pin_nsa = pin_nsa - self.pin_nsi = pin_nsi - self.pin_gabelschalter = pin_gabelschalter - self.pin_schauzeichen = pin_schauzeichen - self.pin_wecker_enable = pin_wecker_enable - self.pin_wecker_a = pin_wecker_a - self.pin_wecker_b = pin_wecker_b - self.invert_gs = invert_gs + self.gpio_numbering = gpio_numbering + self.pin_nsa = pin_nsa + self.pin_nsi = pin_nsi + self.pin_gabelschalter = pin_gabelschalter + self.pin_schauzeichen = pin_schauzeichen + self.pin_wecker_enable = pin_wecker_enable + self.pin_wecker_a = pin_wecker_a + self.pin_wecker_b = pin_wecker_b + self.invert_gs = invert_gs class FeApUserInterface(object): - def __init__(self, pinconfig): - self.__pinconfig = pinconfig + def __init__(self, pinconfig): + self.__pinconfig = pinconfig - gpio.setmode(self.__pinconfig.gpio_numbering) - gpio.setup(self.__pinconfig.pin_nsa, gpio.IN, gpio.PUD_UP) - gpio.setup(self.__pinconfig.pin_nsi, gpio.IN, gpio.PUD_UP) - gpio.setup(self.__pinconfig.pin_gabelschalter, gpio.IN, gpio.PUD_UP) - gpio.setup(self.__pinconfig.pin_schauzeichen, gpio.OUT) - gpio.setup(self.__pinconfig.pin_wecker_enable, gpio.OUT) - gpio.setup(self.__pinconfig.pin_wecker_a, gpio.OUT) - gpio.setup(self.__pinconfig.pin_wecker_b, gpio.OUT) - - gpio.add_event_detect(self.__pinconfig.pin_nsa, gpio.BOTH, - self.__on_nsa_change, 20) - gpio.add_event_detect(self.__pinconfig.pin_nsi, gpio.FALLING, - self.__on_nsi_falling, 20) - gpio.add_event_detect(self.__pinconfig.pin_gabelschalter, gpio.BOTH, - self.__on_gabelschalter_change, 20) - #self.__nsa_up_time = 0 - self.__nsi_cnt = 0 - self.__weckt = False + gpio.setmode(self.__pinconfig.gpio_numbering) + gpio.setup(self.__pinconfig.pin_nsa, gpio.IN, gpio.PUD_UP) + gpio.setup(self.__pinconfig.pin_nsi, gpio.IN, gpio.PUD_UP) + gpio.setup(self.__pinconfig.pin_gabelschalter, gpio.IN, gpio.PUD_UP) + gpio.setup(self.__pinconfig.pin_schauzeichen, gpio.OUT) + gpio.setup(self.__pinconfig.pin_wecker_enable, gpio.OUT) + gpio.setup(self.__pinconfig.pin_wecker_a, gpio.OUT) + gpio.setup(self.__pinconfig.pin_wecker_b, gpio.OUT) - self.__nummernschalter_active_callbacks = [] - self.__nummernschalter_done_callbacks = [] - self.__gabelschalter_callbacks = [] + gpio.add_event_detect(self.__pinconfig.pin_nsa, gpio.BOTH, + self.__on_nsa_change, 20) + gpio.add_event_detect(self.__pinconfig.pin_nsi, gpio.FALLING, + self.__on_nsi_falling, 20) + gpio.add_event_detect(self.__pinconfig.pin_gabelschalter, gpio.BOTH, + self.__on_gabelschalter_change, 20) + #self.__nsa_up_time = 0 + self.__nsi_cnt = 0 + self.__weckt = False - def __on_nsa_change(self, pin): - nsastate = gpio.input(self.__pinconfig.pin_nsa) - if nsastate == 0: - #self.__nsa_up_time = time.time() - self.__nsi_cnt = 0 + self.__nummernschalter_active_callbacks = [] + self.__nummernschalter_done_callbacks = [] + self.__gabelschalter_callbacks = [] - for cb in self.__nummernschalter_active_callbacks: - cb() - else: - for cb in self.__nummernschalter_done_callbacks: - cb(self.__nsi_cnt % 10) + def __on_nsa_change(self, pin): + nsastate = gpio.input(self.__pinconfig.pin_nsa) + if nsastate == 0: + #self.__nsa_up_time = time.time() + self.__nsi_cnt = 0 - def __on_nsi_falling(self, pin): - #print 'nsi' - self.__nsi_cnt += 1 - - def __on_gabelschalter_change(self, pin): - gbstate = gpio.input(self.__pinconfig.pin_gabelschalter) - if self.__pinconfig.invert_gs: - gbstate = 1 - gbstate - print 'gabelschalter:', gbstate - for cb in self.__gabelschalter_callbacks: - cb(gbstate) - - def __wecker_thread(self): - while self.__weckt: - c = 0 - gpio.output(self.__pinconfig.pin_wecker_enable, 1) - while c < 1000: - gpio.output(self.__pinconfig.pin_wecker_a, 1) - gpio.output(self.__pinconfig.pin_wecker_b, 0) - time.sleep(0.02) - gpio.output(self.__pinconfig.pin_wecker_a, 0) - gpio.output(self.__pinconfig.pin_wecker_b, 1) - time.sleep(0.02) - c += 40 - print 'ring' - gpio.output(self.__pinconfig.pin_wecker_enable, 0) + for cb in self.__nummernschalter_active_callbacks: + cb() + else: + for cb in self.__nummernschalter_done_callbacks: + cb(self.__nsi_cnt % 10) - print '' - time.sleep(4) + def __on_nsi_falling(self, pin): + #print 'nsi' + self.__nsi_cnt += 1 + + def __on_gabelschalter_change(self, pin): + gbstate = gpio.input(self.__pinconfig.pin_gabelschalter) + if self.__pinconfig.invert_gs: + gbstate = 1 - gbstate + print 'gabelschalter:', gbstate + for cb in self.__gabelschalter_callbacks: + cb(gbstate) + + def __wecker_thread(self): + while self.__weckt: + c = 0 + gpio.output(self.__pinconfig.pin_wecker_enable, 1) + while c < 1000: + gpio.output(self.__pinconfig.pin_wecker_a, 1) + gpio.output(self.__pinconfig.pin_wecker_b, 0) + time.sleep(0.02) + gpio.output(self.__pinconfig.pin_wecker_a, 0) + gpio.output(self.__pinconfig.pin_wecker_b, 1) + time.sleep(0.02) + c += 40 + print 'ring' + gpio.output(self.__pinconfig.pin_wecker_enable, 0) + + print '' + time.sleep(4) - def add_gabelschalter_callback(self, cb): - self.__gabelschalter_callbacks.append(cb) + def add_gabelschalter_callback(self, cb): + self.__gabelschalter_callbacks.append(cb) - def add_nummernschalter_active_callback(self, cb): - self.__nummernschalter_active_callbacks.append(cb) + def add_nummernschalter_active_callback(self, cb): + self.__nummernschalter_active_callbacks.append(cb) - def add_nummernschalter_done_callback(self, cb): - self.__nummernschalter_done_callbacks.append(cb) + def add_nummernschalter_done_callback(self, cb): + self.__nummernschalter_done_callbacks.append(cb) - def set_wecker(self, enabled): - if enabled and not self.__weckt: - self.__weckt = True - t = threading.Thread(target=self.__wecker_thread) - t.start() - elif not enabled: - self.__weckt = False + def set_wecker(self, enabled): + if enabled and not self.__weckt: + self.__weckt = True + t = threading.Thread(target=self.__wecker_thread) + t.start() + elif not enabled: + self.__weckt = False - def set_schauzeichen(self, enabled): - gpio.output(self.__pinconfig.pin_schauzeichen, 1 if enabled else 0) + def set_schauzeichen(self, enabled): + gpio.output(self.__pinconfig.pin_schauzeichen, 1 if enabled else 0) if __name__ == '__main__': - gpio.setmode(gpio.BOARD) - pinconfig = FeApPinConfiguration() - t = FeApUserInterface(pinconfig) + gpio.setmode(gpio.BOARD) + pinconfig = FeApPinConfiguration() + t = FeApUserInterface(pinconfig) - def dailed(num): - print num - - t.add_nummernschalter_callback(dailed) - - t.set_schauzeichen(True) - time.sleep(0.5) - t.set_schauzeichen(False) - time.sleep(0.5) - t.set_schauzeichen(True) - time.sleep(0.5) - t.set_schauzeichen(False) - time.sleep(0.5) - t.set_schauzeichen(True) - time.sleep(0.5) - t.set_schauzeichen(False) - time.sleep(0.5) - t.set_schauzeichen(True) - time.sleep(0.5) - t.set_schauzeichen(False) - time.sleep(0.5) - - t.set_wecker(True) - time.sleep(20) - t.set_wecker(False) - while True: - time.sleep(1) + def dailed(num): + print num + t.add_nummernschalter_callback(dailed) + t.set_schauzeichen(True) + time.sleep(0.5) + t.set_schauzeichen(False) + time.sleep(0.5) + t.set_schauzeichen(True) + time.sleep(0.5) + t.set_schauzeichen(False) + time.sleep(0.5) + t.set_schauzeichen(True) + time.sleep(0.5) + t.set_schauzeichen(False) + time.sleep(0.5) + t.set_schauzeichen(True) + time.sleep(0.5) + t.set_schauzeichen(False) + time.sleep(0.5) + t.set_wecker(True) + time.sleep(20) + t.set_wecker(False) + while True: + time.sleep(1) diff --git a/configreader.py b/configreader.py index fa4a129..b63ff30 100644 --- a/configreader.py +++ b/configreader.py @@ -6,129 +6,124 @@ import phoneinterface import fetapd class ConfigurationReader(object): - DEFAULTS = { - 'gpio_numbering': 'BOARD', - 'pin_nsa': '11', - 'pin_nsi': '13', - 'pin_gabelschalter': '15', - 'pin_schauzeichen': '12', - 'pin_wecker_enable': '16', - 'pin_wecker_a': '18', - 'pin_wecker_b': '19', - 'invert_gs' : 'false', + DEFAULTS = { + 'gpio_numbering': 'BOARD', + 'pin_nsa': '11', + 'pin_nsi': '13', + 'pin_gabelschalter': '15', + 'pin_schauzeichen': '12', + 'pin_wecker_enable': '16', + 'pin_wecker_a': '18', + 'pin_wecker_b': '19', + 'invert_gs' : 'false', - 'default_proxy': '' - } + 'default_proxy': '' + } - def __init__(self): - self.__cp = ConfigParser.ConfigParser(defaults=ConfigurationReader.DEFAULTS) - self.__pinconfig = None - self.__dialconfig = None - self.__proxyconfigs = None - self.__phoneconfig = None + def __init__(self): + self.__cp = ConfigParser.ConfigParser(defaults=ConfigurationReader.DEFAULTS) + self.__pinconfig = None + self.__dialconfig = None + self.__proxyconfigs = None + self.__phoneconfig = None - def __get_global_val(self, option): - return self.__cp.get('fetapd', option) + def __get_global_val(self, option): + return self.__cp.get('fetapd', option) - def __get_global_val_int(self, option): - return int(self.__cp.get('fetapd', option)) + def __get_global_val_int(self, option): + return int(self.__cp.get('fetapd', option)) - def __get_global_val_bool(self, option): - return self.__cp.get('fetapd', option).lower() in ['true', 'yes', '1'] + def __get_global_val_bool(self, option): + return self.__cp.get('fetapd', option).lower() in ['true', 'yes', '1'] - def __get_proxy_val(self, proxyname, option): - return self.__cp.get('proxy_'+proxyname, option) + def __get_proxy_val(self, proxyname, option): + return self.__cp.get('proxy_'+proxyname, option) - def __get_proxy_val_int(self, proxyname, option): - return self.__cp.getint('proxy_'+proxyname, option) + def __get_proxy_val_int(self, proxyname, option): + return self.__cp.getint('proxy_'+proxyname, option) - def __read_shortcuts(self): - fname = self.__get_global_val('shortcuts_file') - shortcuts = {} - with open(fname, 'r') as csvfile: - for row in csv.DictReader(csvfile): - print 'row', row - shortcuts[row['shortcut']] = row['number'] - print 'shortcuts:', shortcuts - return shortcuts + def __read_shortcuts(self): + fname = self.__get_global_val('shortcuts_file') + shortcuts = {} + with open(fname, 'r') as csvfile: + for row in csv.DictReader(csvfile): + print 'row', row + shortcuts[row['shortcut']] = row['number'] + print 'shortcuts:', shortcuts + return shortcuts - def __read_blacklist(self): - fname = self.__get_global_val('blacklist_file') - blacklist = [] - with open(fname, 'r') as csvfile: - for row in csv.DictReader(csvfile): - blacklist.append(row['number']) - return blacklist + def __read_blacklist(self): + fname = self.__get_global_val('blacklist_file') + blacklist = [] + with open(fname, 'r') as csvfile: + for row in csv.DictReader(csvfile): + blacklist.append(row['number']) + return blacklist - def read(self, f): - self.__cp.read(f) + def read(self, f): + self.__cp.read(f) - print 'pin_nsa:', self.__get_global_val_int('pin_nsa'), - self.__pinconfig = apparatinterface.FeApPinConfiguration( - gpio_numbering = self.__get_global_val('gpio_numbering'), - pin_nsa = self.__get_global_val_int('pin_nsa'), - pin_nsi = self.__get_global_val_int('pin_nsi'), - pin_gabelschalter = self.__get_global_val_int('pin_gabelschalter'), - pin_schauzeichen = self.__get_global_val_int('pin_schauzeichen'), - pin_wecker_enable = self.__get_global_val_int('pin_wecker_enable'), - pin_wecker_a = self.__get_global_val_int('pin_wecker_a'), - pin_wecker_b = self.__get_global_val_int('pin_wecker_b'), - invert_gs = self.__get_global_val_bool('invert_gs'), - ) + print 'pin_nsa:', self.__get_global_val_int('pin_nsa'), + self.__pinconfig = apparatinterface.FeApPinConfiguration( + gpio_numbering = self.__get_global_val('gpio_numbering'), + pin_nsa = self.__get_global_val_int('pin_nsa'), + pin_nsi = self.__get_global_val_int('pin_nsi'), + pin_gabelschalter = self.__get_global_val_int('pin_gabelschalter'), + pin_schauzeichen = self.__get_global_val_int('pin_schauzeichen'), + pin_wecker_enable = self.__get_global_val_int('pin_wecker_enable'), + pin_wecker_a = self.__get_global_val_int('pin_wecker_a'), + pin_wecker_b = self.__get_global_val_int('pin_wecker_b'), + invert_gs = self.__get_global_val_bool('invert_gs'), + ) - self.__dialconfig = fetapd.DialConfiguration( - self.__get_global_val_int('dial_timeout'), - self.__read_shortcuts(), - self.__read_blacklist(), - ) + self.__dialconfig = fetapd.DialConfiguration( + self.__get_global_val_int('dial_timeout'), + self.__read_shortcuts(), + self.__read_blacklist(), + ) - proxyconfigs = [] - for secname in self.__cp.sections(): - if secname.startswith('proxy_'): - proxyname = secname[6:] - proxyconfig = phoneinterface.PhoneProxyConfiguration( - name = proxyname, - proxy = self.__get_proxy_val(proxyname, 'proxy'), - identity = self.__get_proxy_val(proxyname, 'identity'), - username = self.__get_proxy_val(proxyname, 'username'), - password = self.__get_proxy_val(proxyname, 'password'), - realm = self.__get_proxy_val(proxyname, 'realm'), - prefix = self.__get_proxy_val(proxyname, 'prefix') - ) - proxyconfigs.append(proxyconfig) + proxyconfigs = [] + for secname in self.__cp.sections(): + if secname.startswith('proxy_'): + proxyname = secname[6:] + proxyconfig = phoneinterface.PhoneProxyConfiguration( + name = proxyname, + proxy = self.__get_proxy_val(proxyname, 'proxy'), + identity = self.__get_proxy_val(proxyname, 'identity'), + username = self.__get_proxy_val(proxyname, 'username'), + password = self.__get_proxy_val(proxyname, 'password'), + realm = self.__get_proxy_val(proxyname, 'realm'), + prefix = self.__get_proxy_val(proxyname, 'prefix') + ) + proxyconfigs.append(proxyconfig) - self.__phoneconfig = phoneinterface.PhoneConfiguration( - sound_device = self.__get_global_val('sound_device'), - incoming_timeout = self.__get_global_val_int('incoming_timeout'), - linphone_config = self.__get_global_val('linphone_config'), - default_proxy = self.__get_global_val('default_proxy'), - stun_server = self.__get_global_val('stun_server'), - proxies = proxyconfigs - ) + self.__phoneconfig = phoneinterface.PhoneConfiguration( + sound_device = self.__get_global_val('sound_device'), + incoming_timeout = self.__get_global_val_int('incoming_timeout'), + linphone_config = self.__get_global_val('linphone_config'), + default_proxy = self.__get_global_val('default_proxy'), + stun_server = self.__get_global_val('stun_server'), + proxies = proxyconfigs + ) - @property - def pinconfig(self): - return self.__pinconfig - - - @property - def dialconfig(self): - return self.__dialconfig - - - @property - def phoneconfig(self): - return self.__phoneconfig - + @property + def pinconfig(self): + return self.__pinconfig + @property + def dialconfig(self): + return self.__dialconfig + @property + def phoneconfig(self): + return self.__phoneconfig diff --git a/fetapd.py b/fetapd.py index 809f940..5680c9d 100644 --- a/fetapd.py +++ b/fetapd.py @@ -7,13 +7,13 @@ import configreader class DialConfiguration(object): - def __init__(self, dial_timeout, shortcuts, blacklist): - self.dial_timeout = dial_timeout - self.shortcuts = shortcuts - self.blacklist = blacklist + def __init__(self, dial_timeout, shortcuts, blacklist): + self.dial_timeout = dial_timeout + self.shortcuts = shortcuts + self.blacklist = blacklist class IllegalEventError(Exception): - pass + pass """ @@ -21,47 +21,47 @@ An abstract state, needed to define all possible events. """ class AbstractState(object): - def on_registration_in_progress(self): - raise IllegalEventError() + def on_registration_in_progress(self): + raise IllegalEventError() - def on_registration_successful(self): - raise IllegalEventError() + def on_registration_successful(self): + raise IllegalEventError() - def on_registration_lost(self): - raise IllegalEventError() + def on_registration_lost(self): + raise IllegalEventError() - def on_gabelschalter_up(self): - raise IllegalEventError() + def on_gabelschalter_up(self): + raise IllegalEventError() - def on_gabelschalter_down(self): - raise IllegalEventError() - - def on_incoming_call(self): - raise IllegalEventError() - - def on_call_ended(self): - raise IllegalEventError() - - def on_call_accepted(self): - raise IllegalEventError() - - def on_call_ringing(self): - raise IllegalEventError() + def on_gabelschalter_down(self): + raise IllegalEventError() - def on_invalid_number(self): - raise IllegalEventError() - - def on_nummernschalter_active(self): - raise IllegalEventError() + def on_incoming_call(self): + raise IllegalEventError() - def on_nummernschalter_input(self, num): - raise IllegalEventError() - - def on_timeout(self): - raise IllegalEventError() + def on_call_ended(self): + raise IllegalEventError() - def leave(self): - return None + def on_call_accepted(self): + raise IllegalEventError() + + def on_call_ringing(self): + raise IllegalEventError() + + def on_invalid_number(self): + raise IllegalEventError() + + def on_nummernschalter_active(self): + raise IllegalEventError() + + def on_nummernschalter_input(self, num): + raise IllegalEventError() + + def on_timeout(self): + raise IllegalEventError() + + def leave(self): + return None """ @@ -70,338 +70,338 @@ behaviour for some events (overriden if necessary). """ class BaseState(AbstractState): - def __init__(self, controller): - self._controller = controller + def __init__(self, controller): + self._controller = controller - def on_registration_lost(self): - return InitState + def on_registration_lost(self): + return InitState - def on_gabelschalter_up(self): - return None + def on_gabelschalter_up(self): + return None - def on_gabelschalter_down(self): - return None + def on_gabelschalter_down(self): + return None - def on_incoming_call(self): - self._controller.phone.decline_call() + def on_incoming_call(self): + self._controller.phone.decline_call() - def on_call_ended(self): - # When an incoming call is declined, a call_ended event occurs, which - # needs to be ignored, here. - return None + def on_call_ended(self): + # When an incoming call is declined, a call_ended event occurs, which + # needs to be ignored, here. + return None - def on_nummernschalter_active(self): - return None + def on_nummernschalter_active(self): + return None - def on_nummernschalter_input(self, num): - return None + def on_nummernschalter_input(self, num): + return None class InitState(BaseState): - def __init__(self, controller): - super(InitState, self).__init__(controller) - self._controller.feap.set_schauzeichen(True) + def __init__(self, controller): + super(InitState, self).__init__(controller) + self._controller.feap.set_schauzeichen(True) - def on_registration_in_progress(self): - print('registration in progress') - return RegisteringState + def on_registration_in_progress(self): + print('registration in progress') + return RegisteringState class RegisteringState(BaseState): - def __init__(self, controller): - super(RegisteringState, self).__init__(controller) + def __init__(self, controller): + super(RegisteringState, self).__init__(controller) - def on_registration_successful(self): - print('registration successful') - self._controller.feap.set_schauzeichen(False) - return IdleState + def on_registration_successful(self): + print('registration successful') + self._controller.feap.set_schauzeichen(False) + return IdleState class IdleState(BaseState): - def on_incoming_call(self): - print('incomfing call') - caller = self._controller.phone.get_remote_number() - print('From: %s' % caller) - if caller in self._controller.dialconfig.blacklist: - print('Caller on blacklist - declining') - self._controller.phone.decline_call() - return CallTerminatingState - else: - return SchelltState - - def on_gabelschalter_up(self): - print('gabel up') - return DialingState - + def on_incoming_call(self): + print('incomfing call') + caller = self._controller.phone.get_remote_number() + print('From: %s' % caller) + if caller in self._controller.dialconfig.blacklist: + print('Caller on blacklist - declining') + self._controller.phone.decline_call() + return CallTerminatingState + else: + return SchelltState + + def on_gabelschalter_up(self): + print('gabel up') + return DialingState + class SchelltState(BaseState): - def __init__(self, controller): - super(SchelltState, self).__init__(controller) - self._controller.feap.set_wecker(True) + def __init__(self, controller): + super(SchelltState, self).__init__(controller) + self._controller.feap.set_wecker(True) - def leave(self): - self._controller.feap.set_wecker(False) + def leave(self): + self._controller.feap.set_wecker(False) - def on_gabelschalter_up(self): - return AcceptingState - - def on_call_ended(self): - return IdleState + def on_gabelschalter_up(self): + return AcceptingState + + def on_call_ended(self): + return IdleState class AcceptingState(BaseState): - def __init__(self, controller): - super(AcceptingState, self).__init__(controller) - self._controller.phone.accept_call() + def __init__(self, controller): + super(AcceptingState, self).__init__(controller) + self._controller.phone.accept_call() - def on_call_accepted(self): - return CallRunningState + def on_call_accepted(self): + return CallRunningState class CallTerminatingState(BaseState): - def __init__(self, controller): - super(CallTerminatingState, self).__init__(controller) - self._controller.phone.end_call() + def __init__(self, controller): + super(CallTerminatingState, self).__init__(controller) + self._controller.phone.end_call() - def on_call_ended(self): - return IdleState - - def on_call_accepted(self): - return None + def on_call_ended(self): + return IdleState + + def on_call_accepted(self): + return None class ForgottenState(BaseState): - def on_gabelschalter_down(self): - return IdleState + def on_gabelschalter_down(self): + return IdleState class BusyBeepingState(BaseState): - def __init__(self, controller): - super(BusyBeepingState, self).__init__(controller) - self._controller.phone.play_busy_tone() + def __init__(self, controller): + super(BusyBeepingState, self).__init__(controller) + self._controller.phone.play_busy_tone() - def leave(self): - self._controller.phone.stop_playing() + def leave(self): + self._controller.phone.stop_playing() - def on_timeout(self): - return ForgottenState - - def on_gabelschalter_down(self): - return IdleState + def on_timeout(self): + return ForgottenState + + def on_gabelschalter_down(self): + return IdleState class CallRunningState(BaseState): - def on_gabelschalter_down(self): - return CallTerminatingState - - def on_call_ended(self): - return BusyBeepingState + def on_gabelschalter_down(self): + return CallTerminatingState + + def on_call_ended(self): + return BusyBeepingState class WecktState(BaseState): - def __init__(self, controller): - super(WecktState, self).__init__(controller) - self._controller.phone.play_ringback_tone() + def __init__(self, controller): + super(WecktState, self).__init__(controller) + self._controller.phone.play_ringback_tone() - def leave(self): - self._controller.phone.stop_playing() + def leave(self): + self._controller.phone.stop_playing() - def on_gabelschalter_down(self): - return CallTerminatingState - - def on_call_ended(self): - return BusyBeepingState - - def on_call_accepted(self): - return CallRunningState + def on_gabelschalter_down(self): + return CallTerminatingState + + def on_call_ended(self): + return BusyBeepingState + + def on_call_accepted(self): + return CallRunningState class ConnectingState(BaseState): - def on_gabelschalter_down(self): - return CallTerminatingState - - def on_call_ringing(self): - return WecktState + def on_gabelschalter_down(self): + return CallTerminatingState - def on_call_accepted(self): - return CallRunningState + def on_call_ringing(self): + return WecktState - def on_invalid_number(self): - # TODO: play sound - return BusyBeepingState + def on_call_accepted(self): + return CallRunningState - def on_call_ended(self): - return BusyBeepingState + def on_invalid_number(self): + # TODO: play sound + return BusyBeepingState + + def on_call_ended(self): + return BusyBeepingState class DialingState(BaseState): - def __init__(self, controller): - super(DialingState, self).__init__(controller) - self._controller.phone.play_dial_tone() - self.__dial_tone = True - self.__number = '' + def __init__(self, controller): + super(DialingState, self).__init__(controller) + self._controller.phone.play_dial_tone() + self.__dial_tone = True + self.__number = '' - def leave(self): - if self.__dial_tone: - self._controller.phone.stop_playing() - self._controller.abort_timeout() + def leave(self): + if self.__dial_tone: + self._controller.phone.stop_playing() + self._controller.abort_timeout() - def on_gabelschalter_down(self): - return IdleState + def on_gabelschalter_down(self): + return IdleState - def on_nummernschalter_active(self): - self._controller.abort_timeout() - if self.__dial_tone: - self._controller.phone.stop_playing() + def on_nummernschalter_active(self): + self._controller.abort_timeout() + if self.__dial_tone: + self._controller.phone.stop_playing() - def on_nummernschalter_input(self, num): - print('nummernschalter: %d' % (num)) - if self.__dial_tone: - self._controller.phone.stop_playing() - self.__number += str(num) - self._controller.abort_timeout() - self._controller.set_timeout(self._controller.dialconfig.dial_timeout * 1000) - self._controller.phone.read_text(str(num)) - - def on_timeout(self): - number = self.__number - print 'Dialing number:', number - if number in self._controller.dialconfig.shortcuts: - number = self._controller.dialconfig.shortcuts[number] - print 'shortcut resolved:', number - self._controller.phone.call(number) - return ConnectingState + def on_nummernschalter_input(self, num): + print('nummernschalter: %d' % (num)) + if self.__dial_tone: + self._controller.phone.stop_playing() + self.__number += str(num) + self._controller.abort_timeout() + self._controller.set_timeout(self._controller.dialconfig.dial_timeout * 1000) + self._controller.phone.read_text(str(num)) + + def on_timeout(self): + number = self.__number + print 'Dialing number:', number + if number in self._controller.dialconfig.shortcuts: + number = self._controller.dialconfig.shortcuts[number] + print 'shortcut resolved:', number + self._controller.phone.call(number) + return ConnectingState class StateMachineController(object): - def __init__(self, phone, feap, dialconfig): - self.__phone = phone - self.__feap = feap - self.__dialconfig = dialconfig + def __init__(self, phone, feap, dialconfig): + self.__phone = phone + self.__feap = feap + self.__dialconfig = dialconfig - self.__state = InitState(self) + self.__state = InitState(self) - self.__timeout = None + self.__timeout = None - self.__running = True - self.__evqueue = queue.Queue() - self.__evthread = threading.Thread(target=self.__event_dispatcher) - self.__evthread.start() - - def __event_dispatcher(self): - while self.__running: - (evname, evargs, evkwargs) = self.__evqueue.get() - if not evname: - return + self.__running = True + self.__evqueue = queue.Queue() + self.__evthread = threading.Thread(target=self.__event_dispatcher) + self.__evthread.start() - print('!!! event: %s' % (evname)) - handler = getattr(self.__state, 'on_%s' % (evname)) - try: - newstate = handler(*evargs, **evkwargs) - except IllegalEventError: - print('illegal event occured!!!!!!!!!!!!!!!!!!!!', self.__state.__class__.__name__) - if not newstate: - continue + def __event_dispatcher(self): + while self.__running: + (evname, evargs, evkwargs) = self.__evqueue.get() + if not evname: + return - self.__state.leave() - self.abort_timeout() + print('!!! event: %s' % (evname)) + handler = getattr(self.__state, 'on_%s' % (evname)) + try: + newstate = handler(*evargs, **evkwargs) + except IllegalEventError: + print('illegal event occured!!!!!!!!!!!!!!!!!!!!', self.__state.__class__.__name__) + if not newstate: + continue - oldstate = self.__state.__class__ - print('%s -> %s' % (oldstate.__name__, newstate.__name__)) - self.__state = newstate(self) + self.__state.leave() + self.abort_timeout() - def queue_event(self, evname, *evargs, **evkwargs): - if not hasattr(AbstractState, 'on_%s' % (evname)): - raise ValueError('Illegal event name: %s' % (evname)) - self.__evqueue.put((evname, evargs, evkwargs)) + oldstate = self.__state.__class__ + print('%s -> %s' % (oldstate.__name__, newstate.__name__)) + self.__state = newstate(self) - def set_timeout(self, timeout): - self.__timeout = threading.Timer(timeout/1000, self.queue_event, args=['timeout']) - self.__timeout.start() + def queue_event(self, evname, *evargs, **evkwargs): + if not hasattr(AbstractState, 'on_%s' % (evname)): + raise ValueError('Illegal event name: %s' % (evname)) + self.__evqueue.put((evname, evargs, evkwargs)) - def abort_timeout(self): - if self.__timeout: - self.__timeout.cancel() - self.__timeout = None + def set_timeout(self, timeout): + self.__timeout = threading.Timer(timeout/1000, self.queue_event, args=['timeout']) + self.__timeout.start() - @property - def phone(self): - return self.__phone + def abort_timeout(self): + if self.__timeout: + self.__timeout.cancel() + self.__timeout = None - @property - def feap(self): - return self.__feap + @property + def phone(self): + return self.__phone - @property - def dialconfig(self): - return self.__dialconfig + @property + def feap(self): + return self.__feap - def stop(self, hard=False): - if hard: - self.__running = False - self.__evqueue.put((None, None, None)) + @property + def dialconfig(self): + return self.__dialconfig + + def stop(self, hard=False): + if hard: + self.__running = False + self.__evqueue.put((None, None, None)) c = None def gabelschalter_cb(state): - global c - if state == 1: - c.queue_event('gabelschalter_up') - else: - c.queue_event('gabelschalter_down') + global c + if state == 1: + c.queue_event('gabelschalter_up') + else: + c.queue_event('gabelschalter_down') def nummernschalter_active_cb(): - global c - c.queue_event('nummernschalter_active') + global c + c.queue_event('nummernschalter_active') def nummernschalter_done_cb(digit): - global c - c.queue_event('nummernschalter_input', digit) + global c + c.queue_event('nummernschalter_input', digit) def phone_cb(event): - if event == PhoneEvent.RegInProgress: - c.queue_event('registration_in_progress') - elif event == PhoneEvent.RegSuccessfull: - c.queue_event('registration_successful') - elif event == PhoneEvent.RegLost: - c.queue_event('registration_lost') - elif event == PhoneEvent.CallIncoming: - c.queue_event('incoming_call') - elif event == PhoneEvent.CallAccepted: - c.queue_event('call_accepted') - elif event == PhoneEvent.CallEnded: - c.queue_event('call_ended') - elif event == PhoneEvent.CallRinging: - c.queue_event('call_ringing') - elif event == PhoneEvent.CallBusy: - c.queue_event('call_ended') - elif event == PhoneEvent.CallInvalidNumber: - c.queue_event('invalid_number') + if event == PhoneEvent.RegInProgress: + c.queue_event('registration_in_progress') + elif event == PhoneEvent.RegSuccessfull: + c.queue_event('registration_successful') + elif event == PhoneEvent.RegLost: + c.queue_event('registration_lost') + elif event == PhoneEvent.CallIncoming: + c.queue_event('incoming_call') + elif event == PhoneEvent.CallAccepted: + c.queue_event('call_accepted') + elif event == PhoneEvent.CallEnded: + c.queue_event('call_ended') + elif event == PhoneEvent.CallRinging: + c.queue_event('call_ringing') + elif event == PhoneEvent.CallBusy: + c.queue_event('call_ended') + elif event == PhoneEvent.CallInvalidNumber: + c.queue_event('invalid_number') if __name__ == '__main__': - cfg = configreader.ConfigurationReader() - cfg.read('fetap.ini') + cfg = configreader.ConfigurationReader() + cfg.read('fetap.ini') - phone = PhoneInterface(cfg.phoneconfig) - feap = FeApUserInterface(cfg.pinconfig) - c = StateMachineController(phone, feap, cfg.dialconfig) + phone = PhoneInterface(cfg.phoneconfig) + feap = FeApUserInterface(cfg.pinconfig) + c = StateMachineController(phone, feap, cfg.dialconfig) - feap.add_gabelschalter_callback(gabelschalter_cb) - feap.add_nummernschalter_active_callback(nummernschalter_active_cb) - feap.add_nummernschalter_done_callback(nummernschalter_done_cb) - phone.add_event_cb(phone_cb) + feap.add_gabelschalter_callback(gabelschalter_cb) + feap.add_nummernschalter_active_callback(nummernschalter_active_cb) + feap.add_nummernschalter_done_callback(nummernschalter_done_cb) + phone.add_event_cb(phone_cb) - phone.start() - - try: - while True: - time.sleep(1) + phone.start() - ''' - c.queue_event('gabelschalter_up') - c.queue_event('nummernschalter_input', 4) - c.queue_event('nummernschalter_input', 2) - #c.queue_event('gabelschalter_down') - #c.queue_event('call_accepted') - c.queue_event('timeout') - c.queue_event('call_ringing') - #c.queue_event('gabelschalter_down') - c.queue_event('call_accepted') - c.queue_event('call_ended') - c.queue_event('timeout') - c.queue_event('gabelschalter_down') - ''' + try: + while True: + time.sleep(1) - except KeyboardInterrupt: - phone.stop() - feap.set_wecker(False) - c.stop() + ''' + c.queue_event('gabelschalter_up') + c.queue_event('nummernschalter_input', 4) + c.queue_event('nummernschalter_input', 2) + #c.queue_event('gabelschalter_down') + #c.queue_event('call_accepted') + c.queue_event('timeout') + c.queue_event('call_ringing') + #c.queue_event('gabelschalter_down') + c.queue_event('call_accepted') + c.queue_event('call_ended') + c.queue_event('timeout') + c.queue_event('gabelschalter_down') + ''' + + except KeyboardInterrupt: + phone.stop() + feap.set_wecker(False) + c.stop() diff --git a/statemachinetest.py b/statemachinetest.py index d9403e5..b2796a1 100644 --- a/statemachinetest.py +++ b/statemachinetest.py @@ -2,213 +2,205 @@ import threading import Queue as queue class IllegalEventError(Exception): - pass + pass class AbstractState(object): - def __init__(self, controller): - pass - - def on_registration_in_progress(self): - raise IllegalEventError() + def __init__(self, controller): + pass - def on_registration_successful(self): - raise IllegalEventError() + def on_registration_in_progress(self): + raise IllegalEventError() - def on_gabelschalter_up(self): - raise IllegalEventError() + def on_registration_successful(self): + raise IllegalEventError() + + def on_gabelschalter_up(self): + raise IllegalEventError() + + def on_gabelschalter_down(self): + raise IllegalEventError() + + def on_incoming_call(self): + raise IllegalEventError() + + def on_call_ended(self): + raise IllegalEventError() + + def on_call_accepted(self): + raise IllegalEventError() + + def on_call_ringing(self): + raise IllegalEventError() + + def on_nummernschalter_input(self, num): + raise IllegalEventError() + + def on_timeout(self): + raise IllegalEventError() - def on_gabelschalter_down(self): - raise IllegalEventError() - - def on_incoming_call(self): - raise IllegalEventError() - - def on_call_ended(self): - raise IllegalEventError() - - def on_call_accepted(self): - raise IllegalEventError() - - def on_call_ringing(self): - raise IllegalEventError() - - def on_nummernschalter_input(self, num): - raise IllegalEventError() - - def on_timeout(self): - raise IllegalEventError() - class InitState(AbstractState): - def on_registration_in_progress(self): - print('registration in progress') - return RegisteringState + def on_registration_in_progress(self): + print('registration in progress') + return RegisteringState class RegisteringState(AbstractState): - def on_registration_successful(self): - print('registration successfull') - return IdleState + def on_registration_successful(self): + print('registration successfull') + return IdleState class IdleState(AbstractState): - def on_incoming_call(self): - print('incomfing call') - - def on_gabelschalter_up(self): - print('gabel up') - return DialingState - - def on_gabelschalter_down(self): - pass + def on_incoming_call(self): + print('incomfing call') - def on_nummernschalter_input(self, x): - pass + def on_gabelschalter_up(self): + print('gabel up') + return DialingState + + def on_gabelschalter_down(self): + pass + + def on_nummernschalter_input(self, x): + pass class SchelltState(AbstractState): - def on_gabelschalter_up(self): - return AcceptingState - - def on_call_ended(self): - return IdleState + def on_gabelschalter_up(self): + return AcceptingState + + def on_call_ended(self): + return IdleState class AcceptingState(AbstractState): - def on_call_accepted(self): - return CallRunningState + def on_call_accepted(self): + return CallRunningState class CallTerminatingState(AbstractState): - def on_call_ended(self): - return IdleState - - def on_call_accepted(self): - return None + def on_call_ended(self): + return IdleState + + def on_call_accepted(self): + return None class ForgottenState(AbstractState): - def on_gabelschalter_down(self): - return IdleState + def on_gabelschalter_down(self): + return IdleState class BusyBeepingState(AbstractState): - def on_timeout(self): - return ForgottenState - - def on_gabelschalter_down(self): - return IdleState + def on_timeout(self): + return ForgottenState + + def on_gabelschalter_down(self): + return IdleState class CallRunningState(AbstractState): - def on_gabelschalter_down(self): - return CallTerminatingState - - def on_call_ended(self): - return BusyBeepingState + def on_gabelschalter_down(self): + return CallTerminatingState + + def on_call_ended(self): + return BusyBeepingState class WecktState(AbstractState): - def on_gabelschalter_down(self): - return CallTerminatingState - - def on_call_ended(self): - return BusyBeepingState - - def on_call_accepted(self): - return CallRunningState + def on_gabelschalter_down(self): + return CallTerminatingState + + def on_call_ended(self): + return BusyBeepingState + + def on_call_accepted(self): + return CallRunningState class ConnectingState(AbstractState): - def on_gabelschalter_down(self): - return CallTerminatingState - - def on_call_ringing(self): - return WecktState + def on_gabelschalter_down(self): + return CallTerminatingState + + def on_call_ringing(self): + return WecktState class DialingState(AbstractState): - def on_gabelschalter_down(self): - return IdleState + def on_gabelschalter_down(self): + return IdleState - def on_nummernschalter_input(self, num): - print('nummernschalter: %d' % (num)) - - def on_timeout(self): - return ConnectingState + def on_nummernschalter_input(self, num): + print('nummernschalter: %d' % (num)) + def on_timeout(self): + return ConnectingState class TelefonapparatUserInterface(object): - def __init__(self): - pass + def __init__(self): + pass - def add_gabelschalter_callback(self, cb): - pass + def add_gabelschalter_callback(self, cb): + pass - def add_nummernschalter_callback(self, cb): - pass + def add_nummernschalter_callback(self, cb): + pass - def set_wecker(self, enabled): - pass + def set_wecker(self, enabled): + pass - def set_schauzeichen(self, enabled): - pass + def set_schauzeichen(self, enabled): + pass class StateMachineController(object): - def __init__(self): - self.__state = InitState(self) + def __init__(self): + self.__state = InitState(self) - self.__running = True - self.__evqueue = queue.Queue() - self.__evthread = threading.Thread(target=self.__event_dispatcher) - self.__evthread.start() - - def __event_dispatcher(self): - while self.__running: - (evname, evargs, evkwargs) = self.__evqueue.get() - if not evname: - return + self.__running = True + self.__evqueue = queue.Queue() + self.__evthread = threading.Thread(target=self.__event_dispatcher) + self.__evthread.start() - print('!!! event: %s' % (evname)) - handler = getattr(self.__state, 'on_%s' % (evname)) - try: - newstate = handler(*evargs, **evkwargs) - except IllegalEventError: - print('illegal event occured!!!!!!!!!!!!!!!!!!!!') - if not newstate: - continue + def __event_dispatcher(self): + while self.__running: + (evname, evargs, evkwargs) = self.__evqueue.get() + if not evname: + return - oldstate = self.__state.__class__ - print('%s -> %s' % (oldstate.__name__, newstate.__name__)) - self.__state = newstate(self) + print('!!! event: %s' % (evname)) + handler = getattr(self.__state, 'on_%s' % (evname)) + try: + newstate = handler(*evargs, **evkwargs) + except IllegalEventError: + print('illegal event occured!!!!!!!!!!!!!!!!!!!!') + if not newstate: + continue - - def queue_event(self, evname, *evargs, **evkwargs): - if not hasattr(AbstractState, 'on_%s' % (evname)): - raise ValueError('Illegal event name: %s' % (evname)) - self.__evqueue.put((evname, evargs, evkwargs)) + oldstate = self.__state.__class__ + print('%s -> %s' % (oldstate.__name__, newstate.__name__)) + self.__state = newstate(self) - def stop(self, hard=False): - if hard: - self.__running = False - self.__evqueue.put((None, None, None)) - - - + def queue_event(self, evname, *evargs, **evkwargs): + if not hasattr(AbstractState, 'on_%s' % (evname)): + raise ValueError('Illegal event name: %s' % (evname)) + self.__evqueue.put((evname, evargs, evkwargs)) + def stop(self, hard=False): + if hard: + self.__running = False + self.__evqueue.put((None, None, None)) if __name__ == '__main__': - c = StateMachineController() - - c.queue_event('registration_in_progress') - c.queue_event('registration_successful') - c.queue_event('gabelschalter_up') - c.queue_event('nummernschalter_input', 4) - c.queue_event('nummernschalter_input', 2) - #c.queue_event('gabelschalter_down') - #c.queue_event('call_accepted') - c.queue_event('timeout') - c.queue_event('call_ringing') - #c.queue_event('gabelschalter_down') - c.queue_event('call_accepted') - c.queue_event('call_ended') - c.queue_event('timeout') - c.queue_event('gabelschalter_down') - - c.stop() + c = StateMachineController() + c.queue_event('registration_in_progress') + c.queue_event('registration_successful') + c.queue_event('gabelschalter_up') + c.queue_event('nummernschalter_input', 4) + c.queue_event('nummernschalter_input', 2) + #c.queue_event('gabelschalter_down') + #c.queue_event('call_accepted') + c.queue_event('timeout') + c.queue_event('call_ringing') + #c.queue_event('gabelschalter_down') + c.queue_event('call_accepted') + c.queue_event('call_ended') + c.queue_event('timeout') + c.queue_event('gabelschalter_down') + c.stop()