def add(self, node): """ >>> nodes = NetworkedNodes("saclay") >>> nodes.add("m3-1") >>> nodes.add("m3-1.saclay.iot-lab.info") >>> nodes.add("m3-2.saclay.iot-lab.info") >>> for n in sorted(nodes, key=lambda n: n.uri): ... print(n.uri) m3-1.saclay.iot-lab.info m3-2.saclay.iot-lab.info >>> for n in sorted(nodes.network.nodes()): ... print(nodes.network.nodes[n]["info"].uri) m3-1.saclay.iot-lab.info m3-2.saclay.iot-lab.info """ if self._is_uri(node): uri = node node = uri.split(".")[0] else: uri = common.get_uri(self.site, node) if uri in self.nodes: return super().add(uri) info = self[node] self.network.add_node(node, info=info)
def __delitem__(self, node): """ >>> import io >>> nodes = NetworkedNodes("grenoble", ... io.BytesIO( ... b"m3-1 m3-2 2\\nm3-2 m3-3 1" ... ) ... ) >>> del nodes["m3-1"] >>> for n in sorted(nodes, key=lambda n: n.uri): ... print(n.uri) m3-2.grenoble.iot-lab.info m3-3.grenoble.iot-lab.info >>> del nodes["m3-3.grenoble.iot-lab.info"] >>> for n in sorted(nodes, key=lambda n: n.uri): ... print(n.uri) m3-2.grenoble.iot-lab.info """ if self._is_uri(node): uri = node node = node.split(".")[0] else: uri = common.get_uri(self.site, node) self.network.remove_node(node) super().__delitem__(uri)
def __init__(self, site, edgelist_file=None, state=None, weight_distance=True, api=None, node_class=BaseNode): # pylint: disable=too-many-arguments # Maybe fix later """ >>> import io >>> nodes = NetworkedNodes("grenoble", ... io.BytesIO( ... b"m3-1 m3-2 2\\nm3-2 m3-3 1" ... ) ... ) >>> for n in sorted(nodes, key=lambda n: n.uri): ... print(n.uri) m3-1.grenoble.iot-lab.info m3-2.grenoble.iot-lab.info m3-3.grenoble.iot-lab.info >>> for n in sorted(nodes.network.nodes()): ... print(nodes.network.nodes[n]["info"].uri) m3-1.grenoble.iot-lab.info m3-2.grenoble.iot-lab.info m3-3.grenoble.iot-lab.info >>> nodes = NetworkedNodes("grenoble") >>> len(nodes) 0 >>> nodes = NetworkedNodes("grenoble", ... io.BytesIO( ... b"m3-1 m3-2 2\\nm3-2 m3-3 1" ... ), ... weight_distance=False, ... ) >>> for n in sorted(nodes, key=lambda n: n.uri): ... print(n.uri) m3-1.grenoble.iot-lab.info m3-2.grenoble.iot-lab.info m3-3.grenoble.iot-lab.info """ self.site = site if edgelist_file is not None: self.network = networkx.read_edgelist(edgelist_file, data=[("weight", float)]) super().__init__( [common.get_uri(site, n) for n in self.network.nodes()], state, api, node_class) info = {n: self[n] for n in self.network.nodes()} networkx.set_node_attributes(self.network, info, "info") if weight_distance: for node1, node2 in self.network.edges(): info1 = self[node1] info2 = self[node2] edge = self.network[node1][node2] edge["weight"] = info1.distance(info2) else: self.network = networkx.Graph() super().__init__(state=state, api=api, node_class=node_class)
def load_network(sink, edgelist_file, iotlab_site=construct_network.DEFAULT_IOTLAB_SITE): sink = "m3-{}".format(sink) network = SinkNetworkedNodes(iotlab_site, sink, edgelist_file) if get_uri(iotlab_site, sink) not in network: raise construct_network.NetworkConstructionError( "Sink {} not in network {}".format(sink, network)) return network
def profile(self, exp_id, profile, sink_profile=None): # pylint: disable=arguments-differ # Adds additional, but optional arguments if sink_profile is None: return super().profile(exp_id, profile) res1 = iotlabcli.node.node_command(self.api, "profile", exp_id, list(self.non_sink_node_uris), profile) res2 = iotlabcli.node.node_command( self.api, "profile", exp_id, [common.get_uri(self.site, self.sink)], sink_profile) for res in ['0', '1']: if res in res1 and res in res2: res1[res].extend(res2[res]) res1[res].sort() elif res not in res1 and res in res2: res1[res] = res2[res] return res1
def flash(self, exp_id, firmware, sink_firmware=None): # pylint: disable=arguments-differ # Adds additional, but optional arguments if sink_firmware is None or sink_firmware == firmware: return super().flash(exp_id, firmware) res1 = iotlabcli.node.node_command(self.api, "flash", exp_id, list(self.non_sink_node_uris), firmware.path) res2 = iotlabcli.node.node_command( self.api, "flash", exp_id, [common.get_uri(self.site, self.sink)], sink_firmware.path) for res in ['0', '1']: if res in res1 and res in res2: res1[res].extend(res2[res]) res1[res].sort() elif res not in res1 and res in res2: res1[res] = res2[res] return res1
def select(self, nodes): """ >>> import io >>> nodes = NetworkedNodes("grenoble", ... io.BytesIO( ... b"m3-1 m3-2 2\\nm3-2 m3-3 1" ... ) ... ) >>> nodes = nodes.select(['m3-2', 'm3-3.grenoble.iot-lab.info']) >>> for n in sorted(nodes, key=lambda n: n.uri): ... print(n.uri) m3-2.grenoble.iot-lab.info m3-3.grenoble.iot-lab.info """ res = super().select([ n if self._is_uri(n) else common.get_uri(self.site, n) for n in nodes ]) res.network = networkx.Graph(self.network.subgraph(nodes)) return res
def __iter__(self): """ >>> import io >>> nodes = SinkNetworkedNodes("grenoble", "m3-2", ... io.BytesIO( ... b"m3-1 m3-2 2\\nm3-2 m3-3 1" ... ) ... ) >>> for n in sorted(nodes, key=lambda n: n.uri): ... print(n.uri) m3-1.grenoble.iot-lab.info m3-2.grenoble.iot-lab.info m3-3.grenoble.iot-lab.info >>> for n in nodes: ... print(n.uri) ... break m3-2.grenoble.iot-lab.info """ sink_uri = common.get_uri(self.site, self.sink) # ensure sink to be first yield self[sink_uri] for node in self.nodes: if node != sink_uri: yield self[node]
def construct_network(sink, iotlab_site=DEFAULT_IOTLAB_SITE, min_distance=MIN_DISTANCE, max_distance=MAX_DISTANCE, min_neighbors=MIN_NEIGHBORS, max_neighbors=MAX_NEIGHBORS, max_nodes=MAX_NODES, api=None): def _restrict_potential_neighbors(node_set, node, network): potential_neighbors = set(n for n in node_set.values() if _node_num(n) not in NODE_BLACKLIST[iotlab_site]) potential_neighbors.remove(node) # select nodes where # neigh is is within max_distance of node and # neigh is not already in network # neigh is further away than min_distance from all other nodes and # and there is no node in network that is within min_distance of neigh return [ neigh for neigh in potential_neighbors if (node.distance(neigh) < max_distance) and (neigh not in network) and ((neigh.distance(w) >= min_distance) for w in potential_neighbors - {neigh}) and not any((neigh.distance(x) < min_distance) for x in network) ] if sink in NODE_BLACKLIST[iotlab_site]: logging.warning("Sink {} in blacklist for site {}".format(sink, iotlab_site)) sink = "{}-{}".format(ARCHI_SHORT, sink) if api is None: api = get_default_api() # get all nodes that are alive and not booked from iotlab_site node_selection = SinkNetworkedNodes.all_nodes(iotlab_site, "Alive", ARCHI_FULL, api, sink=sink) if get_uri(iotlab_site, sink) not in node_selection: raise NetworkConstructionError("Sink {} is not 'Alive' (maybe booked " "by other experiment?)".format(sink)) result = SinkNetworkedNodes(iotlab_site, sink) sink = result[sink] # BFS from sink queue = Queue() visited = set([sink]) queue.put(sink) def _save_result(): draw_network(result, False, with_labels=True) plt.savefig(os.path.join(DATA_PATH, "{}_logic.svg".format(result)), dpi=150) plt.clf() draw_network(result, True, with_labels=True) plt.savefig(os.path.join(DATA_PATH, "{}_geo.svg".format(result)), dpi=150) result.save_edgelist( os.path.join(DATA_PATH, "{}.edgelist.gz".format(result)) ) plt.clf() while not queue.empty() and len(result) < max_nodes: node = queue.get() candidates = _restrict_potential_neighbors( node_selection.nodes, node_selection[node.uri], result ) if not candidates: continue if node == sink: # sink always has two neighbors num_neigh = 2 else: num_neigh = random.randint( min(min_neighbors, len(candidates)), min(max_neighbors, len(candidates)) ) neighbor_sample = random.sample(candidates, num_neigh) for neigh in neighbor_sample: if neigh not in visited: result.add_edge(node, neigh) if len(result) == max_nodes: _save_result() return result visited.add(neigh) queue.put(neigh) _save_result() return result
def non_sink_node_uris(self): return set(n for n in self.nodes if n != common.get_uri(self.site, self.sink))
def __getitem__(self, node): if not self._is_uri(node): node = common.get_uri(self.site, node) return super().__getitem__(node)