def nano_server(endpoint):
    s = Socket(PAIR)
    s.bind('ipc://' + endpoint)
    #s.bind('tcp://127.0.0.1:9001')
    try:
        while True:
            s.recv()
            s.send('ok')
    finally:
        s.close()
def main():
    ap = argparse.ArgumentParser()
    gr = ap.add_mutually_exclusive_group()
    gr.add_argument('--rep', metavar="URL",
        help="The topology url of replier socket")
    gr.add_argument('--pullpush', metavar="URL", nargs=2,
        help="The topology urls of pull and push sockets for request processing")
    options = ap.parse_args()

    if options.rep:
        sock = Socket(REP)
        sock.configure(options.rep)
        sock.set_string_option(SOL_SOCKET, SOCKET_NAME, "rep")
        read = write = sock
    else:
        read = Socket(PULL)
        read.set_string_option(SOL_SOCKET, SOCKET_NAME, "pull")
        write = Socket(PUSH)
        write.set_string_option(SOL_SOCKET, SOCKET_NAME, "push")

        read.configure(options.pullpush[0])
        write.configure(options.pullpush[1])


    while True:
        num = int(read.recv())
        res = factorize_naive(num)
        formula = str(num) + '=' + '*'.join(map(str, res))
        write.send(formula.encode('ascii'))
Exemple #3
0
def test_vehicle_data_logging():
    proc = wake_up_maya(start_position=None, constraints_for_training=None)

    # read data
    socket = Socket(SUB)
    socket.set_string_option(SUB, SUB_SUBSCRIBE, b"Publish Counter")
    socket.connect(FLAGS.log_port)

    # send control commands
    socket_out = Socket(PAIR)
    socket_out.connect(FLAGS.control_port)

    num_of_agents = 9
    num_of_steps = 30

    for steps in range(num_of_steps):
        for ptr in range(num_of_agents):
            vehicle_data = socket.recv()
            msg = parse_data(vehicle_data)
            tf.logging.info("%s" % msg)
        control_signal = "%s:%s" % (int(time.time() * 1000), 0)
        motor = 0.5
        brake = 0.
        steer = 0.
        hand_brake = 0.
        left_light = 0
        right_light = 0
        control_signal += ":%s:%s:%s:%s:%s:%s:%s" % ("my_ego_vehicle", motor,
                                                     brake, steer, hand_brake,
                                                     left_light, right_light)
        socket_out.send(control_signal.encode())

    maya_to_sleep(proc)
Exemple #4
0
 def _bg(self):
     sock = Socket(REQ)
     sock.connect('inproc://server')
     while self.running:
         for func in self.bg_tasks:
             msg = self.dump((func, []))
             sock.send(msg)
             self.load(sock.recv())
         time.sleep(10)
def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('-n', '--requests', metavar="NUM",
        help="Number of requests to issue (default %(default)d)",
        default=10000, type=int)
    ap.add_argument('-c', '--concurrent', metavar="NUM",
        help="Number of requests sent simultaneously (default %(default)d)",
        default=1000, type=int)
    ap.add_argument('-m', '--max-value', metavar="NUM",
        help="Maximum number that's sent for factorizing (default %(default)d)",
        default=10**12, type=int)
    ap.add_argument('--min-value', metavar="NUM",
        help="Maximum number that's sent for factorizing (default %(default)d)",
        default=10**11, type=int)
    ap.add_argument('--topology', metavar="URL", required=True,
        help="Url for topology to join to")
    options = ap.parse_args()

    sock = Socket(REQ, domain=AF_SP_RAW)
    sock.set_string_option(SOL_SOCKET, SOCKET_NAME, "client")
    sock.configure(options.topology)

    start_time = time.time()
    reqiter = requests(options)
    req = {}
    for i in range(options.concurrent):
        rid, val = next(reqiter)
        sock.send(b'\x00\x00\x00\x00' + struct.pack('>L', rid | 0x80000000)
            + str(val).encode('ascii'))
        req[rid] = val
    errors = 0
    sp  = 0
    n = 0
    while req:
        data = sock.recv()
        rid = struct.unpack_from('>L', data)[0] & ~0x80000000
        factors = map(int, data[4:].decode('ascii').split(','))
        checkval = reduce(int.__mul__, factors)
        if rid not in req:
            sp += 1
        elif req.pop(rid) != checkval:
            errors += 1
        else:
            n += 1

        try:
            rid, val = next(reqiter)
        except StopIteration:
            continue
        else:
            sock.send(b'\x00\x00\x00\x00' + struct.pack('>L', rid | 0x80000000)
                + str(val).encode('ascii'))
            req[rid] = val

    sec = time.time() - start_time
    print("Done", options.requests, "requests in", sec,
          "seconds, errors:", errors, ", spurious messages:", sp)
Exemple #6
0
 def _bg(self):
     sock = Socket(REQ)
     sock.connect("inproc://server")
     while self.running:
         for func in self.bg_tasks:
             msg = self.dump((func, []))
             sock.send(msg)
             self.load(sock.recv())
         time.sleep(10)
def start_service(service_name, service_protocol, service_port):
    socket = Socket(REP)
    socket.bind('%s://*:%s' % (service_protocol, service_port))

    print 'Starting service %s' % service_name

    while True:
        request = socket.recv()
        print 'Request: %s' % request
        socket.send('The answer is 42')
Exemple #8
0
def test_lidar_logging():
    proc = wake_up_maya(start_position=None, constraints_for_training=None)

    socket = Socket(SUB)
    socket.set_string_option(SUB, SUB_SUBSCRIBE, b"lidar")
    socket.connect(FLAGS.log_port_lidar)
    lidar = socket.recv()
    ts, point_cloud = parse_lidar_data(lidar)
    tf.logging.info("timestamp: %s, point cloud: %s" % (ts, point_cloud))
    maya_to_sleep(proc)
Exemple #9
0
def test_image_logging():
    proc = wake_up_maya(start_position=None, constraints_for_training=None)

    socket = Socket(SUB)
    socket.set_string_option(SUB, SUB_SUBSCRIBE, b"image")
    socket.connect(FLAGS.log_port_image)
    image = socket.recv()
    ts, image = parse_image(image)
    tf.logging.info("ts: %s image shape: %s" % (ts, image.shape))
    maya_to_sleep(proc)
Exemple #10
0
def brain_loop(args):
    sock_node = Socket(BUS)
    sock_node.bind('tcp://*:%s' % BRAIN_PORT)
    sock_node.recv_timeout = 250
    #sock_node.send_buffer_size = 1000
    sock_node.send_timeout = 200
    seq = 0

    timer = set_mode(args.mode)
    server = Server(args)

    while True:
        ch, value = chanselect([timer.chan, server.chan], [])

        #print 'AFTER chanselect', ch is timer.chan, time.time()
        if ch is timer.chan:
            lights.only(*value)
            #print "LIGHTS", value
            try:
                seq += 1
                sock_node.send(
                    '%i %s %s' %
                    (seq, CMD_LIGHTS, ' '.join(lights.rev_lookup[led_pin]
                                               for led_pin in value)))
            except Exception as ex:
                #print ex
                pass
        elif ch is server.chan:
            if value[0] == 'status':
                node = None
                try:
                    seq += 1
                    sock_node.send('%i PING' % seq)
                    while True:
                        node_msg = sock_node.recv().split()
                        if int(node_msg[0]) == seq:
                            node = 'ok'
                            break
                        elif int(node_msg[0]) > seq:
                            raise Exception('Skipped ping message')
                except Exception as ex:
                    node = repr(ex)
                value[1].put({'loop': 'ok', 'node': node})
            elif value[0] == 'set_period':
                timer.period = value[1]
            elif value[0] == 'trip':
                timer.trip = True
            elif value[0] == 'mode':
                mode = value[1]
                print("new mode tho %s" % mode)
                timer = set_mode(mode)
            else:
                print "UNKNOWN COMMAND:", value

    time.sleep(2)
Exemple #11
0
def test_hd_map_logging():
    proc = wake_up_maya(start_position=None, constraints_for_training=None)

    socket = Socket(SUB)
    socket.set_string_option(SUB, SUB_SUBSCRIBE, b"hd_map")
    socket.connect(FLAGS.log_port_hd_map)
    hd_map = socket.recv()
    my_hd_map = parse_hd_map(hd_map)

    tf.logging.info("%s" % my_hd_map)
    maya_to_sleep(proc)
def register_service(service_name, service_address, discovery_host,
                     discovery_port):
    socket = Socket(RESPONDENT)
    socket.connect('tcp://%s:%s' % (discovery_host, discovery_port))

    print 'Starting service registration [service: %s %s, discovery: %s:%s]' \
        % (service_name, service_address, discovery_host, discovery_port)

    while True:
        message = socket.recv()
        if message == 'service query':
            socket.send('%s|%s' % (service_name, service_address))
Exemple #13
0
class StreamClient(CaptureSource):
    def __init__(self, server_addr, direction):
        super().__init__(direction + '_stream')
        self.server_addr = 'tcp://{}:8081'.format(server_addr)
        self.sock = Socket(SUB)
        self.sock.connect(self.server_addr)
        self.sock.set_string_option(SUB, SUB_SUBSCRIBE, '')
        print('Started streaming capture source {} from {}'.format(
            self.direction, self.server_addr))

    def acquire_next_image(self):
        img = unpack_image(self.sock.recv())
        return img, time.time()
Exemple #14
0
def master_loop():
    sock_slave = Socket(PAIR)
    sock_slave.bind('tcp://*:%s' % MASTER_PORT)
    sock_slave.recv_timeout = 250
    #sock_slave.send_buffer_size = 1000
    sock_slave.send_timeout = 200
    seq = 0

    timer = LightTimer()
    server = Server()

    while True:
        ch, value = chanselect([timer.chan, server.chan], [])
        #print 'AFTER chanselect', ch is timer.chan, time.time()
        if ch is timer.chan:
            lights.only(*value)
            #print "LIGHTS", value
            try:
                seq += 1
                sock_slave.send('%i %s %s' % (
                    seq,
                    CMD_LIGHTS,
                    ' '.join(lights.rev_lookup[led_pin] for led_pin in value)))
            except Exception as ex:
                #print ex
                pass
        elif ch is server.chan:
            if value[0] == 'status':
                slave = None
                try:
                    seq += 1
                    sock_slave.send('%i PING' % seq)
                    while True:
                        slave_msg = sock_slave.recv().split()
                        if int(slave_msg[0]) == seq:
                            slave = 'ok'
                            break
                        elif int(slave_msg[0]) > seq:
                            raise Exception('Skipped ping message')
                except Exception as ex:
                    slave = repr(ex)
                value[1].put({'loop': 'ok', 'slave': slave})
            elif value[0] == 'set_period':
                timer.period = value[1]
            elif value[0] == 'trip':
                timer.trip = True
            else:
                print "UNKNOWN COMMAND:", value
    time.sleep(2)
def nano_client(endpoint):
    s = Socket(PAIR)
    s.connect('ipc://' + endpoint)
    #s.connect('tcp://127.0.0.1:9001')
    count = 0

    payload = test_str(SIZE)

    start = time.time()
    try:
        while True:
            s.send(payload)
            s.recv()
            count += 1
    except:
        pass
    finally:
        end = time.time()
        total = end - start
        print 'total: ', count
        print 'took: ', total
        print 'req / sec:', count / total
        print 'bandwidth: %f MBps' % (((count / total) * SIZE) / 2 ** 20)
        s.close()
def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('--topology', metavar="URL", required=True,
        help="Url for topology to join to")
    options = ap.parse_args()

    sock = Socket(PULL)
    sock.set_string_option(SOL_SOCKET, SOCKET_NAME, "push")
    sock.configure(options.topology)

    while True:
        data = sock.recv()
        num, factors = data.decode('ascii').split('=', 1)
        factors = map(int, factors.split('*'))
        checkval = reduce(int.__mul__, factors)
        assert int(num) == checkval
Exemple #17
0
class NanomsgSubscriber(HiddenSubscriber):
    """ Subscriber class subscribing to a certain topic

        Attributes:
           context (zmq.Context):
           socket (Socket): Socket object of ZMQ context
           topic (String): Topic subscriber subscribes to
    """
    def __init__(self, url, topic):
        """ Initializes object

            Args:
                url (String): url to publish messages to
                topic (String): Topic to publish messages under
        """
        super(NanomsgSubscriber, self).__init__(topic)
        self._socket = Socket(SUB)
        self._socket.recv_timeout = 500  # Wait 500ms for receiving msgs
        self._socket.connect(url)
        self._socket.set_string_option(SUB, SUB_SUBSCRIBE, topic + '|')
        self._logger = logging.getLogger('NanomsgSubscriber')

    def receive(self):
        """ Receives a message

            Returns:
                String
        """
        message = self._socket.recv()
        return message[len(self.topic) + 1:]

    def __enter__(self):
        """ Statement used for the `` with ... as ...:`` returns
            the object to use in the ``with`` block

            Returns:
                NanomsgSubscriber
        """
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        """ Executed when leaving ``with`` block, regardless whether
            because of an exception or normal program flow
        """
        self._socket.close()
Exemple #18
0
class NanomsgSubscriber(HiddenSubscriber):
    """ Subscriber class subscribing to a certain topic

        Attributes:
           context (zmq.Context):
           socket (Socket): Socket object of ZMQ context
           topic (String): Topic subscriber subscribes to
    """
    def __init__(self, url, topic):
        """ Initializes object

            Args:
                url (String): url to publish messages to
                topic (String): Topic to publish messages under
        """
        super(NanomsgSubscriber, self).__init__(topic)
        self._socket = Socket(SUB)
        self._socket.recv_timeout = 500 # Wait 500ms for receiving msgs
        self._socket.connect(url)
        self._socket.set_string_option(SUB, SUB_SUBSCRIBE, topic + '|')
        self._logger = logging.getLogger('NanomsgSubscriber')

    def receive(self):
        """ Receives a message

            Returns:
                String
        """
        message = self._socket.recv()
        return message[len(self.topic) + 1:]

    def __enter__(self):
        """ Statement used for the `` with ... as ...:`` returns
            the object to use in the ``with`` block

            Returns:
                NanomsgSubscriber
        """
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        """ Executed when leaving ``with`` block, regardless whether
            because of an exception or normal program flow
        """
        self._socket.close()
Exemple #19
0
def slave_loop(master):
    sock_master = Socket(PAIR)
    sock_master.connect('tcp://%s:%s' % (master, MASTER_PORT))

    while True:
        msg = sock_master.recv()
        #print 'HEARD', msg
        bits = msg.split()
        msgid = bits[0]
        cmd = bits[1]

        if cmd == CMD_PING:
            sock_master.send('%s PONG' % msgid)
        elif cmd == CMD_LIGHTS:
            which_pins = [lights.lookup[lgt] for lgt in bits[2:]]
            lights.only(*which_pins)
        else:
            print 'Unhandleable message: %r' % msg
Exemple #20
0
def node_loop(brain):
    sock_brain = Socket(BUS)
    sock_brain.connect('tcp://%s:%s' % (brain, BRAIN_PORT))

    while True:
        msg = sock_brain.recv()
        #print 'HEARD', msg
        bits = msg.split()
        msgid = bits[0]
        cmd = bits[1]

        if cmd == CMD_PING:
            sock_brain.send('%s PONG' % msgid)
        elif cmd == CMD_LIGHTS:
            which_pins = [lights.lookup[lgt] for lgt in bits[2:]]
            lights.only(*which_pins)
        else:
            print 'Unhandleable message: %r' % msg
Exemple #21
0
class ConsoleProxy(object):
    def __init__(self, url, recv_timeout=1000, send_timeout=1000):
        self.url = url.encode()
        self.socket = Socket(REQ)

        self.socket.recv_timeout = recv_timeout
        self.socket.send_timeout = send_timeout

        super(ConsoleProxy, self).__init__()

    def connect(self):
        self.socket.connect(self.url)

    def disconnect(self):
        self.socket.close()

    def send_command(self, cmd_name, echo=True, **kwargs):
        command = {
            "name": cmd_name,
            "args": kwargs
        }

        dump = msgpack.packb(command)

        if echo:
            print('send: ', command)

        try:
            self.socket.send(dump)
        except NanoMsgAPIError as e:
            print('send_error', e.msg)
            pass

        try:
            recv = self.socket.recv()
            unpack_msg = msgpack.unpackb(recv, encoding='utf-8')

            if echo:
                print('recv: ', recv)
                print(unpack_msg)

            return unpack_msg
        except NanoMsgAPIError as e:
            print('recv_error', e.msg)
Exemple #22
0
class Client(Common):
    def __init__(self, uri="inproc://server", id=None):
        self.sock = Socket(REQ)
        self.sock.connect(uri)
        self.id = id

    def close(self):
        self.sock.close()

    def call(self, func, *args):
        msg = self.dump((func, args))
        self.sock.send(msg)
        return self.load(self.sock.recv())

    def sync_call(self, func, *args):
        id = self.call(func, *args)
        print "got id", id
        while True:
            res = self.getresult(id)
            if res:
                return res
            time.sleep(0.1)

    def result(self, id, result):
        return self.call("result", id, result)

    def getresult(self, id):
        return self.call("getresult", id)

    def getstate(self, key):
        return self.call("getstate", key)

    def setstate(self, key, value):
        return self.call("setstate", key, value)

    def getlog(self, id, since=0):
        return self.call("getlog", id, since)

    def out(self, msg):
        return self.call("out", self.id, msg)

    def err(self, msg):
        return self.call("err", self.id, msg)
