예제 #1
0
파일: config.py 프로젝트: qcapen/mpf
    def validate_config_item2(self, spec, validation_failure_info,
                              item='item not in config!@#',):

        default = 'default required!@#'

        item_type, validation, default = spec.split('|')

        if default.lower() == 'none':
            default = None

        if item == 'item not in config!@#':
            if default == 'default required!@#':
                log.error('Required setting missing from config file. Run with '
                          'verbose logging and look for the last '
                          'ConfigProcessor entry above this line to see where '
                          'the problem is.')
                sys.exit()
            else:
                item = default

        if item_type == 'single':
            item = self.validate_item(item, validation, validation_failure_info)


        elif item_type == 'list':
            item = Util.string_to_list(item)

            new_list = list()

            for i in item:
                new_list.append(
                    self.validate_item(i, validation, validation_failure_info))

            item = new_list

        elif item_type == 'set':
            item = set(Util.string_to_list(item))

            new_set = set()

            for i in item:
                new_set.add(
                    self.validate_item(i, validation, validation_failure_info))

            item = new_set

        elif item_type == 'dict':
            item = self.validate_item(item, validation,
                                               validation_failure_info)

            if not item:
                item = dict()

        else:
            self.log.error("Invalid Type '%s' in config spec %s:%s", item_type,
                           validation_failure_info[0][0],
                           validation_failure_info[1])
            sys.exit()

        return item
예제 #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'] = Util.string_to_list(
                config['start_events'])
        else:
            config['start_events'] = list()

        if 'stop_events' in config:
            config['stop_events'] = Util.string_to_list(config['stop_events'])
        else:
            config['stop_events'] = list()

        # register mode start events
        if 'start_events' in config:
            for event in config['start_events']:
                self.machine.events.add_handler(event, self.start)

        self.config['mode'] = config
예제 #3
0
파일: fast2.py 프로젝트: qcapen/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) + int(num[1])
            self.config['config_number_format'] = 'int'
        else:
            config['number'] = str(config['number'])

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

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

        return this_fast_led
예제 #4
0
파일: fast2.py 프로젝트: qcapen/mpf
    def receive_sa(self, msg):

        self.log.info("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 = Util.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 = Util.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
예제 #5
0
파일: mode.py 프로젝트: HarryXS/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'] = Util.string_to_list(
                config['start_events'])
        else:
            config['start_events'] = list()

        if 'stop_events' in config:
            config['stop_events'] = Util.string_to_list(
                config['stop_events'])
        else:
            config['stop_events'] = list()

        # register mode start events
        if 'start_events' in config:
            for event in config['start_events']:
                self.machine.events.add_handler(event, self.start)

        self.config['mode'] = config
예제 #6
0
파일: virtualdmd.py 프로젝트: mini338/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"] = Util.hex_string_to_list(self.config["pixel_color"])
            self.config["dark_color"] = Util.hex_string_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)
예제 #7
0
    def load_config_file(filename, verify_version=True, halt_on_error=True):
        config = FileManager.load(filename, verify_version, halt_on_error)

        if 'config' in config:
            path = os.path.split(filename)[0]

            for file in Util.string_to_list(config['config']):
                full_file = os.path.join(path, file)
                config = Util.dict_merge(config,
                                         Config.load_config_file(full_file))
        return config
예제 #8
0
파일: config.py 프로젝트: HarryXS/mpf
    def load_config_file(filename, verify_version=True, halt_on_error=True):
        config = FileManager.load(filename, verify_version, halt_on_error)

        if 'config' in config:
            path = os.path.split(filename)[0]

            for file in Util.string_to_list(config['config']):
                full_file = os.path.join(path, file)
                config = Util.dict_merge(config,
                                           Config.load_config_file(full_file))
        return config
예제 #9
0
    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 Util.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 Util.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)
    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 Util.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 Util.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)
예제 #11
0
    def load(self, filename, verify_version=True):
        """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.

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

        """

        config = Util.keys_to_lower(
            self.byteify(json.load(open(filename, 'r'))))

        # if verify_version:
        #     self.check_config_file_version(filename)
        #
        # try:
        #     self.log.debug("Loading configuration file: %s", filename)
        #     config = Util.keys_to_lower(json.loads(open(filename, 'r')))
        # 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)
        #         sys.exit()
        # except:
        #     self.log.critical("Couldn't load from file: %s", filename)
        #     raise

        return config
