示例#1
0
def chat_task(ctx, pipe):
    n = Pyre(ctx)
    n.join("CHAT")
    n.start()

    poller = zmq.Poller()
    poller.register(pipe, zmq.POLLIN)
    poller.register(n.inbox, zmq.POLLIN)
    while(True):
        items = dict(poller.poll())
        if pipe in items and items[pipe] == zmq.POLLIN:
            message = pipe.recv()
            # message to quit
            if message.decode('utf-8') == "$$STOP":
                break
            print("CHAT_TASK: %s" % message)
            n.shout("CHAT", message)
        if n.inbox in items and items[n.inbox] == zmq.POLLIN:
            cmds = n.recv()
            type = cmds.pop(0)
            print("NODE_MSG TYPE: %s" % type)
            print("NODE_MSG PEER: %s" % uuid.UUID(bytes=cmds.pop(0)))
            print("NODE_MSG NAME: %s" % cmds.pop(0))
            if type.decode('utf-8') == "SHOUT":
                print("NODE_MSG GROUP: %s" % cmds.pop(0))
            print("NODE_MSG CONT: %s" % cmds)
    n.stop()
示例#2
0
def chat_task(ctx, pipe, ncmds):
    n = Pyre(ctx)
    n.join("CHAT")
    n.start()

    # wait for someone else to join the chat
    while not n.get_peer_groups():
        pass

    pipe.send('ready'.encode('utf-8'))
    cmds = 0
    t0 = time.time()

    poller = zmq.Poller()
    poller.register(pipe, zmq.POLLIN)
    poller.register(n.inbox, zmq.POLLIN)
    while(True):
        items = dict(poller.poll())
        if pipe in items and items[pipe] == zmq.POLLIN:
            message = pipe.recv()
            # message to quit
            if message.decode('utf-8') == "$$STOP":
                break
            n.shout("CHAT", message)
        if n.inbox in items and items[n.inbox] == zmq.POLLIN:
            n.recv()
            cmds += 1
            if cmds == ncmds:
                msg = 'Got %s msgs in %0.2f sec' % (cmds, time.time() - t0)
                pipe.send(msg.encode('utf-8'))
    n.stop()
示例#3
0
def chat_task(ctx, pipe, ncmds):
    n = Pyre(ctx=ctx)
    n.join("CHAT")
    n.start()

    # wait for someone else to join the chat
    while not n.peer_groups():
        pass

    pipe.send('ready'.encode('utf-8'))
    cmds = 0
    t0 = time.time()

    poller = zmq.Poller()
    poller.register(pipe, zmq.POLLIN)
    poller.register(n.inbox, zmq.POLLIN)
    while (True):
        items = dict(poller.poll())
        if pipe in items and items[pipe] == zmq.POLLIN:
            message = pipe.recv()
            # message to quit
            if message.decode('utf-8') == "$$STOP":
                break
            n.shout("CHAT", message)
        if n.inbox in items and items[n.inbox] == zmq.POLLIN:
            n.recv()
            cmds += 1
            if cmds == ncmds:
                msg = 'Got %s msgs in %0.2f sec' % (cmds, time.time() - t0)
                pipe.send(msg.encode('utf-8'))
    n.stop()
    def discovery_task(self, ctx, pipe):
        self.log.debug("Pyre on iface : {}".format(self.iface))
        n = Pyre(self.groupName, sel_iface=self.iface)
        n.set_header("DISCOVERY_Header1","DISCOVERY_HEADER")
        n.join(self.groupName)
        n.start()

        poller = zmq.Poller()
        poller.register(pipe, zmq.POLLIN)

        while(True):
            items = dict(poller.poll())

            if pipe in items and items[pipe] == zmq.POLLIN:
                message = pipe.recv()
                # message to quit
                if message.decode('utf-8') == "$$STOP":
                    break

                n.shout(self.groupName, message)

        n.stop()
    def discovery_task(self, ctx, pipe):
        self.log.debug("Pyre on iface : {}".format(self.iface))
        n = Pyre(self.groupName, sel_iface=self.iface)
        n.set_header("DISCOVERY_Header1", "DISCOVERY_HEADER")
        n.join(self.groupName)
        n.start()

        poller = zmq.Poller()
        poller.register(pipe, zmq.POLLIN)

        while (True):
            items = dict(poller.poll())

            if pipe in items and items[pipe] == zmq.POLLIN:
                message = pipe.recv()
                # message to quit
                if message.decode('utf-8') == "$$STOP":
                    break

                n.shout(self.groupName, message)

        n.stop()
示例#6
0
answers = {"command": "ANSWER", "information": "MOBIDIK"}

msg_broadcast_name = str(n.name())
wsp_msg = 'whisper sample message'
while True:
    have_command = False
    rec_msg = n.recv()
    msg_type = rec_msg[0].decode('utf-8')
    sender_uuid = uuid.UUID(bytes=rec_msg[1])
    sender_name = rec_msg[2].decode('utf-8')

    data = rec_msg[-1]
    data = data.decode('utf-8')
    if str(data) == 'NameRequest':
        n.shout("CHAT", msg_broadcast_name.encode('utf-8'))

    if str(msg_type) == 'SHOUT' or str(msg_type) == 'WHISPER':
        try:
            jdata = json.loads(data)
            have_command = True
        except Exception as e:
            print('Exception: ', e)

        if have_command:
            for item in jdata['payload']['commandList']:
                if item['command'] == "GOTO":
                    answers['information'] = item['location']
                elif item['command'] == "POSE":
                    answers['information'] = "0, 10, 20"
                elif item['command'] == "RESUME":