Exemple #23
0
class Client(Common):
    def __init__(self, uri='inproc://server', id=None):
        self.sock = Socket(REQ)
        self.sock.connect(uri)
        self.id = id

    def close(self):
        self.sock.close()

    def call(self, func, *args):
        msg = self.dump((func, args))
        self.sock.send(msg)
        return self.load(self.sock.recv())

    def sync_call(self, func, *args):
        id = self.call(func, *args)
        print "got id", id
        while True:
            res = self.getresult(id)
            if res:
                return res
            time.sleep(0.1)

    def result(self, id, result):
        return self.call("result", id, result)

    def getresult(self, id):
        return self.call("getresult", id)

    def getstate(self, key):
        return self.call("getstate", key)

    def setstate(self, key, value):
        return self.call("setstate", key, value)

    def getlog(self, id, since=0):
        return self.call("getlog", id, since)

    def out(self, msg):
        return self.call("out", self.id, msg)

    def err(self, msg):
        return self.call("err", self.id, msg)
Exemple #24
0
class ServiceDiscovery(object):

    def __init__(self, port, deadline=5000):
        self.socket = Socket(SURVEYOR)
        self.port = port
        self.deadline = deadline
        self.services = defaultdict(set)

    def bind(self):
        self.socket.bind('tcp://*:%s' % self.port)
        self.socket.set_int_option(SURVEYOR, SURVEYOR_DEADLINE, self.deadline)

    def discover(self):
        if not self.socket.is_open():
            return self.services

        self.services = defaultdict(set)
        self.socket.send('service query')

        while True:
            try:
                response = self.socket.recv()
            except NanoMsgAPIError:
                break

            service, address = response.split('|')
            self.services[service].add(address)

        return self.services

    def resolve(self, service):
        providers = self.services[service]

        if not providers:
            return None

        return random.choice(tuple(providers))

    def close(self):
        self.socket.close()
Exemple #25
0
class ServiceDiscovery(object):
 
    def __init__(self, port, deadline=5000):
        self.socket = Socket(SURVEYOR)
        self.port = port
        self.deadline = deadline
        self.services = defaultdict(set)
 
    def bind(self):
        self.socket.bind('tcp://172.30.42.174:%s' % self.port)
        self.socket.set_int_option(SURVEYOR, SURVEYOR_DEADLINE, self.deadline)
 
    def discover(self):
        if not self.socket.is_open():
            return self.services
 
        self.services = defaultdict(set)
        self.socket.send('service query')
 
        while True:
            try:
                response = self.socket.recv()
            except NanoMsgAPIError:
                break
 
            service, address = response.split('|')
            self.services[service].add(address)
 
        return self.services
 
    def resolve(self, service):
        providers = self.services[service]
 
        if not providers:
            return None
 
        return random.choice(tuple(providers))
 
    def close(self):
        self.socket.close()
Exemple #26
0
class LogRecorder(object):
    """
    """
    def __init__(self, log_file, sub_addr):
        """ args:
            ::log_file::
                日志文件名
            ::sub_addrs::
                订阅的nanomsg频道列表,暂时先不用,先用内置的列表
        """
        self.log_file = log_file
        self.sub_addr = sub_addr

    def init(self):
        self.writer = get_writer(self.log_file)
        self.socket = Socket(SUB)
        self.socket.set_string_option(SUB, SUB_SUBSCRIBE, "")
        self.socket.bind(self.sub_addr)

    def run(self):
        while True:
            try:
                string = self.socket.recv()
                self.writer.writeline(string)
            except Exception as e:
                print e

    def close(self):
        self.socket.close()

    def archive(self, signal_number, stack_frame):
        self.writer.archive()
        return None

    def __del__(self):
        self.close()
Exemple #27
0
class LogSub(QThread):
    def __init__(self, url):
        self.socket = Socket(SUB)
        self.url = url
        self.handlers = []

        super().__init__()

    def register_handler(self, handler):
        self.handlers.append(handler)

    def run(self):
        self.socket.set_string_option(SUB, SUB_SUBSCRIBE, b'')
        self.socket.connect(self.url)
        while True:
            try:
                msg = self.socket.recv()
                msg_pack = msgpack.unpackb(msg, encoding='utf-8')

                for h in self.handlers:
                    h(**msg_pack)

            except nanomsg.NanoMsgAPIError as e:
                raise
class ClientMq(object):
    def __init__(self, ui_event_engine, outgoing_quue):
        self._ui_event_engine = ui_event_engine
        self._outgoing_quue = outgoing_quue
        self._tick_sock = Socket(SUB)
        self._msg_sock = Socket(PAIR)

        self._active = False
        self._thread = Thread(target=self._run)

    def _run(self):
        while self._active:
            try:
                msg1 = self._tick_sock.recv(flags=1)
                msg1 = msg1.decode("utf-8")
                if msg1 is not None and msg1.index('|') > 0:
                    if msg1[-1] == '\0':
                        msg1 = msg1[:-1]
                    k = TickEvent()
                    k.deserialize(msg1)

                    self._ui_event_engine.put(k)
            except Exception as e:
                pass

            try:
                msg2 = self._msg_sock.recv(flags=1)
                msg2 = msg2.decode("utf-8")
                if msg2 is not None and msg2.index('|') > 0:
                    if msg2[-1] == '\0':
                        msg2 = msg2[:-1]
                    if msg2[-1] == '\x00':
                        msg2 = msg2[:-1]

                    v = msg2.split('|')
                    if v[0] == 's':
                       m = OrderStatusEvent()
                       m.deserialize(msg2)
                       self._ui_event_engine.put(m)
                    elif v[0] == 'f':
                        m = FillEvent()
                        m.deserialize(msg2)
                        self._ui_event_engine.put(m)
                    elif v[0] == 'n':
                        m = PositionEvent()
                        m.deserialize(msg2)
                        self._ui_event_engine.put(m)
                    elif v[0] == 'h':
                        m = HistoricalEvent()
                        m.deserialize(msg2)
                        self._ui_event_engine.put(m)
                    elif v[0] == 'u':
                        m = AccountEvent()
                        m.deserialize(msg2)
                        self._ui_event_engine.put(m)
                    elif v[0] == 'r':
                        m = ContractEvent()
                        m.deserialize(msg2)
                        self._ui_event_engine.put(m)
                    elif v[0] == 'm':
                        m = GeneralEvent()
                        m.deserialize(msg2)
                        self._ui_event_engine.put(m)
                        pass

            except Exception as e:
                pass
                # print('PAIR error: '+ str(i) + '' + str(e));
                # time.sleep(1)

            try:
                msg3 = self._outgoing_quue.get(False)
                self._msg_sock.send(msg3, flags=1)
            except Exception as e:
                pass

    def start(self, timer=True):
        """
        start the mq thread
        """
        self._tick_sock.connect('tcp://127.0.0.1:55555')
        self._tick_sock.set_string_option(SUB, SUB_SUBSCRIBE, '')  # receive msg start with all

        self._msg_sock.connect('tcp://127.0.0.1:55558')
        self._active = True

        if not self._thread.isAlive():
            self._thread.start()

    def stop(self):
        """
        stop the mq thread
        """
        self._active = False

        if self._thread.isAlive():
            self._thread.join()
Exemple #29
0
class ClientMq(object):
    def __init__(self, event_engine):
        self._event_engine = event_engine
        self._tick_sock = Socket(SUB)
        self._msg_sock = Socket(PAIR)

        self._active = False
        self._thread = Thread(target=self._run)

    def _run(self):
        while self._active:
            try:
                msg1 = self._tick_sock.recv(flags=1)
                msg1 = msg1.decode("utf-8")
                if msg1 is not None and msg1.index('|') > 0:
                    if msg1[-1] == '\0':
                        msg1 = msg1[:-1]
                    v = msg1.split('|')
                    k = TickEvent()
                    k.full_symbol = v[0]
                    k.price = v[3]

                    self._event_engine.put(k)
            except Exception as e:
                pass
                # print('SUB error: ' + str(e))

            try:
                msg2 = self._msg_sock.recv(flags=1)
                msg2 = msg2.decode("utf-8")
                if msg2 is not None and msg2.index('|') > 0:
                    if msg2[-1] == '\0':
                        msg2 = msg2[:-1]
                    m = GeneralEvent()
                    m.content = msg2

                    self._event_engine.put(m)
            except Exception as e:
                pass
                # print('PAIR error: '+ str(i) + '' + str(e));
                # time.sleep(1)

    def start(self, timer=True):
        """
        start the mq thread
        """
        self._tick_sock.connect('tcp://127.0.0.1:55555')
        self._tick_sock.set_string_option(SUB, SUB_SUBSCRIBE,
                                          '')  # receive msg start with all

        self._msg_sock.connect('tcp://127.0.0.1:55558')
        self._active = True

        if not self._thread.isAlive():
            self._thread.start()

    def stop(self):
        """
        stop the mq thread
        """
        self._active = False

        if self._thread.isAlive():
            self._thread.join()
Exemple #30
0
class NodeEditor:
    def __init__(self, mouse, gltext, conf):
        self.conf = conf
        self.mouse = mouse  # TODO: use a special mouse object instead of the editor_main object directly.
        self.gltext = gltext
        self.nodes = []
        self.links = []
        self.nodes_dict = {} # integers. 16-bit node addresses
        self.links_dict = {} # a pair of node objects. (node1, node2) is equivalent to (node2, node1), but only one pair exists in links_dict

        self.mouse_hover = False
        self.mouse_dragging = False
        self.selected = None
        self.selected_pos_ofs = vector.Vector()

        h = 0.  # 10 cm from the ground. nnope. for now, h has to be 0.
        r = 1.
        for i in range(10):
            a = float(i) / (r + 10) * 15.
            x, y = r * math.sin(a), r * math.cos(a)
            r += 0.5
            n = Node( vector.Vector((x, h, y)), i + 1, self._get_node_color(i+1), gltext )
            self.append_node(n)

        # n = Node( vector.Vector((0., h, 0.)), 1, gltext ); self.append_node(n)
        # n = Node( vector.Vector((1., h, 0.)), 2, gltext ); self.append_node(n)
        # n = Node( vector.Vector((2., h, -1.)), 3, gltext ); self.append_node(n)
        # n = Node( vector.Vector((-2., h, 2.)), 4, gltext ); self.append_node(n)
        # n = Node( vector.Vector((-1., h, 2.)), 5, gltext ); self.append_node(n)
        # n = Node( vector.Vector((-2., h, 1.)), 6, gltext ); self.append_node(n)
        # n = Node( vector.Vector((-1., h, 0.)), 7, gltext ); self.append_node(n)
        # n = Node( vector.Vector((-1.5, h, -1.)), 8, gltext ); self.append_node(n)
        # n = Node( vector.Vector((0.5, h, 1.)), 9, gltext ); self.append_node(n)
        # n = Node( vector.Vector((-1.4, h, 0.5)), 10, gltext ); self.append_node(n)
        #n.attrs["etx"] = 44

        self.s1 = Socket(SUB)
        self.s1.connect('tcp://127.0.0.1:55555')
        self.s1.set_string_option(SUB, SUB_SUBSCRIBE, '')

    def _get_link(self, src_node, dst_node):
        """ create a new link object if not found from self.links.
        fill self.links and self.links_dict (the dict both with src_node_id and dst_node_id) """
        if (src_node, dst_node) in self.links_dict:
            return self.links_dict[(src_node, dst_node)]
        elif (dst_node, src_node) in self.links_dict:
            return self.links_dict[(dst_node, src_node)]
        else:
            link = Link(src_node, dst_node)
            self.links.append(link)
            self.links_dict[(src_node, dst_node)] = link
            return link

    def _get_node_color(self, origin_node_id):
        if origin_node_id == 10:
            return 0.753, 0.753, 0.753, 1.
        if origin_node_id == 9:
            return 0.824, 0.412, 0.118, 1.
        if origin_node_id == 8:
            return 1.000, 0.000, 1.000, 1.
        if origin_node_id == 7:
            return 1.000, 1.000, 0.000, 1.
        if origin_node_id == 6:
            return 1.000, 0.627, 0.478, 1.
        if origin_node_id == 5:
            return 0.498, 1.000, 0.000, 1.
        if origin_node_id == 4:
            return 0.000, 1.000, 1.000, 1.
        if origin_node_id == 3:
            return 1.000, 0.922, 0.804, 1.
        if origin_node_id == 2:
            return 0.871, 0.722, 0.529, 1.
        if origin_node_id == 1:
            return 0.000, 0.749, 1.000, 1.

        return 0.8, 0.8, 0.8, 1.0

    def append_node(self, node):
        assert node.node_id not in self.nodes_dict
        self.nodes.append(node)
        self.nodes_dict[node.node_id] = node

    def tick(self, dt, keys):
        for link in self.links:
            link.tick(dt)
        for node in self.nodes:
            node.tick(dt)

        try:
            while 1:
                d = self.s1.recv(flags=DONTWAIT)
                d = d.strip()
                if d:
                    if d.startswith("data etx"):
                        # ['data', 'etx', '0001000000000200', 'node', '0A', 'index', '0', 'neighbor', '8', 'etx', '10', 'retx', '74']
                        d = d.split()
                        #llog.info(d)
                        node_id = int(d[4], 16)

                        # filter out empty rows
                        if int(d[8]) != 0xFFFF:
                            if d[10].startswith("NO_ROUTE"):
                                d[10] = "NO"
                                d[12] = "NO"

                            if int(d[6]) == 0:
                                self.nodes_dict[node_id].attrs["etx_table"] = []

                            self.nodes_dict[node_id].attrs["etx_table"].append("%s e%s r%s" % (d[8], d[10], d[12]))

                    elif d.startswith("event radiopowerstate"):
                        # ['event', 'radiopowerstate', '0052451410156550', 'node', '04', 'state', '1']
                        d = d.split()
                        #llog.info(d)
                        node_id = int(d[4], 16)
                        radiopowerstate = int(d[6], 16)
                        self.nodes_dict[node_id].attrs["radiopowerstate"] = radiopowerstate
                        if radiopowerstate:
                            self.nodes_dict[node_id].poke_radio()
                    elif d.startswith("event beacon"):
                        # ['event', 'beacon', '0052451410156550', 'node', '04', 'options', '0x00', 'parent', '0x0003', 'etx', '30']
                        d = d.split()
                        #llog.info(d)
                        node_id = int(d[4], 16)
                        options = int(d[6], 16)
                        parent = int(d[8], 16)
                        self.nodes_dict[node_id].append_animation(BeaconAnimation(options))
                        self.nodes_dict[node_id].attrs["parent"] = parent
                    elif d.startswith("event packet_to_activemessage") and 0:
                        # ['event', 'packet', '0000372279297175', 'node', '04', 'dest', '0x1234', 'amid', '0x71']
                        d = d.split()
                        #llog.info(d)
                        src_node_id = int(d[4], 16)
                        dst_node_id = int(d[6], 16)
                        amid = int(d[8], 16)
                        if dst_node_id != 0xFFFF: # filter out broadcasts
                            src_node = self.nodes_dict[src_node_id]
                            dst_node = self.nodes_dict[dst_node_id]
                            link = self._get_link(src_node, dst_node)
                            link.poke(src_node)
                    elif d.startswith("event send_ctp_packet"):
                        # event send_ctp_packet 0:0:38.100017602 node 0x0003 dest 0x0004 origin 0x0009 sequence 21 type 0x71 thl 5
                        # event send_ctp_packet 0:0:10.574584572 node 04 dest 0x0003 origin 0x0005 sequence 4 amid 0x98 thl 1
                        llog.info(d)
                        d = d.split()

                        src_node_id = int(d[4], 16)
                        dst_node_id = int(d[6], 16)
                        origin_node_id = int(d[8], 16)
                        sequence_num = int(d[10])
                        amid = int(d[12], 16)
                        thl = int(d[14])

                        src_node = self.nodes_dict[src_node_id]
                        dst_node = self.nodes_dict[dst_node_id]
                        link = self._get_link(src_node, dst_node)
                        link.poke(src_node, packet_color=self._get_node_color(origin_node_id))
                    elif d.startswith("event packet_to_model_busy"):
                        d = d.split()
                        #llog.info(d)
                        src_node_id = int(d[4], 16)
                        dst_node_id = int(d[6], 16)
                        if dst_node_id != 0xFFFF: # filter out broadcasts
                            src_node = self.nodes_dict[src_node_id]
                            dst_node = self.nodes_dict[dst_node_id]
                            link = self._get_link(src_node, dst_node)
                            link.poke_busy(src_node)
                    elif d.startswith("data ctpf_buf_size"):
                        d = d.split()
                        #llog.info(d)
                        node_id = int(d[4], 16)
                        used = int(d[6])
                        capacity = int(d[8])
                        self.nodes_dict[node_id].attrs["ctpf_buf_used"] = used
                        self.nodes_dict[node_id].attrs["ctpf_buf_capacity"] = capacity
                    else:
                        llog.info(d)
                else:
                    break
        except NanoMsgAPIError as e:
            if e.errno != errno.EAGAIN:
                raise

    def _render_links_to_parents(self):
        glLineWidth(1.)
        glColor4f(0.4, 0.4, 0.4, 1.)

        # 1111_11_1______
        glLineStipple(2, 1+2+4+8+32+64+256)
        glEnable(GL_LINE_STIPPLE)
        glLineWidth(2.)
        for node in self.nodes:
            parent_id = node.attrs.get("parent")
            if parent_id and parent_id != 0xFFFF:
                parent_node = self.nodes_dict[parent_id]

                glBegin(GL_LINES)
                glVertex3f(*parent_node.pos)
                glVertex3f(*node.pos)
                glEnd()

        glDisable(GL_LINE_STIPPLE)

    def render(self):
        for link in self.links:
            link.render()
        self._render_links_to_parents()
        for node in self.nodes:
            node.render()

    def render_overlay(self, camera, camera_ocs, projection_mode, w_pixels, h_pixels):
        # calculate node screen positions
        for node in self.nodes:
            # 1. proj obj to camera_ocs
            # 2. proj coord to screenspace
            v = camera_ocs.projv_in(node.pos)
            node.screen_pos.set(camera.screenspace(projection_mode, v, w_pixels, h_pixels))

        # draw lines from the selected node to every other node
        if 0 and self.selected:
            glLineWidth(1.)
            for node in self.nodes:
                if node != self.selected:
                    glColor4f(0.3,0.3,0.3,.9)
                    glBegin(GL_LINES)
                    glVertex3f(*self.selected.screen_pos)
                    glVertex3f(*node.screen_pos)
                    glEnd()

                    glEnable(GL_TEXTURE_2D)
                    s = (self.selected.screen_pos + node.screen_pos) / 2.
                    link_quality = self._calc_link_quality(node, self.selected)
                    self.gltext.drawmm("%.2f" % link_quality, s[0], s[1], bgcolor=(0.2,0.2,0.2,0.7), fgcolor=(1.,1.,1.,1.), z=s[2])
                    glDisable(GL_TEXTURE_2D)

        # draw the nodes themselves
        for node in self.nodes:
            node.render_overlay()

    #def recalculate_screen_pos(self, camera, camera_ocs, projection_mode, w_pixels, h_pixels):
    #    for node in self.nodes:
    #        # 1. proj obj to camera_ocs
    #        # 2. proj coord to screenspace
    #        v = camera_ocs.projv_in(node.pos)
    #        node.screen_pos.set(camera.screenspace(projection_mode, v, w_pixels, h_pixels))

    def intersects(self, sx, sy):
        for node in self.nodes:
            if node.intersects(float(sx), float(sy)):
                return node
        return None

    def save_graph_file(self, filename="sensormap.txt"):
        d = {"format": "sensed node graph", "format_version": "2013-12-19", "nodes": [], "edges": []}

        for node in self.nodes:
            p = node.pos
            n = {"id": node.node_id, "pos": [p[0], p[1], p[2]]}
            d["nodes"].append(n)

        edge_count = 0
        for node1 in self.nodes:
            for node2 in self.nodes:
                if node1 != node2:
                    edge_count += 1
                    e = {"id": edge_count, "source": node1.node_id, "dest": node2.node_id, "link_quality": self._calc_link_quality(node1, node2)}
                    d["edges"].append(e)

        txt = json.dumps(d, indent=4, sort_keys=True)

        with open(filename, "wb") as f:
            f.write(txt)

    def _calc_link_quality(self, node1, node2):
        dist = node1.pos.dist(node2.pos)
        return dist

    def event(self, event):
        if event.type == SDL_MOUSEMOTION:
            for node in self.nodes:
                node.mouse_hover = False
            node = self.intersects(event.motion.x, event.motion.y)
            if node:
                self.mouse_hover = True
                node.mouse_hover = True
            else:
                self.mouse_hover = False

            if self.selected and self.mouse_dragging and self.mouse.mouse_lbdown_floor_coord:
                self.selected.pos.set(self.mouse.mouse_floor_coord + self.selected_pos_ofs)

        elif event.type == SDL_MOUSEBUTTONDOWN:
            if event.button.button == SDL_BUTTON_LEFT:
                node = self.intersects(event.button.x, event.button.y)
                if node:
                    for n in self.nodes:
                        n.selected = False
                    self.selected = node
                    node.selected = True
                    self.selected_pos_ofs.set(node.pos - self.mouse.mouse_lbdown_floor_coord)
                    self.mouse_dragging = True
                else:
                    self.mouse_dragging = False

        elif event.type == SDL_MOUSEBUTTONUP:
            if event.button.button == SDL_BUTTON_LEFT:
                #if self.mouse_dragging:
                if self.mouse.mouse_lbdown_window_coord == self.mouse.mouse_window_coord:
                    node = self.intersects(event.button.x, event.button.y)
                    if not node:
                        self.selected = None
                        for n in self.nodes:
                            n.selected = False
                self.mouse_dragging = False