예제 #12
0
파일: fast2.py 프로젝트: qcapen/mpf
    def pulse(self, milliseconds=None):
        """Pulses this driver. """

        if not milliseconds:
            hex_ms_string = self.driver_settings['pulse_ms']
        else:
            hex_ms_string = Util.int_to_hex_string(milliseconds)

        if self.autofire:
            cmd = (self.driver_settings['trigger_cmd'] +
                   self.driver_settings['number'] + ',' +
                  '01')
            if milliseconds:
                self.log.debug("Received command to pulse driver for %sms, but"
                              "this driver is configured with an autofire rule"
                               ", so that pulse value will be used instead.")
        else:
            cmd = (self.driver_settings['config_cmd'] +
                   self.driver_settings['number'] +
                   ',89,00,10,' +
                   hex_ms_string + ',' +
                   self.driver_settings['pwm1'] + ',00,00,' +
                   self.driver_settings['recycle_ms'])

        self.log.debug("Sending Pulse Command: %s", cmd)
        self.send(cmd)
        self.check_auto()
예제 #13
0
    def load(self, filename, verify_version=True):
        """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.

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

        """

        config = Util.keys_to_lower(self.byteify(json.load(open(filename, 'r'))))

        # if verify_version:
        #     self.check_config_file_version(filename)
        #
        # try:
        #     self.log.debug("Loading configuration file: %s", filename)
        #     config = Util.keys_to_lower(json.loads(open(filename, 'r')))
        # 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)
        #         sys.exit()
        # except:
        #     self.log.critical("Couldn't load from file: %s", filename)
        #     raise

        return config
예제 #14
0
파일: fadecandy.py 프로젝트: HarryXS/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['led_settings']['gamma']
        self.whitepoint = Util.string_to_list(
            self.machine.config['led_settings']['whitepoint'])

        self.whitepoint[0] = float(self.whitepoint[0])
        self.whitepoint[1] = float(self.whitepoint[1])
        self.whitepoint[2] = float(self.whitepoint[2])

        self.linear_slope = (
            self.machine.config['led_settings']['linear_slope'])
        self.linear_cutoff = (
            self.machine.config['led_settings']['linear_cutoff'])
        self.keyframe_interpolation = (
            self.machine.config['led_settings']['keyframe_interpolation'])
        self.dithering = self.machine.config['led_settings']['dithering']

        if not self.dithering:
            self.disable_dithering()

        if not self.keyframe_interpolation:
            self.update_every_tick = False

        self.set_global_color_correction()
        self.write_firmware_options()
예제 #15
0
    def get_hw_switch_states(self):

        if not self.initial_states_sent:

            if 'virtual_platform_start_active_switches' in self.machine.config:

                initial_active_switches = [
                    self.machine.switches[x].number
                    for x in Util.string_to_list(
                        self.machine.
                        config['virtual_platform_start_active_switches'])
                ]

                for k, v in self.hw_switches.iteritems():
                    if k in initial_active_switches:
                        self.hw_switches[k] ^= 1

            self.initial_states_sent = True

        else:
            switches = [x for x in self.machine.switches if x.platform == self]

            for switch in switches:
                self.hw_switches[switch.number] = switch.state ^ switch.invert

        return self.hw_switches
