#!/usr/bin/env perl use strict; use warnings; use 5.020; our $VERSION = '0.00'; use File::Slurp qw(read_file); use Getopt::Long; use Net::MQTT::Simple; use Time::HiRes qw(usleep); my $mqtt_host; GetOptions( 'h|host=s' => \$mqtt_host, ); if ( not defined $mqtt_host or not length($mqtt_host) ) { die("Usage: $0 -h [topic=value ...]\n"); } my $mqtt = Net::MQTT::Simple->new($mqtt_host); my $retain = 0; sub parse_content_string { my ($raw_content) = @_; if ( $raw_content =~ m{ ^ / [^/] }x ) { my $content = read_file( $raw_content, { err_mode => 'carp' } ); if ( defined $content ) { chomp $content; } return $content; } # Allow //foo as escape for literal /foo messages $raw_content =~ s{ ^ / / }{/}x; return $raw_content; } for my $arg (@ARGV) { if ( $arg eq 'publish' ) { $retain = 0; } elsif ( $arg eq 'retain' ) { $retain = 1; } elsif ( $arg =~ m{ ^ (? [^=]+) = (? .*) $ }x ) { my $content = parse_content_string( $+{content} ); if ($retain) { $mqtt->retain( $+{topic}, $content ); } else { $mqtt->publish( $+{topic}, $content ); } } } # XXX Net::MQTT::Simple passes data to the socket layer, but does not wait for # it to be successfully sent. So (especially on fast systems, e.g. modern # Core i5/i7 CPUs) we might terminate before all data was transmitted, leading # to loss of some messages. # # Fixing this probably requires a dive into Net::MQTT::Simple and possibly # changes in its API, so let's dance the workaround dance for now. usleep(100_000); __END__ =head1 NAME =head1 SYNOPSIS =head1 VERSION =head1 DESCRIPTION =head1 OPTIONS =over =back =head1 EXIT STATUS =head1 CONFIGURATION None. =head1 DEPENDENCIES =over =back =head1 BUGS AND LIMITATIONS =head1 AUTHOR Copyright (C) 2017 by Daniel Friesel Ederf@finalrewind.orgE =head1 LICENSE 0. You just DO WHAT THE FUCK YOU WANT TO.