Exemple #31
0
class ClientMq(object):
    def __init__(self, event_engine, outgoing_quue):
        self._event_engine = event_engine
        self._outgoing_quue = outgoing_quue
        self._tick_sock = Socket(SUB)
        self._msg_sock = Socket(PAIR)

        self._active = False
        self._thread = Thread(target=self._run)

    def _run(self):
        while self._active:
            try:
                msg1 = self._tick_sock.recv(flags=1)
                msg1 = msg1.decode("utf-8")
                if msg1 is not None and msg1.index('|') > 0:
                    if msg1[-1] == '\0':
                        msg1 = msg1[:-1]
                    v = msg1.split('|')
                    k = TickEvent()
                    k.full_symbol = v[0]
                    k.price = v[3]

                    self._event_engine.put(k)
            except Exception as e:
                pass
                # print('SUB error: ' + str(e))

            try:
                msg2 = self._msg_sock.recv(flags=1)
                msg2 = msg2.decode("utf-8")
                if msg2 is not None and msg2.index('|') > 0:
                    if msg2[-1] == '\0':
                        msg2 = msg2[:-1]
                    if msg2[-1] == '\x00':
                        msg2 = msg2[:-1]
                    m = GeneralEvent()
                    m.content = msg2
                    self._event_engine.put(m)

                    v = msg2.split('|')
                    if v[0] == 's':
                        m = OrderStatusEvent()
                        m.broker_order_id = v[1]
                        m.internal_order_id = v[1]
                        m.order_status = v[2]
                        self._event_engine.put(m)
                    elif v[0] == 'f':
                        m = FillEvent()
                        m.broker_order_id = v[1]
                        m.internal_order_id = v[1]
                        m.timestamp = v[2]
                        m.fill_price = v[3]
                        m.fill_size = v[4]
                        self._event_engine.put(m)
                    else:
                        pass

            except Exception as e:
                pass
                # print('PAIR error: '+ str(i) + '' + str(e));
                # time.sleep(1)

            try:
                msg3 = self._outgoing_quue.get(False)
                print(msg3)
                self._msg_sock.send(msg3, flags=1)
            except Exception as e:
                pass

    def start(self, timer=True):
        """
        start the mq thread
        """
        self._tick_sock.connect('tcp://127.0.0.1:55555')
        self._tick_sock.set_string_option(SUB, SUB_SUBSCRIBE,
                                          '')  # receive msg start with all

        self._msg_sock.connect('tcp://127.0.0.1:55558')
        self._active = True

        if not self._thread.isAlive():
            self._thread.start()

    def stop(self):
        """
        stop the mq thread
        """
        self._active = False

        if self._thread.isAlive():
            self._thread.join()
Exemple #32
0
class Daemon(Common):
    change_funcs = set()
    bg_tasks = []

    def __init__(self, state, logs, worker_class):
        self.state = state
        self.logs = logs
        self.worker_class = worker_class

        self.sock = Socket(REP)
        self.sock.bind("inproc://server")
        self.sock.bind("ipc://socket")

        self.results = {}
        self.threads = {}
        self.running = True

        self.change_lock = Lock()

        self.id_gen = iter(range(10000000)).next

        self.init()

    def init(self):
        pass

    def recv(self):
        msg = self.sock.recv()
        # print "Received", self.load(msg)
        return self.load(msg)

    def send(self, *args):
        msg = self.dump(*args)
        return self.sock.send(msg)

    def run(self):
        t = Thread(target=self._bg)
        t.start()
        t = Thread(target=self._run)
        t.start()
        return t

    def _bg(self):
        sock = Socket(REQ)
        sock.connect("inproc://server")
        while self.running:
            for func in self.bg_tasks:
                msg = self.dump((func, []))
                sock.send(msg)
                self.load(sock.recv())
            time.sleep(10)

    def handle_result(self, id, result):
        print "Got result id=%r result=%r" % (id, result)
        self.results[id] = result
        self.send("ok")

    def handle_setstate(self, key, value):
        print "Set state key=%r value=%r" % (key, value)
        self.state.set(key, value)
        self.send("ok")

    def handle_getstate(self, key):
        value = self.state.get(key)
        print "Get state key=%r value=%r" % (key, value)
        self.send(value)

    def handle_out(self, id, txt):
        print "Got %s id=%r result=%r" % ("out", id, txt)
        self.logs.append(id, "out", txt)
        self.send("ok")

    def handle_err(self, id, txt):
        print "Got %s id=%r result=%r" % ("err", id, txt)
        self.logs.append(id, "err", txt)
        self.send("ok")

    def handle_getresult(self, id):
        result = self.results.get(id)
        if result:
            del self.results[id]
            del self.threads[id]
        print "sending result=%r for id=%r" % (result, id)
        self.send(result)

    def handle_getlog(self, id, since):
        result = self.logs.get(id, since)
        print "sending log=%r for id=%r" % (result, id)
        self.send(result)

    def _run(self):
        while self.running:
            (cmd, args) = self.recv()
            func = getattr(self, "handle_" + cmd, None)
            if func:
                func(*args)
                continue

            t_id, t = self.spawn_worker(cmd, args)
            self.send(t_id)
            self.threads[t_id] = t
            print "started thread for id=%r func=%r args=%r" % (t_id, func, args)

    def spawn_worker(self, cmd, args):
        t_id = self.id_gen()
        target = lambda: self.wrap(t_id, cmd, args)
        t = Thread(target=target)
        t.start()
        return t_id, t

    def wrap(self, id, cmd, args):
        if cmd in self.change_funcs:
            self.change_lock.acquire()
        try:
            w = self.worker_class(id)
            func = getattr(w, cmd, w.noop)
            if hasattr(func, "api_exposed"):
                try:
                    res = func(*args)
                except Exception, e:
                    res = repr(e)
            else:
from __future__ import print_function
from nanomsg import Socket, PAIR, PUB

s1 = Socket(PAIR)
s2 = Socket(PAIR)
s1.bind('inproc://bob')
s2.connect('inproc://bob')
s1.send(b'hello nanomsg')
print(s2.recv())
s1.close()
s2.close()



with Socket(PAIR) as s3:
	with Socket(PAIR) as s4:
		s3.bind('inproc://demo')
		s4.connect('inproc://demo')
		s3.send('hi, I use "with"')
		print(s4.recv())
		s4.send('Ok, I see.')
		print(s3.recv())


Exemple #34
0
socket = Socket(PAIR)

socket_address = 'ipc:///home/d1plo1d/git_repos/teg/packages/teg-linuxcnc/example_socket'

socket.bind(socket_address)
# s2.connect(socket_address)
# print(s2.recv())
# s2.close()

while True:
    print "SENDING??"
    try:
        socket.send(b'hello nanomsg', DONTWAIT)
        print "SENT!"
    except NanoMsgAPIError:
        print "Unable to send nanomsg. Will retry."
    try:
        message = socket.recv(flags=DONTWAIT)
        print("Received request: %s" % message)
    except NanoMsgAPIError:
        pass

    #  Do some 'work'
    time.sleep(1)

    #  Send reply back to client
    # socket.send(b"World")

socket.close()
Exemple #35
0
# vim: set fileencoding=utf-8

from nanomsg import Socket, PAIR

URL = "ipc:///tmp/example3"

socket = Socket(PAIR)
print("Socket created")

socket.connect(URL)
print("Connected to URL {}".format(URL))

message = socket.recv()
print("Received: {}".format(message))

socket.close()
print("Socket closed")
Exemple #36
0
class Daemon(Common):
    change_funcs = set()
    bg_tasks = []

    def __init__(self, state, logs, worker_class):
        self.state = state
        self.logs = logs
        self.worker_class = worker_class

        self.sock = Socket(REP)
        self.sock.bind('inproc://server')
        self.sock.bind('ipc://socket')

        self.results = {}
        self.threads = {}
        self.running = True

        self.change_lock = Lock()

        self.id_gen = iter(range(10000000)).next

        self.init()

    def init(self):
        pass

    def recv(self):
        msg = self.sock.recv()
        #print "Received", self.load(msg)
        return self.load(msg)

    def send(self, *args):
        msg = self.dump(*args)
        return self.sock.send(msg)

    def run(self):
        t = Thread(target=self._bg)
        t.start()
        t = Thread(target=self._run)
        t.start()
        return t

    def _bg(self):
        sock = Socket(REQ)
        sock.connect('inproc://server')
        while self.running:
            for func in self.bg_tasks:
                msg = self.dump((func, []))
                sock.send(msg)
                self.load(sock.recv())
            time.sleep(10)

    def handle_result(self, id, result):
        print "Got result id=%r result=%r" % (id, result)
        self.results[id] = result
        self.send("ok")

    def handle_setstate(self, key, value):
        print "Set state key=%r value=%r" % (key, value)
        self.state.set(key, value)
        self.send("ok")

    def handle_getstate(self, key):
        value = self.state.get(key)
        print "Get state key=%r value=%r" % (key, value)
        self.send(value)

    def handle_out(self, id, txt):
        print "Got %s id=%r result=%r" % ('out', id, txt)
        self.logs.append(id, 'out', txt)
        self.send("ok")

    def handle_err(self, id, txt):
        print "Got %s id=%r result=%r" % ('err', id, txt)
        self.logs.append(id, 'err', txt)
        self.send("ok")

    def handle_getresult(self, id):
        result = self.results.get(id)
        if result:
            del self.results[id]
            del self.threads[id]
        print "sending result=%r for id=%r" % (result, id)
        self.send(result)

    def handle_getlog(self, id, since):
        result = self.logs.get(id, since)
        print "sending log=%r for id=%r" % (result, id)
        self.send(result)

    def _run(self):
        while self.running:
            (cmd, args) = self.recv()
            func = getattr(self, 'handle_' + cmd, None)
            if func:
                func(*args)
                continue

            t_id, t = self.spawn_worker(cmd, args)
            self.send(t_id)
            self.threads[t_id] = t
            print "started thread for id=%r func=%r args=%r" % (t_id, func,
                                                                args)

    def spawn_worker(self, cmd, args):
        t_id = self.id_gen()
        target = lambda: self.wrap(t_id, cmd, args)
        t = Thread(target=target)
        t.start()
        return t_id, t

    def wrap(self, id, cmd, args):
        if cmd in self.change_funcs:
            self.change_lock.acquire()
        try:
            w = self.worker_class(id)
            func = getattr(w, cmd, w.noop)
            if hasattr(func, 'api_exposed'):
                try:
                    res = func(*args)
                except Exception, e:
                    res = repr(e)
            else:
Exemple #37
0
from nanomsg import poll, Socket, PUSH, PULL
from time import time
import sys
import argparse

parser = argparse.ArgumentParser(
    description='Extract parameters from command-line')
parser.add_argument('-cn', '--clientnumber', default='1')
args = parser.parse_args()

client_number = int(args.clientnumber)

client_sock = Socket(PULL)
client_sock.connect('ipc://nanopushpull.bin')
timeout = 2  # seconds
not_finished = True
while not_finished:
    time_before_poll = time()
    r, _ = poll([client_sock], [], timeout)
    time_after_poll = time()
    if (time_after_poll - time_before_poll - timeout > 0):
        print("client #%d: timeout exceeded - no more messages?" %
              (client_number))
        break
    elif len(r) > 0:
        print("client #%d: got %s" % (client_number, client_sock.recv()))
    else:
        print("client #%d: something odd happened" % (client_number))
        break
client_sock.close()
class StrategyEngine(BaseEngine):
    """
    Send to and receive from msg  server ,used for strategy 
    """
    config_filename = "config_server.yaml"
    setting_filename = "cta_strategy_setting.json"
    data_filename = "cta_strategy_data.json"
# init

    def __init__(self, configfile: str = '', id: int = 1):
        super(StrategyEngine, self).__init__(event_engine=EventEngine(10))
        """
        two sockets to send and recv msg
        """
        self.__active = False
        self.id = os.getpid()
        self.engine_type = EngineType.LIVE
        self._recv_sock = Socket(SUB)
        self._send_sock = Socket(PUSH)
        self._handlers = defaultdict(list)
        if configfile:
            self.config_filename = configfile
        filepath = Path.cwd().joinpath("etc/" + self.config_filename)
        with open(filepath, encoding='utf8') as fd:
            self._config = yaml.load(fd)
        self.ordercount = 0

        #  stragegy manage
        self.strategy_setting = {}  # strategy_name: dict
        self.strategy_data = {}     # strategy_name: dict

        self.classes = {}           # class_name: stategy_class
        self.strategies = {}        # strategy_name: strategy

        # self.classes_id = {}     # class_id : strategy
        # self.strategies_id = {}     # strategy_ID: strategy

        self.symbol_strategy_map = defaultdict(
            list)                   # full_symbol: strategy list
        self.orderid_strategy_map = {}  # vt_orderid: strategy
        self.strategy_orderid_map = defaultdict(
            set)                    # strategy_name: client_order_id list

        self.stop_order_count = 0   # for generating stop_orderid
        self.stop_orders = {}       # stop_orderid: stop_order
        self.init_thread = None
        self.init_queue = Queue()

        # order,tick,position ,etc manage
        self.ticks = {}
        self.orders = {}               # clientorder id list
        self.trades = {}
        self.positions = {}
        self.accounts = {}
        self.contracts = {}
        self.active_orders = {}        # SQ id list

        self.rq_client = None
        self.rq_symbols = set()

        self.offset_converter = OffsetConverter(self)

        self.autoinited = False
        self.autostarted = False
        self.dayswitched = False

        self.init_engine()

