コード例 #1
0
ファイル: modes.py プロジェクト: jabdoa2/mpf
    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
コード例 #2
0
    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
コード例 #3
0
ファイル: fast.py プロジェクト: jherrm/mpf
    def configure_led(self, config):

        if not self.rgb_connection:
            self.log.critical("A request was made to configure a FAST LED, "
                              "but no connection to an LED processor is "
                              "available")
            sys.exit()

        if not self.flag_led_tick_registered:
            self.machine.events.add_handler('timer_tick', self.update_leds)
            self.flag_led_tick_registered = True

        # if the LED number is in <channel> - <led> format, convert it to a
        # FAST hardware number
        if '-' in config['number_str']:
            num = config['number_str'].split('-')
            config['number'] = int((num[0] * 64) + num[1])
            self.config['config_number_format'] = 'int'
        else:
            config['number'] = str(config['number'])

        if self.config['config_number_format'] == 'int':
            config['number'] = Config.int_to_hex_string(config['number'])
        else:
            config['number'] = Config.normalize_hex_string(config['number'])

        this_fast_led = FASTDirectLED(config['number'])
        self.fast_leds.add(this_fast_led)

        return this_fast_led
コード例 #4
0
ファイル: virtualdmd.py プロジェクト: jherrm/mpf
    def __init__(self,  slide, machine, dmd_object=None, x=None, y=None, h_pos=None,
                 v_pos=None, layer=0, **kwargs):

        super(VirtualDMD, self).__init__(slide, x, y, h_pos, v_pos, layer)

        if not dmd_object:
            self.dmd_object = machine.display.displays['dmd']
        else:
            self.dmd_object = dmd_object

        self.config = kwargs

        self.name = 'VirtualDMD'

        if self.dmd_object.depth == 8:

            if 'pixel_color' not in kwargs:
                self.config['pixel_color'] = 'ff5500'

            if 'dark_color' not in self.config:
                self.config['dark_color'] = '221100'

            if 'pixel_spacing' not in self.config:
                self.config['pixel_spacing'] = 2

            # convert hex colors to list of ints
            self.config['pixel_color'] = Config.hexstring_to_list(
                self.config['pixel_color'])
            self.config['dark_color'] = Config.hexstring_to_list(
                self.config['dark_color'])

            # This needs to match the source DMD or it could get weird
            self.config['shades'] = self.dmd_object.config['shades']

            self.palette = mpf.media_controller.display_modules.dmd.create_palette(
                bright_color=self.config['pixel_color'],
                dark_color=self.config['dark_color'],
                steps=self.config['shades'])

        if ('width' in self.config and
                'height' not in self.config):
            self.config['height'] = self.config['width'] / 4
        elif ('height' in self.config and
                'width' not in self.config):
            self.config['width'] = self.config['height'] * 4
        elif ('width' not in self.config and
                'height' not in self.config):
            self.config['width'] = 512
            self.config['height'] = 128

        # Create a Pygame surface for the on screen DMD
        self.element_surface = pygame.Surface((self.config['width'],
                                      self.config['height']),
                                      depth=self.dmd_object.depth)

        if self.dmd_object.depth == 8:
            self.element_surface.set_palette(self.palette)

        self.layer = layer
        self.set_position(x, y, h_pos, v_pos)
コード例 #5
0
ファイル: logic_blocks.py プロジェクト: jabdoa2/mpf
    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')
コード例 #6
0
ファイル: logic_blocks.py プロジェクト: jherrm/mpf
    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')
コード例 #7
0
ファイル: fast.py プロジェクト: jherrm/mpf
    def receive_sa(self, msg):

        self.log.debug("Received SA: %s", msg)

        hw_states = dict()

        num_local, local_states, num_nw, nw_states = msg.split(',')

        for offset, byte in enumerate(bytearray.fromhex(nw_states)):
            for i in range(8):
                num = Config.int_to_hex_string((offset * 8) + i)
                if byte & (2**i):
                    hw_states[(num, 1)] = 1
                else:
                    hw_states[(num, 1)] = 0

        for offset, byte in enumerate(bytearray.fromhex(local_states)):
            for i in range(8):

                num = Config.int_to_hex_string((offset * 8) + i)

                if byte & (2**i):
                    hw_states[(num, 0)] = 1
                else:
                    hw_states[(num, 0)] = 0

        self.hw_switch_data = hw_states
コード例 #8
0
ファイル: logic_blocks.py プロジェクト: jabdoa2/mpf
    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")
コード例 #9
0
    def _load_mode(self, mode_string):
        """Loads a mode, reads in its config, and creates the Mode object.

        Args:
            mode: String name of the mode you're loading. This is the name of
                the mode's folder in your game's machine_files/modes folder.

        """
        self.log.debug('Processing mode: %s', mode_string)

        config = dict()

        # find the folder for this mode:
        mode_path = os.path.join(
            self.machine.machine_path,
            self.machine.config['media_controller']['paths']['modes'],
            mode_string)

        if not os.path.exists(mode_path):
            mode_path = os.path.abspath(
                os.path.join(
                    'mpf',
                    self.machine.config['media_controller']['paths']['modes'],
                    mode_string))

        # Is there an MPF default config for this mode? If so, load it first
        mpf_mode_config = os.path.join(
            'mpf', self.machine.config['media_controller']['paths']['modes'],
            mode_string, 'config', mode_string + '.yaml')

        if os.path.isfile(mpf_mode_config):
            config = Config.load_config_file(mpf_mode_config)

        # Now figure out if there's a machine-specific config for this mode, and
        # if so, merge it into the config

        mode_config_folder = os.path.join(
            self.machine.machine_path,
            self.machine.config['media_controller']['paths']['modes'],
            mode_string, 'config')

        found_file = False
        for path, _, files in os.walk(mode_config_folder):
            for file in files:
                file_root, file_ext = os.path.splitext(file)

                if file_root == mode_string:
                    config = Util.dict_merge(
                        config,
                        Config.load_config_file(os.path.join(path, file)))
                    found_file = True
                    break

            if found_file:
                break

        return Mode(self.machine, config, mode_string, mode_path)
