def validate_config_item2(self, spec, validation_failure_info, item='item not in config!@#',): default = 'default required!@#' item_type, validation, default = spec.split('|') if default.lower() == 'none': default = None if item == 'item not in config!@#': if default == 'default required!@#': log.error('Required setting missing from config file. Run with ' 'verbose logging and look for the last ' 'ConfigProcessor entry above this line to see where ' 'the problem is.') sys.exit() else: item = default if item_type == 'single': item = self.validate_item(item, validation, validation_failure_info) elif item_type == 'list': item = Util.string_to_list(item) new_list = list() for i in item: new_list.append( self.validate_item(i, validation, validation_failure_info)) item = new_list elif item_type == 'set': item = set(Util.string_to_list(item)) new_set = set() for i in item: new_set.add( self.validate_item(i, validation, validation_failure_info)) item = new_set elif item_type == 'dict': item = self.validate_item(item, validation, validation_failure_info) if not item: item = dict() else: self.log.error("Invalid Type '%s' in config spec %s:%s", item_type, validation_failure_info[0][0], validation_failure_info[1]) sys.exit() return item
def configure_mode_settings(self, config): """Processes this mode's configuration settings from a config dictionary. """ if not ('priority' in config and type(config['priority']) is int): config['priority'] = 0 if 'start_events' in config: config['start_events'] = Util.string_to_list( config['start_events']) else: config['start_events'] = list() if 'stop_events' in config: config['stop_events'] = Util.string_to_list( config['stop_events']) else: config['stop_events'] = list() # register mode start events if 'start_events' in config: for event in config['start_events']: self.machine.events.add_handler(event, self.start) self.config['mode'] = config
def configure_mode_settings(self, config): """Processes this mode's configuration settings from a config dictionary. """ if not ('priority' in config and type(config['priority']) is int): config['priority'] = 0 if 'start_events' in config: config['start_events'] = Util.string_to_list( config['start_events']) else: config['start_events'] = list() if 'stop_events' in config: config['stop_events'] = Util.string_to_list(config['stop_events']) else: config['stop_events'] = list() # register mode start events if 'start_events' in config: for event in config['start_events']: self.machine.events.add_handler(event, self.start) self.config['mode'] = config
def __init__(self, machine, name, player, config): self.machine = machine self.name = name self.player = player self.handler_keys = set() self.enabled = False config_spec = ''' enable_events: list|None disable_events: list|None reset_events: list|None restart_events: list|None restart_on_complete: boolean|False disable_on_complete: boolean|True persist_state: boolean|False ''' self.config = Config.process_config(config_spec=config_spec, source=config) if 'events_when_complete' not in config: self.config['events_when_complete'] = ([ 'logicblock_' + self.name + '_complete']) else: self.config['events_when_complete'] = Util.string_to_list( config['events_when_complete'])
def __init__(self, machine, name, config, collection=None, validate=True): self.shots = list() # list of strings for shot in Util.string_to_list(config['shots']): self.shots.append(machine.shots[shot]) # If this device is setup in a machine-wide config, make sure it has # a default enable event. # TODO add a mode parameter to the device constructor and do the logic # there. if not machine.modes: if 'enable_events' not in config: config['enable_events'] = 'ball_starting' if 'disable_events' not in config: config['disable_events'] = 'ball_ended' if 'reset_events' not in config: config['reset_events'] = 'ball_ended' if 'profile' in config: for shot in self.shots: shot.update_enable_table(profile=config['profile'], mode=None) super(ShotGroup, self).__init__(machine, name, config, collection, validate=validate) self.rotation_enabled = True if self.debug: self._enable_related_device_debugging()
def __init__(self, machine, config): super(FadeCandyOPClient, self).__init__(machine, config) self.log = logging.getLogger('FadeCandyClient') self.update_every_tick = True self.gamma = self.machine.config['led_settings']['gamma'] self.whitepoint = Util.string_to_list( self.machine.config['led_settings']['whitepoint']) self.whitepoint[0] = float(self.whitepoint[0]) self.whitepoint[1] = float(self.whitepoint[1]) self.whitepoint[2] = float(self.whitepoint[2]) self.linear_slope = ( self.machine.config['led_settings']['linear_slope']) self.linear_cutoff = ( self.machine.config['led_settings']['linear_cutoff']) self.keyframe_interpolation = ( self.machine.config['led_settings']['keyframe_interpolation']) self.dithering = self.machine.config['led_settings']['dithering'] if not self.dithering: self.disable_dithering() if not self.keyframe_interpolation: self.update_every_tick = False self.set_global_color_correction() self.write_firmware_options()
def get_hw_switch_states(self): if not self.initial_states_sent: if 'virtual_platform_start_active_switches' in self.machine.config: initial_active_switches = [ self.machine.switches[x].number for x in Util.string_to_list( self.machine. config['virtual_platform_start_active_switches']) ] for k, v in self.hw_switches.iteritems(): if k in initial_active_switches: self.hw_switches[k] ^= 1 self.initial_states_sent = True else: switches = [x for x in self.machine.switches if x.platform == self] for switch in switches: self.hw_switches[switch.number] = switch.state ^ switch.invert return self.hw_switches
def bcp_receive_get(self, names, **kwargs): """Processes an incoming BCP 'get' command by posting an event 'bcp_get_<name>'. It's up to an event handler to register for that event and to send the response BCP 'set' command. """ for name in Util.string_to_list(names): self.machine.events.post('bcp_get_{}'.format(name))
def getOptions(self): return { 'force_platform': self.get_platform(), 'mpfconfigfile': "mpf/mpfconfig.yaml", 'machine_path': self.getMachinePath(), 'configfile': Util.string_to_list(self.getConfigFile()), 'debug': True, 'bcp': self.get_use_bcp() }
def register_mpfmc_trigger_events(self, config, **kwargs): """Scans an MPF config file and creates trigger events for the config settings that need them. Args: config: An MPF config dictionary (can be the machine-wide or a mode- specific one). **kwargs: Not used. Included to catch any additional kwargs that may be associted with this method being registered as an event handler. """ self.log.debug("Registering Trigger Events") try: for event in config['show_player'].keys(): self.create_trigger_event(event) except KeyError: pass try: for event in config['slide_player'].keys(): self.create_trigger_event(event) except KeyError: pass try: for event in config['event_player'].keys(): self.create_trigger_event(event) except KeyError: pass try: for k, v in config['sound_player'].iteritems(): if 'start_events' in v: for event in Util.string_to_list(v['start_events']): self.create_trigger_event(event) if 'stop_events' in v: for event in Util.string_to_list(v['stop_events']): self.create_trigger_event(event) except KeyError: pass
def load_config_file(filename, verify_version=True, halt_on_error=True): config = FileManager.load(filename, verify_version, halt_on_error) if 'config' in config: path = os.path.split(filename)[0] for file in Util.string_to_list(config['config']): full_file = os.path.join(path, file) config = Util.dict_merge(config, Config.load_config_file(full_file)) return config
def _load_plugins(self): self.log.info("Loading plugins...") # TODO: This should be cleaned up. Create a Plugins superclass and # classmethods to determine if the plugins should be used. for plugin in Util.string_to_list(self.config['mpf']['plugins']): self.log.debug("Loading '%s' plugin", plugin) pluginObj = self.string_to_class(plugin)(self) self.plugins.append(pluginObj)
def collect_balls(self, target='home, trough'): """Used to ensure that all balls are in contained in ball devices with the tag or list of tags you pass. Typically this would be used after a game ends, or when the machine is reset or first starts up, to ensure that all balls are in devices tagged with 'home' and/or 'trough'. Args: target: A string of the tag name or a list of tags names of the ball devices you want all the balls to end up in. Default is ['home', 'trough']. """ # I'm embarrassed at how ugly this code is. But meh, it works... tag_list = Util.string_to_list(target) self.log.debug("Collecting all balls to devices with tags '%s'", tag_list) target_devices = set() source_devices = set() balls_to_collect = False for tag in tag_list: for device in self.machine.ball_devices.items_tagged(tag): target_devices.add(device) for device in self.machine.ball_devices: if device not in target_devices: if device.balls: source_devices.add(device) balls_to_collect = True self.log.debug("Ejecting all balls from: %s", source_devices) if balls_to_collect: self.machine.events.post('collecting_balls') for device in target_devices: self.machine.events.replace_handler( 'balldevice_{}_ball_enter'.format(device.name), self._collecting_balls_entered_callback, target=target) for device in source_devices: device.eject_all() else: self.log.debug("All balls are collected")
def _load_plugins(self): self.log.info("Loading plugins...") # TODO: This should be cleaned up. Create a Plugins superclass and # classmethods to determine if the plugins should be used. for plugin in Util.string_to_list( self.config['mpf']['plugins']): self.log.debug("Loading '%s' plugin", plugin) pluginObj = self.string_to_class(plugin)(self) self.plugins.append(pluginObj)
def _load_config_file(self, filename, verify_version=True, halt_on_error=True): config_file = MPFConfigFile(filename, FileManager.load(filename, verify_version, halt_on_error, True)) try: if 'config' in config_file.config: path = os.path.split(filename)[0] for file in Util.string_to_list(config_file.config['config']): full_file = os.path.join(path, file) new_config = self._load_config_file(full_file) config_file.add_child_file(new_config) return config_file except TypeError: return dict()
def are_balls_collected(self, target=None, antitarget=None): """Checks to see if all the balls are contained in devices tagged with the parameter that was passed. Note if you pass a target that's not used in any ball devices, this method will return True. (Because you're asking if all balls are nowhere, and they always are. :) Args: target: String or list of strings of the tags you'd like to collect the balls to. Default of None will be replaced with 'home' and 'trough'. """ if not target: target = ['home', 'trough'] self.log.debug( "Checking to see if all the balls are in devices tagged" " with '%s'", target) if type(target) is str: target = Util.string_to_list(target) count = 0 devices = set() for tag in target: for device in self.machine.ball_devices.items_tagged(tag): devices.add(device) if len(devices) == 0: # didn't find any devices matching that tag, so we return True return True for device in devices: count += device.get_status('balls') self.log.debug('Found %s ball(s) in %s. Found %s total', device.get_status('balls'), device.name, count) if count == self.machine.ball_controller.num_balls_known: self.log.debug("Yes, all balls are collected") return True else: self.log.debug( "No, all balls are not collected. Balls Counted: %s. " "Total balls known: %s", count, self.machine.ball_controller.num_balls_known) return False
def are_balls_collected(self, target=None, antitarget=None): """Checks to see if all the balls are contained in devices tagged with the parameter that was passed. Note if you pass a target that's not used in any ball devices, this method will return True. (Because you're asking if all balls are nowhere, and they always are. :) Args: target: String or list of strings of the tags you'd like to collect the balls to. Default of None will be replaced with 'home' and 'trough'. """ if not target: target = ['home', 'trough'] self.log.debug("Checking to see if all the balls are in devices tagged" " with '%s'", target) if type(target) is str: target = Util.string_to_list(target) count = 0 devices = set() for tag in target: for device in self.machine.ball_devices.items_tagged(tag): devices.add(device) if len(devices) == 0: # didn't find any devices matching that tag, so we return True return True for device in devices: count += device.get_status('balls') self.log.debug('Found %s ball(s) in %s. Found %s total', device.get_status('balls'), device.name, count) if count == self.machine.ball_controller.num_balls_known: self.log.debug("Yes, all balls are collected") return True else: self.log.debug("No, all balls are not collected. Balls Counted: %s. " "Total balls known: %s", count, self.machine.ball_controller.num_balls_known) return False
def process_random_event_player(self, config, mode=None, priority=0): # config is localized to 'event_player' if self.debug: self.log.debug("Processing random_event_player configuration. Priority:" " %s", priority) event_keys = set() for event_name, events in config.iteritems(): if type(events) is not list: events = Util.string_to_list(events) event_keys.add(self.machine.events.add_handler(event_name, self._random_event_player_callback, priority, event_list=events)) return self.unload_event_player_events, event_keys
def process_random_event_player(self, config, mode=None, priority=0): # config is localized to 'event_player' if self.debug: self.log.debug( "Processing random_event_player configuration. Priority:" " %s", priority) event_keys = set() for event_name, events in config.iteritems(): if type(events) is not list: events = Util.string_to_list(events) event_keys.add( self.machine.events.add_handler( event_name, self._random_event_player_callback, priority, event_list=events)) return self.unload_event_player_events, event_keys
def get_hw_switch_states(self): if not self.initial_states_sent: if 'virtual_platform_start_active_switches' in self.machine.config: initial_active_switches = [self.machine.switches[x].number for x in Util.string_to_list( self.machine.config['virtual_platform_start_active_switches'])] for k, v in self.hw_switches.iteritems(): if k in initial_active_switches: self.hw_switches[k] ^= 1 self.initial_states_sent = True else: switches = [x for x in self.machine.switches if x.platform == self] for switch in switches: self.hw_switches[switch.number] = switch.state ^ switch.invert return self.hw_switches
def validate_config_item(spec, item='item not in config!@#'): try: if item.lower() == 'none': item = None except AttributeError: pass default = 'default required!@#' if '|' in spec: item_type, default = spec.split('|') if type(default) is str and default.lower() == 'none': default = None else: item_type = spec if item == 'item not in config!@#': if default == 'default required!@#': log.error( 'Required setting missing from config file. Run with ' 'verbose logging and look for the last ' 'ConfigProcessor entry above this line to see where ' 'the problem is.') sys.exit() else: item = default if item_type == 'list': return Util.string_to_list(item) if item_type == 'list_of_dicts': if type(item) is list: return item elif type(item) is dict: return [item] elif item_type == 'set': return set(Util.string_to_list(item)) elif item_type == 'dict': if type(item) is dict or type(item) is CaseInsensitiveDict: return item elif not default: return dict() else: log.error('Config error. "%s" is not a dictionary', item) sys.exit() elif item_type == 'int': try: return int(item) except TypeError: return None elif item_type == 'float': try: return float(item) except TypeError: return None elif item_type in ('string', 'str'): if item: return str(item) else: return None elif item_type in ('boolean', 'bool'): if type(item) is bool: return item else: return str(item).lower() in ('yes', 'true') elif item_type == 'ms': return Timing.string_to_ms(item) elif item_type == 'secs': return Timing.string_to_secs(item) elif item_type == 'list_of_lists': return Util.list_of_lists(item)
def __init__(self, machine): if ('bcp' not in machine.config or 'connections' not in machine.config['bcp']): return self.log = logging.getLogger('BCP') self.machine = machine self.config = machine.config['bcp'] self.receive_queue = Queue() self.bcp_events = dict() self.connection_config = self.config['connections'] self.bcp_clients = list() self.bcp_receive_commands = {'error': self.bcp_receive_error, 'switch': self.bcp_receive_switch, 'trigger': self.bcp_receive_trigger, 'get': self.bcp_receive_get, 'set': self.bcp_receive_set, 'reset_complete': self.bcp_receive_reset_complete, 'external_show_start': self.external_show_start, 'external_show_stop': self.external_show_stop, 'external_show_frame': self.external_show_frame, } self.dmd = None self.filter_player_events = True self.filter_machine_vars = True self.filter_shots = True self.send_player_vars = False self.send_machine_vars = False self.mpfmc_trigger_events = set() self.track_volumes = dict() self.volume_control_enabled = False # Add the following to the set of events that already have mpf mc # triggers since these are all posted on the mc side already self.mpfmc_trigger_events.add('timer_tick') self.mpfmc_trigger_events.add('ball_started') self.mpfmc_trigger_events.add('ball_ended') self.mpfmc_trigger_events.add('player_add_success') try: if self.machine.config['dmd']['physical']: self._setup_dmd() except KeyError: pass try: self.bcp_events = self.config['event_map'] self.process_bcp_events() except KeyError: pass try: self._setup_track_volumes(self.machine.config['volume']) except KeyError: self.log.warning("No 'Volume:' section in config file") if ('player_variables' in self.config and self.config['player_variables']): self.send_player_vars = True self.config['player_variables'] = ( Util.string_to_list(self.config['player_variables'])) if '__all__' in self.config['player_variables']: self.filter_player_events = False self._setup_player_monitor() if ('machine_variables' in self.config and self.config['machine_variables']): self.send_machine_vars = True self.config['machine_variables'] = ( Util.string_to_list(self.config['machine_variables'])) if '__all__' in self.config['machine_variables']: self.filter_machine_vars = False self._setup_machine_var_monitor() if ('shots' in self.config and self.config['shots']): self.config['shots'] = ( Util.string_to_list(self.config['shots'])) if '__all__' in self.config['shots']: self.filter_shots = False self._setup_shot_monitor() self.register_mpfmc_trigger_events(self.machine.config) try: self.register_triggers(self.machine.config['triggers']) except KeyError: pass self.machine.events.add_handler('init_phase_2', self._setup_bcp_connections) self.machine.events.add_handler('timer_tick', self.get_bcp_messages) self.machine.events.add_handler('player_add_success', self.bcp_player_added) self.machine.events.add_handler('machine_reset_phase_1', self.bcp_reset) self.machine.events.add_handler('increase_volume', self.increase_volume) self.machine.events.add_handler('decrease_volume', self.decrease_volume) self.machine.events.add_handler('enable_volume_keys', self.enable_volume_keys) self.machine.events.add_handler('disable_volume_keys', self.disable_volume_keys) self.machine.events.add_handler('bcp_get_led_coordinates', self.get_led_coordinates) self.machine.mode_controller.register_start_method(self.bcp_mode_start, 'mode') self.machine.mode_controller.register_start_method(self.register_triggers, 'triggers') self.machine.mode_controller.register_load_method( self.register_mpfmc_trigger_events)
def validate_config_item2( self, spec, validation_failure_info, item='item not in config!@#', ): default = 'default required!@#' item_type, validation, default = spec.split('|') if default.lower() == 'none': default = None if item == 'item not in config!@#': if default == 'default required!@#': log.error( 'Required setting missing from config file. Run with ' 'verbose logging and look for the last ' 'ConfigProcessor entry above this line to see where ' 'the problem is.') sys.exit() else: item = default if item_type == 'single': item = self.validate_item(item, validation, validation_failure_info) elif item_type == 'list': item = Util.string_to_list(item) new_list = list() for i in item: new_list.append( self.validate_item(i, validation, validation_failure_info)) item = new_list elif item_type == 'set': item = set(Util.string_to_list(item)) new_set = set() for i in item: new_set.add( self.validate_item(i, validation, validation_failure_info)) item = new_set elif item_type == 'dict': item = self.validate_item(item, validation, validation_failure_info) if not item: item = dict() else: self.log.error("Invalid Type '%s' in config spec %s:%s", item_type, validation_failure_info[0][0], validation_failure_info[1]) sys.exit() return item
action="store_true", dest="create", help="Create a new machine if not found") parser.add_argument("-N", action="store", dest="mpfconfigfile", default=os.path.join("mpf", "mpfconfig.yaml"), metavar='config_file', help="The MPF framework default config file. Default is " "mpf/mpfconfig.yaml") parser.add_argument("--version", action="version", version=version.version_str, help="Displays the MPF Wizard version info and exits") args = parser.parse_args() args.configfile = Util.string_to_list(args.configfile) try: os.makedirs('logs') except OSError as exception: if exception.errno != errno.EEXIST: raise # logging config dictLogConfig = { 'version': 1, 'formatters': { 'standard': { 'format': '%(asctime)s : %(levelname)s : %(name)s : %(message)s' }
def validate_item(self, item, validator, validation_failure_info): try: if item.lower() == 'none': item = None except AttributeError: pass if ':' in validator: validator = validator.split(':') # item could be str, list, or list of dicts item = Util.event_config_to_dict(item) return_dict = dict() for k, v in item.iteritems(): return_dict[self.validate_item( k, validator[0], validation_failure_info)] = (self.validate_item( v, validator[1], validation_failure_info)) item = return_dict elif '%' in validator: if type(item) is str: try: item = eval(validator.replace('%', "'" + item + "'")) except KeyError: self.validation_error(item, validation_failure_info) else: item = None elif validator == 'str': if item is not None: item = str(item) else: item = None elif validator == 'float': try: item = float(item) except (TypeError, ValueError): # TODO error pass elif validator == 'int': try: item = int(item) except (TypeError, ValueError): # TODO error pass elif validator in ('bool', 'boolean'): if type(item) is str: if item.lower() in ['false', 'f', 'no', 'disable', 'off']: item = False elif not item: item = False else: item = True elif validator == 'ms': item = Timing.string_to_ms(item) elif validator == 'secs': item = Timing.string_to_secs(item) elif validator == 'ticks': item = Timing.string_to_ticks(item) elif validator == 'ticks_int': item = int(Timing.string_to_ticks(item)) elif validator == 'list': item = Util.string_to_list(item) else: self.log.error("Invalid Validator '%s' in config spec %s:%s", validator, validation_failure_info[0][0], validation_failure_info[1]) sys.exit() return item
def register_sound_event(self, config, priority=0, block=False): """Sets up game sounds from the config file. Args: config: Python dictionary which contains the game sounds settings. """ self.log.debug("Registering sound events from config: %s", config) if 'sound' not in config: return False elif type(config['sound']) is str: config['sound'] = self.machine.sounds[config['sound']] # this is kind of weird because once the sound has been registered, the # sound will still be converted from the string to the object. This is # an unintended side effect of passing around a dict, but I guess it's # ok? We just have to check to make sure we have a string before we # try to convert it to an object. If not, the conversion has already # been done. if 'start_events' not in config: config['start_events'] = list() else: config['start_events'] = Util.string_to_list( config['start_events']) if 'stop_events' not in config: config['stop_events'] = list() else: config['stop_events'] = Util.string_to_list( config['stop_events']) if 'duration' not in config or config['duration'] is None: config['duration'] = None if 'loops' not in config or config['loops'] is None: config['loops'] = 0 if 'priority' not in config or config['priority'] is None: config['priority'] = 0 if 'fade_in' not in config or config['fade_in'] is None: config['fade_in'] = 0 if 'fade_out' not in config or config['fade_out'] is None: config['fade_out'] = 0 if 'channel' not in config or config['channel'] is None: config['channel'] = 'auto' if 'volume' not in config or config['volume'] is None: config['volume'] = 1 elif config['volume'] > 2: config['volume'] = 2 config['key'] = uuid.uuid4() #config['event_keys'] = set() for event in config['start_events']: self.log.debug("Checking config for event '%s'", event) settings = copy.copy(config) settings.pop('start_events') settings.pop('stop_events') if event not in self.sound_events: self.sound_events[event] = list() self.log.debug("Adding '%s' to sound_events list", event) self.machine.events.add_handler(event, self._sound_event_callback, event_name=event) kwargs = dict() # temp sound_event_entry = dict() sound_event_entry['settings'] = settings sound_event_entry['kwargs'] = kwargs sound_event_entry['priority'] = priority sound_event_entry['block'] = block sound_event_entry['type'] = 'start' self.log.debug("Registering Sound for Event: %s. Settings: %s", event, settings) self.sound_events[event].append(sound_event_entry) for event in config['stop_events']: settings = copy.copy(config) settings.pop('start_events') settings.pop('stop_events') if event not in self.sound_events: self.sound_events[event] = list() self.machine.events.add_handler(event, self._sound_event_callback, event_name=event) kwargs = dict() # temp sound_event_entry = dict() sound_event_entry['settings'] = settings sound_event_entry['kwargs'] = kwargs sound_event_entry['priority'] = priority sound_event_entry['block'] = block sound_event_entry['type'] = 'stop' self.log.debug("Registering Sound for Event: %s. Settings: %s", event, settings) self.sound_events[event].append(sound_event_entry) # todo sort by priority return config['key']
def __init__(self, machine): if ('bcp' not in machine.config or 'connections' not in machine.config['bcp']): return self.log = logging.getLogger('BCP') self.machine = machine self.config = machine.config['bcp'] self.receive_queue = Queue() self.bcp_events = dict() self.connection_config = self.config['connections'] self.bcp_clients = list() self.bcp_receive_commands = { 'error': self.bcp_receive_error, 'switch': self.bcp_receive_switch, 'trigger': self.bcp_receive_trigger, 'get': self.bcp_receive_get, 'set': self.bcp_receive_set, 'reset_complete': self.bcp_receive_reset_complete, 'external_show_start': self.external_show_start, 'external_show_stop': self.external_show_stop, 'external_show_frame': self.external_show_frame, } self.dmd = None self.filter_player_events = True self.filter_machine_vars = True self.filter_shots = True self.send_player_vars = False self.send_machine_vars = False self.mpfmc_trigger_events = set() self.track_volumes = dict() self.volume_control_enabled = False # Add the following to the set of events that already have mpf mc # triggers since these are all posted on the mc side already self.mpfmc_trigger_events.add('timer_tick') self.mpfmc_trigger_events.add('ball_started') self.mpfmc_trigger_events.add('ball_ended') self.mpfmc_trigger_events.add('player_add_success') try: if self.machine.config['dmd']['physical']: self._setup_dmd() except KeyError: pass try: self.bcp_events = self.config['event_map'] self.process_bcp_events() except KeyError: pass try: self._setup_track_volumes(self.machine.config['volume']) except KeyError: self.log.warning("No 'Volume:' section in config file") if ('player_variables' in self.config and self.config['player_variables']): self.send_player_vars = True self.config['player_variables'] = (Util.string_to_list( self.config['player_variables'])) if '__all__' in self.config['player_variables']: self.filter_player_events = False self._setup_player_monitor() if ('machine_variables' in self.config and self.config['machine_variables']): self.send_machine_vars = True self.config['machine_variables'] = (Util.string_to_list( self.config['machine_variables'])) if '__all__' in self.config['machine_variables']: self.filter_machine_vars = False self._setup_machine_var_monitor() if ('shots' in self.config and self.config['shots']): self.config['shots'] = (Util.string_to_list(self.config['shots'])) if '__all__' in self.config['shots']: self.filter_shots = False self._setup_shot_monitor() self.register_mpfmc_trigger_events(self.machine.config) try: self.register_triggers(self.machine.config['triggers']) except KeyError: pass self.machine.events.add_handler('init_phase_2', self._setup_bcp_connections) self.machine.events.add_handler('timer_tick', self.get_bcp_messages) self.machine.events.add_handler('player_add_success', self.bcp_player_added) self.machine.events.add_handler('machine_reset_phase_1', self.bcp_reset) self.machine.events.add_handler('increase_volume', self.increase_volume) self.machine.events.add_handler('decrease_volume', self.decrease_volume) self.machine.events.add_handler('enable_volume_keys', self.enable_volume_keys) self.machine.events.add_handler('disable_volume_keys', self.disable_volume_keys) self.machine.events.add_handler('bcp_get_led_coordinates', self.get_led_coordinates) self.machine.mode_controller.register_start_method( self.bcp_mode_start, 'mode') self.machine.mode_controller.register_start_method( self.register_triggers, 'triggers') self.machine.mode_controller.register_load_method( self.register_mpfmc_trigger_events)
def validate_config_item(spec, item='item not in config!@#'): try: if item.lower() == 'none': item = None except AttributeError: pass default = 'default required!@#' if '|' in spec: item_type, default = spec.split('|') if type(default) is str and default.lower() == 'none': default = None else: item_type = spec if item == 'item not in config!@#': if default == 'default required!@#': log.error('Required setting missing from config file. Run with ' 'verbose logging and look for the last ' 'ConfigProcessor entry above this line to see where ' 'the problem is.') sys.exit() else: item = default if item_type == 'list': return Util.string_to_list(item) if item_type == 'list_of_dicts': if type(item) is list: return item elif type(item) is dict: return [item] elif item_type == 'set': return set(Util.string_to_list(item)) elif item_type == 'dict': if type(item) is dict or type(item) is CaseInsensitiveDict: return item elif not default: return dict() else: log.error('Config error. "%s" is not a dictionary', item) sys.exit() elif item_type == 'int': try: return int(item) except TypeError: return None elif item_type == 'float': try: return float(item) except TypeError: return None elif item_type in ('string', 'str'): if item: return str(item) else: return None elif item_type in ('boolean', 'bool'): if type(item) is bool: return item else: return str(item).lower() in ('yes', 'true') elif item_type == 'ms': return Timing.string_to_ms(item) elif item_type == 'secs': return Timing.string_to_secs(item) elif item_type == 'list_of_lists': return Util.list_of_lists(item)
parser.add_argument("-C", action="store", dest="mpfconfigfile", default=os.path.join("mpf", "mpfconfig.yaml"), metavar='config_file', help="The MPF framework default config file. Default is " "mpf/mpfconfig.yaml") parser.add_argument("--version", action="version", version=version.version_str, help="Displays the MPF, config file, and BCP version info " "and exits") args = parser.parse_args() args.configfile = Util.string_to_list(args.configfile) # Configure logging. Creates a logfile and logs to the console. # Formatting options are documented here: # https://docs.python.org/2.7/library/logging.html#logrecord-attributes try: os.makedirs('logs') except OSError as exception: if exception.errno != errno.EEXIST: raise logging.basicConfig( level=args.loglevel, format='%(asctime)s : %(levelname)s : %(name)s : %(message)s', filename=args.logfile,
# if --version was passed, print the version and quit if options_dict['version']: print "Mission Pinball Framework version:", version.__version__ print "Requires Config File version:", version.__config_version__ sys.exit() # add the first positional argument into the options dict as the machine path try: options_dict['machinepath'] = args[0] except KeyError: print "Error: You need to specify the path to your machine_files folder "\ "for the game you want to run." sys.exit() options_dict['configfile'] = Util.string_to_list(options_dict['configfile']) # Configure logging. Creates a logfile and logs to the console. # Formating options are documented here: # https://docs.python.org/2.7/library/logging.html#logrecord-attributes try: os.makedirs('logs') except OSError as exception: if exception.errno != errno.EEXIST: raise logging.basicConfig(level=options.loglevel, format='%(asctime)s : %(levelname)s : %(name)s : %(message)s', filename=options.logfile, filemode='w')
def validate_item(self, item, validator, validation_failure_info): try: if item.lower() == 'none': item = None except AttributeError: pass if ':' in validator: validator = validator.split(':') # item could be str, list, or list of dicts item = Util.event_config_to_dict(item) return_dict = dict() for k, v in item.iteritems(): return_dict[self.validate_item(k, validator[0], validation_failure_info)] = ( self.validate_item(v, validator[1], validation_failure_info) ) item = return_dict elif '%' in validator: if type(item) is str: try: item = eval(validator.replace('%', "'" + item + "'")) except KeyError: self.validation_error(item, validation_failure_info) else: item = None elif validator == 'str': if item is not None: item = str(item) else: item = None elif validator == 'float': try: item = float(item) except (TypeError, ValueError): # TODO error pass elif validator == 'int': try: item = int(item) except (TypeError, ValueError): # TODO error pass elif validator in ('bool', 'boolean'): if type(item) is str: if item.lower() in ['false', 'f', 'no', 'disable', 'off']: item = False elif not item: item = False else: item = True elif validator == 'ms': item = Timing.string_to_ms(item) elif validator == 'secs': item = Timing.string_to_secs(item) elif validator == 'ticks': item = Timing.string_to_ticks(item) elif validator == 'ticks_int': item = int(Timing.string_to_ticks(item)) elif validator == 'list': item = Util.string_to_list(item) else: self.log.error("Invalid Validator '%s' in config spec %s:%s", validator, validation_failure_info[0][0], validation_failure_info[1]) sys.exit() return item