# init functions
    def init_engine(self):
        self.init_nng()
        self.init_rqdata()
        self.load_contract()
        self.load_strategy_class()
        self.load_strategy_setting()
        self.load_strategy_data()
        self.register_event()

    def init_nng(self):
        self._recv_sock.set_string_option(
            SUB, SUB_SUBSCRIBE, '')  # receive msg start with all
        self._recv_sock.set_int_option(SOL_SOCKET, RCVTIMEO, 100)
        self._recv_sock.connect(self._config['serverpub_url'])
        self._send_sock.connect(self._config['serverpull_url'])

    def init_rqdata(self):

        result = rqdata_client.init()
        if result:
            self.write_log("RQData数据接口初始化成功")

    def load_contract(self):
        contractfile = Path.cwd().joinpath("etc/ctpcontract.yaml")
        with open(contractfile, encoding='utf8') as fc:
            contracts = yaml.load(fc)
        print('loading contracts, total number:', len(contracts))
        for sym, data in contracts.items():
            contract = ContractData(
                symbol=data["symbol"],
                exchange=Exchange(data["exchange"]),
                name=data["name"],
                product=PRODUCT_CTP2VT[str(data["product"])],
                size=data["size"],
                pricetick=data["pricetick"],
                net_position=True if str(
                    data["positiontype"]) == THOST_FTDC_PT_Net else False,
                long_margin_ratio=data["long_margin_ratio"],
                short_margin_ratio=data["short_margin_ratio"],
                full_symbol=data["full_symbol"]
            )
            # For option only
            if contract.product == Product.OPTION:
                contract.option_underlying = data["option_underlying"],
                contract.option_type = OPTIONTYPE_CTP2VT.get(
                    str(data["option_type"]), None),
                contract.option_strike = data["option_strike"],
                contract.option_expiry = datetime.strptime(
                    str(data["option_expiry"]), "%Y%m%d"),
            self.contracts[contract.full_symbol] = contract

    def register_event(self):
        """"""
        self.event_engine.register(EventType.TICK, self.process_tick_event)
        self.event_engine.register(
            EventType.ORDERSTATUS, self.process_orderstatus_event)
        self.event_engine.register(EventType.FILL, self.process_trade_event)
        self.event_engine.register(
            EventType.POSITION, self.process_position_event)
        self.event_engine.register(
            EventType.ACCOUNT, self.process_account_event)
        self.event_engine.register(
            EventType.CONTRACT, self.process_contract_event)
        self.event_engine.register(
            EventType.STRATEGY_CONTROL, self.process_strategycontrol_event)
        self.event_engine.register(
            EventType.HEADER, self.process_general_event)
        self.event_engine.register(EventType.TIMER, self.process_timer_event)
# event handler

    def process_timer_event(self, event):
        # auto init and start strategy at 8:57, 20:57
        nowtime = datetime.now().time()
        dayinitflag = (nowtime > time(hour=8, minute=55)) and (
            nowtime < time(hour=8, minute=56))
        daystartflag = (nowtime > time(hour=8, minute=57)) and (
            nowtime < time(hour=8, minute=58))
        nightinitflag = (nowtime > time(hour=20, minute=55)) and (
            nowtime < time(hour=20, minute=56))
        nightstartflag = (nowtime > time(hour=20, minute=57)) and (
            nowtime < time(hour=20, minute=58))
        if (dayinitflag or nightinitflag) and (not self.autoinited):
            for name, strategy in self.strategies.items():
                if strategy.autostart:
                    self.init_strategy(name)
            self.dayswitched = False
            self.autoinited = True

        if (daystartflag or nightstartflag) and (not self.autostarted):
            for name, strategy in self.strategies.items():
                if strategy.autostart:
                    self.start_strategy(name)
            self.autostarted = True
            self.dayswitched = False

        # auto stop strategy at 16:00 and 3:00
        if (nowtime > time(hour=16, minute=0)) and (nowtime < time(hour=16, minute=1)) and (not self.dayswitched):
            for name, strategy in self.strategies.items():
                if strategy.autostart:
                    self.reset_strategy(name)
            self.dayswitched = True
            self.autostarted = False
            self.autoinited = False
        if (nowtime > time(hour=3, minute=0)) and (nowtime < time(hour=3, minute=1)) and (not self.dayswitched):
            for name, strategy in self.strategies.items():
                if strategy.autostart:
                    self.reset_strategy(name)
            self.dayswitched = True
            self.autostarted = False
            self.autoinited = False

    def process_general_event(self, event):
        for name, strategy in self.strategies.items():
            self.call_strategy_func(strategy, strategy.on_headermsg, event)
        pass

    def process_tick_event(self, event: Event):
        """"""
        tick = event.data

        strategies = self.symbol_strategy_map[tick.full_symbol]
        if not strategies:
            return
        # self.check_stop_order(tick)
        for strategy in strategies:
            if strategy.inited:
                self.call_strategy_func(strategy, strategy.on_tick, tick)
        self.ticks[tick.full_symbol] = tick

    def process_orderstatus_event(self, event: Event):
        """"""
        order = event.data

        self.offset_converter.update_order(order)  # 重新计算冻结

        if order.clientID != self.id:
            return

        self.orders[order.client_order_id] = order
        # If order is active, then update data in dict.
        if order.is_active():
            print('order is active')
            self.active_orders[order.client_order_id] = order
        # Otherwise, pop inactive order from in dict
        elif order.client_order_id in self.active_orders:
            self.active_orders.pop(order.client_order_id)

        strategy = self.orderid_strategy_map.get(order.client_order_id, None)
        if not strategy:
            print(order.client_order_id, 'dont find strategy')
            return

        # Remove client_order_id if order is no longer active.
        client_order_ids = self.strategy_orderid_map[strategy.strategy_name]
        if (order.client_order_id in client_order_ids) and (not order.is_active()):
            print('rm inactive order in strategy order map')
            client_order_ids.remove(order.client_order_id)

        # For server stop order, call strategy on_stop_order function
        # if order.type == OrderType.STOP:
        #     so = StopOrder(
        #         full_symbol=order.full_symbol,
        #         direction=order.direction,
        #         offset=order.offset,
        #         price=order.price,
        #         volume=order.volume,
        #         stop_orderid=order.vt_orderid,
        #         strategy_name=strategy.strategy_name,
        #         status=STOP_STATUS_MAP[order.status],
        #         vt_orderid=order.vt_orderid,
        #     )
        #     self.call_strategy_func(strategy, strategy.on_stop_order, so)

        # Call strategy on_order function
        self.call_strategy_func(strategy, strategy.on_order, order)

    def process_trade_event(self, event: Event):
        """"""
        trade = event.data

        self.offset_converter.update_trade(trade)

        if trade.clientID != self.id:
            return
        strategy = self.orderid_strategy_map.get(trade.client_order_id, None)
        if not strategy:
            return

        # if trade.direction == Direction.LONG:
        #     strategy.pos += trade.volume
        # else:
        #     strategy.pos -= trade.volume

        self.call_strategy_func(strategy, strategy.on_trade, trade)
        self.put_strategy_event(strategy)

        self.trades[trade.vt_tradeid] = trade

        # send qry pos to update position
        m = Event(type=EventType.QRY,
                  des=event.source,
                  src=str(self.id),
                  msgtype=MSG_TYPE.MSG_TYPE_QRY_POS)
        self._send_sock.send(m.serialize())
        # self.put(m)

    def process_position_event(self, event: Event):
        """"""
        position = event.data

        self.offset_converter.update_position(position)

        self.positions[position.key] = position

    def process_account_event(self, event: Event):
        """"""
        account = event.data
        self.accounts[account.accountid] = account

    def process_contract_event(self, event: Event):
        """"""
        contract = event.data
        self.contracts[contract.full_symbol] = contract

    def process_strategycontrol_event(self, event: Event):
        msgtype = event.msg_type
        deslist = ['@*', str(self.id), '@' + str(self.id)]
        if (event.destination not in deslist):
            return
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_STATUS):
            m = Event(type=EventType.STRATEGY_CONTROL,
                      des='@0',
                      src=str(self.id),
                      msgtype=MSG_TYPE.MSG_TYPE_STRATEGY_STATUS
                      )
            self._send_sock.send(m.serialize())
        # elif (event.destination not in deslist ) :
        #     return
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_ADD):
            v = event.data.split('|')
            classname = v[0]
            strname = v[1]
            fulsym = v[2]
            setting = json.loads(v[3])
            self.add_strategy(classname, strname, fulsym, setting)
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_INIT):
            self.init_strategy(event.data)
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_INIT_ALL):
            self.init_all_strategies()
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_START):
            self.start_strategy(event.data)
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_START_ALL):
            self.start_all_strategies()
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_STOP):
            self.stop_strategy(event.data)
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_STOP_ALL):
            self.stop_all_strategies()
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_RELOAD):
            self.classes.clear()
            self.load_strategy_class(True)
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_RESET):
            self.reset_strategy(event.data)
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_RESET_ALL):
            self.reset_all_strategies()
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_EDIT):
            v = event.data.split('|')
            setting = json.loads(v[1])
            self.edit_strategy(v[0], setting)
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_REMOVE):
            if self.remove_strategy(event.data):
                m = Event(type=EventType.STRATEGY_CONTROL,
                          data=event.data,
                          des='@0',
                          src=str(self.id),
                          msgtype=MSG_TYPE.MSG_TYPE_STRATEGY_RTN_REMOVE
                          )
                self._send_sock.send(m.serialize())
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_REMOVE_DUPLICATE):
            self.remove_strategy(event.data, True)
        elif (msgtype == MSG_TYPE.MSG_TYPE_STRATEGY_GET_DATA):
            # print('begin get data')
            if event.data:
                strategy = self.strategies.get(event.data, None)
                if strategy:
                    self.put_strategy_event(strategy)
            else:  # get all strategy data
                for strategy in self.strategies.values():
                    self.put_strategy_event(strategy)

    def call_strategy_func(
        self, strategy: StrategyBase, func: Callable, params: Any = None
    ):
        """
        Call function of a strategy and catch any exception raised.
        """
        try:
            if params:
                func(params)
            else:
                func()
        except Exception:
            strategy.trading = False
            strategy.inited = False

            msg = f"触发异常已停止\n{traceback.format_exc()}"
            self.write_log(msg, strategy)
# strategy manage

    def add_strategy(
        self, class_name: str, strategy_name: str, full_symbol: str, setting: dict
    ):
        """
        Add a new strategy.
        """
        print("begin add strategy")
        if strategy_name in self.strategies:
            self.write_log(f"创建策略失败,存在重名{strategy_name}")
            return
        if class_name not in self.classes:
            self.write_log(
                f'strategy class[{class_name}] not exist, please check')
            return
        strategy_class = self.classes[class_name]

        strategy = strategy_class(self, strategy_name, full_symbol, setting)
        self.strategies[strategy_name] = strategy

        # Add full_symbol to strategy map.
        strategies = self.symbol_strategy_map[full_symbol]
        strategies.append(strategy)
        # print("335 add strategy")
        # Update to setting file.
        self.update_strategy_setting(strategy_name, setting)

        self.put_strategy_event(strategy)
        print("end add strategy")

    def init_strategy(self, strategy_name: str):
        """
        Init a strategy.
        """
        self.init_queue.put(strategy_name)

        if not self.init_thread:
            self.init_thread = Thread(target=self._init_strategy)
            self.init_thread.start()

    def _init_strategy(self):
        """
        Init strategies in queue.
        """
        while not self.init_queue.empty():
            strategy_name = self.init_queue.get()
            strategy = self.strategies[strategy_name]

            if strategy.inited:
                self.write_log(f"{strategy_name}已经完成初始化,禁止重复操作")
                continue

            self.write_log(f"{strategy_name}开始执行初始化")

            # Call on_init function of strategy
            self.call_strategy_func(strategy, strategy.on_init)

            # Restore strategy data(variables)
            data = self.strategy_data.get(strategy_name, None)
            if data:
                for name in strategy.variables:
                    value = data.get(name, None)
                    if value:
                        setattr(strategy, name, value)

            # Subscribe market data
            contract = self.get_contract(strategy.full_symbol)
            if contract:
                m = Event(type=EventType.SUBSCRIBE,
                          msgtype=MSG_TYPE.MSG_TYPE_SUBSCRIBE_MARKET_DATA)
                m.destination = "CTP.MD"
                m.source = str(self.id)
                req = SubscribeRequest()
                req.sym_type = SYMBOL_TYPE.CTP
                req.content = contract.symbol
                m.data = req
                self._send_sock.send(m.serialize())
            else:
                self.write_log(f"行情订阅失败,找不到合约{strategy.full_symbol}", strategy)

            # qry pos and acc
            m = Event(type=EventType.QRY, msgtype=MSG_TYPE.MSG_TYPE_QRY_POS)
            m.destination = strategy.api + '.' + strategy.account
            m.source = str(self.id)
            self._send_sock.send(m.serialize())

            m = Event(type=EventType.QRY,
                      msgtype=MSG_TYPE.MSG_TYPE_QRY_ACCOUNT)
            m.destination = strategy.api + '.' + strategy.account
            m.source = str(self.id)
            self._send_sock.send(m.serialize())

            # Put event to update init completed status.
            strategy.inited = True
            self.put_strategy_event(strategy)
            self.write_log(f"{strategy_name}初始化完成")

        self.init_thread = None

    def start_strategy(self, strategy_name: str):
        """
        Start a strategy.
        """
        strategy = self.strategies[strategy_name]
        if not strategy.inited:
            self.write_log(f"策略{strategy.strategy_name}启动失败,请先初始化")
            return

        if strategy.trading:
            self.write_log(f"{strategy_name}已经启动,请勿重复操作")
            return

        # qry pos and acc
        m = Event(type=EventType.QRY, msgtype=MSG_TYPE.MSG_TYPE_QRY_POS)
        m.destination = strategy.api + '.' + strategy.account
        m.source = str(self.id)
        self._send_sock.send(m.serialize())

        m = Event(type=EventType.QRY,
                  msgtype=MSG_TYPE.MSG_TYPE_QRY_ACCOUNT)
        m.destination = strategy.api + '.' + strategy.account
        m.source = str(self.id)
        self._send_sock.send(m.serialize())

        self.call_strategy_func(strategy, strategy.on_start)
        strategy.trading = True

        self.put_strategy_event(strategy)

    def stop_strategy(self, strategy_name: str):
        """
        Stop a strategy.
        """
        strategy = self.strategies[strategy_name]
        if not strategy.trading:
            return

        # Call on_stop function of the strategy
        self.call_strategy_func(strategy, strategy.on_stop)

        # Change trading status of strategy to False
        strategy.trading = False

        # Cancel all orders of the strategy
        self.cancel_all(strategy)

        # Update GUI
        self.put_strategy_event(strategy)

    def reset_strategy(self, strategy_name: str):
        "Reset a strategy"
        strategy = self.strategies[strategy_name]
        if not strategy.inited:
            return
        # stop first
        self.call_strategy_func(strategy, strategy.on_stop)
        strategy.trading = False
        self.cancel_all(strategy)
        # reset
        self.call_strategy_func(strategy, strategy.on_reset)
        strategy.inited = False

        self.put_strategy_event(strategy)

    def edit_strategy(self, strategy_name: str, setting: dict):
        """
        Edit parameters of a strategy.
        """
        strategy = self.strategies[strategy_name]
        strategy.update_setting(setting)

        self.update_strategy_setting(strategy_name, setting)
        self.put_strategy_event(strategy)

    def remove_strategy(self, strategy_name: str, duplicate: bool = False):
        """
        Remove a strategy.
        """
        print("begin remove")
        strategy = self.strategies[strategy_name]
        if strategy.trading:
            self.write_log(f"策略{strategy.strategy_name}移除失败,请先停止")
            return

        # Remove setting
        if not duplicate:
            self.remove_strategy_setting(strategy_name)

        # Remove from symbol strategy map
        strategies = self.symbol_strategy_map[strategy.full_symbol]
        strategies.remove(strategy)

        # Remove from active orderid map
        if strategy_name in self.strategy_orderid_map:
            orderids = self.strategy_orderid_map.pop(strategy_name)

            # Remove vt_orderid strategy map
            for _orderid in orderids:
                if _orderid in self.orderid_strategy_map:
                    self.orderid_strategy_map.pop(_orderid)

        # Remove from strategies
        self.strategies.pop(strategy_name)
        print("end remove")
        return True

    def load_strategy_class(self, reload: bool = False):
        """
        Load strategy class from source code.
        """
        # app_path = Path(__file__).parent.parent
        # path1 = app_path.joinpath("cta_strategy", "strategies")
        # self.load_strategy_class_from_folder(
        #     path1, "vnpy.app.cta_strategy.strategies")

        path2 = Path.cwd().joinpath("mystrategy")
        self.load_strategy_class_from_folder(path2, "", reload)

    def load_strategy_class_from_folder(self, path: Path, module_name: str = "", reload: bool = False):
        """
        Load strategy class from certain folder.
        """
        for dirpath, dirnames, filenames in os.walk(path):
            for filename in filenames:
                if filename.endswith(".py"):
                    strategy_module_name = "mystrategy.".join(
                        [module_name, filename.replace(".py", "")])
                    self.load_strategy_class_from_module(
                        strategy_module_name, reload)

    def load_strategy_class_from_module(self, module_name: str, reload: bool = False):
        """
        Load strategy class from module file.
        """
        try:
            module = importlib.import_module(module_name)
        # if reload delete old attribute
            if reload:
                for attr in dir(module):
                    if attr not in ('__name__', '__file__'):
                        delattr(module, attr)
                importlib.reload(module)
            for name in dir(module):
                value = getattr(module, name)
                if (isinstance(value, type) and issubclass(value, CtaTemplate) and value is not CtaTemplate):
                    self.classes[value.__name__] = value
        except:  # noqa
            msg = f"策略文件{module_name}加载失败,触发异常:\n{traceback.format_exc()}"
            self.write_log(msg)

    def load_strategy_data(self):
        """
        Load strategy data from json file.
        """
        self.strategy_data = load_json(self.data_filename)

    def sync_strategy_data(self, strategy: StrategyBase):
        """
        Sync strategy data into json file.
        """
        data = strategy.get_variables()
        # Strategy status (inited, trading) should not be synced.
        data.pop("inited")
        data.pop("trading")

        self.strategy_data = load_json(self.data_filename)

        self.strategy_data[strategy.strategy_name] = data
        save_json(self.data_filename, self.strategy_data)

    def get_all_strategy_class_names(self):
        """
        Return names of strategy classes loaded.
        """
        return list(self.classes.keys())

    def get_strategy_class_parameters(self, class_name: str):
        """
        Get default parameters of a strategy class.
        """
        strategy_class = self.classes[class_name]

        parameters = {}
        for name in strategy_class.parameters:
            parameters[name] = getattr(strategy_class, name)

        return parameters

    def get_strategy_parameters(self, strategy_name):
        """
        Get parameters of a strategy.
        """
        strategy = self.strategies[strategy_name]
        return strategy.get_parameters()

    def init_all_strategies(self):
        """
        """
        for strategy_name in self.strategies.keys():
            self.init_strategy(strategy_name)

    def start_all_strategies(self):
        """
        """
        for strategy_name in self.strategies.keys():
            self.start_strategy(strategy_name)

    def stop_all_strategies(self):
        """
        """
        for strategy_name in self.strategies.keys():
            self.stop_strategy(strategy_name)

    def reset_all_strategies(self):
        for strategy_name in self.strategies.keys():
            self.reset_strategy(strategy_name)

    def load_strategy_setting(self):
        """
        Load setting file.
        """
        self.strategy_setting = load_json(self.setting_filename)

        for strategy_name, strategy_config in self.strategy_setting.items():
            self.add_strategy(
                strategy_config["class_name"],
                strategy_name,
                strategy_config["full_symbol"],
                strategy_config["setting"]
            )

    def update_strategy_setting(self, strategy_name: str, setting: dict):
        """
        Update setting file.
        """
        strategy = self.strategies[strategy_name]
        # in order to save other engine's setting, should load again
        self.strategy_setting = load_json(self.setting_filename)
        self.strategy_setting[strategy_name] = {
            "class_name": strategy.__class__.__name__,
            "full_symbol": strategy.full_symbol,
            "setting": setting,
        }

        save_json(self.setting_filename, self.strategy_setting)

    def remove_strategy_setting(self, strategy_name: str):
        """
        Update setting file.
        """
        if strategy_name not in self.strategy_setting:
            return
        # in order to save other engine's setting, should load again
        self.strategy_setting = load_json(self.setting_filename)
        self.strategy_setting.pop(strategy_name)
        save_json(self.setting_filename, self.strategy_setting)

    # def put_stop_order_event(self, stop_order: StopOrder):
    #     """
    #     Put an event to update stop order status.
    #     """
    #     event = Event(EVENT_CTA_STOPORDER, stop_order)
    #     self.event_engine.put(event)

    def put_strategy_event(self, strategy: StrategyBase):
        """
        Put an event to update strategy status.
        """
        data = strategy.get_data()
        sdata = {}
        sdata[strategy.strategy_name] = data
        # event = Event(EVENT_CTA_STRATEGY, data)
        # self.event_engine.put(event)
        msg = json.dumps(sdata)
        m = Event(type=EventType.STRATEGY_CONTROL, data=msg, des='@0', src=str(
            self.id), msgtype=MSG_TYPE.MSG_TYPE_STRATEGY_RTN_DATA)

        self._send_sock.send(m.serialize())

        #save_json(self.data_filename, sdata)