コード例 #10
0
ファイル: switch.py プロジェクト: jabdoa2/mpf
    def __init__(self, machine, name, config, collection=None):
        self.log = logging.getLogger("Switch." + name)
        super(Switch, self).__init__(machine, name, config, collection, platform_section="switches")

        self.machine = machine
        self.name = name
        self.config = config
        self.deactivation_events = list()
        self.activation_events = list()
        self.state = 0
        """ The logical state of a switch. 1 = active, 0 = inactive. This takes
        into consideration the NC or NO settings for the switch."""
        self.hw_state = 0
        """ The physical hardware state of the switch. 1 = active,
        0 = inactive. This is what the actual hardware is reporting and does
        not consider whether a switch is NC or NO."""

        # todo read these in and/or change to dict
        self.type = "NO"
        """ Specifies whether the switch is normally open ('NO', default) or
        normally closed ('NC')."""
        if "type" in config and config["type"].upper() == "NC":
            self.type = "NC"

        if "debounce" not in config:
            config["debounce"] = True

        if "activation_events" in config:
            self.activation_events = Config.string_to_lowercase_list(config["activation_events"])

        if "deactivation_events" in config:
            self.deactivation_events = Config.string_to_lowercase_list(config["deactivation_events"])

        # 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()

        self.last_changed = None
        self.hw_timestamp = None

        self.log.debug("Creating '%s' with config: %s", name, config)

        self.hw_switch, self.number, self.hw_state = self.platform.configure_switch(config)

        self.log.debug("Current hardware state of switch '%s': %s", self.name, self.hw_state)

        # If we're using physical hardware, set the initial logical switch
        # state based on the hw_state
        if self.machine.physical_hw:
            if self.type == "NC":
                self.state = self.hw_state ^ 1
            else:
                self.state = self.hw_state
コード例 #11
0
ファイル: switch_controller.py プロジェクト: jherrm/mpf
    def _initialize_switches(self):
        self.update_switches_from_hw()

        for switch in self.machine.switches:
            # Populate self.switches
            self.set_state(switch.name, switch.state, reset_time=True)

            # Populate self.registered_switches
            self.registered_switches[switch.name + '-0'] = list()
            self.registered_switches[switch.name + '-1'] = list()

            if self.machine.config['mpf']['auto_create_switch_events']:
                switch.activation_events.add(
                    self.machine.config['mpf']['switch_event_active'].replace(
                        '%', switch.name))

                switch.deactivation_events.add(
                    self.machine.config['mpf'][
                        'switch_event_inactive'].replace(
                        '%', switch.name))

            if 'activation_events' in switch.config:
                for event in Config.string_to_lowercase_list(
                        switch.config['activation_events']):

                    if "|" in event:
                        ev_name, ev_time = event.split("|")
                        self.add_switch_handler(
                            switch_name=switch.name,
                            callback=self.machine.events.post,
                            state=1,
                            ms=Timing.string_to_ms(ev_time),
                            callback_kwargs={'event': ev_name}
                        )
                    else:
                        switch.activation_events.add(event)

            if 'deactivation_events' in switch.config:
                for event in Config.string_to_lowercase_list(
                        switch.config['deactivation_events']):

                    if "|" in event:
                        ev_name, ev_time = event.split("|")
                        self.add_switch_handler(
                            switch_name=switch.name,
                            callback=self.machine.events.post,
                            state=0,
                            ms=Timing.string_to_ms(ev_time),
                            callback_kwargs={'event': ev_name}
                        )
                    else:
                        switch.deactivation_events.add(event)
コード例 #12
0
ファイル: mode_controller.py プロジェクト: HarryXS/mpf
    def _load_mode(self, mode_string):
        """Loads a mode, reads in its config, and creates the Mode object.

        Args:
            mode: String name of the mode you're loading. This is the name of
                the mode's folder in your game's machine_files/modes folder.

        """
        self.log.debug('Processing mode: %s', mode_string)

        config = dict()

        # find the folder for this mode:
        mode_path = os.path.join(self.machine.machine_path,
            self.machine.config['media_controller']['paths']['modes'], mode_string)

        if not os.path.exists(mode_path):
            mode_path = os.path.abspath(os.path.join('mpf', self.machine.config['media_controller']['paths']['modes'], mode_string))

        # Is there an MPF default config for this mode? If so, load it first
        mpf_mode_config = os.path.join(
            'mpf',
            self.machine.config['media_controller']['paths']['modes'],
            mode_string,
            'config',
            mode_string + '.yaml')

        if os.path.isfile(mpf_mode_config):
            config = Config.load_config_file(mpf_mode_config)

        # Now figure out if there's a machine-specific config for this mode, and
        # if so, merge it into the config

        mode_config_folder = os.path.join(self.machine.machine_path,
            self.machine.config['media_controller']['paths']['modes'], mode_string, 'config')

        found_file = False
        for path, _, files in os.walk(mode_config_folder):
            for file in files:
                file_root, file_ext = os.path.splitext(file)

                if file_root == mode_string:
                    config = Util.dict_merge(config,
                        Config.load_config_file(os.path.join(path, file)))
                    found_file = True
                    break

            if found_file:
                break

        return Mode(self.machine, config, mode_string, mode_path)
