App-mqtt2job

 view release on metacpan or  search on metacpan

lib/App/mqtt2job.pm  view on Meta::CPAN

package App::mqtt2job;

use strict;
use warnings;

use Template;
use File::Temp;
use Exporter qw/import/;

# ABSTRACT: Helper module for mqtt2job

our @EXPORT_OK = qw/ helper_v1 ha_helper_cfg /;

sub helper_v1 {
    my ($obj) = @_;

    my $unlink = $obj->{rm} ? 1 : 0;

    # helper scripts need to be saved, so set up & prepare a filehandle
    my $fh = File::Temp->new( SUFFIX => "." . ($obj->{suffix} || "pl"), UNLINK => $unlink );
    $obj->{wrapper_location} = $fh->filename;
    
    my $tt = Template->new();
    my $ttout = undef;
    
    $tt->process( _helper_v1(), $obj, \$ttout );

    return _save($fh, $ttout, $obj->{rm});
}

sub ha_helper_cfg {
    my ($obj) = @_;

    my $tt = Template->new();
    my $ttout = undef;
    
    $tt->process( _ha_helper_cfg(), $obj, \$ttout );

    return $ttout;
}

sub _save {
    my ($fh, $output) = @_;
    print $fh $output;
    return $fh;
}

sub _helper_v1 {
    my $tpl = undef;
    $tpl = <<'_RUNNER_TPL';
#![% shebang %]

use strict;
use warnings;

use Net::MQTT::Simple;
use DateTime;
use JSON; 
use Capture::Tiny ':all';

my $dt_start = DateTime->now();
my $mqtt = Net::MQTT::Simple->new("[% mqtt_server %]:[% mqtt_port %]");

$mqtt->retain("[% base_topic %]/status/" . "[% task || "unknown" %]", encode_json({ status => "initiated", dt => "$dt_start", msg => "[% cmd %]" }) );
my $real_cmd = "[% job_dir %]/[% cmd %]";
my $real_args = "[% args %]";

print STDERR "$dt_start: [MQTT TASK] $real_cmd $real_args\n";

my ($output, $exit) = tee_merged {
    my @args = split(" ", $real_args);
    system($real_cmd, @args);
};

my $msg = ($exit == 0) ? "ok" : "failed";

my $dt_end = DateTime->now();
my $dt_elapsed_obj = $dt_end - $dt_start;
my $dt_elapsed = $dt_elapsed_obj->in_units("seconds");

my @split_output = split("\n", $output);
my $last_line = $split_output[$#split_output];

$output =~ s/\n//g;

$mqtt->retain("[% base_topic %]/status/" . "[% task || "unknown" %]", encode_json({ status => "completed", dt => "$dt_end", last_line => "$last_line", output => "$output", elapsed => "$dt_elapsed", msg => "$msg" }) );
print STDERR "$dt_end: [MQTT TASK] $real_cmd $real_args (${dt_elapsed}s) Exit: $exit\n";

$mqtt->disconnect;
[% UNLESS no_unlink %]unlink "[% wrapper_location %]";[% END %]
_RUNNER_TPL
    return \$tpl;
}

sub _ha_helper_cfg {
    my $tpl = undef;
$tpl = <<'_HA_CFG_TPL';
=====================================================================
TRIGGER: (automation)
=====================================================================
alias: mqtt2job [% task %]
description: ""
triggers:
  - seconds: "0"
    trigger: time_pattern
    enabled: true
conditions: []
actions:
  - action: mqtt.publish
    metadata: {}
    data:
      topic: [% base_topic %]
      payload: |-
        { 
          "cmd": "[% cmd %]",
          "args": "[% args %]", 
          "dt": "{{ now().strftime("%Y-%m-%d %H:%M:%S") }}",
          "task": "[% task %]",
          "status": "queue"
        }
mode: single

=====================================================================
SENSORS: (configuration.yaml)
=====================================================================
  sensor:
    - name: "[% task %] status"
      state_topic: "[% base_topic %]/status/[% task || "unknown" %]"
      value_template: "{{ value_json.status }}"
    - name: "[% task %] datetime"
      state_topic: "[% base_topic %]/status/[% task || "unknown" %]"
      value_template: "{{ value_json.dt }}"
    - name: "[% task %] message"
      state_topic: "[% base_topic %]/status/[% task || "unknown" %]"
      value_template: "{{ value_json.msg }}"
    - name: "[% task %] elapsed"
      state_topic: "[% base_topic %]/status/[% task || "unknown" %]"



( run in 0.818 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )