示例#1
0
    def __init__(self, port, channels, test=False):
        self.app = NescApp()
        # only take the variable names without
        self.vars = self.app.variables.variables()
        # I pass the variables to the simulator
        self.sim = Tossim(self.vars)
        self.nodes = {}
        # the serial forwarder stuff is needed only by the java interaface
        # or the listen.py script
        # in testing mode this is only a problem
        self.test = test
        if not (self.test):
            self.sf = SerialForwarder(port)

        self.throttle = Throttle(self.sim, 10)
        # operations on the topology and the radio channel
        self.topology = RadioNetwork(self.sim.radio())
        self.channels = list(channels)
        # adding all the channels
        for c in channels:
            self.add_channel(c)
示例#2
0
class Simulation(object):
    def __init__(self, port, channels, test=False):
        self.app = NescApp()
        # only take the variable names without
        self.vars = self.app.variables.variables()
        # I pass the variables to the simulator
        self.sim = Tossim(self.vars)
        self.nodes = {}
        # the serial forwarder stuff is needed only by the java interaface
        # or the listen.py script
        # in testing mode this is only a problem
        self.test = test
        if not (self.test):
            self.sf = SerialForwarder(port)

        self.throttle = Throttle(self.sim, 10)
        # operations on the topology and the radio channel
        self.topology = RadioNetwork(self.sim.radio())
        self.channels = list(channels)
        # adding all the channels
        for c in channels:
            self.add_channel(c)

    def single_node(self):
        print "adding a simple lonely node"
        self.add_node(0)

    def process(self):
        if not (self.test):
            self.sf.process()

    # handle separately colors and moreoveor
    def add_channel(self, channel):
        self.sim.addChannel(channel, sys.stdout)
        if not (channel in self.channels):
            self.channels.append(channel)

    def remove_channel(self, channel):
        self.sim.removeChannel(channel, sys.stdout)
        if channel in self.channels:
            self.channels.remove(channel)

    def add_node(self, idx):
        # otherwise add to the dictionary the correct node
        if not (idx in self.nodes):
            if len(self.nodes) == MAX_NODES:
                print "Not possible to add more nodes, reached limit"

            else:
                self.nodes[idx] = self.sim.getNode(idx)

    def start(self, batch=False):
        "Starts the simulation"
        for n in self.nodes.values():
            n.bootAtTime(random.randint(100001, 900009))

        self.process()
        self.throttle.initialize()

        # make sure they all boot
        self.run_some_events()
        if not (batch):
            self.cycle()

    def cycle(self):
        "Loop at infinite runnign all the events in the queue"
        print "start cycling, use C-c to send data interactively"
        while True:
            try:
                self.throttle.checkThrottle()
                self.sim.runNextEvent()
                self.process()
                # processing what it's got from it
            except KeyboardInterrupt:
                # with the first interrupt we go in interactive mode, the second quits the program
                try:
                    self.interactive()
                    print "\nrestarting the cycle, running other events...\n"
                    continue
                except KeyboardInterrupt:
                    sys.exit()

    def connected(self, node1, node2):
        return self.topology.connected(node1, node2)

    def make_topology(self, topo_file):
        "Creates the topology from the given file"
        for line in open(topo_file):
            vals = line.split()
            vals = (int(vals[0]), int(vals[1]), float(vals[2]))
            self.add_connection(*vals)

    def make_rand_graph(self):
        "Creates a random graph"
        for vals in rand_graph(MAX_NODES, 5):
            self.add_connection(*vals)

    def make_bin_tree(self, len):
        "Creates a binary tree structure for the topology"
        for vals in bin_tree(len):
            self.add_connection(*vals)
        print self.topology

    def make_given_topology(self, couples):
        for x, y in couples:
            self.add_connection(x, y)

    def setup_noise(self, noise_file):
        for line in open(noise_file):
            val = int(line.strip())
            for n in self.nodes.values():
                n.addNoiseTraceReading(val)

        for n in self.nodes.values():
            n.createNoiseModel()

    def add_connection(self, n1, n2, distance=-59):
        """
        Add to the radio channel a connection between the two nodes
        If the given nodes are not present already add them
        """
        self.add_node(n1)
        self.add_node(n2)
        self.topology.add_connection(n1, n2, distance)

    def remove_connection(self, n1, n2):
        # here we don't need to remove the nodes themselves
        self.topology.remove_connection(n1, n2)

    def interactive(self):
        # Use a dictionary and function calls instead
        def send_interactive():
            self.send_packet(self.make_serial())
            self.send_packet(self.make_non_serial())

        choices = (
            ("topology management", self.manipulate_topology),
            ("packet creation", send_interactive),
            ("variable inspection", self.inspect_variable),
            ("node inspection", self.inspect_node),
            ("channel management", self.manage_channels),
        )

        MenuMaker(choices).call_option()

    def run_some_events(self):
        "Run some of the events"
        # TODO: pass some arguments to make sure they're enough
        time = self.sim.time()
        while time + RUNTIME * 10000000000 > self.sim.time():
            self.throttle.checkThrottle()
            self.sim.runNextEvent()

        self.throttle.printStatistics()

    def check_vars_all_nodes(self, var, value):
        return self.check_vars_nodes(sorted(self.nodes.keys()), var, value)

    def check_vars_nodes(self, nodes, var, value):
        "Check that all the variables of nodes have that value"
        for n in nodes:
            val = self.get_variable(n, var)
            print "node %d = %d" % (n, val)
            if val != value:
                return False

        return True

    def inspect_variable(self):
        "Ask for a variable to inspect and returns it"
        readline.parse_and_bind("tab: complete")
        node = input("which node you want to inspect?\n")
        print_var_table(self.vars)
        # see if this is actually correct
        c = rlcompleter.Completer(dict(zip(self.vars, self.vars)))
        readline.set_completer(c.complete)
        var = raw_input("which variable do you want to inspect?\n")
        print "node %d:var %s = %s" % (node, var, self.get_variable(node, var))

    def inspect_node(self):
        "Show all the variables in a certain node"
        node = input("which node you want to inspect?\n")
        self.print_node_vars(node)

    def get_variable(self, node, var):
        return self.nodes[node].getVariable(var).getData()

    def filter_variable(self, mod=MODULES_REGEXP):
        for v in self.vars:
            if match(mod, v):
                yield v

    def print_node_vars(self, node):
        for v in self.filter_variable():
            print self.get_variable(node, v)

    def print_var_nodes(self, var):
        for x in sorted(self.nodes):
            print "%d -> %s" % (x, self.get_variable(x, var))

    def inactive_channels(self):
        "returns the inactive debug channels"
        return list(set(CHANNELS) - set(self.channels))

    def manage_channels(self):
        def add_channel():
            # only give the remaining to add not all of them
            readline.parse_and_bind("tab: complete")
            c = rlcompleter.Completer(dict(zip(CHANNELS, CHANNELS)))
            readline.set_completer(c.complete)
            channel = raw_input("what channel you want to add?\n")
            # TODO: see how to add for only one mote
            self.add_channel(channel)

        def rem_channel():
            readline.parse_and_bind("tab: complete")
            c = rlcompleter.Completer(dict(zip(self.channels, self.channels)))
            readline.set_completer(c.complete)
            channel = raw_input("what channel you want to remove?\n")
            self.remove_channel(channel)

        def activate_all():
            for c in self.inactive_channels():
                self.add_channel(c)

        def see_channels():
            print self.channels

        choices = (
            ("Add a new debug channel", add_channel),
            ("Remove a debug channel", rem_channel),
            ("See debug channels activated", see_channels),
            ("Activate all debug channels", activate_all),
        )

        MenuMaker(choices).call_option()

    def manipulate_topology(self):
        # only way to have a print inside of a lambda call
        print_out = lambda: sys.stdout.write(str(self.topology))

        def add_nodes():
            try:
                n1, n2 = input("first node\n"), input("second node\n")
            except Exception:
                print "input error"
                self.manipulate_topology()

            else:
                self.add_connection(n1, n2)

        def rem_nodes():
            nodes = raw_input("what are the nodes to remove (symmetrically) write X Y?\n")
            try:
                n1, n2 = map(int, nodes.split(" "))
            except ValueError:
                print "write better values"
                self.manipulate_topology()
            else:
                self.remove_connection(n1, n2)

        def disconnect_node():
            try:
                node = input("what node you want to disconnect\n")
            except Exception:
                self.manipulate_topology()
            else:
                self.topology.disconnect_node(node)

        choices = (
            ("see topology", print_out),
            ("add one connection", add_nodes),
            ("remove one connection", rem_nodes),
            ("disconnect one node", disconnect_node),
        )

        MenuMaker(choices).call_option()

    def make_serial(self):
        return self.sim.newSerialPacket()

    def make_non_serial(self):
        return self.sim.newPacket()

    def send_packet(self, pkt):
        "Takes a BlinkMsg already generated and sends it via serial"
        msg = make_packet()
        pkt = self.sim.newSerialPacket()
        pkt.setData(msg.get_data())
        pkt.setType(msg.am_type)
        pkt.setDestination(0)
        pkt.deliver(0, self.sim.time() + 3)
        self.run_some_events()
        print "sended packet:\n%s" % str(msg)