# strategy functions
  #get ,qry
    def query_bar_from_rq(
        self, symbol: str, exchange: Exchange, interval: Interval, start: datetime, end: datetime
    ):
        """
        Query bar data from RQData.
        """
        data = rqdata_client.query_bar(
            symbol, exchange, interval, start, end
        )
        return data

    def load_bar(
        self,
        full_symbol: str,
        days: int,
        interval: Interval,
        callback: Callable[[BarData], None],
        datasource: str = 'DataBase'
    ):
        """"""

        tradedays = abs(days)
        weekday = datetime.now().weekday()
        adddays = 2 if (days - weekday > 0) else 0
        if weekday == 6:
            tradedays = days + 1
        else:
            tradedays = days + adddays

        symbol, exchange = extract_full_symbol(full_symbol)
        end = datetime.now()
        start = end - timedelta(days=tradedays)
        # Query bars from RQData by default, if not found, load from database.
        bars = self.query_bar_from_rq(symbol, exchange, interval, start, end)
        if not bars:
            bars = database_manager.load_bar_data(
                symbol=symbol,
                exchange=exchange,
                interval=interval,
                start=start,
                end=end,
            )

        for bar in bars:
            callback(bar)

    def load_tick(self, full_symbol: str, days: int, callback: Callable, datasource: str = 'DataBase'):
        tradedays = abs(days)
        weekday = datetime.now().weekday()
        adddays = 2 if (days - weekday > 0) else 0
        if weekday == 6:
            tradedays = days + 1
        else:
            tradedays = days + adddays

        symbol, exchange = extract_full_symbol(full_symbol)
        end = datetime.now()
        start = end - timedelta(tradedays)

        ticks = database_manager.load_tick_data(symbol, exchange, start, end)

        for tick in ticks:
            callback(tick)

    def get_tick(self, full_symbol):
        """
        Get latest market tick data by full_symbol.
        """
        return self.ticks.get(full_symbol, None)

    def get_order(self, orderid: int):
        """
        Get latest order data by orderid.
        """
        return self.orders.get(orderid, None)

    def get_trade(self, vt_tradeid):
        """
        Get trade data by vt_tradeid.
        """
        return self.trades.get(vt_tradeid, None)

    def get_position(self, key):
        """
        Get latest position data by vt_positionid.
        """
        return self.positions.get(key, None)

    def get_account(self, accountid):
        """
        Get latest account data by accountid.
        """
        return self.accounts.get(accountid, None)

    def get_contract(self, full_symbol):
        """
        Get contract data by full_symbol.
        """
        return self.contracts.get(full_symbol, None)

    def get_all_ticks(self):
        """
        Get all tick data.
        """
        return list(self.ticks.values())

    def get_all_orders(self):
        """
        Get all order data.
        """
        return list(self.orders.values())

    def get_all_trades(self):
        """
        Get all trade data.
        """
        return list(self.trades.values())

    def get_all_positions(self):
        """
        Get all position data.
        """
        return list(self.positions.values())

    def get_all_accounts(self):
        """
        Get all account data.
        """
        return list(self.accounts.values())

    def get_all_contracts(self):
        """
        Get all contract data.
        """
        return list(self.contracts.values())

    def get_all_active_orders(self, full_symbol: str = ""):
        """
        Get all active orders by full_symbol.

        If full_symbol is empty, return all active orders.
        """
        if not full_symbol:
            return list(self.active_orders.values())
        else:
            active_orders = [
                order
                for order in self.active_orders.values()
                if order.full_symbol == full_symbol
            ]
            return active_orders

    def get_position_holding(self, acc: str, full_symbol: str):
        return self.offset_converter.get_position_holding(acc, full_symbol)

    def get_strategy_active_orderids(self, strategy_name: str):
        oidset = self.strategy_orderid_map[strategy_name]
        return oidset

  #order, cancel

    def send_order(
        self,
        strategy: StrategyBase,
        original_req: OrderRequest,
        lock: bool = False
    ):
        """
        Send a new order to server.
        """
        # Convert with offset converter
        req_list = self.offset_converter.convert_order_request(
            original_req, lock)

        # Send Orders
        orderids = []

        for req in req_list:
            req.clientID = self.id
            req.client_order_id = self.ordercount
            self.ordercount += 1
            m = Event(type=EventType.ORDER,
                      data=req,
                      des=req.api + '.' + req.account,
                      src=str(self.id)
                      )
            if req.api == "CTP.TD":
                m.msg_type = MSG_TYPE.MSG_TYPE_ORDER_CTP
            elif req.api == "PAPER.TD":
                m.msg_type = MSG_TYPE.MSG_TYPE_ORDER_PAPER
            else:
                print("error:api not support!")
                return []
            msg = m.serialize()
            print(f'tradeclient {self.id} send msg: {msg}')
            self._send_sock.send(msg)
            orderids.append(req.client_order_id)
            self.offset_converter.update_order_request(req)
            # Save relationship between orderid and strategy.
            self.orderid_strategy_map[req.client_order_id] = strategy
            self.strategy_orderid_map[strategy.strategy_name].add(
                req.client_order_id)

        return orderids

    def cancel_order(self, strategy: StrategyBase, orderid: int):
        """
        Cancel existing order by orderid.
        """
        order = self.get_order(orderid)
        if not order:
            self.write_log(f"撤单失败,找不到委托{orderid}", strategy)
            return

        req = order.create_cancel_request()
        m = Event(type=EventType.CANCEL,
                  data=req,
                  des=order.api + '.' + order.account,
                  src=str(self.id),
                  msgtype=MSG_TYPE.MSG_TYPE_ORDER_ACTION
                  )
        msg = m.serialize()
        print(f'tradeclient {self.id} send msg: {msg}')
        self._send_sock.send(msg)

    def cancel_all(self, strategy: StrategyBase):
        """
        Cancel all active orders of a strategy.
        """
        orderids = self.strategy_orderid_map[strategy.strategy_name]
        if not orderids:
            print(strategy.strategy_name, 'has no active order')
            return

        for orderid in copy(orderids):
            print('cancel oid:', orderid)
            self.cancel_order(strategy, orderid)

    def send_testmsg(self):
        m = Event(des='CTP.MD', src=str(self.id),
                  msgtype=MSG_TYPE.MSG_TYPE_TEST)
        msg = m.serialize()
        self._send_sock.send(msg)
        print(f'tradeclient {self.id} send msg: {msg}')

# start and stop
    def start(self, timer=True):
        """
        start the dispatcher thread and begin to recv msg through nng
        """
        self.event_engine.start()
        print('tradeclient started ,pid = %d ' % os.getpid())
        self.__active = True
        while self.__active:
            try:
                msgin = self._recv_sock.recv(flags=0)
                msgin = msgin.decode("utf-8")
                if msgin is not None and msgin.index('|') > 0:
                    if msgin[0] == '@':
                        print('tradeclient(pid = %d) rec @ msg:' %
                              (self.id), msgin, 'at ', datetime.now())
                    if msgin[-1] == '\0':
                        msgin = msgin[:-1]
                    if msgin[-1] == '\x00':
                        msgin = msgin[:-1]
                    m = Event()
                    m.deserialize(msgin)
                    self.event_engine.put(m)
            except Exception as e:
                pass
                #print("TradeEngineError {0}".format(str(e.args[0])).encode("utf-8"))

    def stop(self):
        """
        stop 
        """
        self.__active = False
        self.event_engine.stop()

    def put(self, event):
        """
        send event msg,TODO:check the event
        """
        #
        self._send_sock.send(event.serialize(), flags=1)

    def register_handler(self, type_, handler):
        """
        register handler/subscriber
        """
        # self.event_engine.register(type_,handler)
        # handlerList = self._handlers[type_]

        # if handler not in handlerList:
        #     self._handlers[type_].append(handler)
        #     #handlerList.append(handler)
        pass

    def unregister_handler(self, type_, handler):
        """
        unregister handler/subscriber
        """
        # handlerList = self._handlers[type_]

        # if handler in handlerList:
        #     self._handlers.remove(handler)

        # if not handlerList:
        #     del self._handlers[type_]
        pass

    def write_log(self, msg: str, strategy: StrategyBase = None):
        """
        Create engine log event.
        """
        # if strategy:
        #     msg = f"{strategy.strategy_name}: {msg}"

        # log = LogData(msg=msg, gateway_name="CtaStrategy")
        # event = Event(type=EVENT_CTA_LOG, data=log)
        # self.event_engine.put(event)
        print(msg)
Exemple #39
0
    def run(self, stopflag, q):
        # signal.signal(signal.SIGINT, signal.SIG_IGN)
        qO, qN, qD = q
        print('tcp://*:' + self.port)
        s1 = Socket(REP)
        # s1.recv_buffer_size=1024*1024
        # s1.reconnect_interval_max=1000
        s1.bind('tcp://*:' + self.port)
        pb_n = args_pb2.p_n()
        s_n = self.s_n
        ps_n = s_n * (s_n + 1)
        pb_n.s_n = s_n
        # print("nanoMesg up")
        time.sleep(0.5)
        running = True
        pb_sid = args_pb2.p_sid()
        pb_sid.sid = 0
        clients = dict()
        sys_platform = sys.platform
        while (running):
            # print("loop start")
            if stopflag.value > len(clients.keys()):
                running = False
                break
            if sys_platform == 'win32':
                try:
                    recvstr = s1.recv()
                except KeyboardInterrupt:
                    if len(clients.keys()) <= 0:
                        running = False
                    elif stopflag.value >= 0:
                        print("stopflag.value: ", stopflag.value)
                        with stopflag.get_lock():
                            stopflag.value += 1
                        continue
                        # os.kill(self.ppid, signal.CTRL_C_EVENT)
            else:
                recvstr = s1.recv()
            # recvstr=s1.recv()
            # print(ord('c'),ord('p'),ord('r'),ord('k'),"recvstr[0]: ",recvstr[0])
            if recvstr[0] == ord('c'):
                pb_cap = args_pb2.p_cap()
                pb_cap.ParseFromString(recvstr[1:])
                # print("pb_cap.idx",pb_cap.idx)
                s1.send(pb_n.SerializeToString())
            elif recvstr[0] == ord('p'):
                pb_gpuid = args_pb2.p_str()
                pb_gpuid.ParseFromString(recvstr[1:])
                # TODO 解析  p_str get ohist
                if pb_gpuid.histNum > 0:
                    # print(list(pb_gpuid.ohist))
                    qD.put(
                        (pb_gpuid.histNum, self.bestcs, list(pb_gpuid.ohist)))
                pb_ga = args_pb2.p_ga()
                pb_ga.start = 0
                pb_ga.stop = -1
                ii = -1
                ind_ = []
                try:
                    ii, ind_, self.bestcs = qO.get(
                        False
                    )  #TODO change proto to allow ord('p') fail and retry later.
                except queue.Empty:
                    if stopflag.value >= 1:
                        print("stopflag.value: ", stopflag.value)
                        pb_ga.idx = -2
                        stopflag.value += 1
                    else:
                        pb_ga.idx = -1
                    s1.send(pb_ga.SerializeToString())
                    continue
                # ind_=[random.random()]*(s_n*(s_n+1))
                pb_ga.idx = ii
                pb_ga.bestfv = self.bestcs
                for i in range(s_n):
                    pb_ga.params.append(ind_[i])
                for i in range(s_n * s_n - s_n):
                    pb_ga.params.append(ind_[i + s_n])
                for i in range(s_n):
                    pb_ga.params.append(ind_[i + s_n * s_n])
                s1.send(pb_ga.SerializeToString())
                # clients_lastTimeS[pb_ga.idx]=time.perf_counter()
                # print("p: ",clients_lastTimeS[pb_ga.idx])
                if pb_gpuid.str not in clients:
                    clients[pb_gpuid.str] = gpuClient()
                    print(pb_gpuid.str, " connected.")
                else:
                    clients[pb_gpuid.str].updateTimeStamp()
            elif recvstr[0] == ord('r'):
                res = args_pb2.res()
                res.ParseFromString(recvstr[1:])
                # print("res chi2 recv",res.e, " ridx: ",res.ridx)
                if stopflag.value >= 1:
                    pb_sid.sid = -1
                    print("time spend: ", clients.pop(res.idx).runTime)
                    if len(clients.keys()) <= 0:
                        running = False
                    # print("stopflag: ",stopflag.value)
                    # s1.close()
                s1.send(pb_sid.SerializeToString())
                # print("pb_sid send",pb_sid.sid, " ridx: ",res.ridx)
                if res.idx in clients:
                    clients[res.idx].updateRunTime()
                #TODO 解析res get shist
                qN.put((res.ridx, res.e))
                if res.hist:
                    # self.counter=self.counter+1
                    # print(self.counter,self.bestcs)
                    if self.bestcs < 3.2E31:
                        qD.put((-1, self.bestcs, list(res.shist)))

            elif recvstr[0] == ord('k'):
                pidx = args_pb2.p_sid()
                pidx.ParseFromString(recvstr[1:])
                # print("keepalive: ",pidx.sid)
                s1.send('l')
            else:
                print("Err recv: ", recvstr[0])
        s1.close()
        qN.close()
        qD.close()
        qN.join_thread()
        qD.join_thread()
        print("paramsServ done!")
Exemple #40
0
from __future__ import print_function
from nanomsg import Socket, PAIR, PUB
s2 = Socket(PAIR)
s2.connect('ipc:///tmp/wand1.ipc')
while (True):
    print(s2.recv())
s2.close()
Exemple #41
0
class TradeEngine(BaseEngine):
    """
    Send to and receive from msg  server ,used for strategy 
    """
    setting_filename = "cta_strategy_setting.json"
    data_filename = "cta_strategy_data.json"

    def __init__(self,config:dict):
        super(TradeEngine, self).__init__()
        """
        two sockets to send and recv msg
        """
        self.__active = False
        self.id = 0
        self.engine_type = EngineType.LIVE     
        self._recv_sock = Socket(SUB)
        self._send_sock = Socket(PUSH)
        self._config = config
        self._handlers = defaultdict(list)

#  stragegy manage
        self.strategy_setting = {}  # strategy_name: dict
        self.strategy_data = {}     # strategy_name: dict

        self.classes = {}           # class_name: stategy_class
        self.strategies = {}        # strategy_name: strategy

        self.symbol_strategy_map = defaultdict(
            list)                   # vt_symbol: strategy list
        self.orderid_strategy_map = {}  # vt_orderid: strategy
        self.strategy_orderid_map = defaultdict(
            set)                    # strategy_name: orderid list

        self.stop_order_count = 0   # for generating stop_orderid
        self.stop_orders = {}       # stop_orderid: stop_order
        self.init_thread = None
        self.init_queue = Queue()

# order,tick,position ,etc manage
        self.ticks = {}
        self.orders = {}
        self.trades = {}
        self.positions = {}
        self.accounts = {}
        self.contracts = {}

        self.active_orders = {}



        self.rq_client = None
        self.rq_symbols = set()

        self.offset_converter = OffsetConverter(self)

        self.init_engine()


    def init_engine(self):
        self.init_nng()
        self.init_rqdata()
        self.load_strategy_class()
        self.load_strategy_setting()
        self.load_strategy_data()  
        self.register_event()


    def init_rqdata(self):

        result = rqdata_client.init()
        if result:
            self.write_log("RQData数据接口初始化成功")

    def register_event(self):
        """"""
        self.event_engine.register(EventType.TICK, self.process_tick_event)
        self.event_engine.register(EventType.ORDERSTATUS, self.process_order_event)
        self.event_engine.register(EventType.FILL, self.process_trade_event)
        self.event_engine.register(EventType.POSITION, self.process_position_event)
        self.event_engine.register(EventType.ACCOUNT, self.process_account_event)
        self.event_engine.register(EventType.CONTRACT, self.process_contract_event)        


    def process_tick_event(self, event: Event):
        """"""
        tick = event

        strategies = self.symbol_strategy_map[tick.full_symbol]
        if not strategies:
            return
        # self.check_stop_order(tick)
        for strategy in strategies:
            if strategy.inited:
                self.call_strategy_func(strategy, strategy.on_tick, tick)
        self.ticks[tick.full_symbol] = tick

    def process_order_event(self, event: Event):
        """"""
        order = event
        
        self.offset_converter.update_order(order)

        strategy = self.orderid_strategy_map.get(order.vt_orderid, None)
        if not strategy:
            return

        # Remove vt_orderid if order is no longer active.
        vt_orderids = self.strategy_orderid_map[strategy.strategy_name]
        if order.vt_orderid in vt_orderids and not order.is_active():
            vt_orderids.remove(order.vt_orderid)

        # For server stop order, call strategy on_stop_order function
        # if order.type == OrderType.STOP:
        #     so = StopOrder(
        #         vt_symbol=order.vt_symbol,
        #         direction=order.direction,
        #         offset=order.offset,
        #         price=order.price,
        #         volume=order.volume,
        #         stop_orderid=order.vt_orderid,
        #         strategy_name=strategy.strategy_name,
        #         status=STOP_STATUS_MAP[order.status],
        #         vt_orderid=order.vt_orderid,
        #     )
        #     self.call_strategy_func(strategy, strategy.on_stop_order, so)  

        # Call strategy on_order function
        self.call_strategy_func(strategy, strategy.on_order, order)

        
        self.orders[order.vt_orderid] = order

        # If order is active, then update data in dict.
        if order.is_active():
            self.active_orders[order.vt_orderid] = order
        # Otherwise, pop inactive order from in dict
        elif order.vt_orderid in self.active_orders:
            self.active_orders.pop(order.vt_orderid)     

    def process_trade_event(self, event: Event):
        """"""
        trade = event

        self.offset_converter.update_trade(trade)

        strategy = self.orderid_strategy_map.get(trade.vt_orderid, None)
        if not strategy:
            return

        # if trade.direction == Direction.LONG:
        #     strategy.pos += trade.volume
        # else:
        #     strategy.pos -= trade.volume

        self.call_strategy_func(strategy, strategy.on_trade, trade)
        self.put_strategy_event(strategy)

        self.trades[trade.vt_tradeid] = trade


    def process_position_event(self, event: Event):
        """"""
        position = event

        self.offset_converter.update_position(position)

        self.positions[position.vt_positionid] = position

    def process_account_event(self, event: Event):
        """"""
        account = event
        self.accounts[account.vt_accountid] = account

    def process_contract_event(self, event: Event):
        """"""
        contract = event
        self.contracts[contract.vt_symbol] = contract

    def call_strategy_func(
        self, strategy: StrategyBase, func: Callable, params: Any = None
    ):
        """
        Call function of a strategy and catch any exception raised.
        """
        try:
            if params:
                func(params)
            else:
                func()
        except Exception:
            strategy.trading = False
            strategy.inited = False

            msg = f"触发异常已停止\n{traceback.format_exc()}"
            self.write_log(msg, strategy)

    def add_strategy(
        self, class_name: str, strategy_name: str, vt_symbol: str, setting: dict
    ):
        """
        Add a new strategy.
        """
        if strategy_name in self.strategies:
            self.write_log(f"创建策略失败,存在重名{strategy_name}")
            return

        strategy_class = self.classes[class_name]

        strategy = strategy_class(self, strategy_name, vt_symbol, setting)
        self.strategies[strategy_name] = strategy

        # Add vt_symbol to strategy map.
        strategies = self.symbol_strategy_map[vt_symbol]
        strategies.append(strategy)

        # Update to setting file.
        self.update_strategy_setting(strategy_name, setting)

        self.put_strategy_event(strategy)

    def init_strategy(self, strategy_name: str):
        """
        Init a strategy.
        """ 
        self.init_queue.put(strategy_name)

        if not self.init_thread:
            self.init_thread = Thread(target=self._init_strategy)
            self.init_thread.start()

    def _init_strategy(self):
        """
        Init strategies in queue.
        """
        while not self.init_queue.empty():
            strategy_name = self.init_queue.get()
            strategy = self.strategies[strategy_name]

            if strategy.inited:
                self.write_log(f"{strategy_name}已经完成初始化,禁止重复操作")
                continue

            self.write_log(f"{strategy_name}开始执行初始化")

            # Call on_init function of strategy
            self.call_strategy_func(strategy, strategy.on_init)

            # Restore strategy data(variables)
            data = self.strategy_data.get(strategy_name, None)
            if data:
                for name in strategy.variables:
                    value = data.get(name, None)
                    if value:
                        setattr(strategy, name, value)

            # Subscribe market data
            contract = self.get_contract(strategy.vt_symbol)
            if contract:
                req = SubscribeEvent()
                req.destination = contract.gateway_name
                req.source = "0"                
                req.content = strategy.symbol
                self.put(req)
            else:
                self.write_log(f"行情订阅失败,找不到合约{strategy.vt_symbol}", strategy)

            # Put event to update init completed status.
            strategy.inited = True
            self.put_strategy_event(strategy)
            self.write_log(f"{strategy_name}初始化完成")
        
        self.init_thread = None

    def start_strategy(self, strategy_name: str):
        """
        Start a strategy.
        """
        strategy = self.strategies[strategy_name]
        if not strategy.inited:
            self.write_log(f"策略{strategy.strategy_name}启动失败,请先初始化")
            return

        if strategy.trading:
            self.write_log(f"{strategy_name}已经启动,请勿重复操作")
            return

        self.call_strategy_func(strategy, strategy.on_start)
        strategy.trading = True

        self.put_strategy_event(strategy)

    def stop_strategy(self, strategy_name: str):
        """
        Stop a strategy.
        """
        strategy = self.strategies[strategy_name]
        if not strategy.trading:
            return

        # Call on_stop function of the strategy
        self.call_strategy_func(strategy, strategy.on_stop)

        # Change trading status of strategy to False
        strategy.trading = False

        # Cancel all orders of the strategy
        # self.cancel_all(strategy)

        # Update GUI
        self.put_strategy_event(strategy)

    def edit_strategy(self, strategy_name: str, setting: dict):
        """
        Edit parameters of a strategy.
        """
        strategy = self.strategies[strategy_name]
        strategy.update_setting(setting)

        self.update_strategy_setting(strategy_name, setting)
        self.put_strategy_event(strategy)

    def remove_strategy(self, strategy_name: str):
        """
        Remove a strategy.
        """
        strategy = self.strategies[strategy_name]
        if strategy.trading:
            self.write_log(f"策略{strategy.strategy_name}移除失败,请先停止")
            return

        # Remove setting
        self.remove_strategy_setting(strategy_name)

        # Remove from symbol strategy map
        strategies = self.symbol_strategy_map[strategy.vt_symbol]
        strategies.remove(strategy)

        # Remove from active orderid map
        if strategy_name in self.strategy_orderid_map:
            vt_orderids = self.strategy_orderid_map.pop(strategy_name)

            # Remove vt_orderid strategy map
            for vt_orderid in vt_orderids:
                if vt_orderid in self.orderid_strategy_map:
                    self.orderid_strategy_map.pop(vt_orderid)

        # Remove from strategies
        self.strategies.pop(strategy_name)

        return True

    def load_strategy_class(self):
        """
        Load strategy class from source code.
        """
        path1 = Path(__file__).parent.joinpath("")
        self.load_strategy_class_from_folder(
            path1, "mystrategy")

        path2 = Path.cwd().joinpath("")
        self.load_strategy_class_from_folder(path2, "mystrategy")

    def load_strategy_class_from_folder(self, path: Path, module_name: str = ""):
        """
        Load strategy class from certain folder.
        """
        for dirpath, dirnames, filenames in os.walk(str(path)):
            for filename in filenames:
                if filename.endswith(".py"):
                    strategy_module_name = ".".join(
                        [module_name, filename.replace(".py", "")])
                    self.load_strategy_class_from_module(strategy_module_name)

    def load_strategy_class_from_module(self, module_name: str):
        """
        Load strategy class from module file.
        """
        try:
            module = importlib.import_module(module_name)

            for name in dir(module):
                value = getattr(module, name)
                if (isinstance(value, type) and issubclass(value, StrategyBase) and value is not StrategyBase):
                    self.classes[value.__name__] = value
        except:  # noqa
            msg = f"策略文件{module_name}加载失败,触发异常:\n{traceback.format_exc()}"
            self.write_log(msg)

    def load_strategy_data(self):
        """
        Load strategy data from json file.
        """
        self.strategy_data = load_json(self.data_filename)

    def sync_strategy_data(self, strategy: StrategyBase):
        """
        Sync strategy data into json file.
        """
        data = strategy.get_variables()
        data.pop("inited")      # Strategy status (inited, trading) should not be synced.
        data.pop("trading")

        self.strategy_data[strategy.strategy_name] = data
        save_json(self.data_filename, self.strategy_data)

    def get_all_strategy_class_names(self):
        """
        Return names of strategy classes loaded.
        """
        return list(self.classes.keys())

    def get_strategy_class_parameters(self, class_name: str):
        """
        Get default parameters of a strategy class.
        """
        strategy_class = self.classes[class_name]

        parameters = {}
        for name in strategy_class.parameters:
            parameters[name] = getattr(strategy_class, name)

        return parameters

    def get_strategy_parameters(self, strategy_name):
        """
        Get parameters of a strategy.
        """
        strategy = self.strategies[strategy_name]
        return strategy.get_parameters()

    def init_all_strategies(self):
        """
        """
        for strategy_name in self.strategies.keys():
            self.init_strategy(strategy_name)

    def start_all_strategies(self):
        """
        """
        for strategy_name in self.strategies.keys():
            self.start_strategy(strategy_name)

    def stop_all_strategies(self):
        """
        """
        for strategy_name in self.strategies.keys():
            self.stop_strategy(strategy_name)

    def load_strategy_setting(self):
        """
        Load setting file.
        """
        self.strategy_setting = load_json(self.setting_filename)

        for strategy_name, strategy_config in self.strategy_setting.items():
            self.add_strategy(
                strategy_config["class_name"], 
                strategy_name,
                strategy_config["vt_symbol"], 
                strategy_config["setting"]
            )

    def update_strategy_setting(self, strategy_name: str, setting: dict):
        """
        Update setting file.
        """
        strategy = self.strategies[strategy_name]

        self.strategy_setting[strategy_name] = {
            "class_name": strategy.__class__.__name__,
            "vt_symbol": strategy.vt_symbol,
            "setting": setting,
        }
        save_json(self.setting_filename, self.strategy_setting)

    def remove_strategy_setting(self, strategy_name: str):
        """
        Update setting file.
        """
        if strategy_name not in self.strategy_setting:
            return

        self.strategy_setting.pop(strategy_name)
        save_json(self.setting_filename, self.strategy_setting)

    # def put_stop_order_event(self, stop_order: StopOrder):
    #     """
    #     Put an event to update stop order status.
    #     """
    #     event = Event(EVENT_CTA_STOPORDER, stop_order)
    #     self.event_engine.put(event)

    def put_strategy_event(self, strategy: StrategyBase):
        """
        Put an event to update strategy status.
        """
        data = strategy.get_data()
        # event = Event(EVENT_CTA_STRATEGY, data)
        # self.event_engine.put(event)
        pass






    def init_nng(self):
        self._recv_sock.set_string_option(SUB, SUB_SUBSCRIBE, '')  # receive msg start with all
        self._recv_sock.set_int_option(SOL_SOCKET,RCVTIMEO,100)
        self._recv_sock.connect(self._config['serverpub_url'])
        self._send_sock.connect(self._config['serverpull_url'])
    #------------------------------------ public functions -----------------------------#
    
    def query_bar_from_rq(
        self, symbol: str, exchange: Exchange, interval: Interval, start: datetime, end: datetime
    ):
        """
        Query bar data from RQData.
        """
        data = rqdata_client.query_bar(
            symbol, exchange, interval, start, end
        )
        return data   
    
    
    def load_bar(
        self, 
        vt_symbol: str, 
        days: int, 
        interval: Interval,
        callback: Callable[[BarData], None]
    ):
        """"""
        symbol, exchange = extract_vt_symbol(vt_symbol)
        end = datetime.now()
        start = end - timedelta(days)

        # Query bars from RQData by default, if not found, load from database.
        bars = self.query_bar_from_rq(symbol, exchange, interval, start, end)
        if not bars:
            bars = database_manager.load_bar_data(
                symbol=symbol,
                exchange=exchange,
                interval=interval,
                start=start,
                end=end,
            )

        for bar in bars:
            callback(bar)
    
    
    
    def get_tick(self, vt_symbol):
        """
        Get latest market tick data by vt_symbol.
        """
        return self.ticks.get(vt_symbol, None)

    def get_order(self, vt_orderid):
        """
        Get latest order data by vt_orderid.
        """
        return self.orders.get(vt_orderid, None)

    def get_trade(self, vt_tradeid):
        """
        Get trade data by vt_tradeid.
        """
        return self.trades.get(vt_tradeid, None)

    def get_position(self, vt_positionid):
        """
        Get latest position data by vt_positionid.
        """
        return self.positions.get(vt_positionid, None)

    def get_account(self, vt_accountid):
        """
        Get latest account data by vt_accountid.
        """
        return self.accounts.get(vt_accountid, None)

    def get_contract(self, vt_symbol):
        """
        Get contract data by vt_symbol.
        """
        return self.contracts.get(vt_symbol, None)

    def get_all_ticks(self):
        """
        Get all tick data.
        """
        return list(self.ticks.values())

    def get_all_orders(self):
        """
        Get all order data.
        """
        return list(self.orders.values())

    def get_all_trades(self):
        """
        Get all trade data.
        """
        return list(self.trades.values())

    def get_all_positions(self):
        """
        Get all position data.
        """
        return list(self.positions.values())

    def get_all_accounts(self):
        """
        Get all account data.
        """
        return list(self.accounts.values())

    def get_all_contracts(self):
        """
        Get all contract data.
        """
        return list(self.contracts.values())

    def get_all_active_orders(self, vt_symbol: str = ""):
        """
        Get all active orders by vt_symbol.

        If vt_symbol is empty, return all active orders.
        """
        if not vt_symbol:
            return list(self.active_orders.values())
        else:
            active_orders = [
                order
                for order in self.active_orders.values()
                if order.vt_symbol == vt_symbol
            ]
            return active_orders    
    


    
    
    def start(self, timer=True):
        """
        start the dispatcher thread and begin to recv msg through nng
        """
        self.event_engine.start()
        print('tradeclient started ,pid = %d ' % os.getpid())
        self.__active = True
        # print(self._config['serverpub_url'])
        while self.__active:
            try:
                msgin = self._recv_sock.recv(flags=0)
                msgin = msgin.decode("utf-8")
                if msgin is not None and msgin.index('|') > 0:
                    print('tradeclient(id = %d) rec server msg:'%(self.id), msgin,'at ', datetime.now())
                    if msgin[-1] == '\0':
                        msgin = msgin[:-1]
                    if msgin[-1] == '\x00':
                        msgin = msgin[:-1]
                    v = msgin.split('|')
                    msg2type = MSG_TYPE(int(v[2]))
                    if msg2type == MSG_TYPE.MSG_TYPE_TICK_L1:
                        m = TickEvent()
                        m.deserialize(msgin)
                    elif msg2type == MSG_TYPE.MSG_TYPE_RTN_ORDER:
                       m = OrderStatusEvent()
                       m.deserialize(msgin)
                    elif msg2type == MSG_TYPE.MSG_TYPE_RTN_TRADE:
                        m = FillEvent()
                        m.deserialize(msgin)
                    elif msg2type == MSG_TYPE.MSG_TYPE_RSP_POS:
                        m = PositionEvent()
                        m.deserialize(msgin)
                    elif msg2type == MSG_TYPE.MSG_TYPE_Hist:
                        m = HistoricalEvent()
                        m.deserialize(msgin)
                    elif msg2type == MSG_TYPE.MSG_TYPE_RSP_ACCOUNT:
                        m = AccountEvent()
                        m.deserialize(msgin)
                    elif msg2type == MSG_TYPE.MSG_TYPE_RSP_CONTRACT:
                        m = ContractEvent()
                        m.deserialize(msgin)
                    elif msg2type == MSG_TYPE.MSG_TYPE_INFO:
                        m = InfoEvent()
                        m.deserialize(msgin)
                    else:
                        m = GeneralReqEvent() 
                        m.deserialize(msgin)
                        pass
                    self.event_engine.put(m)
                    # if m.event_type in self._handlers:
                    #     [handler(m) for handler in self._handlers[m.event_type]]
            except Exception as e:
                pass
                #print("TradeEngineError {0}".format(str(e.args[0])).encode("utf-8"))
 
    def stop(self):
        """
        stop 
        """
        self.__active = False
        self.event_engine.stop()

    def put(self, event):
        """
        send event msg,TODO:check the event
        """
        # 
        self._send_sock.send(event.serialize(),flags=1)

    def register_handler(self, type_, handler):
        """
        register handler/subscriber
        """
        # handlerList = self._handlers[type_]

        # if handler not in handlerList:
        #     self._handlers[type_].append(handler)
        #     #handlerList.append(handler)
        pass

    def unregister_handler(self, type_, handler):
        """
        unregister handler/subscriber
        """
        # handlerList = self._handlers[type_]

        # if handler in handlerList:
        #     self._handlers.remove(handler)

        # if not handlerList:
        #     del self._handlers[type_]
        pass

    def write_log(self, msg: str, strategy: StrategyBase = None):
        """
        Create engine log event.
        """
        # if strategy:
        #     msg = f"{strategy.strategy_name}: {msg}"

        # log = LogData(msg=msg, gateway_name="CtaStrategy")
        # event = Event(type=EVENT_CTA_LOG, data=log)
        # self.event_engine.put(event)  
        print(msg)      

    # -------------------------------- end of public functions -----------------------------#
