-
Notifications
You must be signed in to change notification settings - Fork 131
Example Process item
ggodart edited this page Jan 16, 2021
·
8 revisions
The process item allows you to run tasks in parallel to MisterHouse and is described in detail here.
The following are good practice and described in the code below;
- Always define a timeout to trap runaway tasks e.g.
$p_backup_data->set_timeout(600); # time out after 5 minutes
- Always redirect output to a log file so you can tell what happened e.g.
$p_backup_data->set_output($config_parms{data_dir} . "/logs/backup.txt" );
- Always have a
done_now
handler to check if it timed out or successfully finished - It is a good idea to have a general purpose process logging routine as in the example below, the downside of this example is that the print log is only updated AFTER the process finished and your log may thus have out-of-sequence entries. If you need real-time logging, please see below
#-----------------------------------------------------------------------
# create the process item and a voice command to run it
# only needs to be run once so wrap in noloop
#-----------------------------------------------------------------------
#noloop=start
$v_backup_data = new Voice_Cmd('{run, } backup');
$p_backup_data = new Process_Item;
#noloop=stop
#-----------------------------------------------------------------------
# voice command handler to launch the backup
#-----------------------------------------------------------------------
if ( $state = said $v_backup_data) {
print_log("Backup data launched");
# set up the process and start it
set $p_backup_data $config_parms{"code_dir"} . "/backup.sh";
$p_backup_data->set_output(
$config_parms{data_dir} . "/logs/backup.txt" );
$p_backup_data->set_timeout(600); # time out after 5 minutes
start $p_backup_data;
}
#-----------------------------------------------------------------------
# handler to run after the backup process ands
#-----------------------------------------------------------------------
if ( done_now $p_backup_data) {
if ( timed_out $p_backup_data) {
print_log('ERROR: backup.sh - timed out after 5 minutes');
}
print_process_log( "backup.txt", "backup data" );
}
#-----------------------------------------------------------------------
# utility subroutine called after any process ends to append its output
# to the print log, passed the name of the file to print
#-----------------------------------------------------------------------
sub print_process_log {
my ( $filename, $process_name ) = @_;
$filename = $config_parms{data_dir} . "/logs/" . $filename;
open( SOURCE, $filename );
while (<SOURCE>) {
chomp;
my $cline = $_;
print_log("$cline","DEBUG",$process_name );
}
close(SOURCE);
truncate $filename, 0;
}
The most flexible way to do this is to call MiterHouse print_log via an http call to a routine you have created to call print_log, here is an example;
########################################################################
# File : print_log.pl
########################################################################
# This cgi script prints to the log, its passed the message, severity and source
# e.g. http://IP:port/my_mh/print_log.pl?message=test%201&severity=INFORMATIONAL&source=web%20print_log
########################################################################
use strict;
my (
@t, $message, $severity, $source, $returnPage,
);
# get message, severity and source
my m$arg1 = shift;
@t = split( /=/, $arg1 );
$message = $t[1];
my $arg2 = shift;
@t = split( /=/, $arg2 );
$severity = $t[1];
my $arg3 = shift;
@t = split( /=/, $arg3 );
$source = $t[1];
my $returnPage = <<'END';
<html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport"
content="width=device-width, minimum-scale=1, maximum-scale=1"/>
<title>Get State</title>
</head>
<body>
END
$returnPage .= "Message=" . $message . "<br>\n";
$returnPage .= "Severity=" . $severity . "<br>\n";
$returnPage .= "Source = " . $source . "<br>\n";
print_log( $message, $severity, "web-" . $source );
$returnPage .= <<'END1';
</body>
</html>
END1
return &html_page( '', $returnPage );
print_log("my message","DEBUG","my process item");
########################################################################
# General Purpose routine to use http to print a log in new format
# passed message, severity and source
# my_mh/print_log.pl?message=mymess&severity=WARNING&source=source
########################################################################
sub print_log {
my ($message,$severity,$source) = @_;
my $url = "my_mh/print_log.pl?message=" . $message
. "&severity=" . $severity
. "&source=" . $source;
send_url_to_mh ($url);
}
########################################################################
# Minimal routine to send a url to MisterHouse, passed the url
# note my port is 8077
########################################################################
sub send_url_to_mh {
my $URL = $_[0];
my ($myIPaddress) = inet_ntoa( ( gethostbyname(hostname) )[4] );
$URL = "http://" . $myIPaddress . ":8077/" . $URL;
#if ( $debug == 1 ) { print "checking $URL\n"; }
my $ua = LWP::UserAgent->new;
$ua->timeout(5);
my $response = $ua->get($URL);
if ( $response->is_error ) {
print("Error with $URL");
return "error";
}
#if ( $debug == 1 ) { print "HTML response =" . $response->content . "\n"; }
return $response->content;
}