AnyEvent-MQTT
view release on metacpan or search on metacpan
bin/anyevent-mqtt-monitor view on Meta::CPAN
my $man;
my $verbose = 0;
my $retain = 1;
my $history_size = 20;
my $host = '127.0.0.1';
my $port = 1883;
my $qos = MQTT_QOS_AT_MOST_ONCE;
my $keep_alive_timer = 120;
GetOptions('help|?' => \$help,
'man' => \$man,
'verbose+' => \$verbose,
'retain!' => \$retain,
'history-size=i' => \$history_size,
'host=s' => \$host,
'port=i' => \$port,
'qos=i' => \$qos,
'keepalive=i' => \$keep_alive_timer) or pod2usage(2);
pod2usage(1) if ($help);
pod2usage(-exitstatus => 0, -verbose => 2) if $man;
my $mqtt =
AnyEvent::MQTT->new(host => $host, port => $port,
keep_alive_timer => $keep_alive_timer,
on_error => sub {
my ($fatal, $message) = @_;
if ($fatal) {
die $message, "\n";
} else {
warn $message, "\n";
}
});
foreach my $topic (scalar @ARGV ? @ARGV : '#') {
$mqtt->subscribe(topic => $topic, callback => \&log, qos => $qos);
}
my %d;
my $win = Gtk2::Window->new('toplevel');
$win->set_title('MQTT Monitor');
$win->set_default_size(400, 400);
my $vbox = Gtk2::VBox->new(0,0);
$win->add($vbox);
my $slist = Gtk2::SimpleList->new('Topic' => 'text',
'Message' => 'text',
'Time' => 'text');
$slist->signal_connect(button_press_event => \&button_press);
$slist->set_rules_hint(1);
$slist->get_selection->set_mode('single');
$slist->get_selection->unselect_all;
@{$slist->{data}} = ();
my $scrolled = Gtk2::ScrolledWindow->new;
$scrolled->set_policy('automatic', 'automatic');
$scrolled->add($slist);
$vbox->add($scrolled);
foreach (['Quit' => sub { Gtk2->main_quit }]) {
my $button = Gtk2::Button->new($_->[0]);
$button->signal_connect(clicked => $_->[1]);
$vbox->pack_start($button, 0, 0, 0);
}
my $menu = Gtk2::Menu->new();
$menu->set_name('client menu');
my $tearoff = Gtk2::TearoffMenuItem->new();
$menu->append($tearoff);
$tearoff->show;
foreach (['History' => \&history_callback]) {
my ($title, $cb) = @$_;
my $item = Gtk2::MenuItem->new($title);
$item->signal_connect('activate', $cb);
$menu->append($item);
$item->show;
}
$win->show_all;
my $dialog = Gtk2::Window->new();
$dialog->signal_connect("destroy", sub { $dialog->hide(); 1; });
$dialog->set_role('dialog');
$dialog->realize();
my $hist_list = Gtk2::SimpleList->new('Time' => 'text',
'Summary' => 'text');
$hist_list->set_rules_hint(1);
$hist_list->signal_connect(button_press_event => \&hist_button_press);
my $dialog_vbox = Gtk2::VBox->new(0,0);
$dialog->add($dialog_vbox);
$dialog_vbox->add($hist_list);
my $hide_button = Gtk2::Button->new('Hide');
$hide_button->signal_connect(clicked => sub { $dialog->hide(); 1; });
$dialog_vbox->add($hide_button);
my $hist_menu = Gtk2::Menu->new();
$hist_menu->set_name('hist menu');
my $hist_tearoff = Gtk2::TearoffMenuItem->new();
$hist_menu->append($hist_tearoff);
$hist_tearoff->show;
foreach (['Dump' => \&dump_callback]) {
my ($title, $cb) = @$_;
my $item = Gtk2::MenuItem->new($title);
$item->signal_connect('activate', $cb);
$hist_menu->append($item);
$item->show;
}
Gtk2->main;
sub log {
my ($topic, $message, $obj) = @_;
return unless ($retain || !$obj->retain); # skip retained messages
my $t = time;
$d{src}->{$topic} = {} unless (exists $d{src}->{$topic});
my $r = $d{src}->{$topic};
unshift @{$r->{hist}}, [$obj, $t];
if (scalar @{$r->{hist}} > $history_size) {
pop @{$r->{hist}};
}
$r->{last} = $obj;
$r->{last_time} = $t;
$r->{last_time_str} = strftime($timefmt, localtime($t));
$r->{last_summary} = $message;
add_to_list($topic);
}
sub add_to_list {
my ($src) = @_;
my @row = $src;
foreach (qw/last_summary last_time_str/) {
push @row, $d{src}->{$src}->{$_};
}
insert($slist->{data}, \@row);
$d{src}->{$src}->{row} = \@row;
return 1;
}
sub insert {
my ($list, $row, $key, $first, $last) = @_;
$key = $row->[0] unless (defined $key);
$first = 0 unless (defined $first);
$last = (scalar @$list) - 1 unless (defined $last);
# print STDERR "insert: $first $last $key\n";
if ($last == -1) {
# print "inserting in empty list\n";
push @$list, $row;
return;
}
my $first_key = $list->[$first]->[0];
my $last_key = $list->[$last]->[0];
if ($first_key eq $key) {
# print "overwriting at ", $first, " c\n";
$list->[$first] = $row;
return;
}
if ($first_key gt $key) {
# print "inserting at ", $first, " c\n";
splice @$list, $first, 0, $row;
return;
}
if ($key eq $last_key) {
( run in 2.761 seconds using v1.01-cache-2.11-cpan-364913b4093 )