class RecorderEngine(BaseEngine):
    """
    market data recorder 
    """
    config_filename = "config_server.yaml"
    setting_filename = "data_recorder_setting.json"

    # init
    def __init__(self, configfile: str = '', gateway: str = "CTP.MD"):
        super(RecorderEngine, self).__init__(event_engine=EventEngine(10))
        """
        two sockets to send and recv msg
        """
        self.__active = False
        self._thread = Thread(target=self._run)
        self.id = os.getpid()
        self.engine_type = EngineType.LIVE
        self._recv_sock = Socket(SUB)
        self._send_sock = Socket(PUSH)

        if configfile:
            self.config_filename = configfile
        if gateway:
            self.gateway = gateway
        filepath = Path.cwd().joinpath("etc/" + self.config_filename)
        with open(filepath, encoding='utf8') as fd:
            self._config = yaml.load(fd)

        self.tick_recordings = {}
        self.bar_recordings = {}
        self.bar_generators = {}
        self.contracts = {}
        self.subscribed = False
        self.dayswitched = False
        self.init_engine()

# init functions

    def init_engine(self):
        self.init_nng()
        self.load_contract()
        self.load_setting()
        self.register_event()
        self.put_event()

    def init_nng(self):
        self._recv_sock.set_string_option(SUB, SUB_SUBSCRIBE,
                                          '')  # receive msg start with all
        self._recv_sock.set_int_option(SOL_SOCKET, RCVTIMEO, 100)
        self._recv_sock.connect(self._config['serverpub_url'])
        self._send_sock.connect(self._config['serverpull_url'])

    def load_contract(self):
        contractfile = Path.cwd().joinpath("etc/ctpcontract.yaml")
        with open(contractfile, encoding='utf8') as fc:
            contracts = yaml.load(fc)
        print('loading contracts, total number:', len(contracts))
        for sym, data in contracts.items():
            contract = ContractData(
                symbol=data["symbol"],
                exchange=Exchange(data["exchange"]),
                name=data["name"],
                product=PRODUCT_CTP2VT[str(data["product"])],
                size=data["size"],
                pricetick=data["pricetick"],
                net_position=True
                if str(data["positiontype"]) == THOST_FTDC_PT_Net else False,
                long_margin_ratio=data["long_margin_ratio"],
                short_margin_ratio=data["short_margin_ratio"],
                full_symbol=data["full_symbol"])
            # For option only
            if contract.product == Product.OPTION:
                contract.option_underlying = data["option_underlying"],
                contract.option_type = OPTIONTYPE_CTP2VT.get(
                    str(data["option_type"]), None),
                contract.option_strike = data["option_strike"],
                contract.option_expiry = datetime.strptime(
                    str(data["option_expiry"]), "%Y%m%d"),
            self.contracts[contract.full_symbol] = contract

    def load_setting(self):
        """"""
        setting = load_json(self.setting_filename)
        self.tick_recordings = setting.get("tick", {})
        self.bar_recordings = setting.get("bar", {})

    def save_setting(self):
        """"""
        setting = {"tick": self.tick_recordings, "bar": self.bar_recordings}
        save_json(self.setting_filename, setting)

    def register_event(self):
        """"""
        self.event_engine.register(EventType.TICK, self.process_tick_event)
        self.event_engine.register(EventType.CONTRACT,
                                   self.process_contract_event)
        self.event_engine.register(EventType.RECORDER_CONTROL,
                                   self.process_recordercontrol_event)
        self.event_engine.register(EventType.HEADER,
                                   self.process_general_event)
        self.event_engine.register(EventType.TIMER, self.process_timer_event)

    def init_subcribe(self, src: str = 'CTP.MD'):
        symset = set(self.tick_recordings.keys())
        symset.update(self.bar_recordings.keys())
        for sym in symset:
            self.subscribe(sym, src)
        self.subscribed = True

# event handler

    def process_timer_event(self, event):
        # auto subscribe at 8:55, 20:55
        nowtime = datetime.now().time()
        if (nowtime > time(hour=8, minute=50)) and (nowtime < time(
                hour=8, minute=51)) and (not self.subscribed):
            self.init_subcribe()
            self.dayswitched = False
        if (nowtime > time(hour=20, minute=50)) and (nowtime < time(
                hour=20, minute=51)) and (not self.subscribed):
            self.init_subcribe()
            self.dayswitched = False
        # reset at 16:00 and 3:00
        if (nowtime > time(hour=16, minute=0)) and (nowtime < time(
                hour=16, minute=1)) and (not self.dayswitched):
            self.subscribed = False
            self.dayswitched = True
        if (nowtime > time(hour=3, minute=0)) and (nowtime < time(
                hour=3, minute=1)) and (not self.dayswitched):
            self.subscribed = False
            self.dayswitched = True

    def process_general_event(self, event):
        pass

    def process_tick_event(self, event: Event):
        """"""
        tick = event.data
        dayclosetime = tick.datetime.time() < time(
            hour=9, minute=0) and tick.datetime.time() > time(hour=8, minute=0)
        nightclosetime = tick.datetime.time() < time(
            hour=21, minute=0) and tick.datetime.time() > time(hour=16,
                                                               minute=0)
        if dayclosetime or nightclosetime:
            return
        # exclude onrtnsubscribe return first tick which time not in trade time
        if (tick.open_price) and tick.last_price and tick.ask_price_1:
            if tick.full_symbol in self.tick_recordings:
                self.record_tick(tick)

            if tick.full_symbol in self.bar_recordings:
                bg = self.get_bar_generator(tick.full_symbol)
                bg.update_tick(tick)

    def process_contract_event(self, event: Event):
        """"""
        contract = event.data
        self.contracts[contract.full_symbol] = contract

    def process_recordercontrol_event(self, event: Event):
        msgtype = event.msg_type
        deslist = ['@*', str(self.id), '@' + str(self.id)]
        if (event.destination not in deslist):
            return
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_STATUS):
            m = Event(type=EventType.RECORDER_CONTROL,
                      des='@0',
                      src=str(self.id),
                      data=str(self.__active),
                      msgtype=MSG_TYPE.MSG_TYPE_RECORDER_STATUS)
            self._send_sock.send(m.serialize())
            self.put_event()
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_ADD_TICK):
            full_symbol = event.data
            self.add_tick_recording(full_symbol, event.source)
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_ADD_BAR):
            full_symbol = event.data
            self.add_bar_recording(full_symbol, event.source)
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_REMOVE_TICK):
            full_symbol = event.data
            self.remove_tick_recording(full_symbol)
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_REMOVE_BAR):
            full_symbol = event.data
            self.remove_bar_recording(full_symbol)
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_START):
            self.init_subcribe()
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_STOP):
            self.clear()
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_RELOAD):
            pass
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_RESET):
            pass
        elif (msgtype == MSG_TYPE.MSG_TYPE_RECORDER_GET_DATA):
            self.put_event()

    def put_event(self):
        """"""
        tick_symbols = list(self.tick_recordings.keys())
        tick_symbols.sort()

        bar_symbols = list(self.bar_recordings.keys())
        bar_symbols.sort()
        data = {"tick": tick_symbols, "bar": bar_symbols}
        msg = json.dumps(data)
        m = Event(type=EventType.RECORDER_CONTROL,
                  data=msg,
                  des='@0',
                  src=str(self.id),
                  msgtype=MSG_TYPE.MSG_TYPE_RECORDER_RTN_DATA)
        self._send_sock.send(m.serialize())

    def add_bar_recording(self, full_symbol: str, src: str = 'CTP.MD'):
        """"""
        if full_symbol in self.bar_recordings:
            self.write_log(f"已在K线记录列表中:{full_symbol}")
            return

        contract = self.contracts.get(full_symbol, None)
        if not contract:
            self.write_log(f"找不到合约:{full_symbol}")
            return

        self.bar_recordings[full_symbol] = {
            "symbol": contract.symbol,
            "exchange": contract.exchange.value,
            "gateway_name": self.gateway
        }

        self.subscribe(full_symbol, src)
        self.save_setting()
        self.put_event()

        self.write_log(f"添加K线记录成功:{full_symbol}")

    def add_tick_recording(self, full_symbol: str, src: str = 'CTP.MD'):
        """"""
        if full_symbol in self.tick_recordings:
            self.write_log(f"已在Tick记录列表中:{full_symbol}")
            return

        contract = self.contracts.get(full_symbol, None)
        if not contract:
            self.write_log(f"找不到合约:{full_symbol}")
            return

        self.tick_recordings[full_symbol] = {
            "symbol": contract.symbol,
            "exchange": contract.exchange.value,
            "gateway_name": self.gateway
        }

        self.subscribe(full_symbol, src)
        self.save_setting()
        self.put_event()

        self.write_log(f"添加Tick记录成功:{full_symbol}")

    def remove_bar_recording(self, full_symbol: str):
        """"""
        if full_symbol not in self.bar_recordings:
            self.write_log(f"不在K线记录列表中:{full_symbol}")
            return

        self.bar_recordings.pop(full_symbol)
        self.save_setting()
        self.put_event()

        self.write_log(f"移除K线记录成功:{full_symbol}")

    def remove_tick_recording(self, full_symbol: str):
        """"""
        if full_symbol not in self.tick_recordings:
            self.write_log(f"不在Tick记录列表中:{full_symbol}")
            return

        self.tick_recordings.pop(full_symbol)
        self.save_setting()
        self.put_event()

        self.write_log(f"移除Tick记录成功:{full_symbol}")

    def record_tick(self, tick: TickData):
        """"""
        database_manager.save_tick_data([tick])

    def record_bar(self, bar: BarData):
        """"""
        database_manager.save_bar_data([bar])

    def get_bar_generator(self, full_symbol: str):
        """"""
        bg = self.bar_generators.get(full_symbol, None)

        if not bg:
            bg = BarGenerator(self.record_bar)
            self.bar_generators[full_symbol] = bg

        return bg

    def subscribe(self, full_symbol: str, src: str = 'CTP.MD'):
        contract = self.contracts.get(full_symbol, None)
        if contract:
            m = Event(type=EventType.SUBSCRIBE,
                      msgtype=MSG_TYPE.MSG_TYPE_SUBSCRIBE_MARKET_DATA)
            m.destination = src
            m.source = str(self.id)
            req = SubscribeRequest()
            if src == 'CTP.MD':
                req.sym_type = SYMBOL_TYPE.CTP
                req.content = contract.symbol
            else:
                req.sym_type = SYMBOL_TYPE.FULL
                req.content = full_symbol
            m.data = req
            self._send_sock.send(m.serialize())
        else:
            self.write_log(f"行情订阅失败,找不到合约{full_symbol}")

    def clear(self):
        self.bar_recordings.clear()
        self.tick_recordings.clear()
        self.save_setting()
        self.put_event()

    def _run(self):
        while self.__active:
            try:
                msgin = self._recv_sock.recv(flags=0)
                msgin = msgin.decode("utf-8")
                if msgin is not None and msgin.index('|') > 0:
                    if msgin[0] == '@':
                        print('recorder(pid = %d) rec @ msg:' % (self.id),
                              msgin, 'at ', datetime.now())
                    if msgin[-1] == '\0':
                        msgin = msgin[:-1]
                    if msgin[-1] == '\x00':
                        msgin = msgin[:-1]
                    m = Event()
                    m.deserialize(msgin)
                    self.event_engine.put(m)
            except Exception as e:
                pass
                #print("TradeEngineError {0}".format(str(e.args[0])).encode("utf-8"))

# start and stop

    def start(self):
        """
        start the dispatcher thread and begin to recv msg through nng
        """
        print('tradeclient started ,pid = %d ' % os.getpid())
        self.event_engine.start()
        self.__active = True
        self._thread.start()

    def stop(self):
        """
        stop 
        """
        self.__active = False
        self.event_engine.stop()
        self._thread.join()

    def write_log(self, msg: str):
        """
        Create engine log event.
        """

        # log = LogData(msg=msg, gateway_name="CtaStrategy")
        # event = Event(type=EVENT_CTA_LOG, data=log)
        # self.event_engine.put(event)
        print(msg)
Exemple #43
0
NanoMsgAPIError, EAGAIN, SUB_SUBSCRIBE

# first connect to the (remote) pi (b.local) running mangorep

s2 = Socket(REQ)
s2.connect('tcp://b.local:5555')

# set up the query in json
#s = json.dumps({"Cmnd":"sysType"})
s = json.dumps({"Cmnd": "cpuTemp"})

# run the query

while True:
    s2.send(s)
    msg = s2.recv()
    #    print(msg)
    print(json.loads(msg.decode("utf-8")))

    # note that the whole json response is printed here
    # actually it showed up that I am returning a \n newline I don't want...
    # Now corrected in mangorep (line 88 ish)

    time.sleep(2)