示例#7
0
class Bridge(object):
    """docstring for Bridge"""
    def __init__(self, uvc_id):
        super(Bridge, self).__init__()

        self.data_seq = 0
        self.note_seq = 0

        # init capture
        self.cap = uvc.Capture(uvc_id)
        logger.info('Initialised uvc device %s'%self.cap.name)

        # init pyre
        self.network = Pyre(socket.gethostname()+self.cap.name[-4:])
        self.network.start()
        logger.info('Bridging under "%s"'%self.network.name())

        # init sensor sockets
        ctx = zmq.Context()
        generic_url = 'tcp://*:*'
        public_ep   = self.network.endpoint()
        self.note, self.note_url = self.bind(ctx, zmq.PUB , generic_url, public_ep)
        self.data, self.data_url = self.bind(ctx, zmq.PUB , generic_url, public_ep,set_hwm=1)
        self.cmd , self.cmd_url  = self.bind(ctx, zmq.PULL, generic_url, public_ep)

    def loop(self):
        logger.info('Entering bridging loop...')
        self.network.shout('pupil-mobile', self.sensor_attach_json())
        try:
            while True:
                self.poll_network()
                self.poll_cmd_socket()
                self.publish_frame()

        except KeyboardInterrupt:
            pass
        except Exception:
            import traceback
            traceback.print_exc()
        finally:
            self.network.shout('pupil-mobile', json.dumps({
                'subject'   : 'detach',
                'sensor_uuid': self.network.uuid().hex
            }))
            logger.info('Leaving bridging loop...')

    def publish_frame(self):
        frame = self.cap.get_frame_robust()
        now = int(time.time()*1000000)
        index = self.data_seq
        self.data_seq += 1
        self.data_seq %= sequence_limit

        jpeg_buffer = frame.jpeg_buffer
        meta_data = struct.pack('<LLLLQLL', 0x10, frame.width, frame.height, index, now, jpeg_buffer.size, 0)
        self.data.send_multipart([self.network.uuid().hex, meta_data, jpeg_buffer])

    def poll_network(self):
        while has_data(self.network.socket()):
            event = PyreEvent(self.network)
            if event.type == 'JOIN' and event.group == 'pupil-mobile':
                self.network.whisper(event.peer_uuid, self.sensor_attach_json())

    def poll_cmd_socket(self):
        while has_data(self.cmd):
            sensor, cmd_str = self.cmd.recv_multipart()
            try:
                cmd = json.loads(cmd_str)
            except Exception as e:
                logger.debug('Could not parse received cmd: %s'%cmd_str)
            else:
                logger.debug('Received cmd: %s'%cmd)
                if cmd.get('action') == 'refresh_controls':
                    self.publish_controls()
                elif cmd.get('action') == 'set_control_value':
                    val = cmd.get('value', 0)
                    if cmd.get('control_id') == 'CAM_RATE':
                        self.cap.frame_rate = self.cap.frame_rates[val]
                    elif cmd.get('control_id') == 'CAM_RES':
                        self.cap.frame_size = self.cap.frame_sizes[val]
                    self.publish_controls()


    def __del__(self):
        self.note.close()
        self.data.close()
        self.cmd.close()
        self.network.stop()

    def publish_controls(self):
        self.note.send_multipart([
            self.network.uuid().hex,
            self.frame_size_control_json()])
        self.note.send_multipart([
            self.network.uuid().hex,
            self.frame_rate_control_json()])

    def sensor_attach_json(self):
        sensor = {
            "subject"         : "attach",
            "sensor_name"     : self.cap.name,
            "sensor_uuid"     : self.network.uuid().hex,
            "sensor_type"     : 'video',
            "notify_endpoint" : self.note_url,
            "command_endpoint": self.cmd_url,
            "data_endpoint"   : self.data_url
        }
        return json.dumps(sensor)

    def frame_size_control_json(self):
        index = self.note_seq
        self.note_seq += 1
        self.note_seq %= sequence_limit
        curr_fs = self.cap.frame_sizes.index(self.cap.frame_size)
        return json.dumps({
            "subject"         : "update",
            "control_id"      : "CAM_RES",
            "seq"             : index,
            "changes"         : {
                "value"           : curr_fs,
                "dtype"           : 'intmapping',
                "min"             : None,
                "max"             : None,
                "res"             : None,
                "def"             : 0,
                "caption"         : 'Resolution',
                "readonly"        : False,
                "map"             : [{
                    'value'  : idx,
                    'caption': '%ix%i'%fs
                } for idx,fs in enumerate(self.cap.frame_sizes)]
            }
        })

    def frame_rate_control_json(self):
        index = self.note_seq
        self.note_seq += 1
        self.note_seq %= sequence_limit
        curr_fr = self.cap.frame_rates.index(self.cap.frame_rate)
        return json.dumps({
            "subject"         : "update",
            "control_id"      : "CAM_RATE",
            "seq"             : index,
            "changes"         : {
                "value"           : curr_fr,
                "dtype"           : 'intmapping',
                "min"             : None,
                "max"             : None,
                "res"             : None,
                "def"             : 0,
                "caption"         : 'Frame Rate',
                "readonly"        : False,
                "map"             : [{
                    'value'  : idx,
                    'caption': '%.1f Hz'%fr
                } for idx,fr in enumerate(self.cap.frame_rates)]
            }
        })

    def bind(self, ctx, sock_type, url, public_ep, set_hwm=None):
        sock = ctx.socket(sock_type)
        if set_hwm: sock.set_hwm(set_hwm)
        sock.bind(url)
        ep = sock.last_endpoint
        port = ep.split(':')[-1]
        public_ep.split(':')[-1]
        public_addr = public_ep.split(':')[:-1]
        return sock, ':'.join(public_addr+[port])
示例#8
0
#         "features": features_list
#       }]

msg_name_request = 'NameRequest'
dest_name = "receiver_node"
get_info = True
get_queries = True
send_next_query = False
k = 0
q = 0

print('press enter to start the program')
k = input()

# send an order to all nodes(shout) to send their names
n.shout("CHAT", msg_name_request.encode('utf-8'))

while get_queries:
    rec_msg = n.recv()
    msg_type = rec_msg[0].decode('utf-8')

    # get all the nodes in the group
    sender_uuid = uuid.UUID(bytes=rec_msg[1])
    sender_name = rec_msg[2].decode('utf-8')
    nodes_list[sender_name] = sender_uuid

    data = rec_msg[-1]
    data = data.decode('utf-8')
    if str(msg_type) == 'SHOUT' or str(msg_type) == 'WHISPER':
        try:
            jdata = json.loads(data)
示例#9
0
class ZyreToZMQModule:
    """ The ZyreToZMQModule Base Class """
    def __init__(self,
                 ctx=None,
                 name="Default",
                 headers=None,
                 groups=None,
                 config_file=None,
                 polling_timeout=1,
                 sim_time=2):

        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.DEBUG)
        # create the console output logging
        sh = logging.StreamHandler()
        sh.setLevel(logging.INFO)
        # create a logger writing into a log file
        fh = logging.FileHandler(name + ".log")
        fh.setLevel(logging.DEBUG)
        # create formatter and add it to the handlers
        # see https://docs.python.org/2/library/logging.html#logrecord-attributes for what can be logged
        fh.setFormatter(
            logging.Formatter(
                'Name: %(name)s, ProcessName: %(processName)s, ThreadName: %(threadName)s, Module: %(module)s, FunctionName: %(funcName)s, LineNo: %(lineno)d, Level: %(levelname)s, Msg: %(message)s'
            ))
        #sh.setFormatter(logging.Formatter('Module: %(module)s, FunctionName: %(funcName)s, LineNo: %(lineno)d, Level: %(levelname)s, Msg: %(message)s'))
        sh.setFormatter(
            logging.Formatter(
                'Name: %(name)s, %(module)s/%(funcName)s[%(levelname)s]: %(message)s (lineno:%(lineno)d)'
            ))
        # add the handlers to logger
        self.logger.addHandler(sh)
        self.logger.addHandler(fh)
        self.logger.propagate = False  # don't pass messages to parent loggers

        if not type(ctx) == zmq.sugar.context.Context:
            self.logger.warn(
                "Created ZMQ context. Please supply a ZMQ context next time.")
            ctx = zmq.Context()
        self.ctx = ctx
        if not type(name) == str:
            name = "Default"
            self.logger.warn(
                "Please provide a the name as a string. Setting name to default: %s."
                % name)
        self.name = name
        if not headers:
            self.logger.warn(
                "Please provide a model and other header information.")
            headers = {}
        self.headers = headers
        if not groups:
            groups = ["SHERPA"]
            self.logger.warn(
                "Please provide a list with group names to which it will listen. Will set it to default: %s"
                % groups)
        self.groups = groups
        if not config_file:
            # will be opened during configuration
            self.logger.error(
                "No config file provided for initial configuration")
            exit()

        self.config_file = config_file
        self.config = None
        self.alive = True  # used for exiting once the node is stopped
        self.line_controller = None  # stores uid of line controller this module is listening to (to avoid several line controllers)
        self.com_timeout = polling_timeout  # time_out in msec after which poller returns
        self.sim_time = sim_time  # time in msec
        self.inbox = []
        self.outbox = []

        # Node setup
        self.node = Pyre(self.name)
        for key in self.headers:
            self.node.set_header(key, self.headers[key])
        for group in self.groups:
            self.node.join(group)
        #self.node.set_verbose()
        self.node.start()

        # Socket setup
        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

        port = "12911"
        self.zmq_socket = self.ctx.socket(zmq.PUB)
        self.zmq_socket.bind("tcp://*:%s" % port)

        self.run()

    def run(self):
        """ Running loop of this process:
        [COMMUNICATION]     Check communication channels and parse all messages.
        """
        while self.alive:
            try:
                #[COMMUNICATION]
                self.communication()
                #[LOGGING]
                #self.logging()
                time.sleep(1)
            except (KeyboardInterrupt, SystemExit):
                break
        self.node.stop()

    def communication(self):
        """ This function handles the communication """

        # Check if communication is ready
        if not self.poller:
            self.logger.warn("No communication channels yet.")
        # Process input
        items = dict(self.poller.poll(self.com_timeout))
        # Get input from Pyre socket and put it in inbox which is processed in the following steps
        #logger.debug("Start processing incoming messages")
        if self.node.socket() in items and items[
                self.node.socket()] == zmq.POLLIN:
            self.logger.info("Received %d msgs." % len(items))
            #print "msg arrived. inbox len %d" % len(self.inbox)
            msg_frame = self.node.recv()
            msg_type = msg_frame.pop(0)
            peer_uid = uuid.UUID(bytes=msg_frame.pop(0))
            peer_name = msg_frame.pop(0)
            self.logger.info("Msg type: %s" % msg_type)
            self.logger.info("Sender: %s" % peer_name)
            # For shout and whisper take message payload and put it into inbox assuming it is correct
            # For the other zyre msgs create a JSON obj and put that into inbox
            # TODO: add validation
            if msg_type == "SHOUT":
                group = msg_frame.pop(0)
                msg = json.loads(msg_frame.pop(0))
                msg["sender_UUID"] = peer_uid
                msg["sender_name"] = peer_name
                #                self.inbox.append(msg)
                self.outbox.append(msg)
            elif msg_type == "WHISPER":
                msg = json.loads(msg_frame.pop(0))
                msg["sender_UUID"] = peer_uid
                msg["sender_name"] = peer_name
                self.inbox.append(msg)
            # don't care about join and leave messages; if necessary, split to have separate events