コード例 #13
0
    def _load_config(self):
        # creates the main config dictionary from the YAML machine config files.

        self.config = dict()

        # load the MPF config & machine defaults
        self.config = Config.load_config_yaml(
            config=self.config, yaml_file=self.options['mpfconfigfile'])

        # Find the machine_files location. If it starts with a forward or
        # backward slash, then we assume it's from the mpf root. Otherwise we
        # assume it's from the subfolder location specified in the
        # mpfconfigfile location

        if (self.options['machinepath'].startswith('/')
                or self.options['machinepath'].startswith('\\')):
            machine_path = self.options['machinepath']
        else:
            machine_path = os.path.join(
                self.config['mpf']['paths']['machine_files'],
                self.options['machinepath'])

        self.machine_path = os.path.abspath(machine_path)

        # Add the machine folder to our path so we can import modules from it
        sys.path.append(self.machine_path)

        self.log.info("Machine folder: %s", machine_path)

        # Now find the config file location. Same as machine_file with the
        # slash uses to specify an absolute path

        if (self.options['configfile'].startswith('/')
                or self.options['configfile'].startswith('\\')):
            config_file = self.options['configfile']
        else:

            if not self.options['configfile'].endswith('.yaml'):
                self.options['configfile'] += '.yaml'

            config_file = os.path.join(machine_path,
                                       self.config['mpf']['paths']['config'],
                                       self.options['configfile'])

        self.log.info("Base machine config file: %s", config_file)

        # Load the machine-specific config
        self.config = Config.load_config_yaml(config=self.config,
                                              yaml_file=config_file)
コード例 #14
0
ファイル: machine.py プロジェクト: jabdoa2/mpf
    def _load_config(self):
        # creates the main config dictionary from the YAML machine config files.

        self.config = dict()

        # load the MPF config & machine defaults
        self.config = Config.load_config_yaml(config=self.config,
            yaml_file=self.options['mpfconfigfile'])

        # Find the machine_files location. If it starts with a forward or
        # backward slash, then we assume it's from the mpf root. Otherwise we
        # assume it's from the subfolder location specified in the
        # mpfconfigfile location

        if (self.options['machinepath'].startswith('/') or
                self.options['machinepath'].startswith('\\')):
            machine_path = self.options['machinepath']
        else:
            machine_path = os.path.join(self.config['mpf']['paths']
                                        ['machine_files'],
                                        self.options['machinepath'])

        self.machine_path = os.path.abspath(machine_path)

        # Add the machine folder to our path so we can import modules from it
        sys.path.append(self.machine_path)

        self.log.info("Machine folder: %s", machine_path)

        # Now find the config file location. Same as machine_file with the
        # slash uses to specify an absolute path

        if (self.options['configfile'].startswith('/') or
                self.options['configfile'].startswith('\\')):
            config_file = self.options['configfile']
        else:

            if not self.options['configfile'].endswith('.yaml'):
                self.options['configfile'] += '.yaml'

            config_file = os.path.join(machine_path,
                                       self.config['mpf']['paths']['config'],
                                       self.options['configfile'])

        self.log.info("Base machine config file: %s", config_file)

        # Load the machine-specific config
        self.config = Config.load_config_yaml(config=self.config,
                                            yaml_file=config_file)
コード例 #15
0
ファイル: bcp.py プロジェクト: jabdoa2/mpf
    def __init__(self, machine, name, config, receive_queue):

        self.log = logging.getLogger('BCPClient.' + name)
        self.log.info('Setting up BCP Client...')

        self.machine = machine
        self.name = name
        self.receive_queue = receive_queue

        config_spec = '''
                        host: string
                        port: int|5050
                        connection_attempts: int|-1
                        require_connection: boolean|False
                        '''

        self.config = Config.process_config(config_spec, config)

        self.sending_queue = Queue()
        self.receive_thread = None
        self.sending_thread = None
        self.socket = None
        self.connection_attempts = 0
        self.attempt_socket_connection = True
        self.send_goodbye = True

        self.bcp_commands = {
            'hello': self.receive_hello,
            'goodbye': self.receive_goodbye,
        }

        self.setup_client_socket()
コード例 #16
0
ファイル: shots.py プロジェクト: jabdoa2/mpf
    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)
コード例 #17
0
ファイル: shot_group.py プロジェクト: jherrm/mpf
    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()
コード例 #18
0
ファイル: shots.py プロジェクト: jabdoa2/mpf
    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)
コード例 #19
0
ファイル: shots.py プロジェクト: jabdoa2/mpf
    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()
コード例 #20
0
    def initialize_hw_states(self):
        """Reads and processes the hardware states of the physical switches.

        We can't do this in __init__() because we need the switch controller to
        be setup first before we set up the hw switches. This method is
        called via an event handler which listens for `init_phase_2`.
        """

        start_active = list()

        if not self.machine.physical_hw:

            try:
                start_active = Config.string_to_lowercase_list(
                    self.machine.config['virtual platform start active switches'])
            except KeyError:
                pass

        self.log.debug("Syncing the logical and physical switch states.")
        for switch in self.machine.switches:

            if switch.name in start_active:
                switch.state = 1

            self.set_state(switch.name, switch.state, reset_time=True)
コード例 #21
0
ファイル: shots.py プロジェクト: jabdoa2/mpf
    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)
コード例 #22
0
ファイル: shots.py プロジェクト: jabdoa2/mpf
    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)
コード例 #23
0
ファイル: shots.py プロジェクト: jabdoa2/mpf
    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()
コード例 #24
0
ファイル: led.py プロジェクト: jherrm/mpf
    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
コード例 #25
0
ファイル: fadecandy.py プロジェクト: jabdoa2/mpf
    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()