예제 #16
0
파일: logic_blocks.py 프로젝트: HarryXS/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
                    persist_state: boolean|False
                    '''

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

        if 'events_when_complete' not in config:
            self.config['events_when_complete'] = ([
                'logicblock_' + self.name + '_complete'])
        else:
            self.config['events_when_complete'] = Util.string_to_list(
                config['events_when_complete'])
예제 #17
0
    def __init__(self, machine, name, config, collection=None, validate=True):

        self.shots = list()  # list of strings

        for shot in Util.string_to_list(config['shots']):
            self.shots.append(machine.shots[shot])

        # If this device is setup in a machine-wide config, make sure it has
        # a default enable event.

        # TODO add a mode parameter to the device constructor and do the logic
        # there.
        if not machine.modes:

            if 'enable_events' not in config:
                config['enable_events'] = 'ball_starting'
            if 'disable_events' not in config:
                config['disable_events'] = 'ball_ended'
            if 'reset_events' not in config:
                config['reset_events'] = 'ball_ended'

            if 'profile' in config:
                for shot in self.shots:
                    shot.update_enable_table(profile=config['profile'],
                                      mode=None)

        super(ShotGroup, self).__init__(machine, name, config, collection,
                                        validate=validate)

        self.rotation_enabled = True

        if self.debug:
            self._enable_related_device_debugging()
예제 #18
0
    def __init__(self, machine, config):

        super(FadeCandyOPClient, self).__init__(machine, config)

        self.log = logging.getLogger('FadeCandyClient')

        self.update_every_tick = True

        self.gamma = self.machine.config['led_settings']['gamma']
        self.whitepoint = Util.string_to_list(
            self.machine.config['led_settings']['whitepoint'])

        self.whitepoint[0] = float(self.whitepoint[0])
        self.whitepoint[1] = float(self.whitepoint[1])
        self.whitepoint[2] = float(self.whitepoint[2])

        self.linear_slope = (
            self.machine.config['led_settings']['linear_slope'])
        self.linear_cutoff = (
            self.machine.config['led_settings']['linear_cutoff'])
        self.keyframe_interpolation = (
            self.machine.config['led_settings']['keyframe_interpolation'])
        self.dithering = self.machine.config['led_settings']['dithering']

        if not self.dithering:
            self.disable_dithering()

        if not self.keyframe_interpolation:
            self.update_every_tick = False

        self.set_global_color_correction()
        self.write_firmware_options()
예제 #19
0
    def bcp_receive_get(self, names, **kwargs):
        """Processes an incoming BCP 'get' command by posting an event
        'bcp_get_<name>'. It's up to an event handler to register for that
        event and to send the response BCP 'set' command.

        """
        for name in Util.string_to_list(names):
            self.machine.events.post('bcp_get_{}'.format(name))
예제 #20
0
파일: bcp.py 프로젝트: HarryXS/mpf
    def bcp_receive_get(self, names, **kwargs):
        """Processes an incoming BCP 'get' command by posting an event
        'bcp_get_<name>'. It's up to an event handler to register for that
        event and to send the response BCP 'set' command.

        """
        for name in Util.string_to_list(names):
            self.machine.events.post('bcp_get_{}'.format(name))
예제 #21
0
파일: MpfTestCase.py 프로젝트: HarryXS/mpf
 def getOptions(self):
     return {
         'force_platform': self.get_platform(),
         'mpfconfigfile': "mpf/mpfconfig.yaml",
         'machine_path': self.getMachinePath(),
         'configfile': Util.string_to_list(self.getConfigFile()),
         'debug': True,
         'bcp': self.get_use_bcp()
            }
예제 #22
0
 def getOptions(self):
     return {
         'force_platform': self.get_platform(),
         'mpfconfigfile': "mpf/mpfconfig.yaml",
         'machine_path': self.getMachinePath(),
         'configfile': Util.string_to_list(self.getConfigFile()),
         'debug': True,
         'bcp': self.get_use_bcp()
     }
예제 #23
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)
예제 #24
0
파일: fast2.py 프로젝트: qcapen/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'] = Util.int_to_hex_string(config['number'])
        else:
            config['number'] = Util.normalize_hex_string(config['number'])

        return (FASTMatrixLight(config['number'], self.net_connection.send),
                config['number'])
예제 #25
0
파일: bcp.py 프로젝트: HarryXS/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 Util.string_to_list(v['start_events']):
                        self.create_trigger_event(event)
                if 'stop_events' in v:
                    for event in Util.string_to_list(v['stop_events']):
                        self.create_trigger_event(event)
        except KeyError:
            pass
예제 #26
0
    def register_mpfmc_trigger_events(self, config, **kwargs):
        """Scans an MPF config file and creates trigger events for the config
        settings that need them.

        Args:
            config: An MPF config dictionary (can be the machine-wide or a mode-
                specific one).
            **kwargs: Not used. Included to catch any additional kwargs that may
                be associted with this method being registered as an event
                handler.

        """

        self.log.debug("Registering Trigger Events")

        try:
            for event in config['show_player'].keys():
                self.create_trigger_event(event)
        except KeyError:
            pass

        try:
            for event in config['slide_player'].keys():
                self.create_trigger_event(event)
        except KeyError:
            pass

        try:
            for event in config['event_player'].keys():
                self.create_trigger_event(event)
        except KeyError:
            pass

        try:
            for k, v in config['sound_player'].iteritems():
                if 'start_events' in v:
                    for event in Util.string_to_list(v['start_events']):
                        self.create_trigger_event(event)
                if 'stop_events' in v:
                    for event in Util.string_to_list(v['stop_events']):
                        self.create_trigger_event(event)
        except KeyError:
            pass
예제 #27
0
    def _configure(self):
        self.config = self.machine.config['languages']
        self.machine.language = self
        self.languages = Util.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('(\(.*?\))')
예제 #28
0
파일: fast2.py 프로젝트: qcapen/mpf
    def create_driver_settings(self, machine, pulse_ms=None, **kwargs):
        return_dict = dict()
        if pulse_ms is None:
            pulse_ms = machine.config['mpf']['default_pulse_ms']

        return_dict['pulse_ms'] = Util.int_to_hex_string(pulse_ms)
        return_dict['pwm1'] = 'ff'
        return_dict['pwm2'] = 'ff'
        return_dict['recycle_ms'] = '00'

        return return_dict
예제 #29
0
파일: language.py 프로젝트: HarryXS/mpf
    def _configure(self):
        self.config = self.machine.config['languages']
        self.machine.language = self
        self.languages = Util.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('(\(.*?\))')
예제 #30
0
    def _load_plugins(self):
        self.log.info("Loading plugins...")

        # TODO: This should be cleaned up. Create a Plugins superclass and
        # classmethods to determine if the plugins should be used.

        for plugin in Util.string_to_list(self.config['mpf']['plugins']):

            self.log.debug("Loading '%s' plugin", plugin)

            pluginObj = self.string_to_class(plugin)(self)
            self.plugins.append(pluginObj)
예제 #31
0
파일: fast2.py 프로젝트: qcapen/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 IO boards, we need to make sure we have hex strings
        elif self.machine_type == 'fast':

            if self.config['config_number_format'] == 'int':
                config['number'] = Util.int_to_hex_string(config['number'])
            else:
                config['number'] = Util.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, self.machine),
                (config['number'], config['connection']))
예제 #32
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))
예제 #33
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))
예제 #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.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)
예제 #35
0
    def adjust_colors(self, **kwargs):
        """Takes a settings dictionary and converts the object and background
        colors into a format Pygame can use.

        Args:
            **kwargs: A settings dictionary for this display element. Specific
                key / value pairs this method uses are shade, bg_shade, color,
                and bg_color.

        This method sets the adjusted_color and adjusted_bg_color attributes.

        """

        if self.slide.depth == 8:
            if 'shade' in kwargs:
                self.adjusted_color = (kwargs['shade'], 0, 0)
            else:
                self.adjusted_color = (15, 0, 0)  # todo default config

            if 'bg_shade' in kwargs:
                self.adjusted_bg_color = (kwargs['bg_shade'], 0, 0)
            else:
                self.adjusted_bg_color = None

        else:  # 24-bit
            if 'color' in kwargs:
                color_list = Util.hex_string_to_list(kwargs['color'])
                self.adjusted_color = (color_list[0], color_list[1],
                                       color_list[2])
            else:
                self.adjusted_color = (255, 255, 255)  # todo default config

            if 'bg_color' in kwargs:
                color_list = Util.hex_string_to_list(kwargs['color'])
                self.adjusted_bg_color = (color_list[0], color_list[1],
                                          color_list[2])
            else:
                self.adjusted_bg_color = None
예제 #36
0
파일: display.py 프로젝트: HarryXS/mpf
    def adjust_colors(self, **kwargs):
        """Takes a settings dictionary and converts the object and background
        colors into a format Pygame can use.

        Args:
            **kwargs: A settings dictionary for this display element. Specific
                key / value pairs this method uses are shade, bg_shade, color,
                and bg_color.

        This method sets the adjusted_color and adjusted_bg_color attributes.

        """

        if self.slide.depth == 8:
            if 'shade' in kwargs:
                self.adjusted_color = (kwargs['shade'], 0, 0)
            else:
                self.adjusted_color = (15, 0, 0)  # todo default config

            if 'bg_shade' in kwargs:
                self.adjusted_bg_color = (kwargs['bg_shade'], 0, 0)
            else:
                self.adjusted_bg_color = None

        else:  # 24-bit
            if 'color' in kwargs:
                color_list = Util.hex_string_to_list(kwargs['color'])
                self.adjusted_color = (color_list[0], color_list[1],
                                       color_list[2])
            else:
                self.adjusted_color = (255, 255, 255)  # todo default config

            if 'bg_color' in kwargs:
                color_list = Util.hex_string_to_list(kwargs['color'])
                self.adjusted_bg_color = (color_list[0], color_list[1],
                                          color_list[2])
            else:
                self.adjusted_bg_color = None
예제 #37
0
    def collect_balls(self, target='home, trough'):
        """Used to ensure that all balls are in contained in ball devices with
        the tag or list of tags you pass.

        Typically this would be used after a game ends, or when the machine is
        reset or first starts up, to ensure that all balls are in devices
        tagged with 'home' and/or 'trough'.

        Args:
            target: A string of the tag name or a list of tags names of the
                ball devices you want all the balls to end up in. Default is
                ['home', 'trough'].

        """
        # I'm embarrassed at how ugly this code is. But meh, it works...

        tag_list = Util.string_to_list(target)

        self.log.debug("Collecting all balls to devices with tags '%s'",
                       tag_list)

        target_devices = set()
        source_devices = set()
        balls_to_collect = False

        for tag in tag_list:
            for device in self.machine.ball_devices.items_tagged(tag):
                target_devices.add(device)

        for device in self.machine.ball_devices:
            if device not in target_devices:
                if device.balls:
                    source_devices.add(device)
                    balls_to_collect = True

        self.log.debug("Ejecting all balls from: %s", source_devices)

        if balls_to_collect:
            self.machine.events.post('collecting_balls')

            for device in target_devices:
                self.machine.events.replace_handler(
                    'balldevice_{}_ball_enter'.format(device.name),
                    self._collecting_balls_entered_callback,
                    target=target)

            for device in source_devices:
                device.eject_all()
        else:
            self.log.debug("All balls are collected")
예제 #38
0
파일: machine.py 프로젝트: HarryXS/mpf
    def _load_plugins(self):
        self.log.info("Loading plugins...")

        # TODO: This should be cleaned up. Create a Plugins superclass and
        # classmethods to determine if the plugins should be used.

        for plugin in Util.string_to_list(
                self.config['mpf']['plugins']):


            self.log.debug("Loading '%s' plugin", plugin)

            pluginObj = self.string_to_class(plugin)(self)
            self.plugins.append(pluginObj)
예제 #39
0
    def _load_config_file(self, filename, verify_version=True, halt_on_error=True):
        config_file = MPFConfigFile(filename, FileManager.load(filename, verify_version, halt_on_error, True))

        try:
            if 'config' in config_file.config:
                path = os.path.split(filename)[0]

                for file in Util.string_to_list(config_file.config['config']):
                    full_file = os.path.join(path, file)
                    new_config = self._load_config_file(full_file)
                    config_file.add_child_file(new_config)
            return config_file
        except TypeError:
            return dict()
예제 #40
0
    def collect_balls(self, target='home, trough'):
        """Used to ensure that all balls are in contained in ball devices with
        the tag or list of tags you pass.

        Typically this would be used after a game ends, or when the machine is
        reset or first starts up, to ensure that all balls are in devices
        tagged with 'home' and/or 'trough'.

        Args:
            target: A string of the tag name or a list of tags names of the
                ball devices you want all the balls to end up in. Default is
                ['home', 'trough'].

        """
        # I'm embarrassed at how ugly this code is. But meh, it works...

        tag_list = Util.string_to_list(target)

        self.log.debug("Collecting all balls to devices with tags '%s'",
                       tag_list)

        target_devices = set()
        source_devices = set()
        balls_to_collect = False

        for tag in tag_list:
            for device in self.machine.ball_devices.items_tagged(tag):
                target_devices.add(device)

        for device in self.machine.ball_devices:
            if device not in target_devices:
                if device.balls:
                    source_devices.add(device)
                    balls_to_collect = True

        self.log.debug("Ejecting all balls from: %s", source_devices)

        if balls_to_collect:
            self.machine.events.post('collecting_balls')

            for device in target_devices:
                self.machine.events.replace_handler(
                    'balldevice_{}_ball_enter'.format(device.name),
                    self._collecting_balls_entered_callback,
                    target=target)

            for device in source_devices:
                device.eject_all()
        else:
            self.log.debug("All balls are collected")
예제 #41
0
    def are_balls_collected(self, target=None, antitarget=None):
        """Checks to see if all the balls are contained in devices tagged with
        the parameter that was passed.

        Note if you pass a target that's not used in any ball devices, this
        method will return True. (Because you're asking if all balls are
        nowhere, and they always are. :)

        Args:
            target: String or list of strings of the tags you'd like to
                collect the balls to. Default of None will be replaced with
                'home' and 'trough'.

        """
        if not target:
            target = ['home', 'trough']

        self.log.debug(
            "Checking to see if all the balls are in devices tagged"
            " with '%s'", target)

        if type(target) is str:
            target = Util.string_to_list(target)

        count = 0
        devices = set()

        for tag in target:
            for device in self.machine.ball_devices.items_tagged(tag):
                devices.add(device)

        if len(devices) == 0:
            # didn't find any devices matching that tag, so we return True
            return True

        for device in devices:
            count += device.get_status('balls')
            self.log.debug('Found %s ball(s) in %s. Found %s total',
                           device.get_status('balls'), device.name, count)

        if count == self.machine.ball_controller.num_balls_known:
            self.log.debug("Yes, all balls are collected")
            return True
        else:
            self.log.debug(
                "No, all balls are not collected. Balls Counted: %s. "
                "Total balls known: %s", count,
                self.machine.ball_controller.num_balls_known)
            return False
예제 #42
0
    def _get_merged_settings(self, section_name):
        # Returns a dict_merged dict of a config section from the machine-wide
        # config with the mode-specific config merged in.

        if section_name in self.machine.config:
            return_dict = copy.deepcopy(self.machine.config[section_name])
        else:
            return_dict = CaseInsensitiveDict()

        if section_name in self.config:
            return_dict = Util.dict_merge(return_dict,
                                          self.config[section_name],
                                          combine_lists=False)

        return return_dict
예제 #43
0
    def are_balls_collected(self, target=None, antitarget=None):
        """Checks to see if all the balls are contained in devices tagged with
        the parameter that was passed.

        Note if you pass a target that's not used in any ball devices, this
        method will return True. (Because you're asking if all balls are
        nowhere, and they always are. :)

        Args:
            target: String or list of strings of the tags you'd like to
                collect the balls to. Default of None will be replaced with
                'home' and 'trough'.

        """
        if not target:
            target = ['home', 'trough']

        self.log.debug("Checking to see if all the balls are in devices tagged"
                       " with '%s'", target)

        if type(target) is str:
            target = Util.string_to_list(target)

        count = 0
        devices = set()

        for tag in target:
            for device in self.machine.ball_devices.items_tagged(tag):
                devices.add(device)

        if len(devices) == 0:
            # didn't find any devices matching that tag, so we return True
            return True

        for device in devices:
            count += device.get_status('balls')
            self.log.debug('Found %s ball(s) in %s. Found %s total',
                           device.get_status('balls'), device.name, count)

        if count == self.machine.ball_controller.num_balls_known:
            self.log.debug("Yes, all balls are collected")
            return True
        else:
            self.log.debug("No, all balls are not collected. Balls Counted: %s. "
                           "Total balls known: %s", count,
                           self.machine.ball_controller.num_balls_known)
            return False
예제 #44
0
파일: config.py 프로젝트: qcapen/mpf
    def process_config(config_spec, source, target=None):
        config_spec = yaml.load(config_spec)
        processed_config = source

        for k in config_spec.keys():
            if k in source:
                processed_config[k] = Config.validate_config_item(
                    config_spec[k], source[k])
            else:
                log.debug('Processing default settings for key "%s:"', k)
                processed_config[k] = Config.validate_config_item(
                    config_spec[k])

        if target:
            processed_config = Util.dict_merge(target, processed_config)

        return processed_config
예제 #45
0
파일: events.py 프로젝트: qcapen/mpf
    def process_random_event_player(self, config, mode=None, priority=0):
        # config is localized to 'event_player'
        if self.debug:
            self.log.debug("Processing random_event_player configuration. Priority:"
                       " %s", priority)

        event_keys = set()

        for event_name, events in config.iteritems():
            if type(events) is not list:
                events = Util.string_to_list(events)

            event_keys.add(self.machine.events.add_handler(event_name,
                self._random_event_player_callback, priority,
                event_list=events))

        return self.unload_event_player_events, event_keys
예제 #46
0
    def process_config(config_spec, source, target=None):
        config_spec = yaml.load(config_spec)
        processed_config = source

        for k in config_spec.keys():
            if k in source:
                processed_config[k] = Config.validate_config_item(
                    config_spec[k], source[k])
            else:
                log.debug('Processing default settings for key "%s:"', k)
                processed_config[k] = Config.validate_config_item(
                    config_spec[k])

        if target:
            processed_config = Util.dict_merge(target, processed_config)

        return processed_config
예제 #47
0
파일: display.py 프로젝트: HarryXS/mpf
    def adjust_color(self, color, transparent=False):
        if self.slide.depth == 8:
            if color:  # Non-black
                return ((color, 0, 0))

            elif transparent:
                return None

            else:  # Black
                return ((0, 0, 0))

        else:  # 24-bit
            if color:  # Non-black
                color_list = Util.hex_string_to_list(color)
                return ((color_list[0], color_list[1], color_list[2]))

            elif transparent:
                return None

            else:  # Black
                return ((0, 0, 0))
예제 #48
0
    def adjust_color(self, color, transparent=False):
        if self.slide.depth == 8:
            if color:  # Non-black
                return ((color, 0, 0))

            elif transparent:
                return None

            else:  # Black
                return ((0, 0, 0))

        else:  # 24-bit
            if color:  # Non-black
                color_list = Util.hex_string_to_list(color)
                return ((color_list[0], color_list[1], color_list[2]))

            elif transparent:
                return None

            else:  # Black
                return ((0, 0, 0))
예제 #49
0
    def process_random_event_player(self, config, mode=None, priority=0):
        # config is localized to 'event_player'
        if self.debug:
            self.log.debug(
                "Processing random_event_player configuration. Priority:"
                " %s", priority)

        event_keys = set()

        for event_name, events in config.iteritems():
            if type(events) is not list:
                events = Util.string_to_list(events)

            event_keys.add(
                self.machine.events.add_handler(
                    event_name,
                    self._random_event_player_callback,
                    priority,
                    event_list=events))

        return self.unload_event_player_events, event_keys
예제 #50
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()
예제 #51
0
    def __init__(self, machine, name, config, collection=None, validate=True):
        config['number_str'] = str(config['number']).upper()
        super(LED, self).__init__(machine, name, config, collection,
                                  platform_section='leds', validate=validate)

        self.config['default_color'] = Util.hex_string_to_list(
            input_string=self.config['default_color'],
            output_length=3)

        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
                     }

        self.set_brightness_compensation(self.config['brightness_compensation'])

        self.current_color = []  # one item for each element, 0-255
예제 #52
0
 def get_merged_config(self):
     merged_config = self.config
     for key in self.child_files:
         merged_config = Util.dict_merge(merged_config, self.child_files[key].get_merged_config())
     
     return merged_config
예제 #53
0
parser.add_argument("-C",
                    action="store",
                    dest="mpfconfigfile",
                    default=os.path.join("mpf", "mpfconfig.yaml"),
                    metavar='config_file',
                    help="The MPF framework default config file. Default is "
                    "mpf/mpfconfig.yaml")

parser.add_argument("--version",
                    action="version",
                    version=version.version_str,
                    help="Displays the MPF, config file, and BCP version info "
                    "and exits")

args = parser.parse_args()
args.configfile = Util.string_to_list(args.configfile)

# Configure logging. Creates a logfile and logs to the console.
# Formatting options are documented here:
# https://docs.python.org/2.7/library/logging.html#logrecord-attributes

try:
    os.makedirs('logs')
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise

logging.basicConfig(
    level=args.loglevel,
    format='%(asctime)s : %(levelname)s : %(name)s : %(message)s',
    filename=args.logfile,
예제 #54
0
    def rotate(self, direction=None, steps=1, states=None,
               exclude_states=None, mode=None, **kwargs):
        """Rotates (or "shifts") the state of all the shots in this group.
        This is used for things like lane change, where hitting the flipper
        button shifts all the states of the shots in the group to the left or
        right.

        This method actually transfers the current state of each shot profile
        to the left or the right, and the shot on the end rolls over to the
        taret on the other end.

        Args:
            direction: String that specifies whether the rotation direction is
                to the left or right. Values are 'right' or 'left'. Default of
                None will cause the shot group to rotate in the direction as
                specified by the rotation_pattern.
            steps: Integer of how many steps you want to rotate. Default is 1.
            states: A string of a state or a list of strings that represent the
                targets that will be selected to rotate. If None (default), then
                all targets will be included.
            exclude_states: A string of a state or a list of strings that
                controls whether any targets will *not* be rotated. (Any
                targets with an active profile in one of these states will not
                be included in the rotation. Default is None which means all
                targets will be rotated)

        Note that this shot group must, and rotation_events for this
        shot group, must both be enabled for the rotation events to work.

        """

        if not self.machine.game:
            return

        if not self.rotation_enabled:

            if self.debug:
                self.log.debug("Received rotation request. "
                               "Rotation Enabled: %s. Will NOT rotate",
                               self.rotation_enabled)

            return

        # if we don't have states or exclude_states, we'll see if the first shot
        # in the group has them and use those. Since all the shots should have
        # the same profile applied, it's ok to just pick from the first one.

        if states:
            states = Util.string_to_lowercase_list(states)
        else:
            states = self.shots[0].enable_table[mode]['settings']['state_names_to_rotate']

        if exclude_states:
            exclude_states = Util.string_to_lowercase_list(exclude_states)
        else:
            exclude_states = (
                self.shots[0].enable_table[mode]['settings']['state_names_to_not_rotate'])

        shot_list = list()

        # build of a list of shots we're actually going to rotate
        for shot in self.shots:

            if ((not states or
                    shot.enable_table[mode]['current_state_name'] in states)
                    and shot.enable_table[mode]['current_state_name']
                    not in exclude_states):

                shot_list.append(shot)

        # shot_state_list is deque of tuples (state num, light show step num)
        shot_state_list = deque()

        for shot in shot_list:

            try:
                current_state = shot.running_light_show.current_location

            except AttributeError:
                current_state = -1

            shot_state_list.append(
                (shot.player[shot.enable_table[mode]['settings']['player_variable']],
                 current_state))

        if self.debug:
            self.log.debug('Rotating. Mode: %s, Direction: %s, Include states:'
                           ' %s, Exclude states: %s, Shots to be rotated: %s',
                           mode, direction, states,
               exclude_states, [x.name for x in shot_list])

            for shot in shot_list:
                shot.log.debug("This shot is part of a rotation event. Current"
                               " state: %s",
                               shot.enable_table[mode]['current_state_name'])

        # figure out which direction we're going to rotate
        if not direction:
            direction = shot_list[0].enable_table[mode]['settings']['rotation_pattern'][0]
            shot_list[0].enable_table[mode]['settings']['rotation_pattern'].rotate(-1)

            if self.debug:
                self.log.debug("Since no direction was specified, pulling from"
                               " rotation pattern: '%s'", direction)

        # rotate that list
        if direction == 'right':
            shot_state_list.rotate(steps)
        else:
            shot_state_list.rotate(steps * -1)

        # step through all our shots and update their states
        for i in range(len(shot_list)):
            shot_list[i].jump(mode=mode, state=shot_state_list[i][0],
                              lightshow_step=shot_state_list[i][1])
예제 #55
0
    def do_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 = (Util.string_to_lowercase_list(
                    show_actions[step_num]['events']))

                step_actions['events'] = event_list

            # slide_player
            if ('display' in show_actions[step_num]
                    and show_actions[step_num]['display']):

                step_actions['display'] = (
                    self.machine.display.slide_builder.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()
예제 #56
0
    def validate_config_item2(
        self,
        spec,
        validation_failure_info,
        item='item not in config!@#',
    ):

        default = 'default required!@#'

        item_type, validation, default = spec.split('|')

        if default.lower() == 'none':
            default = None

        if item == 'item not in config!@#':
            if default == 'default required!@#':
                log.error(
                    'Required setting missing from config file. Run with '
                    'verbose logging and look for the last '
                    'ConfigProcessor entry above this line to see where '
                    'the problem is.')
                sys.exit()
            else:
                item = default

        if item_type == 'single':
            item = self.validate_item(item, validation,
                                      validation_failure_info)

        elif item_type == 'list':
            item = Util.string_to_list(item)

            new_list = list()

            for i in item:
                new_list.append(
                    self.validate_item(i, validation, validation_failure_info))

            item = new_list

        elif item_type == 'set':
            item = set(Util.string_to_list(item))

            new_set = set()

            for i in item:
                new_set.add(
                    self.validate_item(i, validation, validation_failure_info))

            item = new_set

        elif item_type == 'dict':
            item = self.validate_item(item, validation,
                                      validation_failure_info)

            if not item:
                item = dict()

        else:
            self.log.error("Invalid Type '%s' in config spec %s:%s", item_type,
                           validation_failure_info[0][0],
                           validation_failure_info[1])
            sys.exit()

        return item
예제 #57
0
    def validate_item(self, item, validator, validation_failure_info):

        try:
            if item.lower() == 'none':
                item = None
        except AttributeError:
            pass

        if ':' in validator:
            validator = validator.split(':')
            # item could be str, list, or list of dicts
            item = Util.event_config_to_dict(item)

            return_dict = dict()

            for k, v in item.iteritems():
                return_dict[self.validate_item(
                    k, validator[0],
                    validation_failure_info)] = (self.validate_item(
                        v, validator[1], validation_failure_info))

            item = return_dict

        elif '%' in validator:

            if type(item) is str:

                try:
                    item = eval(validator.replace('%', "'" + item + "'"))
                except KeyError:
                    self.validation_error(item, validation_failure_info)
            else:
                item = None

        elif validator == 'str':
            if item is not None:
                item = str(item)
            else:
                item = None

        elif validator == 'float':
            try:
                item = float(item)
            except (TypeError, ValueError):
                # TODO error
                pass

        elif validator == 'int':
            try:
                item = int(item)
            except (TypeError, ValueError):
                # TODO error
                pass

        elif validator in ('bool', 'boolean'):
            if type(item) is str:
                if item.lower() in ['false', 'f', 'no', 'disable', 'off']:
                    item = False

            elif not item:
                item = False

            else:
                item = True

        elif validator == 'ms':
            item = Timing.string_to_ms(item)

        elif validator == 'secs':
            item = Timing.string_to_secs(item)

        elif validator == 'ticks':
            item = Timing.string_to_ticks(item)

        elif validator == 'ticks_int':
            item = int(Timing.string_to_ticks(item))

        elif validator == 'list':
            item = Util.string_to_list(item)

        else:
            self.log.error("Invalid Validator '%s' in config spec %s:%s",
                           validator, validation_failure_info[0][0],
                           validation_failure_info[1])
            sys.exit()

        return item