#             elif msg_type == "LEAVE" or msg_type == "JOIN":
#                 group = msg_frame.pop(0)
#                 event = json.dumps({"metamodel": "http://www.sherpa-project.eu/examples/sherpa_msgs",
#                                     "model": "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
#                                     "type": "leave/join",
#                                     "sender_UUID": peer_uid,
#                                     "sender_name": peer_name,
#                                     "payload": {}
#                                     })
#                 self.inbox.append(event)
            elif msg_type == "ENTER":
                headers = json.loads(msg_frame.pop(0))
                event = {
                    "metamodel":
                    "http://www.sherpa-project.eu/examples/sherpa_msgs",
                    "model":
                    "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
                    "type": "enter",
                    "sender_UUID": peer_uid,
                    "sender_name": peer_name,
                    "payload": {
                        "header": headers
                    }
                }
                self.inbox.append(event)
            elif msg_type == "EXIT":
                event = {
                    "metamodel":
                    "http://www.sherpa-project.eu/examples/sherpa_msgs",
                    "model":
                    "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
                    "type": "exit",
                    "sender_UUID": peer_uid,
                    "sender_name": peer_name,
                    "payload": {}
                }
                self.inbox.append(event)
        # Process output and send all msgs there until it is empty, but only if a line controller is connected.
        if self.outbox:  #only do if there really is something in the outbox
            #if self.lcsm.sm.curr_state._name == "Idle" or self.lcsm.sm.curr_state._name == "Busy":
            if true:
                self.logger.info(
                    "Start processing messages in outbox. Number of msgs in outbox: %d"
                    % len(self.outbox))
                while self.outbox:
                    # since we assume all msgs conform to the sherpa_msgs JSON model, simply shout them out
                    # TODO: add validation
                    msg = self.outbox.pop()
                    if type(msg) == dict:
                        self.logger.info("outbox msg type: " + msg["type"])
                        self.node.shout("SHERPA", json.dumps(msg))

                        #WM message

                        msg_wm_update = {
                            "@worldmodeltype": "RSGUpdate",
                            "operation": "CREATE",
                            "node": {
                                "@graphtype":
                                "Group",
                                "id":
                                "ff483c43-4a36-4197-be49-de829cdd66c8",
                                "attributes": [
                                    {
                                        "key": "name",
                                        "value": "Task Specification Tree"
                                    },
                                    {
                                        "key": "tst:envtst",
                                        "value": msg
                                    },
                                ],
                            },
                            "parentId": "e379121f-06c6-4e21-ae9d-ae78ec1986a1",
                        }

                        print("===")
                        print(json.dumps(msg_wm_update))
                        self.zmq_socket.send_string(json.dumps(msg_wm_update))

                    else:
                        self.logger.warn(
                            "Message is not a dict! Serialization is done here! Msg: \n"
                            + str(msg))
            else:
                self.logger.info(
                    "Can't send messages in outbox. Module not ready.")
示例#10
0
def chat_task(ctx,pipe):
	print("communication started")

	GROUPNAME = "Quizzzzz"
	StopCmnd = "$$quit"
	OPPONENT = "opponent"
	
	print("name: %s" %NAME)
	
	connected_players = 1
	
	# set up node for the user
	n = Pyre(GROUPNAME)
	n.set_header('Name', NAME)
	
	# join the groupchat
	n.join(GROUPNAME)
	#print("UUID %s" %n.uuid())
	 
				
	# start broadcasting signal 
	n.start()

	# set up poller
	poller = zmq.Poller()
	poller.register(pipe,zmq.POLLIN)
	poller.register(n.socket(),zmq.POLLIN)

	# looping constantly to recieve messages
	while True:
		items = dict(poller.poll())
		
		if pipe in items:
			message = pipe.recv()
			if message.decode('utf-8') == StopCmnd:
				break
			# uppercase letters for question to whole group
			elif message.decode('utf-8').isupper() == True: 
				print("Question is: %s" %message)
				n.shouts(GROUPNAME,"Question to group is: %s" %message.decode('utf-8'))
				answer = 0
			# lowercase to last person who asked question in the group
			elif message.decode('utf-8').islower()  == True:
				message = NAME + "'s answer is=" + message
				n.whisper(PEER,message)
			else:
				print("please don't mix up or lowercase or use not only numbers")
	
		else:
			msgrecv = n.recv()
			#print(msgrecv)
			msg_type = msgrecv.pop(0)
			msg_sender = uuid.UUID(bytes=msgrecv.pop(0))
			PEER = msg_sender
			msg_name = msgrecv.pop(0)

			if msg_type.decode('utf-8') == "ENTER":
				headers = json.loads(msgrecv.pop(0).decode('utf-8'))
				print("New player discovered in network")
				print("New player = %s " %headers.get("Name"))
			elif msg_type.decode('utf-8') == "JOIN":
				print("New player has joined the group")
				print("New player = %s" %headers.get("Name"))
				connected_players += 1
				print("#players = %s" %connected_players)
			elif msg_type.decode('utf-8') == "SHOUT":
				print(msgrecv.pop(1))
			elif msg_type.decode('utf-8') == "WHISPER":
				if msgrecv[0] == "You have to ask next question":
					print("You have to ask next question")
					n.shout(GROUPNAME, "%s is new quizmaster" %NAME)
					answer = 0
				else:
					print(msgrecv.pop(0))
					answer +=1
					if answer == connected_players -1: #choosing new quizmaster randomly
						players = n.peers()
						next_master = players.pop(random.randint(0,connected_players-2))
						n.whisper(next_master,"You have to ask next question")
			
	
	print("Left current game")	
	n.stop()