コード例 #26
0
ファイル: modes.py プロジェクト: jabdoa2/mpf
    def _load_mode(self, mode_string):
        """Loads a mode, reads in its config, and creates the Mode object.

        Args:
            mode: String name of the mode you're loading. This is the name of
                the mode's folder in your game's machine_files/modes folder.
        """
        self.log.info('Processing mode: %s', mode_string)

        mode_path = os.path.join(self.machine.machine_path,
            self.machine.config['mediacontroller']['paths']['modes'], mode_string)
        mode_config_file = os.path.join(self.machine.machine_path,
            self.machine.config['mediacontroller']['paths']['modes'],
            mode_string, 'config', mode_string + '.yaml')
        config = Config.load_config_yaml(yaml_file=mode_config_file)

        if 'code' in config['mode']:

            import_str = ('modes.' + mode_string + '.code.' +
                          config['mode']['code'].split('.')[0])
            i = __import__(import_str, fromlist=[''])
            mode_object = getattr(i, config['mode']['code'].split('.')[1])(
                self.machine, config, mode_string, mode_path)

        else:
            mode_object = Mode(self.machine, config, mode_string, mode_path)

        return mode_object
コード例 #27
0
    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))
コード例 #28
0
    def __init__(self, machine):
        self.log = logging.getLogger('switch_player')

        if 'switch_player' not in machine.config:
            machine.log.debug('"switch_player:" section not found in '
                              'machine configuration, so the Switch Player'
                              'plugin will not be used.')
            return

        self.machine = machine
        self.delay = DelayManager()
        self.current_step = 0

        config_spec = '''
                        start_event: string|machine_reset_phase_3
                        start_delay: secs|0
                        '''

        self.config = Config.process_config(
            config_spec, self.machine.config['switch_player'])

        self.machine.events.add_handler(self.config['start_event'],
                                        self._start_event_callback)

        self.step_list = self.config['steps']
        self.start_delay = self.config['start_delay']
コード例 #29
0
ファイル: switch_player.py プロジェクト: jabdoa2/mpf
    def __init__(self, machine):
        self.log = logging.getLogger('switchplayer')

        if 'switchplayer' not in machine.config:
            machine.log.debug('"switchplayer:" section not found in '
                                   'machine configuration, so the Switch Player'
                                   'plugin will not be used.')
            return

        self.machine = machine
        self.delay = DelayManager()
        self.current_step = 0

        config_spec = '''
                        start_event: string|machine_reset_phase_3
                        start_delay: secs|0
                        '''

        self.config = Config.process_config(config_spec,
                                            self.machine.config['switchplayer'])

        self.machine.events.add_handler(self.config['start_event'],
                                        self._start_event_callback)

        self.step_list = self.config['steps']
        self.start_delay = self.config['start_delay']
コード例 #30
0
    def _initialize_switches(self):

        # Set "start active" switches

        start_active = list()

        if not self.machine.physical_hw:

            try:
                start_active = Config.string_to_lowercase_list(
                    self.machine.
                    config['virtual platform start active switches'])
            except KeyError:
                pass

        for switch in self.machine.switches:

            # Populate self.switches
            if switch.name in start_active:
                switch.state = 1  # set state based on physical state
            self.set_state(switch.name, switch.state, reset_time=True)

            # Populate self.registered_switches
            self.registered_switches[switch.name + '-0'] = list()
            self.registered_switches[switch.name + '-1'] = list()
コード例 #31
0
ファイル: drop_target.py プロジェクト: jabdoa2/mpf
    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)
コード例 #32
0
ファイル: bcp.py プロジェクト: town-hall-pinball/mpf
    def __init__(self, machine, name, config, receive_queue):

        self.log = logging.getLogger('BCPClient.' + name)
        self.log.info('Setting up BCP Client...')

        self.machine = machine
        self.name = name
        self.receive_queue = receive_queue

        config_spec = '''
                        host: string
                        port: int|5050
                        connection_attempts: int|-1
                        require_connection: boolean|False
                        '''

        self.config = Config.process_config(config_spec, config)

        self.sending_queue = Queue()
        self.receive_thread = None
        self.sending_thread = None
        self.socket = None
        self.connection_attempts = 0
        self.attempt_socket_connection = True
        self.send_goodbye = True

        self.bcp_commands = {'hello': self.receive_hello,
                             'goodbye': self.receive_goodbye,
                            }

        self.setup_client_socket()
コード例 #33
0
ファイル: fadecandy.py プロジェクト: jabdoa2/mpf
    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()
コード例 #34
0
    def _load_mode(self, mode_string):
        """Loads a mode, reads in its config, and creates the Mode object.

        Args:
            mode: String name of the mode you're loading. This is the name of
                the mode's folder in your game's machine_files/modes folder.
        """
        self.log.info('Processing mode: %s', mode_string)

        mode_path = os.path.join(
            self.machine.machine_path,
            self.machine.config['mediacontroller']['paths']['modes'],
            mode_string)
        mode_config_file = os.path.join(
            self.machine.machine_path,
            self.machine.config['mediacontroller']['paths']['modes'],
            mode_string, 'config', mode_string + '.yaml')
        config = Config.load_config_yaml(yaml_file=mode_config_file)

        if 'code' in config['mode']:

            import_str = ('modes.' + mode_string + '.code.' +
                          config['mode']['code'].split('.')[0])
            i = __import__(import_str, fromlist=[''])
            mode_object = getattr(i, config['mode']['code'].split('.')[1])(
                self.machine, config, mode_string, mode_path)

        else:
            mode_object = Mode(self.machine, config, mode_string, mode_path)

        return mode_object
コード例 #35
0
ファイル: switch_player.py プロジェクト: mini338/mpf
    def __init__(self, machine):
        self.log = logging.getLogger("switch_player")

        if "switch_player" not in machine.config:
            machine.log.debug(
                '"switch_player:" section not found in '
                "machine configuration, so the Switch Player"
                "plugin will not be used."
            )
            return

        self.machine = machine
        self.delay = DelayManager()
        self.current_step = 0

        config_spec = """
                        start_event: string|machine_reset_phase_3
                        start_delay: secs|0
                        """

        self.config = Config.process_config(config_spec, self.machine.config["switch_player"])

        self.machine.events.add_handler(self.config["start_event"], self._start_event_callback)

        self.step_list = self.config["steps"]
        self.start_delay = self.config["start_delay"]
