18 : ClientProfile(endpoint), _logBuffer(logBuffer)
20 _repl.install_window_change_handler();
27 std::lock_guard<std::mutex> guard(
_mutex);
37 return std::string(
"\x1b[1;32mswarm\x1b[0m> ");
41 return std::string(
"\x1b[1;32mmembr\x1b[0m> ");
64 else if (*input ==
'\0')
72 _repl.history_add(command);
95 if (awaiter.WaitForResponse(5
s))
100 std::cout <<
"Pingable: " << (response.echo_enabled() ?
"true" :
"false") << std::endl;
103 if (response.keyvalue_schema().fields_size() > 0)
105 std::cout <<
"Parameters: ";
107 std::cout << std::endl;
111 if (response.event_schema().fields_size() > 0)
113 std::cout <<
"Events: ";
115 std::cout << std::endl;
119 if (response.telemetry_schema().fields_size() > 0)
121 std::cout <<
"Telemetry: ";
123 std::cout << std::endl;
128 std::cout <<
"Discovery timed out." << std::endl;
133 if (report.values_size() > 0)
135 std::cout <<
"Current status: ";
137 std::cout << std::endl;
142 std::cout <<
"No member selected." << std::endl;
149 std::cout <<
"A global discovery request was sent." << std::endl;
159 if (awaiter.WaitForResponse(5
s))
162 switch (value.value_case())
164 case data::Variant::ValueCase::kBoolValue:
165 std::cout << (value.bool_value() ?
"true" :
"false") << std::endl;
168 case data::Variant::ValueCase::kDoubleValue:
169 std::cout << value.double_value() << std::endl;
172 case data::Variant::ValueCase::kIntValue:
173 std::cout << value.int_value() << std::endl;
176 case data::Variant::ValueCase::kStringValue:
177 std::cout <<
"\"" << value.string_value() <<
"\"" << std::endl;
181 std::cout <<
"<unknown>" << std::endl;
187 std::cout <<
"Timeout." << std::endl;
192 std::cout <<
"No resource path specified." << std::endl;
197 std::cout <<
"No member selected." << std::endl;
209 if (awaiter.WaitForResponse(5
s))
211 if (awaiter.GetResponse())
213 std::cout <<
"Value was set." << std::endl;
217 std::cout <<
"Request rejected." << std::endl;
222 std::cout <<
"Timeout." << std::endl;
227 std::cout <<
"Invalid number of parameters." << std::endl;
232 std::cout <<
"No member selected." << std::endl;
245 size = std::stoi(command.
GetPath());
248 if (size < 0 || size > 1024 * 1024 * 256)
250 std::cout <<
"Invalid ping packet size." << std::endl;
258 if (awaiter.WaitForResponse(5
s))
260 std::cout <<
"Response time: " << std::fixed << std::setprecision(2) << awaiter.
GetResponseInMilliseconds() <<
"ms" << std::endl;
264 std::cout <<
"Timeout." << std::endl;
269 std::cout <<
"No member selected." << std::endl;
278 data::event::Notification event;
279 event.set_name(command.
GetPath());
291 std::cout <<
"Event broadcasted." << std::endl;
296 if (awaiter.WaitForResponse(5
s))
298 if (awaiter.GetResponse())
300 std::cout <<
"Event handled remotely." << std::endl;
304 std::cout <<
"Event rejected." << std::endl;
309 std::cout <<
"Timeout." << std::endl;
315 std::cout <<
"No event specified." << std::endl;
321 std::lock_guard<std::mutex> guard(
_mutex);
325 std::cout <<
"MID" <<
"\t" <<
"UUID" <<
"\t" <<
"Class" <<
"\t" <<
"Name" << std::endl;
328 for (
unsigned i = 0; i <
_nodes.size(); ++i)
330 std::cout << i <<
"\t" <<
_nodes[i]->GetUUID() <<
"\t" <<
_nodes[i]->GetDeviceClass() <<
"\t" <<
_nodes[i]->GetName() <<
"\t" <<
_nodes[i]->GetDescription() << std::endl;
335 std::cout <<
"No swarm members found." << std::endl;
345 unsigned idx = std::stoul(command.
GetPath());
348 std::lock_guard<std::mutex> guard(
_mutex);
356 std::cout <<
"Invalid member index." << std::endl;
362 std::cout <<
"Member unselected." << std::endl;
366 std::cout <<
"No effect, no member was selected." << std::endl
367 <<
"To select a member, specify a MID." << std::endl;
377 std::cout <<
"Subscription #" << subscription.GetIdentifier() << std::endl;
378 std::cout <<
" " <<
"Node: " << subscription.GetTarget()->GetUUID() << std::endl;
379 if (subscription.WaitForResponse(0ms))
381 auto response = subscription.GetResponse();
384 std::cout <<
" " <<
"Tick: " << response.tick() << std::endl;
387 if (response.values_size() > 0)
389 std::cout <<
" " <<
"Current values: ";
391 std::cout << std::endl;
395 std::cout <<
" " <<
"Last update was empty." << std::endl;
400 std::cout <<
" " <<
"No update received so far." << std::endl;
406 std::cout <<
"No subscriptions." << std::endl;
415 uint32_t interval = 1;
416 auto intervalParameter = command.
GetParameters().find(
"interval");
419 interval = std::stoi(intervalParameter->second);
423 std::list<std::string> keys;
427 keys.push_back(keyParameter->second);
434 std::cout <<
"Subscribed." << std::endl;
439 std::cout <<
"No member selected." << std::endl;
445 uint64_t identifier = std::stoi(command.
GetPath());
450 std::cout <<
"Unsubcribed." << std::endl;
454 std::cout <<
"Not found." << std::endl;
464 std::cout <<
message.timestamp() <<
"\t" <<
message.level() <<
"\t" <<
message.message() << std::endl;
469 std::cout <<
"No log buffer found." << std::endl;
505 else if (
command.Is(
"rediscover"))
513 else if (
command.Is(
"subscriptions"))
517 else if (
command.Is(
"subscribe"))
521 else if (
command.Is(
"unsubscribe"))
532 std::cout <<
"Available commands:" << std::endl
533 <<
" - members" << std::endl
534 <<
" - rediscover" << std::endl
535 <<
" - info" << std::endl
536 <<
" - select [MID]" << std::endl
537 <<
" - event NAME [KEY=VALUE]..." << std::endl
538 <<
" - get KEY" << std::endl
539 <<
" - set KEY=VALUE" << std::endl
540 <<
" - subscriptions" << std::endl
541 <<
" - subscribe [key=KEY] [interval=N]" << std::endl
542 <<
" - unsubscribe [SID]" << std::endl
543 <<
" - ping [SIZE]" << std::endl
544 <<
" - help" << std::endl
545 <<
" - log" << std::endl
546 <<
" - exit" << std::endl;
551 std::cout <<
"Goodbye!" << std::endl;
559 std::cout <<
"Unknown command verb: " <<
command.GetVerb() << std::endl
560 <<
"Try 'help' to list available commands." << std::endl;
563 catch (
const std::exception& e)
565 std::cout << e.what() << std::endl;
574 if (std::regex_match(value, std::regex(
"[0-9]+", std::regex_constants::icase)))
577 data::Variant variant;
578 variant.set_int_value(std::stoi(value));
581 else if (std::regex_match(value, std::regex(
"[0-9]+\\.[0-9]+", std::regex_constants::icase)))
584 data::Variant variant;
585 variant.set_double_value(std::stod(value));
588 else if (std::regex_match(value, std::regex(
"true", std::regex_constants::icase)))
591 data::Variant variant;
592 variant.set_bool_value(
true);
595 else if (std::regex_match(value, std::regex(
"false", std::regex_constants::icase)))
598 data::Variant variant;
599 variant.set_bool_value(
false);
605 data::Variant variant;
606 variant.set_string_value(value);
virtual const std::string & GetDeviceClass() const =0
Get the class of the underlying device.
static void Trigger(Endpoint *endpoint, const data::event::Notification &event)
Trigger an event globally.
double GetResponseInMilliseconds()
Translate the precise response to a floating point number of milliseconds.
static void WriteToStream(std::ostream &stream, const Variant &value, bool prettyPrint=true, int indentationLevel=0)
Write a string representation of a variant to the stream.
DiscoveryAwaiter CachedQuery(const Node *node)
Send a Discovery query to a remote node, or if the information already exists in the cache...
static UpdateAwaiter Subscribe(Endpoint *endpoint, const Node *node, uint32_t interval=1)
Subscribe to all named values on the remote node.
static TimingAwaiter Ping(Endpoint *endpoint, const Node *node, size_t size)
Measure the latency to a remote node.
void FinishConstruction()
Called when the last constructor has finished its job.
swarmio::services::discovery::Service _discoveryService
Discovery service.
swarmio::services::telemetry::Service _telemetryService
Telemetry service.
void GlobalQuery()
Sends a global Discovery request.
data::telemetry::Status GetCachedStatus(const Node *node)
static ErrorAwaiter Set(Endpoint *endpoint, const Node *node, const std::string &path, const data::Variant &value)
Set a remote value.
ROSLIB_DECL std::string command(const std::string &cmd)
An Awaiter that has a longer lifetime and is updated periodically.
Abstract base class for Endpoint implementations.
Endpoint * GetEndpoint()
Get the associated Endpoint.
T GetResponse()
Get the response value. Will throw an exception if called before the response is received.
virtual const std::string & GetUUID() const =0
Returns the unique identifier of the node.
static ValueAwaiter Get(Endpoint *endpoint, const Node *node, const std::string &path)
Get a remote value.
virtual const std::string & GetName() const =0
Returns the (possibly non-unique) name of the node.
Represents a Node the Endpoint knows about and can send messages to.
swarmio::services::ping::Service _pingService
Ping service.