示例#11
0
class Bridge(object):
    """docstring for Bridge"""
    def __init__(self, uvc_id):
        super(Bridge, self).__init__()

        self.data_seq = 0
        self.note_seq = 0

        # init capture
        self.cap = uvc.Capture(uvc_id)
        logger.info('Initialised uvc device {}'.format(self.cap.name))

        # init pyre
        self.network = Pyre(socket.gethostname()+self.cap.name[-4:])
        self.network.join(GROUP)
        self.network.start()
        logger.info('Bridging under "{}"'.format(self.network.name()))

        # init sensor sockets
        ctx = zmq.Context()
        generic_url = 'tcp://*:*'
        public_ep = self.network.endpoint()
        self.note, self.note_url = self.bind(ctx, zmq.PUB, generic_url, public_ep)
        self.data, self.data_url = self.bind(ctx, zmq.PUB, generic_url, public_ep, set_hwm=1)
        self.cmd, self.cmd_url = self.bind(ctx, zmq.PULL, generic_url, public_ep)

    def loop(self):
        logger.info('Entering bridging loop...')
        self.network.shout(GROUP, self.sensor_attach_json().encode())
        try:
            while True:
                self.poll_network()
                self.poll_cmd_socket()
                self.publish_frame()

        except KeyboardInterrupt:
            pass
        except Exception:
            import traceback
            traceback.print_exc()
        finally:
            self.network.shout(GROUP, json.dumps({
                'subject': 'detach',
                'sensor_uuid': self.network.uuid().hex
            }).encode())
            logger.info('Leaving bridging loop...')

    def publish_frame(self):
        frame = self.cap.get_frame_robust()
        now = time.time()
        index = self.data_seq
        self.data_seq += 1
        self.data_seq %= sequence_limit

        jpeg_buffer = frame.jpeg_buffer
        m = hashlib.md5(jpeg_buffer)
        lower_end = int(m.hexdigest(), 16) % 0x100000000
        meta_data = struct.pack('<LLLLdLL', 0x10, frame.width, frame.height, index, now, jpeg_buffer.size, lower_end)
        self.data.send_multipart([self.network.uuid().hex.encode(), meta_data, jpeg_buffer])

    def poll_network(self):
        for event in self.network.recent_events():
            if event.type == 'JOIN' and event.group == GROUP:
                self.network.whisper(event.peer_uuid, self.sensor_attach_json().encode())

    def poll_cmd_socket(self):
        while has_data(self.cmd):
            sensor, cmd_str = self.cmd.recv_multipart()
            try:
                cmd = json.loads(cmd_str.decode())
            except Exception as e:
                logger.debug('Could not parse received cmd: {}'.format(cmd_str))
            else:
                logger.debug('Received cmd: {}'.format(cmd))
                if cmd.get('action') == 'refresh_controls':
                    self.publish_controls()
                elif cmd.get('action') == 'set_control_value':
                    val = cmd.get('value', 0)
                    if cmd.get('control_id') == 'CAM_RATE':
                        self.cap.frame_rate = self.cap.frame_rates[val]
                    elif cmd.get('control_id') == 'CAM_RES':
                        self.cap.frame_size = self.cap.frame_sizes[val]
                    self.publish_controls()

    def __del__(self):
        self.note.close()
        self.data.close()
        self.cmd.close()
        self.network.stop()

    def publish_controls(self):
        self.note.send_multipart([
            self.network.uuid().hex.encode(),
            self.frame_size_control_json().encode()])
        self.note.send_multipart([
            self.network.uuid().hex.encode(),
            self.frame_rate_control_json().encode()])

    def sensor_attach_json(self):
        sensor = {
            "subject": "attach",
            "sensor_name": self.cap.name,
            "sensor_uuid": self.network.uuid().hex,
            "sensor_type": 'video',
            "notify_endpoint": self.note_url,
            "command_endpoint": self.cmd_url,
            "data_endpoint": self.data_url
        }
        return json.dumps(sensor)

    def frame_size_control_json(self):
        index = self.note_seq
        self.note_seq += 1
        self.note_seq %= sequence_limit
        curr_fs = self.cap.frame_sizes.index(self.cap.frame_size)
        return json.dumps({
            "subject": "update",
            "control_id": "CAM_RES",
            "seq": index,
            "changes": {
                "value": curr_fs,
                "dtype": 'intmapping',
                "min": None,
                "max": None,
                "res": None,
                "def": 0,
                "caption": 'Resolution',
                "readonly": False,
                "map": [{
                    'value': idx,
                    'caption': '{:d}x{:d}'.format(*fs)
                } for idx, fs in enumerate(self.cap.frame_sizes)]
            }
        })

    def frame_rate_control_json(self):
        index = self.note_seq
        self.note_seq += 1
        self.note_seq %= sequence_limit
        curr_fr = self.cap.frame_rates.index(self.cap.frame_rate)
        return json.dumps({
            "subject": "update",
            "control_id": "CAM_RATE",
            "seq": index,
            "changes": {
                "value": curr_fr,
                "dtype": 'intmapping',
                "min": None,
                "max": None,
                "res": None,
                "def": 0,
                "caption": 'Frame Rate',
                "readonly": False,
                "map": [{
                    'value': idx,
                    'caption': '{:.1f} Hz'.format(fr)
                } for idx, fr in enumerate(self.cap.frame_rates)]
            }
        })

    def bind(self, ctx, sock_type, url, public_ep, set_hwm=None):
        sock = ctx.socket(sock_type)
        if set_hwm:
            sock.set_hwm(set_hwm)
        sock.bind(url)
        ep = sock.last_endpoint.decode()
        port = ep.split(':')[-1]
        public_ep.split(':')[-1]
        public_addr = public_ep.split(':')[:-1]
        return sock, ':'.join(public_addr+[port])
示例#12
0
class Network:
    hosting: bool = False

    def __init__(self):
        self.open()

    def get_all_groups(self) -> List[str]:
        """Get the names of groups that can be joined."""
        groups = []
        for peer in self.node.peers():
            group = self.node.peer_header_value(peer, 'hosting')
            if group != None and len(group) > 0:
                groups.append(group)
        return groups

    def get_our_group(self) -> Union[str, None]:
        """What is the name of the group we're in or hosting?"""
        our_groups = self.node.own_groups()
        our_groups.remove('untangled2018')
        if len(our_groups) == 0:
            return None
        return our_groups[0]

    def is_in_group(self) -> bool:
        """Are we in or hosting a group?"""
        return self.get_our_group() != None

    def is_hosting(self) -> bool:
        """Are we hosting?"""
        return self.hosting

    def join_group(self, group: str) -> None:
        """Join a group of given name (assumes you are not in a group already)."""
        if group not in self.get_all_groups():
            raise ValueError('Group named "%s" does not exist'.format(group))

        if self.is_in_group():
            raise ValueError(
                'You must leave the previous group before you join another')

        self.node.join(group)

    def leave_group(self) -> None:
        """Leave any joined group or stop hosting."""
        self.hosting = False

        if not self.is_in_group():
            raise ValueError('You are not in a group')

        for group in self.node.own_groups():
            self.node.leave(group)

    def host_group(self, name: str) -> None:
        """Host a group of given name."""
        if name in self.get_all_groups():
            raise ValueError('A group of the given name already exists')

        if self.is_in_group():
            raise ValueError('Cannot host whilst in a group')

        self.node.set_header('hosting', name)
        self.hosting = True
        self.node.join(name)

    def open(self) -> None:
        """Create a new pyre instance and join untangled."""
        self.node = Pyre()
        self.node.start()
        self.node.join('untangled2018')
        # used to get our messages
        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

    def get_id(self) -> str:
        """Get our id, as a unique node on the network."""
        return self.node.uuid()

    def is_me(self, player_id) -> bool:
        """See if a given id is ours."""
        return self.get_id() == player_id

    def close(self) -> None:
        """Disconnect from everything"""
        self.node.stop()

    def get_messages(self):
        """See what has been sent to us: who has joined, what have people said, etc"""
        # what has changed
        changes = dict(self.poller.poll(0))

        # are these the changes we subscribed for
        if self.node.socket() in changes and changes[
                self.node.socket()] == zmq.POLLIN:
            msgs = self.node.recent_events()
            return msgs

        # nothing to return
        return []

    def pull_game(self, game):
        """Update our game state based on what other people tell us."""
        for msg in self.get_messages():
            # is it relevant to us?
            if msg.group != self.get_our_group():
                continue
            if msg.type == 'SHOUT':
                entities = bson.loads(msg.msg[0])

                if 'ids' in entities:
                    keys = entities['ids']
                    cur_keys = list(game.entities.keys())
                    diff = list(set(cur_keys) - set(keys))
                    for key in diff:
                        del game.entities[key]

                entities = entities['components']
                for key, changed_comps in entities.items():
                    key = uuid.UUID(key)
                    if key not in game.entities:
                        game.entities[key] = {}
                    entity = game.entities[key]
                    for compname, component in changed_comps.items():
                        try:
                            clas = components.__dict__[compname]
                            if clas in entity:
                                entity[clas] = entity[clas].replace(
                                    **component)
                            else:
                                entity[clas] = clas(**component)
                            entity[clas].observed_changes()
                        except Exception:
                            print(
                                'Error updating component, is everyone in the group on the same version?',
                                file=sys.stdout)
            elif self.is_hosting():
                if msg.type == 'JOIN':
                    game.on_player_join(msg.peer_uuid)
                    self.push_game(game, initial=True)
                elif msg.type == 'EXIT' or msg.type == "LEAVE":
                    game.on_player_quit(msg.peer_uuid)

    def push_game(self, game, initial=False):
        """Tell others how we've changed the game state."""
        if len(self.node.peers_by_group(self.get_our_group())) == 0:
            # Nobody else to talk to
            return

        entities = {'components': {}}
        if self.is_hosting():
            entities = {'ids': [], 'components': {}}

        for key, entity in game.entities.items():
            changed_comps = {}
            for component in entity.values():
                if component.is_networked() and (initial
                                                 or component.has_changed()):
                    changed_comps[component.get_name()] = component.as_dict()
                    component.observed_changes()
            if 'ids' in entities:
                entities['ids'].append(key)
            entities['components'][str(key)] = changed_comps
        self.node.shout(self.get_our_group(), bson.dumps(entities))