コード例 #36
0
ファイル: machine.py プロジェクト: jabdoa2/mpf
    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))
コード例 #37
0
ファイル: auditor.py プロジェクト: jabdoa2/mpf
    def _initialize(self):
        # Initializes the auditor. We do this separate from __init__() since
        # we need everything else to be setup first.

        config = """
                    save_events: list|ball_ended
                    audit: list|None
                    events: list|None
                    player: list|None
                    num_player_top_records: int|10
                    """

        self.config = Config.process_config(config, self.machine.config["auditor"])

        self.filename = os.path.join(self.machine.machine_path, self.machine.config["mpf"]["paths"]["audits"])

        # todo add option for abs path outside of machine root

        self.current_audits = self.load_from_disk(self.filename)

        self.make_sure_path_exists(os.path.dirname(self.filename))

        if not self.current_audits:
            self.current_audits = dict()

        # Make sure we have all the sections we need in our audit dict
        if "switches" not in self.current_audits:
            self.current_audits["switches"] = dict()

        if "events" not in self.current_audits:
            self.current_audits["events"] = dict()

        if "player" not in self.current_audits:
            self.current_audits["player"] = dict()

        # Make sure we have all the switches in our audit dict
        for switch in self.machine.switches:
            if switch.name not in self.current_audits["switches"]:
                self.current_audits["switches"][switch.name] = 0

        # Make sure we have all the player stuff in our audit dict
        if "player" in self.config["audit"]:
            for item in self.config["player"]:
                if item not in self.current_audits["player"]:
                    self.current_audits["player"][item] = dict()
                    self.current_audits["player"][item]["top"] = list()
                    self.current_audits["player"][item]["average"] = 0
                    self.current_audits["player"][item]["total"] = 0

        # Register for the events the auditor needs to do its job
        self.machine.events.add_handler("game_starting", self.enable)
        self.machine.events.add_handler("game_ended", self.disable)
        if "player" in self.config["audit"]:
            self.machine.events.add_handler("game_ending", self.audit_player)

        # Enable the shots monitor
        Shot.monitor_enabled = True
        self.machine.register_monitor("shots", self.audit_shot)
コード例 #38
0
ファイル: fast.py プロジェクト: jherrm/mpf
    def configure_matrixlight(self, config):

        if not self.net_connection:
            self.log.critical("A request was made to configure a FAST matrix "
                              "light, but no connection to a NET processor is "
                              "available")
            sys.exit()

        if self.machine_type == 'wpc':  # translate number to FAST light num
            config['number'] = self.wpc_light_map.get(
                                                config['number_str'].upper())
        elif self.config['config_number_format'] == 'int':
            config['number'] = Config.int_to_hex_string(config['number'])
        else:
            config['number'] = Config.normalize_hex_string(config['number'])

        return (FASTMatrixLight(config['number'], self.net_connection.send),
                config['number'])
コード例 #39
0
ファイル: bcp.py プロジェクト: jherrm/mpf
    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
コード例 #40
0
ファイル: language.py プロジェクト: jherrm/mpf
    def _configure(self):
        self.config = self.machine.config["languages"]
        self.machine.language = self
        self.languages = Config.string_to_lowercase_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("(\(.*?\))")
コード例 #41
0
ファイル: language.py プロジェクト: jabdoa2/mpf
    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('(\(.*?\))')
コード例 #42
0
ファイル: fast.py プロジェクト: jherrm/mpf
    def configure_driver(self, config, device_type='coil'):

        if not self.net_connection:
            self.log.critical("A request was made to configure a FAST driver, "
                              "but no connection to a NET processor is "
                              "available")
            sys.exit()

        # If we have WPC driver boards, look up the driver number
        if self.machine_type == 'wpc':
            config['number'] = self.wpc_driver_map.get(
                                                config['number_str'].upper())
            if ('connection' in config and
                    config['connection'].lower() == 'network'):
                config['connection'] = 1
            else:
                config['connection'] = 0  # local driver (default for WPC)

        # If we have fast driver boards, we need to make sure we have hex strs
        elif self.machine_type == 'fast':

            if self.config['config_number_format'] == 'int':
                config['number'] = Config.int_to_hex_string(config['number'])
            else:
                config['number'] = Config.normalize_hex_string(config['number'])

            # Now figure out the connection type
            if ('connection' in config and
                    config['connection'].lower() == 'local'):
                config['connection'] = 0
            else:
                config['connection'] = 1  # network driver (default for FAST)

        else:
            self.log.critical("Invalid machine type: {0{}}".format(
                self.machine_type))
            sys.exit()

        return (FASTDriver(config, self.net_connection.send),
            (config['number'], config['connection']))
コード例 #43
0
    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()
コード例 #44
0
ファイル: machine.py プロジェクト: HarryXS/mpf
    def _load_machine_config(self):
        for num, config_file in enumerate(self.options['configfile']):

            if not (config_file.startswith('/') or
                    config_file.startswith('\\')):

                config_file = os.path.join(self.machine_path,
                    self.config['mpf']['paths']['config'], config_file)

            self.log.info("Machine config file #%s: %s", num+1, config_file)

            self.config = Util.dict_merge(self.config,
                Config.load_config_file(config_file))
コード例 #45
0
    def _load_machine_config(self):
        for num, config_file in enumerate(self.options['configfile']):

            if not (config_file.startswith('/') or
                    config_file.startswith('\\')):

                config_file = os.path.join(self.machine_path,
                    self.config['media_controller']['paths']['config'], config_file)

            self.log.info("Machine config file #%s: %s", num+1, config_file)

            self.config = Util.dict_merge(self.config,
                Config.load_config_file(config_file))
