Пример #1
0
    def connect_agent(self, token):
        """Connect the agent to the simulation and returns a JSON response.

        :param token: The generated token for the agent.
        :return dict: Dictionary with status representing if any errors were found and a general message."""
        Logger.normal('Try to connect a agent.')

        response = {'status': 0, 'message': ''}

        try:
            initial_percepts = self.copycat.connect_agent(token)

            if initial_percepts:
                response['agents'] = [{'agent': self.jsonify_agent(initial_percepts['agent_percepts'])}]
                response['map_percepts'] = initial_percepts['map_percepts']
                response['status'] = 1
                response['message'] = 'Agent connected.'

                Logger.normal('Agent connected.')

                return response
            else:
                response['message'] = 'Agent could not connect.'

                Logger.error('Agent could not connect.')

                return response
        except Exception as e:
            response['message'] = f'An error occurred during connection: {str(e)}.'
            Logger.error(f'Unknown error: {str(e)}.')

            return response
Пример #2
0
    def restart(self):
        """Restart the simulation and returns a JSON response.

        All the agents, social assets and events are converted, the copycat class prevents from the formatter changing
        the objects inside the engine.

        :return dict: Dictionary with status representing if any errors were found, the list of agents and social assets,
        the event with the flood, victims, photos and water samples and a general message."""

        Logger.normal('Try to restart the simulation.')

        try:
            agents, step, current_step, new_map_percepts, report, assets_tokens = self.copycat.restart()
            message = 'Simulation restarted.'

            json_agents_init = [{'agent': self.jsonify_agent(agent)} for agent in agents]

            json_agents = self.jsonify_agents(agents)
            json_actors = [{'agent': agent, 'message': message} for agent in json_agents]
            environment = {'events': self.jsonify_events(step), 'step': current_step}

            percepts = {'status': 1, 'actors': json_actors, 'environment': environment, 'message': 'Simulation restarted.'}
            initial_percepts = {'status': 1, 'agents': json_agents_init, 'map_percepts': new_map_percepts, 'message': ''}
            report_response = {'status': 1, 'report': report, 'message': ''}

            Logger.normal('Simulation restarted.')

            return {'status': 1, 'initial_percepts': initial_percepts, 'assets_tokens': assets_tokens,
                    'report': report_response, 'percepts': percepts, 'message': message}

        except Exception as e:
            Logger.critical(f'Error to restart the simulation, Error: {str(e)}.')

            return {'status': 0, 'message': f'An error occurred during restart: "{str(e)}"'}
Пример #3
0
    def start(self):
        """Start the simulation and returns a JSON response.

        All the agents, social assets and events are converted, the copycat class prevents from the formatter changing
        the objects inside the engine.

        :return dict: Dictionary with status representing if any errors were found, the list of agents and social assets,
        the event with the flood, victims, photos and water samples and a general message."""

        Logger.normal('Try to start the simulation.')

        try:
            response = self.copycat.start()
            message = 'Simulation started.'

            json_agents = self.jsonify_agents(response[0])
            json_actors = [{'agent': agent, 'message': message} for agent in [*json_agents]]
            environment = {'events': self.jsonify_events(response[1]), 'step': response[2]}
            map_percepts = response[3]

            Logger.normal(message)

            return {'status': 1, 'actors': json_actors, 'environment': environment,
                    'map_percepts': map_percepts, 'message': message}

        except Exception as e:
            Logger.error(f'Unknown error: {str(e)}.')

            return {'status': 0, 'message': f'An error occurred during restart: "{str(e)}"'}
Пример #4
0
    def calculate_route(self, parameters):
        """Return the route calculated with the parameters given.

        :param parameters: list with the parameters to calculate the route.
        :return dict: Dictionary with the result of the operation, the route calculated, the distance od the route and
        a message."""

        Logger.normal('Route Calculator Service called.')

        try:
            response = self.copycat.calculate_route(parameters)
            response['route'] = [self.format_location(coord) for coord in response['route']]

            return {'status': 1, 'response': response}

        except Exception as e:
            return {'status': 0, 'message': f'Unknown Error: {str(e)}'}