示例#13
0
class Bridge(object):
    """docstring for Bridge"""
    def __init__(self, uvc_id):
        super(Bridge, self).__init__()

        self.data_seq = 0
        self.note_seq = 0

        # init capture
        self.cap = uvc.Capture(uvc_id)
        logger.info("Initialised uvc device {}".format(self.cap.name))

        # init pyre
        self.network = Pyre(socket.gethostname() + self.cap.name[-4:])
        self.network.join(GROUP)
        self.network.start()
        logger.info('Bridging under "{}"'.format(self.network.name()))

        # init sensor sockets
        ctx = zmq.Context()
        generic_url = "tcp://*:*"
        public_ep = self.network.endpoint()
        self.note, self.note_url = self.bind(ctx, zmq.PUB, generic_url,
                                             public_ep)
        self.data, self.data_url = self.bind(ctx,
                                             zmq.PUB,
                                             generic_url,
                                             public_ep,
                                             set_hwm=1)
        self.cmd, self.cmd_url = self.bind(ctx, zmq.PULL, generic_url,
                                           public_ep)

    def loop(self):
        logger.info("Entering bridging loop...")
        self.network.shout(GROUP, self.sensor_attach_json().encode())
        try:
            while True:
                self.poll_network()
                self.poll_cmd_socket()
                self.publish_frame()

        except KeyboardInterrupt:
            pass
        except Exception:
            import traceback

            traceback.print_exc()
        finally:
            self.network.shout(
                GROUP,
                json.dumps({
                    "subject": "detach",
                    "sensor_uuid": self.network.uuid().hex
                }).encode(),
            )
            logger.info("Leaving bridging loop...")

    def publish_frame(self):
        frame = self.cap.get_frame_robust()
        now = time.time()
        index = self.data_seq
        self.data_seq += 1
        self.data_seq %= sequence_limit

        jpeg_buffer = frame.jpeg_buffer
        m = hashlib.md5(jpeg_buffer)
        lower_end = int(m.hexdigest(), 16) % 0x100000000
        meta_data = struct.pack(
            "<LLLLdLL",
            0x10,
            frame.width,
            frame.height,
            index,
            now,
            jpeg_buffer.size,
            lower_end,
        )
        self.data.send_multipart(
            [self.network.uuid().hex.encode(), meta_data, jpeg_buffer])

    def poll_network(self):
        for event in self.network.recent_events():
            if event.type == "JOIN" and event.group == GROUP:
                self.network.whisper(event.peer_uuid,
                                     self.sensor_attach_json().encode())

    def poll_cmd_socket(self):
        while has_data(self.cmd):
            sensor, cmd_str = self.cmd.recv_multipart()
            try:
                cmd = json.loads(cmd_str.decode())
            except Exception as e:
                logger.debug(
                    "Could not parse received cmd: {}".format(cmd_str))
            else:
                logger.debug("Received cmd: {}".format(cmd))
                if cmd.get("action") == "refresh_controls":
                    self.publish_controls()
                elif cmd.get("action") == "set_control_value":
                    val = cmd.get("value", 0)
                    if cmd.get("control_id") == "CAM_RATE":
                        self.cap.frame_rate = self.cap.frame_rates[val]
                    elif cmd.get("control_id") == "CAM_RES":
                        self.cap.frame_size = self.cap.frame_sizes[val]
                    self.publish_controls()

    def __del__(self):
        self.note.close()
        self.data.close()
        self.cmd.close()
        self.network.stop()

    def publish_controls(self):
        self.note.send_multipart([
            self.network.uuid().hex.encode(),
            self.frame_size_control_json().encode()
        ])
        self.note.send_multipart([
            self.network.uuid().hex.encode(),
            self.frame_rate_control_json().encode()
        ])

    def sensor_attach_json(self):
        sensor = {
            "subject": "attach",
            "sensor_name": self.cap.name,
            "sensor_uuid": self.network.uuid().hex,
            "sensor_type": "video",
            "notify_endpoint": self.note_url,
            "command_endpoint": self.cmd_url,
            "data_endpoint": self.data_url,
        }
        return json.dumps(sensor)

    def frame_size_control_json(self):
        index = self.note_seq
        self.note_seq += 1
        self.note_seq %= sequence_limit
        curr_fs = self.cap.frame_sizes.index(self.cap.frame_size)
        return json.dumps({
            "subject": "update",
            "control_id": "CAM_RES",
            "seq": index,
            "changes": {
                "value":
                curr_fs,
                "dtype":
                "intmapping",
                "min":
                None,
                "max":
                None,
                "res":
                None,
                "def":
                0,
                "caption":
                "Resolution",
                "readonly":
                False,
                "map": [{
                    "value": idx,
                    "caption": "{:d}x{:d}".format(*fs)
                } for idx, fs in enumerate(self.cap.frame_sizes)],
            },
        })

    def frame_rate_control_json(self):
        index = self.note_seq
        self.note_seq += 1
        self.note_seq %= sequence_limit
        curr_fr = self.cap.frame_rates.index(self.cap.frame_rate)
        return json.dumps({
            "subject": "update",
            "control_id": "CAM_RATE",
            "seq": index,
            "changes": {
                "value":
                curr_fr,
                "dtype":
                "intmapping",
                "min":
                None,
                "max":
                None,
                "res":
                None,
                "def":
                0,
                "caption":
                "Frame Rate",
                "readonly":
                False,
                "map": [{
                    "value": idx,
                    "caption": "{:.1f} Hz".format(fr)
                } for idx, fr in enumerate(self.cap.frame_rates)],
            },
        })

    def bind(self, ctx, sock_type, url, public_ep, set_hwm=None):
        sock = ctx.socket(sock_type)
        if set_hwm:
            sock.set_hwm(set_hwm)
        sock.bind(url)
        ep = sock.last_endpoint.decode()
        port = ep.split(":")[-1]
        public_ep.split(":")[-1]
        public_addr = public_ep.split(":")[:-1]
        return sock, ":".join(public_addr + [port])
