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'] = Config.string_to_list( config['start_events']) else: config['start_events'] = list() if 'stop_events' in config: config['stop_events'] = Config.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, config): super(FadeCandyOPClient, self).__init__(machine, config) self.log = logging.getLogger('FadeCandyClient') self.update_every_tick = True self.gamma = self.machine.config['ledsettings']['gamma'] self.whitepoint = Config.string_to_list( self.machine.config['ledsettings']['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['ledsettings']['linear_slope']) self.linear_cutoff = ( self.machine.config['ledsettings']['linear_cutoff']) self.keyframe_interpolation = ( self.machine.config['ledsettings']['keyframe_interpolation']) self.dithering = self.machine.config['ledsettings']['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 set_brightness_compensation(self, value): """Sets the brightness compensation for this LED. args: value: Str or list (of 1-to-3 items) of the new brightness compensation value to set. List items are floats. 1.0 is standard full brightness. 0.0 is off. 2.0 is 200% brightness (which only comes into play if the LED is not at full brightness). If the value is a string, it's converted to a list, broken by commas. The brightness compensation list is three items long, one for each RGB element. If the LED has less than three elements, additional values are ignored. If the value list is only one item, that value is used for all three elements. If the value list is two items, a value of 1.0 is used for the third item. """ if type(value) is not list: value = Config.string_to_list(value) value = [float(x) for x in value] if len(value) == 1: value.extend([value[0], value[0]]) elif len(value) == 2: value.append(1.0) self.config["brightness_compensation"] = value
def __init__(self, machine, name, config, priority): """SequenceShot is where you need certain switches to be hit in the right order, possibly within a time limit. Subclass of `Shot` Args: machine: The MachineController object name: String name of this shot. config: Dictionary that holds the configuration for this shot. """ super(SequenceShot, self).__init__(machine, name, config, priority) self.delay = DelayManager() self.progress_index = 0 """Tracks how far along through this sequence the current shot is.""" # convert our switches config to a list if 'switches' in self.config: self.config['switches'] = \ Config.string_to_list(self.config['switches']) # convert our timout to ms if 'time' in self.config: self.config['time'] = Timing.string_to_ms(self.config['time']) else: self.config['time'] = 0 self.active_delay = False self.enable()
def disable(self): """Disables the shot.""" super(StandardShot, self).disable() for switch in Config.string_to_list(self.config['switch']): self.machine.switch_controller.remove_switch_handler( switch, self._switch_handler)
def enable(self): """Enables the shot.""" super(StandardShot, self).enable() for switch in Config.string_to_list(self.config['switch']): self.machine.switch_controller.add_switch_handler( switch, self._switch_handler, return_info=True)
def __init__(self, machine, name, config, collection=None, validate=True): self.shots = list() # list of strings for shot in Config.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, 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 ''' 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'] = Config.string_to_list( config['events_when_complete']) if 'reset_each_ball' in config and config['reset_each_ball']: if 'ball_starting' not in self.config['reset_events']: self.config['reset_events'].append('ball_starting')
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_on_complete: boolean|False disable_on_complete: boolean|True ''' 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'] = Config.string_to_list( config['events_when_complete']) if 'reset_each_ball' in config and config['reset_each_ball']: if 'ball_starting' not in self.config['reset_events']: self.config['reset_events'].append('ball_starting')
def _load_plugins(self): for plugin in Config.string_to_list(self.config['mpf']['plugins']): self.log.info("Loading '%s' plugin", plugin) i = __import__('mpf.plugins.' + plugin, fromlist=['']) self.plugins.append(i.plugin_class(self))
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_on_complete: boolean|False disable_on_complete: boolean|True """ 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"] = Config.string_to_list(config["events_when_complete"]) if "reset_each_ball" in config and config["reset_each_ball"]: if "ball_starting" not in self.config["reset_events"]: self.config["reset_events"].append("ball_starting")
def __init__(self, machine, name, config, collection, member_collection=None, device_str=None): self.device_str = 'drop_targets' self.log = logging.getLogger('DropTargetBank.' + name) super(DropTargetBank, self).__init__(machine, name, config, collection, machine.drop_targets, self.device_str) # set config defaults if 'reset_events' not in self.config: self.config['reset_events'] = None if 'reset_coils' in self.config: self.config['reset_coils'] = Config.string_to_list( self.config['reset_coils']) # can't read the switches until the switch controller is set up self.machine.events.add_handler('init_phase_1', self.update_count)
def _load_plugins(self): for plugin in Config.string_to_list( self.config['mpf']['plugins']): self.log.info("Loading '%s' plugin", plugin) i = __import__('mpf.plugins.' + plugin, fromlist=['']) self.plugins.append(i.plugin_class(self))
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 Config.string_to_list(v['start_events']): self.create_trigger_event(event) if 'stop_events' in v: for event in Config.string_to_list(v['stop_events']): self.create_trigger_event(event) except KeyError: pass
def _configure(self): self.config = self.machine.config['languages'] self.machine.language = self self.languages = Config.string_to_list( self.machine.config['languages']) # Set the default language to the first entry in the list self.set_language(self.languages[0]) self.default_language = self.languages[0] self.find_text = re.compile('(\(.*?\))')
def _load(self, callback, show_actions=None): self.show_actions = list() self.asset_manager.log.debug("Loading Show %s", self.file_name) if not show_actions: show_actions = self.load_show_from_disk() for step_num in range(len(show_actions)): step_actions = dict() step_actions['tocks'] = show_actions[step_num]['tocks'] # look for empty steps. If we find them we'll just add their tock # time to the previous step. if len(show_actions[step_num]) == 1: # 1 because it still has tocks show_actions[-1]['tocks'] += step_actions['tocks'] continue # Events # make sure events is a list of strings if ('events' in show_actions[step_num] and show_actions[step_num]['events']): event_list = (Config.string_to_list( show_actions[step_num]['events'])) step_actions['events'] = event_list # SlidePlayer if ('display' in show_actions[step_num] and show_actions[step_num]['display']): step_actions['display'] = ( self.machine.display.slidebuilder.preprocess_settings( show_actions[step_num]['display'])) self.show_actions.append(step_actions) # count how many total locations are in the show. We need this later # so we can know when we're at the end of a show self.total_locations = len(self.show_actions) self.loaded = True if callback: callback() self._asset_loaded()
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 Config.string_to_list( self.config['mpf']['plugins']): self.log.debug("Loading '%s' plugin", plugin) i = __import__('mpf.plugins.' + plugin, fromlist=['']) self.plugins.append(i.plugin_class(self))
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['showplayer'].keys(): self.create_trigger_event(event) except KeyError: pass try: for event in config['slideplayer'].keys(): self.create_trigger_event(event) except KeyError: pass try: for k, v in config['soundplayer'].iteritems(): if 'start_events' in v: for event in Config.string_to_list(v['start_events']): self.create_trigger_event(event) if 'stop_events' in v: for event in Config.string_to_list(v['stop_events']): self.create_trigger_event(event) except KeyError: pass
def _event_config_to_dict(self, config): # processes the enable, disable, and reset events from the config file return_dict = dict() if type(config) is dict: return config elif type(config) is str: config = Config.string_to_list(config) # 'if' instead of 'elif' to pick up just-converted str if type(config) is list: for event in config: return_dict[event] = 0 return return_dict
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 = Config.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 Config.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 list_of_switch_numbers: self.hw_switches[x.number] = x.state ^ x.invert return self.hw_switches
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 } self.dmd = None self.filter_player_events = True self.send_player_vars = False self.mpfmc_trigger_events = set() self.track_volumes = dict() self.volume_control_enabled = False 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 if (type(self.config['player_variables']) is str and self.config['player_variables'] == '__all__'): self.filter_player_events = False else: self.config['player_variables'] = (Config.string_to_list( self.config['player_variables'])) self._setup_player_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('game_starting', self.bcp_game_start) 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.modes.register_start_method(self.bcp_mode_start, 'mode') self.machine.modes.register_start_method(self.register_triggers, 'triggers') self.machine.modes.register_load_method( self.register_mpfmc_trigger_events)
def __init__(self, machine, name, config, collection=None): self.log = logging.getLogger('LED.' + name) super(LED, self).__init__(machine, name, config, collection, platform_section='leds') self.log.debug("Creating '%s' with config: %s", name, config) # We save out number_str since the platform driver will convert the # number into a hardware number, but we need the original number for # some things later. self.config['number_str'] = str(config['number']).upper() if 'default_color' in self.config: if type(self.config['default_color']) is str: self.config['default_color'] = self.hexstring_to_list( input_string=self.config['default_color'], output_length=3) else: self.config['default_color'] = [255, 255, 255] self.hw_driver = self.platform.configure_led(self.config) self.fade_in_progress = False self.fade_task = None self.fade_destination_color = [0.0, 0.0, 0.0] self.fade_end_time = None self.state = { # current state of this LED 'color': [0.0, 0.0, 0.0], 'priority': 0, 'destination_color': [0.0, 0.0, 0.0], 'destination_time': 0.0, 'start_color': [0.0, 0.0, 0.0], 'start_time': 0.0 } self.cache = { # cached state of last manual command 'color': [0.0, 0.0, 0.0], 'priority': 0, 'destination_color': [0.0, 0.0, 0.0], 'destination_time': 0.0, 'start_color': [0.0, 0.0, 0.0], 'start_time': 0.0 } if 'brightness_compensation' not in self.config: self.config['brightness_compensation'] = [1.0, 1.0, 1.0] else: # make sure our config string is a list self.config['brightness_compensation'] = ( Config.string_to_list( self.config['brightness_compensation'])) # if there's only one value in the list, use it for all the elements if len(self.config['brightness_compensation']) == 1: self.config['brightness_compensation'].extend( [self.config['brightness_compensation'][0], self.config['brightness_compensation'][0]]) # if there are only two elements, use 1.0 for the third. elif len(self.config['brightness_compensation']) == 2: self.config['brightness_compensation'].append(1.0) # make sure they're all floats for i in range(3): self.config['brightness_compensation'][i] = ( float(self.config['brightness_compensation'][i])) if 'fade_ms' not in self.config: self.config['fade_ms'] = None self.current_color = [] # one item for each element, 0-255 if self.debug_logging: self.log.info("Intial settings: %s", self.config)
def __init__(self, machine, name, config, collection=None): self.log = logging.getLogger('Diverter.' + name) super(Diverter, self).__init__(machine, name, config, collection) self.delay = DelayManager() # Attributes self.active = False self.enabled = False # configure defaults: if 'type' not in self.config: self.config['type'] = 'pulse' # default to pulse to not fry coils if 'activation_time' not in self.config: self.config['activation_time'] = 0 if 'activation_switches' in self.config: self.config['activation_switches'] = Config.string_to_list( self.config['activation_switches']) else: self.config['activation_switches'] = list() if 'disable_switches' in self.config: self.config['disable_switches'] = Config.string_to_list( self.config['disable_switches']) else: self.config['disable_switches'] = list() if 'deactivation_switches' in self.config: self.config['deactivation_switches'] = Config.string_to_list( self.config['deactivation_switches']) else: self.config['deactivation_switches'] = list() if 'activation_coil' in self.config: self.config['activation_coil'] = ( self.machine.coils[self.config['activation_coil']]) if 'deactivation_coil' in self.config: self.config['deactivation_coil'] = ( self.machine.coils[self.config['deactivation_coil']]) else: self.config['deactivation_coil'] = None if 'targets_when_active' in self.config: self.config['targets_when_active'] = Config.string_to_list( self.config['targets_when_active']) else: self.config['targets_when_active'] = ['playfield'] if 'targets_when_inactive' in self.config: self.config['targets_when_inactive'] = Config.string_to_list( self.config['targets_when_inactive']) else: self.config['targets_when_inactive'] = ['playfield'] if 'feeder_devices' in self.config: self.config['feeder_devices'] = Config.string_to_list( self.config['feeder_devices']) else: self.config['feeder_devices'] = list() # Create a list of ball device objects when active and inactive. We need # this because ball eject attempts pass the target device as an object # rather than by name. self.config['active_objects'] = list() self.config['inactive_objects'] = list() for target_device in self.config['targets_when_active']: if target_device == 'playfield': self.config['active_objects'].append('playfield') else: self.config['active_objects'].append( self.machine.balldevices[target_device]) for target_device in self.config['targets_when_inactive']: if target_device == 'playfield': self.config['inactive_objects'].append('playfield') else: self.config['inactive_objects'].append( self.machine.balldevices[target_device]) # convert the activation_time to ms self.config['activation_time'] = Timing.string_to_ms(self.config['activation_time']) # register for events for event in self.config['enable_events']: self.machine.events.add_handler(event, self.enable) for event in self.config['disable_events']: self.machine.events.add_handler(event, self.disable) # register for feeder device eject events for feeder_device in self.config['feeder_devices']: self.machine.events.add_handler('balldevice_' + feeder_device + '_ball_eject_attempt', self._feeder_eject_attempt) # register for deactivation switches for switch in self.config['deactivation_switches']: self.machine.switch_controller.add_switch_handler( switch, self.deactivate) # register for disable switches: for switch in self.config['disable_switches']: self.machine.switch_controller.add_switch_handler( switch, self.disable)
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 } self.dmd = self.machine.platform.configure_dmd() self.filter_player_events = True self.send_player_vars = False self.mpfmc_trigger_events = set() self.track_volumes = dict() self.volume_control_enabled = False 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 if (type(self.config['player_variables']) is str and self.config['player_variables'] == '__all__'): self.filter_player_events = False else: self.config['player_variables'] = ( Config.string_to_list(self.config['player_variables'])) self._setup_player_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('game_starting', self.bcp_game_start) 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.modes.register_start_method(self.bcp_mode_start, 'mode') self.machine.modes.register_start_method(self.register_triggers, 'triggers') self.machine.modes.register_load_method( self.register_mpfmc_trigger_events)
def __init__(self, machine, name, config, collection=None): self.log = logging.getLogger('LED.' + name) super(LED, self).__init__(machine, name, config, collection) self.log.debug("Creating '%s' with config: %s", name, config) # We save out number_str since the platform driver will convert the # number into a hardware number, but we need the original number for # some things later. self.config['number_str'] = str(config['number']).upper() if 'default_color' in self.config: if type(self.config['default_color']) is str: self.config['default_color'] = self.hexstring_to_list( input_string=self.config['default_color'], output_length=3) else: self.config['default_color'] = [255, 255, 255] self.hw_driver = self.machine.platform.configure_led(self.config) self.fade_in_progress = False self.fade_task = None self.fade_destination_color = [0.0, 0.0, 0.0] self.fade_end_time = None self.state = { # current state of this LED 'color': [0.0, 0.0, 0.0], 'priority': 0, 'destination_color': [0.0, 0.0, 0.0], 'destination_time': 0.0, 'start_color': [0.0, 0.0, 0.0], 'start_time': 0.0 } self.cache = { # cached state of last manual command 'color': [0.0, 0.0, 0.0], 'priority': 0, 'destination_color': [0.0, 0.0, 0.0], 'destination_time': 0.0, 'start_color': [0.0, 0.0, 0.0], 'start_time': 0.0 } if 'brightness_compensation' not in self.config: self.config['brightness_compensation'] = [1.0, 1.0, 1.0] else: # make sure our config string is a list self.config['brightness_compensation'] = ( Config.string_to_list( self.config['brightness_compensation'])) # if there's only one value in the list, use it for all the elements if len(self.config['brightness_compensation']) == 1: self.config['brightness_compensation'].extend( [self.config['brightness_compensation'][0], self.config['brightness_compensation'][0]]) # if there are only two elements, use 1.0 for the third. elif len(self.config['brightness_compensation']) == 2: self.config['brightness_compensation'].append(1.0) # make sure they're all floats for i in range(3): self.config['brightness_compensation'][i] = ( float(self.config['brightness_compensation'][i])) if 'fade_ms' not in self.config: self.config['fade_ms'] = None self.current_color = [] # one item for each element, 0-255
def __init__(self, machine, name, config, collection=None, member_collection=None, device_str=None): self.log = logging.getLogger('TargetGroup.' + name) super(TargetGroup, self).__init__(machine, name, config, collection) self.delay = DelayManager() if not device_str: self.device_str = 'targets' else: self.device_str = device_str if not member_collection: member_collection = self.machine.targets self.num_lit = 0 self.num_unlit = 0 self.num_targets = 0 self.targets = list() # make sure our target list is a list self.config[self.device_str] = Config.string_to_list( self.config[self.device_str]) # create our list of objects for target in self.config[self.device_str]: self.targets.append(member_collection[target]) if 'lit_complete_show' not in self.config: self.config['lit_complete_show'] = None if 'lit_complete_script' not in self.config: self.config['lit_complete_script'] = None if 'unlit_complete_show' not in self.config: self.config['unlit_complete_show'] = None if 'unlit_complete_script' not in self.config: self.config['unlit_complete_script'] = None if 'rotate_left_events' not in self.config: self.config['rotate_left_events'] = list() else: self.config['rotate_left_events'] = Config.string_to_list( self.config['rotate_left_events']) if 'rotate_right_events' not in self.config: self.config['rotate_right_events'] = list() else: self.config['rotate_right_events'] = Config.string_to_list( self.config['rotate_right_events']) # If no reset events are specified, just self reset when complete if not self.config['reset_events']: self.config['reset_events'] = {(self.device_str + '_' + self.name + '_complete'): 0} # todo look for config typo where they don't enter a delay time? self.num_targets = len(self.targets) # set event handlers to watch for target state changes for target in self.targets: self.machine.events.add_handler( target.device_str + '_' + target.name + '_lit', self.update_count) self.machine.events.add_handler( target.device_str + '_' + target.name + '_unlit', self.update_count) # need to wait until after the show controller is loaded self.machine.events.add_handler('init_phase_2', self.load_shows) # watch for rotation events for event in self.config['rotate_left_events']: self.machine.events.add_handler(event, self.rotate, direction='left') for event in self.config['rotate_right_events']: self.machine.events.add_handler(event, self.rotate, direction='right')
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, } self.dmd = None self.filter_player_events = True self.send_player_vars = False self.mpfmc_trigger_events = set() self.track_volumes = dict() self.volume_control_enabled = False 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 if type(self.config["player_variables"]) is str and self.config["player_variables"] == "__all__": self.filter_player_events = False else: self.config["player_variables"] = Config.string_to_list(self.config["player_variables"]) self._setup_player_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("game_starting", self.bcp_game_start) 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.modes.register_start_method(self.bcp_mode_start, "mode") self.machine.modes.register_start_method(self.register_triggers, "triggers") self.machine.modes.register_load_method(self.register_mpfmc_trigger_events)
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. """ 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'] = Config.string_to_list( config['start_events']) if 'stop_events' not in config: config['stop_events'] = list() else: config['stop_events'] = Config.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']: 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'] = 'start' 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.sound_events[event].append(sound_event_entry) # todo sort by priority return config['key']
def __init__(self, machine, name, config, collection=None): self.log = logging.getLogger('Target.' + name) if 'enable_events' not in config: config['enable_events'] = {'ball_started': 0} if 'disable_events' not in config: config['disable_events'] = {'ball_ending': 0} super(Target, self).__init__(machine, name, config, collection) self.lit = False self.device_str = 'target' self.delay = DelayManager() # set config defaults if 'light' not in self.config: self.config['light'] = None elif (hasattr(self.machine, 'lights') and self.config['light'] in self.machine.lights): self.log.debug("Configuring with light: %s", self.config['light']) self.config['light'] = self.machine.lights[self.config['light']] elif (hasattr(self.machine, 'leds') and self.config['light'] in self.machine.leds): self.log.debug("Configuring with LED: %s", self.config['light']) self.config['light'] = self.machine.leds[self.config['light']] if 'light_if_unlit' not in self.config: self.config['light_if_unlit'] = True if 'unlight_if_lit' not in self.config: self.config['unlight_if_lit'] = False if 'default_state' not in self.config: self.config['default_state'] = 'unlit' if 'reset_events' in self.config: self.config['reset_events'] = Config.string_to_list( self.config['reset_events']) else: self.config['reset_events'] = [None] # todo change this to dict with timing delays? # light script # unlight script # light color # unlight color # register for switch handlers so we know if this switch is hit # note this only looks for activations self.machine.switch_controller.add_switch_handler(self.config['switch'], self.hit, 1) # register for events self.machine.events.add_handler('action_target_' + self.name + '_light', self.light) self.machine.events.add_handler('action_target_' + self.name + '_unlight', self.unlight) self.machine.events.add_handler('action_target_' + self.name + '_toggle', self.toggle)
def __init__(self, machine, name, config, collection=None, member_collection=None, device_str=None): self.log = logging.getLogger('TargetGroup.' + name) super(TargetGroup, self).__init__(machine, name, config, collection) self.delay = DelayManager() if not device_str: self.device_str = 'targets' else: self.device_str = device_str if not member_collection: member_collection = self.machine.targets self.num_lit = 0 self.num_unlit = 0 self.num_targets = 0 self.targets = list() # make sure our target list is a list self.config[self.device_str] = Config.string_to_list( self.config[self.device_str]) # create our list of objects for target in self.config[self.device_str]: self.targets.append(member_collection[target]) if 'lit_complete_show' not in self.config: self.config['lit_complete_show'] = None if 'lit_complete_script' not in self.config: self.config['lit_complete_script'] = None if 'unlit_complete_show' not in self.config: self.config['unlit_complete_show'] = None if 'unlit_complete_script' not in self.config: self.config['unlt_complete_script'] = None if 'rotate_left_events' not in self.config: self.config['rotate_left_events'] = list() else: self.config['rotate_left_events'] = Config.string_to_list( self.config['rotate_left_events']) if 'rotate_right_events' not in self.config: self.config['rotate_right_events'] = list() else: self.config['rotate_right_events'] = Config.string_to_list( self.config['rotate_right_events']) # If no reset events are specified, just self reset when complete if not self.config['reset_events']: self.config['reset_events'] = {(self.device_str + '_' + self.name + '_complete'): 0} # todo look for config typo where they don't enter a delay time? self.num_targets = len(self.targets) # set event handlers to watch for target state changes for target in self.targets: self.machine.events.add_handler( target.device_str + '_' + target.name + '_lit', self.update_count) self.machine.events.add_handler( target.device_str + '_' + target.name + '_unlit', self.update_count) # need to wait until after the show controller is loaded self.machine.events.add_handler('init_phase_2', self.load_shows) # watch for rotation events for event in self.config['rotate_left_events']: self.machine.events.add_handler(event, self.rotate, direction='left') for event in self.config['rotate_right_events']: self.machine.events.add_handler(event, self.rotate, direction='right')
def _load(self, callback, show_actions=None): self.show_actions = list() self.asset_manager.log.debug("Loading Show %s", self.file_name) if not show_actions: show_actions = self.load_show_from_disk() for step_num in range(len(show_actions)): step_actions = dict() step_actions['tocks'] = show_actions[step_num]['tocks'] # look for empty steps. If we find them we'll just add their tock # time to the previous step. if len(show_actions[step_num] ) == 1: # 1 because it still has tocks show_actions[-1]['tocks'] += step_actions['tocks'] continue # Events # make sure events is a list of strings if ('events' in show_actions[step_num] and show_actions[step_num]['events']): event_list = (Config.string_to_list( show_actions[step_num]['events'])) step_actions['events'] = event_list # SlidePlayer if ('display' in show_actions[step_num] and show_actions[step_num]['display']): step_actions['display'] = ( self.machine.display.slidebuilder.preprocess_settings( show_actions[step_num]['display'])) # Sounds if ('sounds' in show_actions[step_num] and show_actions[step_num]['sounds']): # make sure we have a list of dicts if type(show_actions[step_num]['sounds']) is dict: show_actions[step_num]['sounds'] = ([ show_actions[step_num]['sounds'] ]) for entry in show_actions[step_num]['sounds']: try: entry['sound'] = self.machine.sounds[entry['sound']] except KeyError: self.asset_manager.log.critical( "Invalid sound '%s' " "found in show. ", entry['sound']) raise step_actions['sounds'] = show_actions[step_num]['sounds'] self.show_actions.append(step_actions) # count how many total locations are in the show. We need this later # so we can know when we're at the end of a show self.total_locations = len(self.show_actions) self.loaded = True if callback: callback() self._asset_loaded()
def __init__(self, machine, name, config, collection=None): self.log = logging.getLogger('BallDevice.' + name) super(BallDevice, self).__init__(machine, name, config, collection) self.delay = DelayManager() # set config defaults if 'exit_count_delay' not in self.config: self.config['exit_count_delay'] = ".5s" # todo make optional if 'entrance_count_delay' not in self.config: self.config['entrance_count_delay'] = "0.5s" if 'eject_coil' not in self.config: self.config['eject_coil'] = None if 'eject_switch' not in self.config: self.config['eject_switch'] = None if 'entrance_switch' not in self.config: self.config['entrance_switch'] = None if 'jam_switch' not in self.config: self.config['jam_switch'] = None if 'eject_coil_hold_times' not in self.config: self.config['eject_coil_hold_times'] = list() if 'confirm_eject_type' not in self.config: self.config['confirm_eject_type'] = 'count' # todo make optional? if 'eject_targets' not in self.config: self.config['eject_targets'] = ['playfield'] else: self.config['eject_targets'] = Config.string_to_list( self.config['eject_targets']) if 'eject_timeouts' not in self.config: self.config['eject_timeouts'] = list() else: self.config['eject_timeouts'] = Config.string_to_list( self.config['eject_timeouts']) if 'confirm_eject_switch' not in self.config: self.config['confirm_eject_switch'] = None if 'confirm_eject_event' not in self.config: self.config['confirm_eject_event'] = None if 'balls_per_eject' not in self.config: self.config['balls_per_eject'] = 1 if 'max_eject_attempts' not in self.config: self.config['max_eject_attempts'] = 0 if 'ball_switches' in self.config: self.config['ball_switches'] = Config.string_to_list( self.config['ball_switches']) else: self.config['ball_switches'] = [] if 'ball_capacity' not in self.config: self.config['ball_capacity'] = len(self.config['ball_switches']) if 'debug' not in self.config: self.config['debug'] = False # initialize variables self.balls = 0 # Number of balls currently contained (held) in this device.. self.eject_queue = deque() # Queue of the list of eject targets (ball devices) for the balls this # device is trying to eject. self.num_eject_attempts = 0 # Counter of how many attempts to eject the current ball this device # has tried. Eventually it will give up. # todo log attemps more than one? self.eject_in_progress_target = None # The ball device this device is currently trying to eject to self.num_balls_requested = 0 # The number of balls this device is in the process of trying to get. self.num_jam_switch_count = 0 # How many times the jam switch has been activated since the last # successful eject. self.machine.events.add_handler('machine_reset_phase_1', self._initialize) self.num_balls_ejecting = 0 # The number of balls that are currently in the process of being # ejected. This is either 0, 1, or whatever the balls was # for devices that eject all their balls at once. self.flag_confirm_eject_via_count = False # Notifies the count_balls() method that it should confirm an eject if # it finds a ball missing. We need this to be a standalone variable # since sometimes other eject methods will have to "fall back" on count #-based confirmations. self.valid = False self.need_first_time_count = True # Now configure the device self.configure()
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 } self.dmd = None self.filter_player_events = True self.filter_shots = True self.send_player_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'] = ( Config.string_to_list(self.config['player_variables'])) if '__all__' in self.config['player_variables']: self.filter_player_events = False self._setup_player_monitor() if ('shots' in self.config and self.config['shots']): self.config['shots'] = ( Config.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.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 __init__(self, machine, name, config, collection=None): self.log = logging.getLogger('Target.' + name) if 'enable_events' not in config: config['enable_events'] = {'ball_started': 0} if 'disable_events' not in config: config['disable_events'] = {'ball_ending': 0} super(Target, self).__init__(machine, name, config, collection) self.lit = False self.device_str = 'target' self.delay = DelayManager() # set config defaults if 'light' not in self.config: self.config['light'] = None elif (hasattr(self.machine, 'lights') and self.config['light'] in self.machine.lights): self.log.debug("Configuring with light: %s", self.config['light']) self.config['light'] = self.machine.lights[self.config['light']] elif (hasattr(self.machine, 'leds') and self.config['light'] in self.machine.leds): self.log.debug("Configuring with LED: %s", self.config['light']) self.config['light'] = self.machine.leds[self.config['light']] if 'light_if_unlit' not in self.config: self.config['light_if_unlit'] = True if 'unlight_if_lit' not in self.config: self.config['unlight_if_lit'] = False if 'default_state' not in self.config: self.config['default_state'] = 'unlit' if 'reset_events' in self.config: self.config['reset_events'] = Config.string_to_list( self.config['reset_events']) else: self.config['reset_events'] = [None] # todo change this to dict with timing delays? # light script # unlight script # light color # unlight color # register for events self.machine.events.add_handler('action_target_' + self.name + '_light', self.light) self.machine.events.add_handler('action_target_' + self.name + '_unlight', self.unlight) self.machine.events.add_handler('action_target_' + self.name + '_toggle', self.toggle) self.machine.events.add_handler('init_phase_3', self._register_switch_handlers)
def __init__(self, machine, name, config=None, collection=-1, platform_section=None): self.machine = machine self.name = name.lower() self.tags = list() self.label = None self.debug_logging = False self.config = defaultdict(lambda: None, config) if config: self.config.update(config) if 'tags' in config: self.tags = Config.string_to_list(config['tags']) if 'label' in config: self.label = config['label'] # todo change to multi lang # todo more pythonic way, like self.label = blah if blah? if 'debug' in config and config['debug']: self.debug_logging = True self.log.info("Enabling debug logging for this device") if platform_section: if self.machine.physical_hw: if 'platform' not in config: if self.machine.config['hardware'][ platform_section] != 'default': self.platform = (self.machine.hardware_platforms[ self.machine.config['hardware'] [platform_section]]) else: self.platform = self.machine.default_platform else: self.platform = (self.machine.hardware_platforms[ config['platform']]) else: self.platform = self.machine.default_platform # set event handlers to enable, disable, and reset this device # note that not all devices will use all of these methods # these lists of events can be strings or dicts if 'enable_events' in self.config: self.config['enable_events'] = self._event_config_to_dict( self.config['enable_events']) else: self.config['enable_events'] = dict() for event, delay in self.config['enable_events'].iteritems(): self._create_events(ev_name=event, ev_type='enable', delay=delay, callback=self.enable) if 'disable_events' in self.config: self.config['disable_events'] = self._event_config_to_dict( self.config['disable_events']) else: self.config['disable_events'] = dict() for event, delay in self.config['disable_events'].iteritems(): self._create_events(ev_name=event, ev_type='disable', delay=delay, callback=self.disable) if 'reset_events' in self.config: self.config['reset_events'] = self._event_config_to_dict( self.config['reset_events']) else: self.config['reset_events'] = dict() for event, delay in self.config['reset_events'].iteritems(): self._create_events(ev_name=event, ev_type='reset', delay=delay, callback=self.reset) # Add this instance to the collection for this type of device if collection != -1: # Have to use -1 here instead of None to catch an empty collection collection[name] = self
def __init__(self, machine, name, config, collection=None): self.log = logging.getLogger('Diverter.' + name) super(Diverter, self).__init__(machine, name, config, collection) self.delay = DelayManager() # Attributes self.active = False self.enabled = False self.platform = None # configure defaults: if 'type' not in self.config: self.config['type'] = 'pulse' # default to pulse to not fry coils if 'activation_time' not in self.config: self.config['activation_time'] = 0 if 'activation_switches' in self.config: self.config['activation_switches'] = Config.string_to_list( self.config['activation_switches']) else: self.config['activation_switches'] = list() if 'disable_switches' in self.config: self.config['disable_switches'] = Config.string_to_list( self.config['disable_switches']) else: self.config['disable_switches'] = list() if 'deactivation_switches' in self.config: self.config['deactivation_switches'] = Config.string_to_list( self.config['deactivation_switches']) else: self.config['deactivation_switches'] = list() if 'activation_coil' in self.config: self.config['activation_coil'] = ( self.machine.coils[self.config['activation_coil']]) if 'deactivation_coil' in self.config: self.config['deactivation_coil'] = ( self.machine.coils[self.config['deactivation_coil']]) else: self.config['deactivation_coil'] = None if 'targets_when_active' in self.config: self.config['targets_when_active'] = Config.string_to_list( self.config['targets_when_active']) else: self.config['targets_when_active'] = ['playfield'] if 'targets_when_inactive' in self.config: self.config['targets_when_inactive'] = Config.string_to_list( self.config['targets_when_inactive']) else: self.config['targets_when_inactive'] = ['playfield'] if 'feeder_devices' in self.config: self.config['feeder_devices'] = Config.string_to_list( self.config['feeder_devices']) else: self.config['feeder_devices'] = list() # Create a list of ball device objects when active and inactive. We need # this because ball eject attempts pass the target device as an object # rather than by name. self.config['active_objects'] = list() self.config['inactive_objects'] = list() for target_device in self.config['targets_when_active']: if target_device == 'playfield': self.config['active_objects'].append('playfield') else: self.config['active_objects'].append( self.machine.balldevices[target_device]) for target_device in self.config['targets_when_inactive']: if target_device == 'playfield': self.config['inactive_objects'].append('playfield') else: self.config['inactive_objects'].append( self.machine.balldevices[target_device]) # convert the activation_time to ms self.config['activation_time'] = Timing.string_to_ms( self.config['activation_time']) # register for events for event in self.config['enable_events']: self.machine.events.add_handler(event, self.enable) for event in self.config['disable_events']: self.machine.events.add_handler(event, self.disable) # register for feeder device eject events for feeder_device in self.config['feeder_devices']: self.machine.events.add_handler( 'balldevice_' + feeder_device + '_ball_eject_attempt', self._feeder_eject_attempt) self.machine.events.add_handler('init_phase_3', self._register_switches) self.platform = self.config['activation_coil'].platform
def __init__(self, machine, name, config=None, collection=-1): self.machine = machine self.name = name.lower() self.tags = list() self.label = None self.debug_logging = False self.config = defaultdict(lambda: None, config) if config: self.config.update(config) if 'tags' in config: self.tags = Config.string_to_list(config['tags']) if 'label' in config: self.label = config['label'] # todo change to multi lang # todo more pythonic way, like self.label = blah if blah? if 'debug_logging' in config and config['debug_logging']: self.debug_logging = True self.log.info("Enabling debug_logging for this device") # set event handlers to enable, disable, and reset this device # note that not all devices will use all of these methods # these lists of events can be strings or dicts if 'enable_events' in self.config: self.config['enable_events'] = self._event_config_to_dict( self.config['enable_events']) else: self.config['enable_events'] = dict() for event, delay in self.config['enable_events'].iteritems(): self._create_events(ev_name=event, ev_type='enable', delay=delay, callback=self.enable) if 'disable_events' in self.config: self.config['disable_events'] = self._event_config_to_dict( self.config['disable_events']) else: self.config['disable_events'] = dict() for event, delay in self.config['disable_events'].iteritems(): self._create_events(ev_name=event, ev_type='disable', delay=delay, callback=self.disable) if 'reset_events' in self.config: self.config['reset_events'] = self._event_config_to_dict( self.config['reset_events']) else: self.config['reset_events'] = dict() for event, delay in self.config['reset_events'].iteritems(): self._create_events(ev_name=event, ev_type='reset', delay=delay, callback=self.reset) # Add this instance to the collection for this type of device if collection != -1: # Have to use -1 here instead of None to catch an empty collection collection[name] = self