Пример #5
0
    def finish_social_asset_connections(self, tokens):
        Logger.normal('Finishing social assets connections.')

        try:
            response = self.copycat.finish_social_asset_connections(tokens)
            json_actors = []
            if response is not None:
                for agent in response:
                    json_actors.append({'asset': self.jsonify_asset(agent), 'message': 'Social asset connected'})

            Logger.normal('Social assets connection finished.')

            return {'status': 1, 'actors': json_actors, 'message': 'Finish social asset connections'}

        except Exception as e:
            Logger.error(f'Unknown error {str(e)}.')

            return {'status': 0, 'message': f'An error occurred during connection: {str(e)}.'}
Пример #6
0
    def do_step(self, token_action_list):
        """Do one step against the simulation.

        Do one step means that the simulation will process all the actions sent and activate the next step.

        :param token_action_list: The actions sent by each agent or social asset.
        :return tuple|None: If not terminated the first position holds the results from the actions sent and the second,
        the current step, else None."""

        Logger.normal(f'Process step {self.cycler.current_step}.')

        actions = [
            token_action_param['action']
            for token_action_param in token_action_list
        ]
        tokens = [
            token_action_param['token']
            for token_action_param in token_action_list
        ]

        self.actions_amount += len(token_action_list)
        self.actions_amount_by_step.append(
            (self.cycler.current_step, len(token_action_list)))
        self.actions_by_step.append((self.cycler.current_step, actions))
        self.action_token_by_step.append(
            (self.cycler.current_step, zip(tokens, actions)))

        if self.terminated:
            return None

        actions_results, requests = self.cycler.execute_actions(
            token_action_list)
        step = self.cycler.get_step()

        self.cycler.current_step += 1
        self.cycler.update_steps()

        if self.cycler.check_steps():
            self.terminated = True
            return actions_results, step, self.cycler.current_step, requests

        self.cycler.activate_step()

        return actions_results, step, self.cycler.current_step, requests
Пример #7
0
    def restart(self, config_file, load_sim, write_sim):
        """Restart the simulation by regenerating all the simulation and reseting all the log variables.

        :return tuple: First position holding the agents, second position the social assets, third position holding
        the current step, fourth position holding the report for previous match and the the fifth holding the social asset
        that need to be disconnected."""

        Logger.normal('Restart the simulation.')

        social_assets_tokens = self.cycler.get_assets_tokens()
        report = self.cycler.match_report()
        self.cycler.restart(config_file, load_sim, write_sim)
        self.terminated = False
        self.actions_amount = 0
        self.actions_by_step.clear()
        self.actions_amount_by_step.clear()
        self.action_token_by_step.clear()

        return (*self.start(), report, social_assets_tokens)
Пример #8
0
    def simulation_report(self):
        Logger.normal('Generate simulation report.')
        response = {'status': 0, 'message': ''}

        try:
            report = self.copycat.simulation_report()

            if isinstance(report, str):
                Logger.error('Error to generate simulation report.')
                response['message'] = 'Error to generate simulation report.'
            
            else:
                response['status'] = 1
                response['report'] = report

        except Exception as e:
            response['message'] = str(e)

        return response