"""
Example output:-

{'Cmnd': 'cpuTemp', 'Args': None, 'rslt': "temp=42.9'C\n"}
{'Cmnd': 'cpuTemp', 'Args': None, 'rslt': "temp=41.9'C\n"}
{'Cmnd': 'cpuTemp', 'Args': None, 'rslt': "temp=41.9'C\n"}
{'Cmnd': 'cpuTemp', 'Args': None, 'rslt': "temp=41.9'C\n"}
Exemple #44
0
class NodeEditor:
    #STATE_PLAYBACK_ON_EDGE = 0x01 #
    STATE_PLAYBACK = 0x02 # playback from random place
    STATE_PAUSED = 0x03

    # seek
    # get_delta_packets(dt)
    # get_current_timestamp

    def __init__(self, nugui, mouse, gltext, conf):
        self.conf = conf
        self.mouse = mouse  # TODO: use a special mouse object instead of the editor_main object directly.
        self.gltext = gltext
        self.nugui = nugui

        self.world = world.World("ff", self.conf)
        self.underworld = world.World("", self.conf) # not visible. used serializing keyframes

        self.mouse_x = 0.
        self.mouse_y = 0.
        self.mouse_hover = False
        self.mouse_dragging = False
        self.selected = None
        self.selected_pos_ofs = vector.Vector()

        self.node_renderer = renderers.NodeRenderer(self.gltext)
        self.link_renderer = renderers.LinkRenderer()

        # saved when closing the windows. loaded at startup.
        self.session_filename = os.path.normpath(os.path.join(self.conf.path_database, "session_conf.txt"))
        self.load_session()

        self.recording = True
        self.state = self.STATE_PLAYBACK

        self.worldstreamer = world_streamer.WorldStreamer(sync_window_seconds=self.conf.sync_depth_seconds)

        #self.current_playback_time = 0. # timepoint of the simulation that is currently visible on screen. can be dragged around with a slider.
        self.timeslider_end_time = 0.

        self.graph_window = graph_window.GraphWindow(self.gltext)
        self.graph_window_initialized = False

        self.s1 = Socket(SUB)
        self.s1.connect('tcp://127.0.0.1:55555')
        self.s1.set_string_option(SUB, SUB_SUBSCRIBE, '')

    def tick(self, dt, keys):
        self.world.tick(dt)
        self.underworld.tick(dt)
        self.net_poll_packets()

        fresh_packets = self.worldstreamer.tick()
        for p in fresh_packets:
            self.handle_packet(p[1], self.underworld, barebones=True)

        if self.state == self.STATE_PLAYBACK:
            packets = self.worldstreamer.get_delta_packets(dt)
            for p in packets:
                self.handle_packet(p[1], self.world)

        if self.worldstreamer.need_keyframe():
            llog.info("need keyframe!")
            w = self.underworld.serialize_world()

            #import pprint
            #llog.info("\n\n\nSAVING")
            #llog.info(pprint.pformat(w))

            self.worldstreamer.put_keyframe(w)

        # always set the graph start 10 seconds before the first sample time. user-friendly start condition for the zoom-scroller.
        if self.worldstreamer.start_time != None and not self.graph_window_initialized:
            self.graph_window_initialized = True
            self.graph_window.set_totalsample_start(self.worldstreamer.start_time - 10.)
            self.graph_window.set_totalsample_end(self.worldstreamer.end_time)
            self.graph_window.set_sample_visibility(self.worldstreamer.start_time - 10., self.worldstreamer.end_time)

        if self.graph_window_initialized:
            self.graph_window.set_totalsample_end(self.worldstreamer.end_time)

        self.graph_window.tick()

        if self.graph_window_initialized:
            # if the graph was moved by keyboard/mouse
            if self.graph_window.wanted_x2_was_moved:
                self.graph_window.wanted_x2_was_moved = False
                newtime = self.graph_window.wanted_visiblesample_x2

                if newtime != self.worldstreamer.current_time:
                    llog.info("seeking from %.2f to %.2f between %.2f %.2f", self.worldstreamer.current_time, newtime, self.worldstreamer.start_time, self.worldstreamer.end_time)
                    keyframe, packets = self.worldstreamer.seek(newtime)
                    self.world.deserialize_world(keyframe)
                    llog.info("seeking returned %i packets", len(packets))
                    if packets:
                        # calc the timestamp from where to start using animations. use only 2 seconds worth, because
                        # it's not very nice to animate all packets at once if seek returned 30 minutes worth of packets for example.
                        # TODO: but if the keyframe is too close to the seek time, then we won't get even 2 seconds worth of packets.
                        #       then we'll have to use the previous keyframe. oh, too much work..
                        animations_start = packets[-1][0] - 2.
                        for p in packets:
                            timestamp, packet = p
                            if timestamp < animations_start:
                                # won't use animations for these packets
                                self.handle_packet(packet, self.world, barebones=True)
                            else:
                                self.handle_packet(packet, self.world)

            if self.state == self.STATE_PLAYBACK:
                self.graph_window.move_sample_right_edge(self.worldstreamer.current_time)

    def net_poll_packets(self):
        try:
            # handle all incoming packets
            # TODO: sync packets by timestamp. sync time configurable. 5 seconds default?
            #       print error if a packet arrives out of sync? how to denote this info?
            while 1:
                msg = self.s1.recv(flags=DONTWAIT)
                if not msg:
                    break

                msg = msg.strip()
                if msg:
                    try:
                        # append the packet to timesyncer
                        # get the timestamp.
                        d = msg.split(None, 5)
                        #d = d[1:] # cut off the seqno
                        # ['data', 'etx', '0001000000000200', 'node', '0A', 'index', '0', 'neighbor', '8', 'etx', '10', 'retx', '74']
                        if d[0] == "data" or d[0] == "event":
                            # get nodeid from packet
                            node_id_name = d[4]
                            nodeid = int(node_id_name.split("_", 1)[0], 16)
                            self.worldstreamer.put_packet(float(d[2]), msg, nodeid)
                    except:
                        llog.exception("")

        except NanoMsgAPIError as e:
            if e.errno != errno.EAGAIN:
                raise

    def handle_packet(self, msg, world, barebones=False):
        """ barebones : if True, then won't use any animations and non-essential poking of the world.
        Will result in a fast barebones world that is still usable for generating keyframes. """

        #llog.info("handle: %s", msg)
        d = msg.split()
        #d = d[1:] # cut off the seqno
        if d[0] == "data" or d[0] == "event":

            #timestamp = float(d[2])
            #timesyncer.append(timestamp, msg)

            # ['data', 'etx', '0001000000000200', 'node', '0A', 'index', '0', 'neighbor', '8', 'etx', '10', 'retx', '74']
            # ['data', 'etx', '0001000000000200', 'node', '0A_sniffy', 'index', '0', 'neighbor', '8', 'etx', '10', 'retx', '74']
            node_id_name = d[4]
            node = world.get_create_named_node(node_id_name)
            src_node = node
            src_node_id = node.node_id

            if d[0] == "data":

                if d[1] == "etx":
                    # ['data', 'etx', '0001000000000200', 'node', '0A', 'index', '0', 'neighbor', '8', 'etx', '10', 'retx', '74']

                    # filter out empty rows
                    if int(d[8]) != 0xFFFF:
                        if d[10].startswith("NO_ROUTE"):
                            d[10] = "NO"
                            d[12] = "NO"

                        # when receiving entry with index 0, then clear out the whole table.
                        if int(d[6]) == 0:
                            node.attrs["etx_table"] = []

                        attrs_etx_table = node.attrs.get("etx_table", [])
                        attrs_etx_table.append("%04X e%s r%s" % (int(d[8]), d[10], "00" if d[12] == "0" else d[12]))
                elif d[1] == "ctpf_buf_size":
                    used = int(d[6])
                    capacity = int(d[8])
                    node.attrs["ctpf_buf_used"] = used
                    node.attrs["ctpf_buf_capacity"] = capacity

            elif d[0] == "event":

                if d[1] == "radiopowerstate":
                    # ['event', 'radiopowerstate', '0052451410156550', 'node', '04', 'state', '1']
                    radiopowerstate = int(d[6], 16)
                    node.attrs["radiopowerstate"] = radiopowerstate
                    if not barebones:
                        if radiopowerstate:
                            node.poke_radio()

                elif d[1] == "beacon":
                    # ['event', 'beacon', '0052451410156550', 'node', '04', 'options', '0x00', 'parent', '0x0003', 'etx', '30']
                    options = int(d[6], 16)
                    parent = int(d[8], 16)
                    node.attrs["parent"] = parent
                    if not barebones:
                        node.append_animation(animations.BeaconAnimation(options))

                elif d[1] == "packet_to_activemessage" and 0:
                    # ['event', 'packet', '0000372279297175', 'node', '04', 'dest', '0x1234', 'amid', '0x71']
                    dst_node_id = int(d[6], 16)
                    amid = int(d[8], 16)
                    if dst_node_id != 0xFFFF: # filter out broadcasts
                        dst_node = world.get_create_node(dst_node_id)
                        if not barebones:
                            link = world.get_link(src_node, dst_node)
                            link.poke(src_node)

                elif d[1] == "send_ctp_packet":
                    # event send_ctp_packet 0:0:38.100017602 node 03 dest 0x0004 origin 0x0009 sequence 21 type 0x71 thl 5
                    # event send_ctp_packet 0:0:10.574584572 node 04 dest 0x0003 origin 0x0005 sequence 4 amid 0x98 thl 1
                    dst_node_id = int(d[6], 16)
                    origin_node_id = int(d[8], 16)
                    sequence_num = int(d[10])
                    amid = int(d[12], 16)
                    thl = int(d[14])

                    dst_node = world.get_create_node(dst_node_id)
                    if not barebones:
                        link = world.get_link(src_node, dst_node)
                        # TODO: refactor node color
                        link.poke(src_node, packet_color=world.get_node_color(origin_node_id))

                elif d[1] == "packet_to_model_busy":
                    dst_node_id = int(d[6], 16)
                    if dst_node_id != 0xFFFF: # filter out broadcasts
                        src_node = node
                        dst_node = world.get_create_node(dst_node_id)
                        if not barebones:
                            link = self.world.get_link(src_node, dst_node)
                            link.poke_busy(src_node)

                elif d[1] == "send_done":
                    # 'event send_done 1425601510.21 node 2C13_8 rm 0x02 dest 0x37B6 amid 0x71 error 0x00 retry_count 9 acked 0x01 congested 0x00 dropped 0x00'
                    ramplex_id = int(d[6],16)
                    dst_node_id = int(d[8],16)
                    amid = int(d[10],16)
                    error = int(d[12],16)
                    retry_count = int(d[14],16)
                    acked = int(d[16],16)
                    congested = int(d[18],16)
                    dropped = int(d[20],16)

                    if not barebones and retry_count > 0:
                        node.append_animation(animations.SendRetryAnimation(max_age=1., start_color=(1.,0.,0.,1.), end_color=(0.,0.,0.,0.2), retry_count=retry_count))

            else:
                llog.info("unknown msg %s", repr(msg))

    def _render_links_to_parents(self):
        glLineWidth(1.)
        glColor4f(0.4, 0.4, 0.4, 1.)

        # 1111_11_1______
        glLineStipple(2, 1+2+4+8+32+64+256)
        glEnable(GL_LINE_STIPPLE)
        glLineWidth(2.)
        for node in self.world.nodes:
            parent_id = node.attrs.get("parent")
            if parent_id and parent_id != 0xFFFF:
                parent_node = self.world.get_create_node(parent_id)

                glBegin(GL_LINES)
                glVertex3f(*parent_node.pos)
                glVertex3f(*node.pos)
                glEnd()

        glDisable(GL_LINE_STIPPLE)

    def render(self):
        for link in self.world.links:
            self.link_renderer.render(link)
        self._render_links_to_parents()
        for node in self.world.nodes:
            self.node_renderer.render(node)

    def render_overlay(self, camera, camera_ocs, projection_mode, w_pixels, h_pixels):
        # calculate node screen positions
        for node in self.world.nodes:
            # 1. proj obj to camera_ocs
            # 2. proj coord to screenspace
            v = camera_ocs.projv_in(node.pos)
            node.screen_pos.set(camera.screenspace(projection_mode, v, w_pixels, h_pixels))

        # draw lines from the selected node to every other node
        if 0 and self.selected:
            glLineWidth(1.)
            for node in self.world.nodes:
                if node != self.selected:
                    glColor4f(0.3,0.3,0.3,.9)
                    glBegin(GL_LINES)
                    glVertex3f(*self.selected.screen_pos)
                    glVertex3f(*node.screen_pos)
                    glEnd()

                    glEnable(GL_TEXTURE_2D)
                    s = (self.selected.screen_pos + node.screen_pos) / 2.
                    link_quality = self._calc_link_quality(node, self.selected)
                    self.gltext.drawmm("%.2f" % link_quality, s[0], s[1], bgcolor=(0.2,0.2,0.2,0.7), fgcolor=(1.,1.,1.,1.), z=s[2])
                    glDisable(GL_TEXTURE_2D)

        # draw the nodes themselves
        for node in self.world.nodes:
            self.node_renderer.render_overlay(node)

        t = self.gltext

        # render some information

        glEnable(GL_TEXTURE_2D)
        y = 5.
        t.drawtl(" sync depth  : %.1f s " % (self.worldstreamer.sync_window_seconds), 5, y, bgcolor=(0.8,0.8,0.8,.9), fgcolor=(0.,0.,0.,1.), z=100.); y += t.height
        t.drawtl(" recording   : yes ", 5, y); y += t.height
        txt = "-" if self.worldstreamer.start_time == None else round(self.worldstreamer.end_time - self.worldstreamer.start_time)
        t.drawtl(" duration    : %s s " % (txt), 5, y); y += t.height
        t.drawtl(" num packets : %i " % self.worldstreamer.num_packets_sorted, 5, y); y += t.height

        # render and handle rewind-slider

        if 1:
            txt = "-" if self.worldstreamer.start_time == None else timestamp_to_timestr(self.worldstreamer.start_time)
            t.drawbl(txt, 5, h_pixels - 53, bgcolor=(0,0,0,.6), fgcolor=(.8,.8,.8,1.), z=100.)
            txt = "-" if self.worldstreamer.end_time == None else timestamp_to_timestr(self.worldstreamer.end_time)
            t.drawbr(txt, w_pixels-5, h_pixels-53)
            txt = "-" if self.worldstreamer.current_time == None else timestamp_to_timestr(self.worldstreamer.current_time)
            t.drawbm(txt, w_pixels/2, h_pixels-53, bgcolor=(0,0,0,.9))

            glLineWidth(1.)
            glDisable(GL_TEXTURE_2D)


    #        self.render_timeslide_scrollbar(h_pixels-80, w_pixels-10, w_pixels-20, 10)

        if 0:
            if self.worldstreamer.start_time == None:
                self.nugui.slider(1001, 10, h_pixels-40, w_pixels-20, 0., 0., 0., True)
            else:
                # don't update slider end time while dragging the slider
                if self.nugui.id_active != 1001:
                    self.timeslider_end_time = self.worldstreamer.end_time
                newtime = self.nugui.slider(1001, 10, h_pixels-40, w_pixels-20, self.worldstreamer.current_time, self.worldstreamer.start_time, self.timeslider_end_time)
                if newtime != self.worldstreamer.current_time:
                    llog.info("seeking from %.2f to %.2f between %.2f %.2f", self.worldstreamer.current_time, newtime, self.worldstreamer.start_time, self.worldstreamer.end_time)
                    keyframe, packets = self.worldstreamer.seek(newtime)
                    self.world.deserialize_world(keyframe)
                    llog.info("seeking returned %i packets", len(packets))
                    for p in packets:
                        self.handle_packet(p[1], self.world)


        self.graph_window.place_on_screen(0, h_pixels-51, w_pixels, 50)
        self.graph_window.render()


        txt = "playing" if self.state == self.STATE_PLAYBACK else "paused"
        if self.nugui.button(1002, 5, h_pixels-90, txt, w=64):
            if self.state == self.STATE_PLAYBACK:
                self.state = self.STATE_PAUSED
            else:
                self.state = self.STATE_PLAYBACK

    def intersects_node(self, sx, sy):
        for node in self.world.nodes:
            if node.intersects(float(sx), float(sy)):
                return node
        return None

    def save_graph_file(self, filename="sensormap.txt"):
        d = {"format": "sensed node graph", "format_version": "2013-12-19", "nodes": [], "edges": []}

        for node in self.world.nodes:
            p = node.pos
            n = {"id": node.node_id, "pos": [p[0], p[1], p[2]]}
            d["nodes"].append(n)

        edge_count = 0
        for node1 in self.world.nodes:
            for node2 in self.world.nodes:
                if node1 != node2:
                    edge_count += 1
                    e = {"id": edge_count, "source": node1.node_id, "dest": node2.node_id, "link_quality": self._calc_link_quality(node1, node2)}
                    d["edges"].append(e)

        txt = json.dumps(d, indent=4, sort_keys=True)

        with open(filename, "wb") as f:
            f.write(txt)

    def _calc_link_quality(self, node1, node2):
        dist = node1.pos.dist(node2.pos)
        return dist

    def load_session(self):
        """ load node positions. write to self.session_node_positions """
        try:
            with open(self.session_filename, "rb") as f:
                session_conf = json.load(f)
        except IOError:
            #log.warning("'%s' file not found" % path)
            session_conf = None

        # extract node positions from the conf dict
        if session_conf and "node_positions" in session_conf:
            c = session_conf.get("node_positions")
            # convert entries {"0x51AB": (1,2,3), ..} to format {20907, (1,2,3)}
            self.world.session_node_positions = {int(k, 16): v for k, v in c.items()}

    def save_session(self):
        """ save node positions. mix together prev session positions and new positions. """
        # convert entries {20907: (1,2,3), ..} to format {"0x51AB", (1,2,3)}
        node_positions_session = {"0x%04X" % k: v for k, v in self.world.session_node_positions.items()}
        node_positions_used = {"0x%04X" % n.node_id: (n.pos[0], n.pos[1], n.pos[2]) for n in self.world.nodes}
        node_positions_session.update(node_positions_used)

        session_conf = {"node_positions": node_positions_session}
        txt = json.dumps(session_conf, indent=4, sort_keys=True)

        with open(self.session_filename, "wb") as f:
            f.write(txt)

    def close(self):
        self.save_session()

    def is_world_move_allowed(self):
        if self.graph_window.is_coordinate_inside_window(self.mouse_x, self.mouse_y):
            return False
        return True

    def event(self, event):

        if self.graph_window.event(event):
            return True

        if event.type == SDL_MOUSEMOTION:
            self.mouse_x = float(event.motion.x)
            self.mouse_y = float(event.motion.y)

            for node in self.world.nodes:
                node.mouse_hover = False
            node = self.intersects_node(event.motion.x, event.motion.y)
            if node:
                self.mouse_hover = True
                node.mouse_hover = True
            else:
                self.mouse_hover = False

            if self.selected and self.mouse_dragging and self.mouse.mouse_lbdown_floor_coord:
                self.selected.pos.set(self.mouse.mouse_floor_coord + self.selected_pos_ofs)
                return True

        elif event.type == SDL_MOUSEBUTTONDOWN:

            if event.button.button == SDL_BUTTON_LEFT:
                node = self.intersects_node(event.button.x, event.button.y)
                if node:
                    for n in self.world.nodes:
                        n.selected = False
                    self.selected = node
                    node.selected = True
                    self.selected_pos_ofs.set(node.pos - self.mouse.mouse_lbdown_floor_coord)
                    self.mouse_dragging = True
                else:
                    self.mouse_dragging = False

        elif event.type == SDL_MOUSEBUTTONUP:
            if event.button.button == SDL_BUTTON_LEFT:
                #if self.mouse_dragging:
                if self.mouse.mouse_lbdown_window_coord == self.mouse.mouse_window_coord:
                    node = self.intersects_node(event.button.x, event.button.y)
                    if not node:
                        self.selected = None
                        for n in self.world.nodes:
                            n.selected = False
                self.mouse_dragging = False
Exemple #45
0
class PullWorker(threading.Thread):
    """ End point of pipeline
    """
    def __init__(self, url, event):
        """ Initializes object

            Args:
                url (String): Url to bind to
        """
        super(PullWorker, self).__init__()
        self._socket = Socket(PULL)
        self._url = url
        self._socket.bind(self._url)
        self._queue = Queue.Queue()
        self._stop = event

    def receive(self):
        """ Reveives message
        """
        raw_msg = self._socket.recv()
        parsed = {}
        try:
            parsed = json.loads(raw_msg)
        except:
            logging.exception(
                'PullWorker: Received msg could not be JSON parsed %s' %
                raw_msg)
        return parsed

    def run(self):
        """ Thread run method
        """
        while not self._stop.is_set():
            dic = self.receive()
            self._queue.put(dic)
        self.__exit__()

    def next_message(self):
        """ Return next message of queue

            Returns:
                message: Dictionary representing send message
        """
        msg = self._queue.get()
        self._queue.task_done()
        return msg

    def __enter__(self):
        """ Statement used for the `` with ... as ...:`` returns
            the object to use in the ``with`` block

            Returns:
                PullWorker
        """
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        """ Executed when leaving ``with`` block, regardless whether
            because of an exception or normal program flow
        """
        self._socket.close()