コード例 #46
0
ファイル: osc.py プロジェクト: jabdoa2/mpf
    def __init__(self, machine):

        if 'osc' not in machine.config:
            machine.log.debug('"OSC:" section not found in the machine '
                                   'configuration, so the OSC plugin will not '
                                   'be used.')
            return

        if not import_success:
            machine.log.warning('OSC plugin requires PyOSC which does not '
                                     'appear to be installed. No prob, but FYI '
                                     'that the OSC will not be available.')
            return

        self.log = logging.getLogger('osc')
        self.machine = machine

        config_spec = '''
                        client_port: int|8000
                        debug_messages: boolean|False
                        '''

        self.config = Config.process_config(config_spec,
                                          self.machine.config['osc'])

        if self.config['machine_ip'].upper() == 'AUTO':
            self.config['machine_ip'] = socket.gethostbyname(
                                                        socket.gethostname())

        if 'client_updates' in self.config:
            self.config['client_updates'] = self.config['client_updates'].split(
                                                                            ' ')
        else:
            self.config['client_updates'] = None

        self.OSC_clients = dict()
        self.client_needs_sync = False
        self.client_last_update_time = None
        self.last_loop_time = 1
        self.client_mode = 'name'
        self.clients_to_delete = list()
        self.clients_to_add = list()

        # If this machine uses WPC driver boards then we can drive devices by #
        if self.machine.config['hardware']['driverboards'][0:3] == 'wpc':
            self.wpc = True
        else:
            self.wpc = False

        # register for events
        self.machine.events.add_handler('init_phase_4', self.start)
コード例 #47
0
    def __init__(self, machine):

        if 'osc' not in machine.config:
            machine.log.debug('"OSC:" section not found in the machine '
                              'configuration, so the OSC plugin will not '
                              'be used.')
            return

        if not import_success:
            machine.log.warning('OSC plugin requires PyOSC which does not '
                                'appear to be installed. No prob, but FYI '
                                'that the OSC will not be available.')
            return

        self.log = logging.getLogger('osc')
        self.machine = machine

        config_spec = '''
                        client_port: int|8000
                        debug_messages: boolean|False
                        '''

        self.config = Config.process_config(config_spec,
                                            self.machine.config['osc'])

        if self.config['machine_ip'].upper() == 'AUTO':
            self.config['machine_ip'] = socket.gethostbyname(
                socket.gethostname())

        if 'client_updates' in self.config:
            self.config['client_updates'] = self.config[
                'client_updates'].split(' ')
        else:
            self.config['client_updates'] = None

        self.OSC_clients = dict()
        self.client_needs_sync = False
        self.client_last_update_time = None
        self.last_loop_time = 1
        self.client_mode = 'name'
        self.clients_to_delete = list()
        self.clients_to_add = list()

        # If this machine uses WPC driver boards then we can drive devices by #
        if self.machine.config['hardware']['driverboards'][0:3] == 'wpc':
            self.wpc = True
        else:
            self.wpc = False

        # register for events
        self.machine.events.add_handler('init_phase_4', self.start)
コード例 #48
0
ファイル: bcp.py プロジェクト: jabdoa2/mpf
    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
コード例 #49
0
ファイル: devices.py プロジェクト: jabdoa2/mpf
    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
コード例 #50
0
ファイル: logic_blocks.py プロジェクト: jabdoa2/mpf
    def __init__(self, machine, name, player, config):
        self.log = logging.getLogger('Sequence.' + name)
        self.log.debug("Creating Sequence LogicBlock")

        super(Sequence, self).__init__(machine, name, player, config)

        config_spec = '''
                        events: list_of_lists
                      '''

        self.config = Config.process_config(config_spec=config_spec,
                                            source=self.config)

        if 'player_variable' not in config:
            self.config['player_variable'] = self.name + '_step'

        self.player[self.config['player_variable']] = 0
コード例 #51
0
    def __init__(self, machine):

        super(HardwarePlatform, self).__init__(machine)

        self.log = logging.getLogger('SmartMatrix')
        self.log.info("Configuring SmartMatrix hardware interface.")

        self.dmd_frame = bytearray()
        self.queue = None

        config_spec = '''
                      port: string
                      use_separate_thread: boolean|True
                      '''

        self.config = Config.process_config(
            config_spec=config_spec, source=self.machine.config['smartmatrix'])
コード例 #52
0
ファイル: logic_blocks.py プロジェクト: jabdoa2/mpf
    def __init__(self, machine, name, player, config):
        self.log = logging.getLogger('Accrual.' + name)
        self.log.debug("Creating Accrual LogicBlock")

        super(Accrual, self).__init__(machine, name, player, config)

        config_spec = '''
                        events: list_of_lists
                      '''

        self.config = Config.process_config(config_spec=config_spec,
                                            source=self.config)

        if 'player_variable' not in config:
            self.config['player_variable'] = self.name + '_status'

        # populate status list
        self.player[self.config['player_variable']] = (
            [False] * len(self.config['events']))
コード例 #53
0
    def __init__(self, options):
        self.options = options
        self.log = logging.getLogger('machinewizard')
        self.log.info("MPF Wizard v%s", version.__version__)
        self.log.debug("Init Options: {}".format(self.options))
        self.verify_system_info()

        self.done = False
        self.machine_path = None  # Path to this machine's folder root

        FileManager.init()

        self.mpfconfig = dict()
        self.mpfconfig = Config.load_config_file(self.options['mpfconfigfile'])

        self.config_files = dict()
        #self.config = Config.load_config_file(self.options['mpfconfigfile'])
        self._set_machine_path()
        self._load_config_from_files()
        
        self.log.info('machine config loaded')