示例#14
0
    def network_manager(self, ctx, write_pipe, node_name, overlay_network_name,
                        read_pipe):
        # create the poller to wait for messages from pipes and network
        poller = zmq.Poller()
        poller.register(write_pipe, zmq.POLLIN)
        # create the Pyre node object
        node = Pyre(node_name + str(uuid.uuid4()))
        # register node to the network, start it and register for events with
        # the poller.
        node.join(overlay_network_name)
        node.start()
        poller.register(node.socket(), zmq.POLLIN)

        while (True):
            # do stuff, aka wait and decode messages
            items = dict(poller.poll())

            if write_pipe in items and items[write_pipe] == zmq.POLLIN:
                # here is where the thread receives internal data
                # check if we have to send something outside
                # or eventually die gracefully
                message = write_pipe.recv()
                # here I have a Command + a FardNetworkData object
                decoded_message = pickle.loads(message)

                command = decoded_message[0]
                network_data = decoded_message[1]

                if command == "$$STOP":
                    # message to quit here
                    break
                elif command == "$$GET_PEERS":
                    # only synchronous command, retrieves the peers inside the
                    # network of tasks.
                    group = network_data.group
                    peers = node.peers_by_group(group)
                    list_of_peers = []
                    for peer in peers:
                        list_of_peers.append(str(peer))
                    write_pipe.send(pickle.dumps(str(";".join(list_of_peers))))
                elif command == "$$SEND_MESSAGE" in decoded_message:
                    # send message to a single peer using Pyre
                    # if requested, send back the message to the same node that
                    # sent it.
                    peer = network_data.peer
                    network_data.sender_peer = str(node.uuid())
                    network_data.message_type = "peer"
                    node.whisper(uuid.UUID(peer), pickle.dumps(network_data))
                    if network_data.auto_send and peer == network_data.sender_peer:
                        read_pipe.send(pickle.dumps(network_data))
                elif command == "$$SEND_TASK_MESSAGE":
                    # send message to a group of identical tasks using Pyre.
                    # Currently implemented with a shout that is ignored by a
                    # receiver if the task name is different from his.
                    # if requested, send back the message to the same node that
                    # sent it.
                    network_data.sender_peer = str(node.uuid())
                    network_data.message_type = "task"
                    node.shout(group, pickle.dumps(network_data))
                    if network_data.auto_send:
                        read_pipe.send(pickle.dumps(network_data))
                elif command == "$$SEND_GROUP_MESSAGE":
                    # send message to the whole application using Pyre
                    # if requested, send back the message to the same node that
                    # sent it.
                    group = network_data.group
                    network_data.sender_peer = str(node.uuid())
                    network_data.message_type = "group"
                    node.shout(group, pickle.dumps(network_data))
                    if network_data.auto_send:
                        read_pipe.send(pickle.dumps(network_data))
            else:
                # here is where the thread receives data from the outside
                # decode messages and reroute them accordingly
                cmds = node.recv()
                msg_type = cmds.pop(0).decode('utf-8')
                peer_uuid = uuid.UUID(bytes=cmds.pop(0))
                sender_node_name = cmds.pop(0).decode('utf-8')
                if msg_type == "SHOUT":
                    group = cmds.pop(0).decode('utf-8')
                    read_pipe.send(cmds.pop(0))
                elif msg_type == "WHISPER":
                    read_pipe.send(cmds.pop(0))
                # elif msg_type == "ENTER":
                #     headers = json.loads(cmds.pop(0).decode('utf-8'))
                # print("NODE_MSG HEADERS: %s" % headers)
                # for key in headers:
                #     print("key = {0}, value = {1}".format(key, headers[key]))
                # print("NODE_MSG CONT: %s" % cmds)

        node.stop()
示例#15
0
class Authority():
    def __init__(self):
        self.node = Pyre("GAME_AUTH")
        self.node.set_header("AUTHORITY", "TRUE")
        self.node.start()
        self.node.join("world:position")
        self.node.join("ctf:teams")
        self.node.join("ctf:dropflag")
        self.node.join("ctf:gotflag")

        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

        self.players = AuthorityPlayerManager()

        self.teams = {"blue": [], "red": []}

        self.level = SaveLevel('./assets/maps/CAPFLAG MAP NAT')
        red_spawn_pos = self.level.get_place(Place.RED_SPAWN)
        blue_spawn_pos = self.level.get_place(Place.BLUE_SPAWN)

        self.flags = {
            "blue": {
                "x": blue_spawn_pos[0],
                "y": blue_spawn_pos[1],
                "owner": '',
                "timer": 0
            },
            "red": {
                "x": red_spawn_pos[0],
                "y": red_spawn_pos[1],
                "owner": '',
                "timer": 0
            }
        }

        self.serve()

    def set_teams(self):
        blue_players = self.teams["blue"]
        red_players = self.teams["red"]

        # Check for removed players in RED
        for i, playerUUID in enumerate(red_players):
            if playerUUID not in self.players.players.keys():
                red_players.pop(i)
        # Check for removed players in BLUE
        for i, playerUUID in enumerate(blue_players):
            if playerUUID not in self.players.players.keys():
                blue_players.pop(i)

        # Add new players
        for playerUUID, player in self.players.players.items():
            if not (playerUUID in blue_players or playerUUID in red_players):
                if len(blue_players) > len(red_players):
                    red_players.append(playerUUID)
                else:
                    blue_players.append(playerUUID)

        print("Teams: " + "RED: " + ','.join(red_players) + " | BLUE: " +
              ','.join(blue_players))
        self.node.shout("ctf:teams", bson.dumps(self.teams))

    def set_flags(self, flag_info):
        return

    def update_flags(self):
        self.node.shout("ctf:flags", bson.dumps(self.flags))

    def get_team_from_uuid(self, uuid):
        place = None

        if str(uuid) in self.teams['red']:
            place = Place.RED_SPAWN
        elif str(uuid) in self.teams['blue']:
            place = Place.BLUE_SPAWN

        return place

    def serve(self):
        clock = Clock()
        while True:
            clock.tick(60)

            # check network
            events = self.get_events()
            if events:
                try:
                    for event in events:
                        # Update the teams on JOIN and EXIT
                        if event.type == 'JOIN':
                            if event.group == 'ctf:dropflag':
                                for team, flag in self.flags.items():
                                    if flag['owner'] == '':
                                        self.node.shout(
                                            'ctf:dropflag',
                                            bson.dumps({
                                                'x': flag['x'],
                                                'y': flag['y'],
                                                'team': team
                                            }))
                            elif event.group == 'ctf:gotflag':
                                for team, flag in self.flags.items():
                                    if flag['owner'] != '':
                                        self.node.shout(
                                            'ctf:gotflag',
                                            bson.dumps({
                                                'uuid': flag['owner'],
                                                'team': team
                                            }))
                            elif event.group == 'ctf:teams':
                                self.players.set(self.node.peers())
                                self.set_teams()
                                place = self.get_team_from_uuid(
                                    event.peer_uuid)
                                pos = self.level.get_place(place)
                                self.node.whisper(
                                    event.peer_uuid,
                                    bson.dumps({
                                        'type': 'teleport',
                                        'x': pos[0],
                                        'y': pos[1]
                                    }))
                        elif event.type == 'EXIT':
                            for team, flag in self.flags.items():
                                if flag['owner'] == str(event.peer_uuid):
                                    # flag owner is leaving, drop
                                    player = self.players.get(event.peer_uuid)
                                    flag['x'] = player.x
                                    flag['y'] = player.y
                                    flag['owner'] = ''
                                    self.node.shout(
                                        'ctf:dropflag',
                                        bson.dumps({
                                            'x': flag['x'],
                                            'y': flag['y'],
                                            'team': team
                                        }))
                            self.players.set(self.node.peers())
                            self.set_teams()
                        elif event.type == 'SHOUT':
                            if event.group == "world:position":
                                new_position = bson.loads(event.msg[0])
                                network_player = self.players.get(
                                    event.peer_uuid)
                                network_player.set_position(new_position)

                                # check if flag has been captured
                                for team, flag in self.flags.items():
                                    if flag['owner'] != str(event.peer_uuid):
                                        continue
                                    tile = self.level.get_tile(
                                        new_position['x'], new_position['y'])
                                    if tile == TileType.RED_BLOCK and team == 'blue':
                                        # TODO: blue's flag has been captured
                                        spawn = Place.BLUE_SPAWN
                                    elif tile == TileType.BLUE_BLOCK and team == 'red':
                                        # TODO: red's flag has been captured
                                        spawn = Place.RED_SPAWN
                                    else:
                                        continue
                                    position = self.level.get_place(spawn)
                                    flag['x'] = position[0]
                                    flag['y'] = position[1]
                                    flag['owner'] = ''
                                    self.node.shout(
                                        'ctf:dropflag',
                                        bson.dumps({
                                            'x': flag['x'],
                                            'y': flag['y'],
                                            'team': team
                                        }))
                            if event.group == 'ctf:gotflags':
                                flag_info = bson.loads(event.msg[0])
                                self.set_flags(flag_info)
                        elif event.type == 'WHISPER':
                            msg = bson.loads(event.msg[0])
                            network_player = self.players.get(event.peer_uuid)
                            if msg['type'] == 'death_report':
                                player = self.players.get(event.peer_uuid)
                                previously_owned_flag = None
                                if self.flags['blue']['owner'] == str(
                                        event.peer_uuid):
                                    previously_owned_flag = 'blue'
                                elif self.flags['red']['owner'] == str(
                                        event.peer_uuid):
                                    previously_owned_flag = 'red'

                                if previously_owned_flag:
                                    flag = self.flags[previously_owned_flag]
                                    flag['owner'] = ''
                                    self.node.shout(
                                        'ctf:dropflag',
                                        bson.dumps({
                                            'x':
                                            player.x,
                                            'y':
                                            player.y,
                                            'team':
                                            previously_owned_flag
                                        }))

                                place = self.get_team_from_uuid(
                                    event.peer_uuid)
                                pos = self.level.get_place(place)
                                self.node.whisper(
                                    event.peer_uuid,
                                    bson.dumps({
                                        'type': 'teleport',
                                        'x': pos[0],
                                        'y': pos[1]
                                    }))
                                player.x = pos[0]
                                player.y = pos[1]

                except Exception as e:
                    print(e)
                    import traceback
                    print(traceback.format_exc())
                    pass

            for team, flag in self.flags.items():
                if flag["owner"] != '': continue
                for uuid, player in self.players.players.items():
                    if flag['x'] == player.x and flag['y'] == player.y:
                        team_place = self.get_team_from_uuid(uuid)
                        pos = self.level.get_place(team_place)
                        if team == 'red' and team_place == Place.RED_SPAWN or team == 'blue' and team_place == Place.BLUE_SPAWN:
                            if player.x == pos[0] and player.y == pos[1]:
                                continue

                            self.node.shout(
                                'ctf:dropflag',
                                bson.dumps({
                                    'x': pos[0],
                                    'y': pos[1],
                                    'team': team
                                }))
                        else:
                            flag["owner"] = uuid
                            self.node.shout(
                                'ctf:gotflag',
                                bson.dumps({
                                    'uuid': uuid,
                                    'team': team
                                }))
                            break

    def poll(self):
        return dict(self.poller.poll(0))

    def peers(self):
        return self.node.peers()

    def stop(self):
        self.node.stop()

    def get_events(self):
        changes = self.poll()
        if self.node.socket() in changes and changes[
                self.node.socket()] == zmq.POLLIN:
            events = self.node.recent_events()
            return events