Пример #9
0
    def save_logs(self):
        """Write all the saved logs to a file on the root of the project, the file will be inside a folder structure
        based on the date and time the simulation ran."""

        Logger.normal('Save the logs.')

        year, month, day, hour, minute, config_file, logs = self.copycat.get_logs()
        path = pathlib.Path(__file__).parents[3] / str(year) / str(month) / str(day) / str(config_file)

        os.makedirs(str(path.absolute()), exist_ok=True)

        hour = '{:0>2d}'.format(hour)
        minute = '{:0>2d}'.format(minute)

        for log in logs:
            delivered_items = []
            for item_log in logs[log]['environment']['delivered_items']:
                delivered_items.extend(item_log['items'])
            json_items = self.jsonify_delivered_items(delivered_items)

            json_agents = self.jsonify_agents(logs[log]['agents']['agents'])
            json_assets = self.jsonify_assets(logs[log]['assets']['assets'])
            json_active_agents = self.jsonify_agents(logs[log]['agents']['active_agents'])
            json_active_assets = self.jsonify_assets(logs[log]['assets']['active_assets'])
            json_action_token_by_step = self.jsonify_action_token_by_step(logs[log]['actions']['action_token_by_step'])
            json_acts_by_step = self.jsonify_amount_of_actions_by_step(logs[log]['actions']['amount_of_actions_by_step'])
            json_actions_by_step = self.jsonify_actions_by_step(logs[log]['actions']['actions_by_step'])

            logs[log]['environment']['delivered_items'] = json_items
            logs[log]['agents']['agents'] = json_agents
            logs[log]['assets']['assets'] = json_assets
            logs[log]['agents']['active_agents'] = json_active_agents
            logs[log]['assets']['active_assets'] = json_active_assets
            logs[log]['actions']['action_token_by_step'] = json_action_token_by_step
            logs[log]['actions']['amount_of_actions_by_step'] = json_acts_by_step
            logs[log]['actions']['actions_by_step'] = json_actions_by_step

            map_log = re.sub('([\w\s\d]+?\\\\)|([\w\s\d]+?/)|(\.\w+)', '', log)

            with open(str((path / f'LOG FILE {map_log} at {hour}h {minute}min.txt').absolute()), 'w') as file:
                file.write(json.dumps(logs[log], sort_keys=False, indent=4))
                file.write('\n\n' + '=' * 120 + '\n\n')
Пример #10
0
    def match_report(self):
        Logger.normal('Generate match report.')
        response = {'status': 0, 'message': ''}
        report = {'status': 0, 'message': ''}

        try:
            match_report = self.copycat.match_report()

            report['status'] = 1
            report['report'] = match_report

            response['report'] = report

        except Exception as e:
            response['message'] = str(e)
            report['message'] = str(e)

            response['report'] = report

        return response
Пример #11
0
    def disconnect_social_asset(self, token):
        """Disconnect the social asset to the simulation and returns a JSON response.

        :param token: The generated token for the social asset.
        :return dict: Dictionary with status representing if any errors were found and a general message."""

        Logger.normal('Try to disconnect a social asset.')

        try:
            response = self.copycat.disconnect_social_asset(token)

            if response:
                Logger.normal('Social asset disconnected.')

                return {'status': 1, 'message': 'Social asset disconnected.'}

            else:
                Logger.normal('Social asset is not connected.')

                return {'status': 0, 'message': 'Social asset is not connected.'}

        except Exception as e:
            Logger.error(f'Unknown error: {str(e)}.')

            return {'status': 0, 'message': f'An error occurred during disconnection: {str(e)}.'}
Пример #12
0
    def do_step(self, token_action_list):
        """Do a step on the simulation.

        After the step, all the results from the actions are converted to JSON.

        :param token_action_list: List with all the tokens combined with the action|parameter sent.
        :return dict: Dictionary with a status representing if any errors were found, the list of agents and social
        assets, the event with the flood, victims, photos, and water samples and a general message."""

        Logger.normal('Try to process the current step.')

        try:
            Logger.normal('Process the agents actions.')
            response = self.copycat.do_step(token_action_list)

            if response is None:
                return {'status': 1, 'message': 'Simulation finished.'}

            json_actors = []
            for obj in response[0]:
                if 'agent' in obj:
                    json_actors.append({'agent': self.jsonify_agent(obj['agent']), 'message': obj['message']})
                else:
                    json_actors.append({'asset': self.jsonify_asset(obj['social_asset']), 'message': obj['message']})

            json_events = self.jsonify_events(response[1])
            environment = {'events': json_events, 'step': response[2]}

            if response[3]:
                Logger.normal('A social asset request connection will start.')

                messages = {'environment': environment, 'actors': json_actors}
                current_step = response[2] - 1

                return {'status': 2, 'requests': response[3], 'messages': messages,
                        'current_step': current_step, 'message': 'Step completed.'}

            Logger.normal('Step processed.')

            return {'status': 1, 'actors': json_actors, 'environment': environment, 'message': 'Step completed.'}

        except Exception as e:
            Logger.error(f'Unknown error: {str(e)}.')
            return {'status': 0, 'message': f'An error occurred during step: "{str(e)}"'}