コード例 #54
0
ファイル: logic_blocks.py プロジェクト: jabdoa2/mpf
    def __init__(self, machine, name, player, config):
        self.log = logging.getLogger('Counter.' + name)
        self.log.debug("Creating Counter LogicBlock")

        super(Counter, self).__init__(machine, name, player, config)

        self.delay = DelayManager()

        self.ignore_hits = False
        self.hit_value = -1

        config_spec = '''
                        count_events: list|None
                        count_complete_value: int|0
                        multiple_hit_window: ms|0
                        count_interval: int|1
                        direction: string|up
                        starting_count: int|0
                      '''

        self.config = Config.process_config(config_spec=config_spec,
                                            source=self.config)

        if 'event_when_hit' not in self.config:
            self.config['event_when_hit'] = ('counter_' + self.name + '_hit')

        if 'player_variable' not in self.config:
            self.config['player_variable'] = self.name + '_count'

        self.hit_value = self.config['count_interval']

        if self.config['direction'] == 'down' and self.hit_value > 0:
            self.hit_value *= -1
        elif self.config['direction'] == 'up' and self.hit_value < 0:
            self.hit_value *= -1

        self.player[self.config['player_variable']] = (
            self.config['starting_count'])
コード例 #55
0
    def load(self, filename, verify_version=True, halt_on_error=False):
        """Loads a YAML file from disk.

        Args:
            filename: The file to load.
            verify_version: Boolean which specifies whether this method should
                verify whether this file's config_version is compatible with
                this version of MPF. Default is True.
            halt_on_error: Boolean which controls what happens if the file
                can't be loaded. (Not found, invalid format, etc. If True, MPF
                will raise an error and exit. If False, an empty config
                dictionary will be returned.

        Returns:
            A dictionary of the settings from this YAML file.

        """
        if verify_version and not Config.check_config_file_version(filename):
            raise Exception(
                "Config file version mismatch: {}".format(filename))

        try:
            self.log.debug("Loading configuration file: %s", filename)

            with open(filename, 'r') as f:
                config = Util.keys_to_lower(yaml.load(f))
        except yaml.YAMLError, exc:
            if hasattr(exc, 'problem_mark'):
                mark = exc.problem_mark
                self.log.critical(
                    "Error found in config file %s. Line %s, "
                    "Position %s", filename, mark.line + 1, mark.column + 1)

            if halt_on_error:
                sys.exit()
            else:
                config = dict()
コード例 #56
0
ファイル: ball_device.py プロジェクト: jabdoa2/mpf
    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()
コード例 #57
0
ファイル: devices.py プロジェクト: jabdoa2/mpf
    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
コード例 #58
0
    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()
コード例 #59
0
 def _load_mpf_config(self):
     self.config = Config.load_config_file(self.options['mpfconfigfile'])
