def difficulty(self, value): if value not in self.difficulties: logger.warning("Difficulty {} not in {}: skipping".format( value, ", ".join(self.difficulties))) else: logger.debug("Setting difficulty to {}".format(value)) self._difficulty = value
def status(self, value): if value not in self.STATUSES: logger.warning("Status {} not in {}: skipping".format( value, ", ".join(self.STATUSES))) return if value == self.status: logger.debug("Status is already {}: skipping".format(value)) return logger.debug("Setting status to {}".format(value)) self._status = value if self._status == "inactive": self.skip_skippable_animations() if self.unskippable_animation_task and self.unskippable_animation_task.active( ): self.unskippable_animation_task.cancel() self.on_inactive() elif self._status == "playing": self.skip_skippable_animations() if self.unskippable_animation_task and self.unskippable_animation_task.active( ): self.unskippable_animation_task.cancel() self.on_playing() elif self._status == "success": self.on_success()
def cancel_looping_task(self): if self.looping_task is not None: logger.debug('Cancelling looping task') try: self.looping_task.cancel() except Exception as e: logger.warning("Could not cancel looping task (reason={})".format(e))
def status(self, value): if value not in self.STATUSES: logger.warning("Status {} not in {}: skipping".format( value, ", ".join(self.STATUSES))) return if value == self.status: logger.debug("Status is already {}: skipping".format(value)) return logger.debug("Setting status to {}".format(value)) self._status = value for task_name, task in self.tasks.items(): if task.active(): task.cancel() self.tasks = {} if self._status == "chaos": self.on_chaos() elif self._status == "mute": self.on_mute() elif self._status == "playing": self.on_playing() elif self._status == "success": self.on_success()
def onMessage(self, payload, isBinary): if isBinary: logger.warning( "Binary message received ({} bytes): ignoring".format( len(payload))) return try: unicode_message = payload.decode('utf8') except UnicodeDecodeError: logger.exception("Cannot decode {}: ignoring".format(payload)) return try: message = json.loads(unicode_message) except json.JSONDecodeError: logger.exception( "Cannot load {}: ignoring".format(unicode_message)) return ok, warning = self.validate_message(message) if not ok: logger.info("Received {}".format(message)) logger.warning(warning) logger.info("Ignoring") else: logger.debug("Received {}".format(message)) self.log_message(message, to_server=False) self.factory.process_event(message[P.EVENT])
def cancel_release_task(self): logger.debug('Cancelling release task') try: self.release_task.cancel() except Exception as e: logger.warning( "Could not cancel release task (reason={})".format(e))
def action_set_variable(self, arguments, paragraphs, context): variable_name = arguments['variable']['variable'] if type(self.variables[variable_name]) is Timer: logger.warning("set_variable action is not supported for timer variables") return computed_value = self.compute(arguments['value'], context) self.variables[variable_name] = computed_value
def fetch_and_init_rules(self): scenario_rules = requests.get( '{}/get_scenario/'.format(self.storage_url), params={'room_id': self.room_id}, ).json() self.rule_definitions = scenario_rules['rules'] for trigger_type in self.on_trigger_type_rules: self.on_trigger_type_rules[trigger_type] = [] self.timers = set() self.variables = {} variable_definitions = scenario_rules['variables'] for variable in variable_definitions: if variable['type'] == 'timer': context = {R.CONTEXT_EXPIRING_TIMER: variable['name']} init_value = Timer( self, 0, False, self.process_rules, [], context, ) else: init_value = variable['init_value'] self.variables[variable['name']] = init_value for rule in self.rule_definitions: for trigger in rule['content']['triggers']: if trigger['template'] in self.on_trigger_type_rules: self.on_trigger_type_rules[trigger['template']].append( { "trigger": trigger, "rule": rule, } ) elif trigger['template'] == 'timed_trigger': self.timers.add( Timer( self, trigger['arguments']['session_time'], False, self.process_rule, rule, {}, ) ) elif trigger['template'] == 'periodic_trigger': self.timers.add( Timer( self, trigger['arguments']['period'], True, self.process_rule, rule, {}, ) ) elif trigger['template'] == 'timer_trigger': variable_timer_name = trigger['arguments']['timer']['variable'] self.variables[variable_timer_name].callback_args[0].append(rule) else: logger.warning("Unknown trigger type {}: skipping".format(trigger['template']))
def __init__(self, *args, **kwargs): super(SoundPlayer, self).__init__(*args, **kwargs) initial_master_volume = self.node_params.get('master_volume', None) master_volume_mixer = self.node_params.get('mixer', '') default_initial_volume = self.node_params.get('default_volume', 100) player = self.node_params.get('player', 'pyglet') if player == 'vlc': self.sound_player = self.vlc_play_sound elif player == 'pyglet': self.sound_player = self.pyglet_play_sound self.pyglet_players = [] loop = LoopingCall(self.pyglet_loop) loop.start(1 / 30) else: raise ValueError( "Bad player value ({}). Possible values are vlc or " "pyglet.".format(player)) try: self.master_volume = MasterVolume( initial_volume=initial_master_volume, mixer=master_volume_mixer, ) except Exception: logger.exception() logger.warning( "Unable to initialize the master volume controller. Further " "actions on the master volume will be ignored.") self.master_volume = None self.sounds = {} for sound in self.node_params.get('sounds', []): id_ = sound['id'] path = sound['path'] volume = sound.get('volume', default_initial_volume) if player == 'vlc': media = vlc.Media(path) media.parse() # / 1000 because we will be interested by the value in seconds duration = media.get_duration() / 1000 self.sounds[id_] = { 'media': media, 'duration': duration, 'volume': volume, } else: media = pyglet.media.load(path, streaming=False) self.sounds[id_] = { 'media': media, 'volume': volume, }
def __init__(self, *args, **kwargs): super(MusicPlayer, self).__init__(*args, **kwargs) initial_master_volume = self.node_params.get('master_volume', None) master_volume_mixer = self.node_params.get('mixer', '') default_initial_volume = self.node_params.get('default_volume', 100) player = self.node_params.get('player', 'vlc') if player == 'vlc': track_handler = VLCSelfReleasingTrackPlayer looping_track_handler = VLCLoopingTrackPlayer elif player == 'pyglet': track_handler = PygletTrackPlayer looping_track_handler = PygletLoopingTrackPlayer loop = LoopingCall(self.pyglet_loop) loop.start(1 / 30) else: raise ValueError( "Bad player value ({}). Possible values are vlc or " "pyglet.".format(player)) try: self.master_volume = MasterVolume( initial_volume=initial_master_volume, mixer=master_volume_mixer, ) except Exception: logger.exception() logger.warning( "Unable to initialize the master volume controller. Further " "actions on the master volume will be ignored.") self.master_volume = None self.tracks = {} for track in self.node_params.get('tracks', []): id_ = track['id'] path = track['path'] volume = track.get('volume', default_initial_volume) mode = track.get('mode', 'one_shot') if mode == 'loop': loop_a = track['loop_a'] loop_b = track['loop_b'] handler = looping_track_handler( media_path=path, loop_a=loop_a, loop_b=loop_b, initial_volume=volume, ) else: handler = track_handler( media_path=path, initial_volume=volume, ) self.tracks[id_] = handler
def send_to_node(self, name, channel, event): nodes = self.nodes.get(( name, channel, ), []) if nodes: for node in nodes: node.send_event(event) else: logger.warning( "Node {}@{} is not registered: skipping event".format( name, channel))
def pause(self): if self.task and self.task.active() and self.processor.state == STATE_TICKING: now = time.monotonic() delta_since_last_schedule = now - self.last_schedule_timestamp if delta_since_last_schedule > self.last_computed_delay: logger.warning( "Timer precision issue (now={}, last_schedule_timestamp={}, delta={}, last_computed_delay={}): " "rounding last_computed_delay to 0".format( now, self.last_schedule_timestamp, delta_since_last_schedule, self.last_computed_delay ) ) self.last_computed_delay = 0 else: self.last_computed_delay -= delta_since_last_schedule self.task.cancel()
def fetch_and_init_rules(self): rule_sets = requests.get( '{}/get_rules_from_room_id/?room_id={}'.format( self.storage_url, self.room_id)).json() activated_rules = [] activated_variables = [] for rule_set in rule_sets: activated_rules.extend(rule_set['rules']) activated_variables.extend(rule_set['variables']) self.rule_definitions = activated_rules for trigger_type in self.on_trigger_type_rules: self.on_trigger_type_rules[trigger_type] = [] self.timers = set() self.variables = {} for variable in activated_variables: if variable['type'] == 'timer': context = {R.CONTEXT_EXPIRING_TIMER: variable['name']} init_value = Timer( self, 0, False, self.process_rules, [], context, ) else: init_value = variable['init_value'] self.variables[variable['name']] = init_value for rule in self.rule_definitions: for trigger in rule['content']['triggers']: if trigger['template'] in self.on_trigger_type_rules: self.on_trigger_type_rules[trigger['template']].append({ "trigger": trigger, "rule": rule, }) elif trigger['template'] == 'timed_trigger': self.timers.add( Timer( self, trigger['arguments']['session_time'], False, self.process_rule, rule, {}, )) elif trigger['template'] == 'periodic_trigger': self.timers.add( Timer( self, trigger['arguments']['period'], True, self.process_rule, rule, {}, )) elif trigger['template'] == 'timer_trigger': variable_timer_name = trigger['arguments']['timer'][ 'variable'] self.variables[variable_timer_name].callback_args[ 0].append({ "trigger": {}, "rule": rule, }) else: logger.warning("Unknown trigger type {}: skipping".format( trigger['template'])) self.buttons = {} cards = requests.get('{}/get_cards_from_room_id/?room_id={}'.format( self.storage_url, self.room_id)).json() for card in cards: card_rows = requests.get('{}/card_row/?card={}'.format( self.storage_url, card['id'])).json() for row in card_rows: if row['widget'] == 'buttons_group': for button in row['widget_params']: self.buttons[button['id']] = button
def onMessage(self, payload, isBinary): if isBinary: logger.warning( "Binary message received ({} bytes): ignoring".format( len(payload))) return try: unicode_message = payload.decode('utf8') except UnicodeDecodeError: logger.exception("Cannot load {}: ignoring".format(payload)) return try: message = json.loads(unicode_message) except json.JSONDecodeError: logger.exception( "Cannot load {}: ignoring".format(unicode_message)) return ok, warning = self.validate_message(message) if not ok: logger.info("Received {}".format(message)) logger.warning(warning) logger.info("Ignoring") else: logger.debug("Received {}".format(message)) self.log_message(message, to_server=True) if self.client_type == P.CLIENT_NODE: if message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_EVENT: event = message[P.EVENT] self.factory.process_event(self.name, self.channel, event) elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_LOG: level = message[P.LOG_LEVEL] content = message[P.LOG_CONTENT] if level == P.LOG_LEVEL_INFO: self.factory.send_log_info(content) elif level == P.LOG_LEVEL_ERROR: self.factory.send_log_error(content) elif self.client_type == P.CLIENT_ADMIN: room_id = message[P.ROOM_ID] if message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_RUN: self.factory.process_run_room(room_id) elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_HALT: self.factory.process_halt_room(room_id) elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_RESET: self.factory.process_reset_room(room_id) elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_SEND_EVENT_TO: node = message[P.SEND_EVENT_NODE] event_to_send = message[P.EVENT] self.factory.process_send_event_to(room_id, node, event_to_send) elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_SEND_EVENT_AS: node = message[P.SEND_EVENT_NODE] event_to_send = message[P.EVENT] self.factory.process_send_event_as(room_id, node, event_to_send) elif message[ P.MESSAGE_TYPE] == P.MESSAGE_TYPE_PRESSED_ADMIN_BUTTON: button_id = message[P.PRESSED_BUTTON_ID] self.factory.process_on_admin_button_pressed( room_id, button_id) else: self.process_i_am_message(message)