class ZyreToZMQModule:
    """ The ZyreToZMQModule Base Class """
   
    
    def __init__(self,ctx = None,name = "Default",headers=None,groups=None,config_file=None,polling_timeout = 1,sim_time=2):

        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.DEBUG)
        # create the console output logging
        sh = logging.StreamHandler()
        sh.setLevel(logging.INFO)
        # create a logger writing into a log file
        fh = logging.FileHandler(name + ".log")
        fh.setLevel(logging.DEBUG)
        # create formatter and add it to the handlers
        # see https://docs.python.org/2/library/logging.html#logrecord-attributes for what can be logged
        fh.setFormatter(logging.Formatter('Name: %(name)s, ProcessName: %(processName)s, ThreadName: %(threadName)s, Module: %(module)s, FunctionName: %(funcName)s, LineNo: %(lineno)d, Level: %(levelname)s, Msg: %(message)s'))
        #sh.setFormatter(logging.Formatter('Module: %(module)s, FunctionName: %(funcName)s, LineNo: %(lineno)d, Level: %(levelname)s, Msg: %(message)s'))
        sh.setFormatter(logging.Formatter('Name: %(name)s, %(module)s/%(funcName)s[%(levelname)s]: %(message)s (lineno:%(lineno)d)'))
        # add the handlers to logger
        self.logger.addHandler(sh)
        self.logger.addHandler(fh)
        self.logger.propagate = False # don't pass messages to parent loggers

        if not type(ctx) ==  zmq.sugar.context.Context:
            self.logger.warn("Created ZMQ context. Please supply a ZMQ context next time.")
            ctx = zmq.Context()
        self.ctx = ctx
        if not type(name) == str:
            name = "Default"
            self.logger.warn("Please provide a the name as a string. Setting name to default: %s." % name)
        self.name = name
        if not headers:
            self.logger.warn("Please provide a model and other header information.")
            headers = {}
        self.headers = headers
        if not groups:
            groups = ["SHERPA"]
            self.logger.warn("Please provide a list with group names to which it will listen. Will set it to default: %s" %groups)
        self.groups = groups
        if not config_file:
            # will be opened during configuration
            self.logger.error("No config file provided for initial configuration")
            exit()
      
        self.config_file = config_file
        self.config = None
        self.alive = True # used for exiting once the node is stopped
        self.line_controller = None # stores uid of line controller this module is listening to (to avoid several line controllers)
        self.com_timeout = polling_timeout # time_out in msec after which poller returns
        self.sim_time = sim_time # time in msec
        self.inbox = []
        self.outbox = []
             
        # Node setup
        self.node = Pyre(self.name)
        for key in self.headers:
            self.node.set_header(key,self.headers[key])
        for group in self.groups:
            self.node.join(group)
        #self.node.set_verbose()
        self.node.start()
        
        # Socket setup
        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

        port = "12911" 
        self.zmq_socket = self.ctx.socket(zmq.PUB)
        self.zmq_socket.bind("tcp://*:%s" % port)
   

        self.run()


    def run(self):
        """ Running loop of this process:
        [COMMUNICATION]     Check communication channels and parse all messages.
        """
        while self.alive:
            try:
                #[COMMUNICATION]
                self.communication()
                #[LOGGING]
                #self.logging()
                time.sleep(1)
            except (KeyboardInterrupt, SystemExit):
                break
        self.node.stop()


    def communication(self):
        """ This function handles the communication """

        # Check if communication is ready
        if not self.poller:
            self.logger.warn("No communication channels yet.")
        # Process input
        items = dict(self.poller.poll(self.com_timeout))
        # Get input from Pyre socket and put it in inbox which is processed in the following steps
        #logger.debug("Start processing incoming messages")
        if self.node.socket() in items and items[self.node.socket()] == zmq.POLLIN: 
            self.logger.info("Received %d msgs." % len(items))
            #print "msg arrived. inbox len %d" % len(self.inbox)
            msg_frame = self.node.recv()
            msg_type = msg_frame.pop(0)
            peer_uid = uuid.UUID(bytes=msg_frame.pop(0))
            peer_name = msg_frame.pop(0)   
            self.logger.info("Msg type: %s" % msg_type)         
            self.logger.info("Sender: %s" % peer_name)   
            # For shout and whisper take message payload and put it into inbox assuming it is correct
            # For the other zyre msgs create a JSON obj and put that into inbox
            # TODO: add validation
            if msg_type == "SHOUT":
                group = msg_frame.pop(0)
                msg = json.loads(msg_frame.pop(0))
                msg["sender_UUID"] = peer_uid
                msg["sender_name"] = peer_name