コード例 #60
0
ファイル: fast.py プロジェクト: jabdoa2/mpf
    def __init__(self, machine):
        super(HardwarePlatform, self).__init__(machine)
        self.log = logging.getLogger('FAST')
        self.log.debug("Configuring FAST hardware.")

        if not serial_imported:
            self.log.error('Could not import "pySerial". This is required for '
                           'the FAST platform interface')
            sys.exit()

        # ----------------------------------------------------------------------
        # Platform-specific hardware features. WARNING: Do not edit these. They
        # are based on what the FAST hardware can and cannot do.
        self.features['max_pulse'] = 255  # todo
        self.features['hw_timer'] = False
        self.features['hw_rule_coil_delay'] = True  # todo
        self.features['variable_recycle_time'] = True  # todo
        self.features['variable_debounce_time'] = True  # todo
        self.features['hw_enable_auto_disable'] = True
        # Make the platform features available to everyone
        self.machine.config['platform'] = self.features
        # ----------------------------------------------------------------------

        self.hw_rules = dict()
        self.dmd_connection = None
        self.net_connection = None
        self.rgb_connection = None
        self.fast_nodes = list()
        self.connection_threads = set()
        self.receive_queue = Queue.Queue()
        self.fast_leds = set()
        self.flag_led_tick_registered = False
        self.flag_switch_registered = False

        config_spec = '''
                    ports: list
                    baud: int|921600
                    config_number_format: string|hex
                    watchdog: ms|1000
                    default_debounce_open: ms|30
                    default_debounce_close: ms|30
                    debug: boolean|False
                    '''

        self.config = Config.process_config(config_spec=config_spec,
                                            source=self.machine.config['fast'])

        self.watchdog_command = 'WD:' + str(hex(self.config['watchdog']))[2:]

        self._connect_to_hardware()

        if 'config_number_format' not in self.machine.config['fast']:
            self.machine.config['fast']['config_number_format'] = 'int'

        self.machine_type = (
            self.machine.config['hardware']['driverboards'].lower())

        if self.machine_type == 'wpc':
            self.log.debug("Configuring the FAST Controller for WPC driver "
                           "boards")

        elif self.machine_type == 'fast':
            self.log.debug(
                "Configuring FAST Controller for FAST driver boards.")

        self.wpc_switch_map = {  # autogenerated, so not in order. Sorry :(
            'SF8': '67', 'SF6': '65', 'SF7': '66', 'SF4': '63',
            'SF5': '64', 'SF2': '61', 'SF3': '62', 'SF1': '60',
            'S57': '26', 'S56': '25', 'S55': '24', 'S54': '23',
            'S53': '22', 'S52': '21', 'S51': '20', 'S58': '27',
            'S44': '1B', 'S45': '1C', 'S46': '1D', 'S47': '1E',
            'S41': '18', 'S42': '19', 'S43': '1A', 'S48': '1F',
            'S78': '37', 'S71': '30', 'S73': '32', 'S72': '31',
            'S75': '34', 'S74': '33', 'S77': '36', 'S76': '35',
            'S68': '2F', 'S66': '2d', 'S67': '2E', 'S64': '2B',
            'S65': '2C', 'S62': '29', 'S63': '2A', 'S61': '28',
            'S18': '07', 'S13': '02', 'S12': '01', 'S11': '00',
            'S17': '06', 'S16': '05', 'S15': '04', 'S14': '03',
            'S93': '42', 'S92': '41', 'S91': '40', 'S97': '46',
            'S96': '45', 'S95': '44', 'S94': '43', 'S98': '47',
            'S81': '38', 'S82': '39', 'S83': '3A', 'S84': '3B',
            'S85': '3C', 'S86': '3D', 'S87': '3E', 'S88': '3F',
            'SD4': '53', 'SD5': '54', 'SD6': '55', 'SD7': '56',
            'SD1': '50', 'SD2': '51', 'SD3': '52', 'SD8': '57',
            'S38': '17', 'S35': '14', 'S34': '13', 'S37': '16',
            'S36': '15', 'S31': '10', 'S33': '12', 'S32': '11',
            'S22': '09', 'S23': '0A', 'S21': '08', 'S26': '0D',
            'S27': '0E', 'S24': '0B', 'S25': '0C', 'S28': '0F',
            'DIP8': '5F', 'DIP1': '58', 'DIP3': '5A', 'DIP2': '59',
            'DIP5': '5C', 'DIP4': '5B', 'DIP7': '5E', 'DIP6': '5D',
                              }

        self.wpc_light_map = {
            'L11': '00',
            'L12': '01',
            'L13': '02',
            'L14': '03',
            'L15': '04',
            'L16': '05',
            'L17': '06',
            'L18': '07',
            'L21': '08',
            'L22': '09',
            'L23': '0A',
            'L24': '0B',
            'L25': '0C',
            'L26': '0D',
            'L27': '0E',
            'L28': '0F',
            'L31': '10',
            'L32': '11',
            'L33': '12',
            'L34': '13',
            'L35': '14',
            'L36': '15',
            'L37': '16',
            'L38': '17',
            'L41': '18',
            'L42': '19',
            'L43': '1A',
            'L44': '1B',
            'L45': '1C',
            'L46': '1D',
            'L47': '1E',
            'L48': '1F',
            'L51': '20',
            'L52': '21',
            'L53': '22',
            'L54': '23',
            'L55': '24',
            'L56': '25',
            'L57': '26',
            'L58': '27',
            'L61': '28',
            'L62': '29',
            'L63': '2A',
            'L64': '2B',
            'L65': '2C',
            'L66': '2D',
            'L67': '2E',
            'L68': '2F',
            'L71': '30',
            'L72': '31',
            'L73': '32',
            'L74': '33',
            'L75': '34',
            'L76': '35',
            'L77': '36',
            'L78': '37',
            'L81': '38',
            'L82': '39',
            'L83': '3A',
            'L84': '3B',
            'L85': '3C',
            'L86': '3D',
            'L87': '3E',
            'L88': '3F',
        }

        self.wpc_driver_map = {
            'C01': '00',
            'C02': '01',
            'C03': '02',
            'C04': '03',
            'C05': '04',
            'C06': '05',
            'C07': '06',
            'C08': '07',
            'C09': '08',
            'C10': '09',
            'C11': '0A',
            'C12': '0B',
            'C13': '0C',
            'C14': '0D',
            'C15': '0E',
            'C16': '0F',
            'C17': '10',
            'C18': '11',
            'C19': '12',
            'C20': '13',
            'C21': '14',
            'C22': '15',
            'C23': '16',
            'C24': '17',
            'C25': '18',
            'C26': '19',
            'C27': '1A',
            'C28': '1B',
            'C29': '1C',
            'C30': '1D',
            'C31': '1E',
            'C32': '1F',
            'C33': '24',
            'C34': '25',
            'C35': '26',
            'C36': '27',
            'FLRM': '20',
            'FLRH': '21',
            'FLLM': '22',
            'FLLH': '23',
            'FURM': '24',
            'FURH': '25',
            'FULM': '26',
            'FULH': '27',
            'C37': '28',
            'C38': '29',
            'C39': '2A',
            'C40': '2B',
            'C41': '2C',
            'C42': '2D',
            'C43': '2E',
            'C44': '2F',
        }

        self.wpc_gi_map = {
            'G01': '00',
            'G02': '01',
            'G03': '02',
            'G04': '03',
            'G05': '04',
            'G06': '05',
            'G07': '06',
            'G08': '07',
        }

        self.pwm8_to_hex_string = {
            0: '00',
            1: '01',
            2: '88',
            3: '92',
            4: 'AA',
            5: 'BA',
            6: 'EE',
            7: 'FE',
            8: 'FF'
        }

        self.pwm8_to_int = {
            0: 0,
            1: 1,
            2: 136,
            3: 146,
            4: 170,
            5: 186,
            6: 238,
            7: 254,
            8: 255
        }

        # todo verify this list
        self.fast_commands = {
            'ID': self.receive_id,  # processor ID
            'WX': self.receive_wx,  # watchdog
            'NN': self.receive_nn,  # node id list
            'NI': self.receive_ni,  # node ID
            'RX': self.receive_rx,  # RGB cmd received
            'DX': self.receive_dx,  # DMD cmd received
            'SX': self.receive_sx,  # sw config received
            'LX': self.receive_lx,  # lamp cmd received
            'PX': self.receive_px,  # segment cmd received
            'SA': self.receive_sa,  # all switch states
            '/N': self.receive_nw_open,  # nw switch open
            '-N': self.receive_nw_closed,  # nw switch closed
            '/L': self.receive_local_open,  # local sw open
            '-L': self.receive_local_closed,  # local sw close
            'WD': self.receive_wd,  # watchdog
        }