10 from __future__
import division, absolute_import, print_function, unicode_literals
12 from logging
import getLogger
16 logger = getLogger(__name__)
20 TIMEOUT = pyuavcan_v0.protocol.NodeStatus().OFFLINE_TIMEOUT_MS / 1000
21 TRANSFER_PRIORITY = pyuavcan_v0.TRANSFER_PRIORITY_LOWEST - 1
22 MIN_RETRY_INTERVAL = 0.5
39 self.
node_id = e.transfer.source_node_id
40 if self.
status and e.message.uptime_sec < self.
status.uptime_sec:
50 self.
node_id = e.transfer.source_node_id
51 self.
status = e.response.status
52 self.
info = e.response
65 EVENT_ID_INFO_UPDATE =
'info_update' 66 EVENT_ID_OFFLINE =
'offline' 99 callback: The specified callback will be invoked when: 101 - Node info for an existing node gets updated 103 Returns: Call remove() or try_remove() on the returned object to unregister the handler. 115 node_id: Returns True if the given node ID exists, false otherwise 122 node_id: Returns an Entry instance for the given node ID. 123 If the requested node ID does not exist, throws KeyError. 125 if (self.
_registry[node_id].monotonic_timestamp + self.
TIMEOUT) < time.monotonic():
132 """Returns a generator or an iterable containing all currently active node ID.""" 136 """Returns a generator that produces a sequence of Entry objects for which the predicate returned True. 138 predicate: A callable that returns a value coercible to bool. 140 for _nid, entry
in self.
_registry.items():
145 """Reports whether there are nodes whose node info is still unknown.""" 146 undiscovered = self.
find_all(
lambda e:
not e.discovered)
147 return len(list(undiscovered)) == 0
150 """Stops the instance. The registry will not be cleared.""" 155 for nid, e
in list(self.
_registry.items())[:]:
156 if (e.monotonic_timestamp + self.
TIMEOUT) < time.monotonic():
161 node_id = e.transfer.source_node_id
164 entry = self.
get(node_id)
168 entry._info_requested_at = 0
173 entry._update_from_status(e)
177 should_retry_now = entry.monotonic_timestamp - entry._info_requested_at > self.
MIN_RETRY_INTERVAL 179 if not entry.discovered
and should_retry_now
and not e.node.is_anonymous:
180 entry._info_requested_at = entry.monotonic_timestamp
182 entry._register_retry()
183 e.node.request(pyuavcan_v0.protocol.GetNodeInfo.Request(), node_id,
191 entry = self.
get(e.transfer.source_node_id)
194 self.
_registry[e.transfer.source_node_id] = entry
197 entry._update_from_info(e)
199 hw_unique_id =
"".join(
format(c,
"02X")
for c
in e.response.hardware_version.unique_id)
201 "[#{0:03d}:pyuavcan_v0.protocol.GetNodeInfo] " +
202 "software_version.major={1:d} " +
203 "software_version.minor={2:d} " +
204 "software_version.vcs_commit={3:08x} " +
205 "software_version.image_crc={4:016X} " +
206 "hardware_version.major={5:d} " +
207 "hardware_version.minor={6:d} " +
208 "hardware_version.unique_id={7!s} " +
211 e.transfer.source_node_id,
212 e.response.software_version.major,
213 e.response.software_version.minor,
214 e.response.software_version.vcs_commit,
215 e.response.software_version.image_crc,
216 e.response.hardware_version.major,
217 e.response.hardware_version.minor,
219 e.response.name.decode()
def find_all(self, predicate)
def _update_from_status(self, e)
def add_update_handler(self, callback)
def are_all_nodes_discovered(self)
def _update_from_info(self, e)
def _call_event_handlers(self, event)
def _on_node_status(self, e)
def __init__(self, remover)
def exists(self, node_id)
def __init__(self, entry, event_id)
def _on_info_response(self, e)
def _register_retry(self)
def get_all_node_id(self)