#                self.inbox.append(msg)
                self.outbox.append(msg)
            elif msg_type == "WHISPER":
                msg = json.loads(msg_frame.pop(0))
                msg["sender_UUID"] = peer_uid
                msg["sender_name"] = peer_name
                self.inbox.append(msg)        
            # don't care about join and leave messages; if necessary, split to have separate events               
#             elif msg_type == "LEAVE" or msg_type == "JOIN":
#                 group = msg_frame.pop(0)
#                 event = json.dumps({"metamodel": "http://www.sherpa-project.eu/examples/sherpa_msgs",
#                                     "model": "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
#                                     "type": "leave/join",
#                                     "sender_UUID": peer_uid,
#                                     "sender_name": peer_name,
#                                     "payload": {}
#                                     })
#                 self.inbox.append(event)
            elif msg_type == "ENTER":
                headers = json.loads(msg_frame.pop(0))
                event = {"metamodel": "http://www.sherpa-project.eu/examples/sherpa_msgs",
                         "model": "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
                         "type": "enter",
                         "sender_UUID": peer_uid,
                         "sender_name": peer_name,
                         "payload": {"header": headers}
                         }
                self.inbox.append(event)
            elif msg_type == "EXIT":
                event = {"metamodel": "http://www.sherpa-project.eu/examples/sherpa_msgs",
                         "model": "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
                         "type": "exit",
                         "sender_UUID": peer_uid,
                         "sender_name": peer_name,
                         "payload": {}
                         }
                self.inbox.append(event)
        # Process output and send all msgs there until it is empty, but only if a line controller is connected.
        if self.outbox: #only do if there really is something in the outbox
            #if self.lcsm.sm.curr_state._name == "Idle" or self.lcsm.sm.curr_state._name == "Busy":
            if true:
                self.logger.info("Start processing messages in outbox. Number of msgs in outbox: %d" % len(self.outbox))
                while self.outbox:
                    # since we assume all msgs conform to the sherpa_msgs JSON model, simply shout them out
                    # TODO: add validation
                    msg = self.outbox.pop()
                    if type(msg) == dict:
                        self.logger.info("outbox msg type: " + msg["type"])
                        self.node.shout("SHERPA", json.dumps(msg))
                        
                        #WM message
                        
                        msg_wm_update = {
                          "@worldmodeltype": "RSGUpdate",
                          "operation": "CREATE",
                          "node": {
                            "@graphtype": "Group",
                            "id": "ff483c43-4a36-4197-be49-de829cdd66c8", 
                            "attributes": [
                                  {"key": "name", "value": "Task Specification Tree"},
                                  {"key": "tst:envtst", "value": msg },
                            ],
                          },
                          "parentId": "e379121f-06c6-4e21-ae9d-ae78ec1986a1",
                        }
                  
                        print ("===")
                        print (json.dumps(msg_wm_update))
                        self.zmq_socket.send_string(json.dumps(msg_wm_update)) 

                    else:
                        self.logger.warn("Message is not a dict! Serialization is done here! Msg: \n" + str(msg))
            else:
                self.logger.info("Can't send messages in outbox. Module not ready.")
示例#17
0
def rethinkdb_writer(ctx, pipe):

    # Database setup
    with open('../configuration.json') as data_file:
        configuration = json.load(data_file)

    group_name = configuration['zyreMediator']['group']

    n = Pyre(configuration['zyreMediator']['name'])
    n.set_interface('usb0')
    n.set_header('TYPE', configuration['zyreMediator']['type'])
    n.join(group_name)
    n.start()

    # Zyre setup
    poller = zmq.Poller()
    poller.register(pipe, zmq.POLLIN)
    poller.register(n.inbox, zmq.POLLIN)

    database_configuration = configuration['database']['mongoDB']
    mongo_connection = MongoClient(database_configuration['host'], database_configuration['port'])

    meteor = mongo_connection['meteor']

    # Add this module to the database
    meteor['modules'].insert([{
        '_id': str(n.uuid()),
        'name': n.name(),
        'type': configuration['zyreMediator']['type'],
        'parent': None
    }])

    ready_message = {
        'type': 'state',
        'senderId': str(n.uuid()),
        'payload': 2
    }

    def logMessage(message_to_log):
        message_to_log['timestamp'] = datetime.datetime.utcnow()
        meteor['events'].insert_one(message_to_log)
        del message_to_log['timestamp']
        del message_to_log['_id']

    n.shout(group_name, json.dumps(ready_message))
    logMessage(ready_message)

    module_name_to_uid_map = {}

    while True:
        items = dict(poller.poll(10))

        if pipe in items and items[pipe] == zmq.POLLIN:
            message = pipe.recv()
            # message to quit
            if message.decode('utf-8') == '$$STOP':
                break

        if n.inbox in items and items[n.inbox] == zmq.POLLIN:

            msg_frame = n.recv()
            msg_type = msg_frame.pop(0)
            peer_uid = uuid.UUID(bytes=msg_frame.pop(0))
            peer_name = msg_frame.pop(0)
            print('NODE_MSG TYPE: %s' % msg_type)
            print('NODE_MSG PEER: %s' % str(peer_uid))
            print('NODE_MSG NAME: %s' % peer_name)

            if msg_type.decode('utf-8') == 'ENTER':

                headers = json.loads(msg_frame.pop(0))

                try:
                    module_type = headers['type']
                except KeyError:
                    print("Your header doesn't contain your type of module")
                    module_type = 'unknown'

                try:
                    parent_module_id = headers['parentId']
                except KeyError:
                    print("The header doesn't contain the module's parent id")
                    parent_module_id = None

                # creates an entry with all known information about the robot
                # in the database if the robot is not in the database
                meteor['modules'].insert_one({
                    '_id': str(peer_uid),
                    'name': peer_name,
                    'type': module_type,
                    'parent': parent_module_id
                })

                module_name_to_uid_map[peer_name] = str(peer_uid)

            elif msg_type.decode('utf-8') == 'EXIT':
                meteor['modules'].remove({'_id': str(peer_uid)})

            elif msg_type.decode('utf-8') == 'SHOUT':

                # write message to database
                group = msg_frame.pop(0)
                try:
                    data = json.loads(msg_frame[0])
                except:
                    data = {}
                    print 'Invalid JSON string'

                # print data

                data['senderId'] = str(peer_uid)
                logMessage(data)

            elif msg_type.decode('utf-8') == 'WHISPER':
                # write message to database
                try:
                    data = json.loads(msg_frame[0])
                except:
                    print 'Invalid JSON string'

                logMessage(data)

    meteor['modules'].remove({'_id': str(n.uuid())})
    n.stop()
示例#18
0
lst_msg = ['physics', 'Biology', 'chemistry', 'maths']
lst_msg = [x.encode('utf-8') for x in lst_msg]
stp_msg = 'stop'
k = 0
while True:
    print('insert command: ')
    k = input()
    print(k)
    if str(k) == 'q':
        print('break')
        n.stop()
        break
    elif str(k) == 'm':
        print('send message')
        # n.shout("CHAT", msg.encode('ascii'))
        n.shout("CHAT", msg.encode('utf-8'))
        # n.shout("CHAT", msg.decode('ascii'))
    elif str(k) == 's':
        print('stop message sent')
        n.shout("CHAT", stp_msg.encode('utf-8'))
    elif str(k) == 'l':
        print('LIST message sent')
        # n.shout("CHAT", lst_msg.encode('utf-8'))
        n.shout("CHAT", lst_msg)
        # n.shout("CHAT", [x.encode('utf-8') for x in lst_msg])
    elif str(k) == 'dic':
        n.shout("CHAT", dic_msg.encode('utf-8'))
    elif str(k) == 'js':
        n.shout("CHAT", jmsg)
    else:
        print('nodes list')