-
Notifications
You must be signed in to change notification settings - Fork 130
Functions
- set_by_to_target
- add_sound
- browser
- convert_k2f and convert_c2f
- convert_direction
- dbm_write-item-logit_dbm
- dbm_read
- dbm_search
- display
- eval_with_timer
- file_backup
- file_cat
- file_changed
- file_default
- file_diff
- file_size
- file_read
- file_read_dir
- file_tail
- file_unchanged
- file_write
- filter_cr
- logit
- mht_item_add, mht_item_delete, mht_item_copy, mht_item_write
- play
- print_log, print_log_simple, print_log_simple, print_msg, print_speaklog
- round
- run
- run_after_delay
- run_voice_cmd
- SendKeys, WaitForAnyWindow, SetWindowText, GetWindowText, SetFocus, EnumChildWindows, sendkeys_find_window
- respond
- speak
- time_add
- time_diff
- time_date_stamp
- time_cron
- time_greater_than, time_greater_or_equal, time_less_than, time_less_or_equal
- time_between
- time_now
- time_random
- time_random_offset
- write_mh_opts
- new_second, new_minute, new_hour
- get
- get_ip_addresses
- html_unescape
- net_domain_name 'address', net_domain_name_start 'search_name', 'address', net_domain_name_done 'search_name'
- net_ping
- net_ftp
- net_connect_check
- net_socket_check
- net_im_send
- net_mail_send
- net_mail_count
- net_mail_summary
- net_mail_read
- net_mail_delete
Checks to see if identified device is already in the chain of set_by devices. Basically identifies never ending loops of setting objects.
Returns:
If no_strip is set to true:
The original object which initiated this action, OR the same set_by object if it appears in the set_by list already.
If no_strip is set to false or undef:
Undef, unless would return something which is not an object, then it returns the text preceding a [, such as web, email, ...
Assigns a sound file to an event name. This allows us to create and review event sounds. See mh/code/common/event_sounds.pl for an example.
Example:
add_sound barcode_scan => 'sound_nature/bird.wav', volume => 20 if $Reload;
if ($state = state_now $barcode_scan) {
play 'barcode_scan';
}
Calls up the web browser defined my the mh.ini browser parm
Examples:
browser 'http://misterhouse.net';
browser "$config_parms{tracking_dir}/today.html" if said $v_show_tracking;
Converts from degrees Kelvin/Centigrade to Farenheight
Example:
$weather{TempF} = convert_c2f($weather{TempC});
Here is a complete list of conversion functions:
convert_k2f # Convert degrees Kelvin to Farenheight
convert_c2f # Convert degrees Celsius to Farenheight
convert_f2c # Convert degrees fahrenheit to celsius
convert_f2k # Convert degrees fahrenheit to kelvin
convert_in2mb # Convert to inches of mercury to millibars
convert_in2mm # convert inches (per hour) to millimeters (per hour)
convert_km2mile # convert kilometers (per hour) to miles (per hour)
convert_mb2in # Convert millibars to inches of mercury
convert_mile2km # convert miles (per hour) to kilometers (per hour)
convert_mm2in # convert millimeters (per hour) to inches (per hour)
convert_mps2mph # convert meters per second to miles per hour
convert_mps2mph # convert miles per hour to meters per second
Converts 0->360 degrees into north, north east, east, etc
Example:
speak "Wind speed is " . round($weather{WindAvgSpeed}) .
" from the " . convert_wind_direction($weather{WindAvgDir});
Writes data into a dbm file. If data for that key exists, it is overwritten. dbm files are useful if you want to store key-value data or hash arrays onto disk for later use.
Usage:
dbm_write($log_file, $log_key, $log_data);
logit_dbm($log_file, $log_key, $log_data);
dbm_write simply stores data as is: $dbm_file{$log_key}=$log_data
logit_dbm also stores an access count: $dbm_file{$log_key}="$access_count $log_data"
Examples:
logit_dbm("$Pgm_Root/data/phone/callerid.dbm",
$cid_number, "$Time_Now $Date_Now $Year name=$cid_name");
See display_callers for an example of how to read dbm files.
Read data from a dbm file. If a key is passed, only that one record is returned. Otherwise, the whole dbm is read.
Usage:
$value = read_dbm($dbm_file, $key);
%data = read_dbm($dbm_file);
Search a dbm file for matches to a string. It currently searches both key and value.
Usage:
($count_searched, $count_matched, %results) = search_dbm($dbm_file, $search_string);
See mh/code/bruce/phone.pl and mh/bin/display_callers for examples.
Displays the specified text string, text file contents, or bitmap (.gif or .jpg).
Simple mode:
display $file_or_text, $time, $title, $font, $window_name, $append;
Options mode:
display option => 'value', text => $file_or_text;
Options:
$time is how long (in seconds) till the box will auto-close.
Defaults to 120. Use 0 to disable auto-close.
$title is the title of the display box.
$font is the font (default is mh.ini parm tk_font).
$window_name will re-use an exisiting display window of the same name.
$append can be top or bottom. Only meaningful with $window_name.
width and height overrides the auto-calculated values based on text
geomeotry places the window: +X+Y (e.g. +0+0 for upper left)
device Use this to pick a specific display. For example,
device=alpha will display data with the &display_alpha function.
app This uses the parms defined in the the mh.ini display_app parm.
This allows us to use custom parms with generic, common code.
Examples:
display "Internet message: $msg", 300, 'Internet message';
display $f_trivia_answer;
display '/pictures/photo.jpg';
display text => $log, time => 0, font => 'fixed', window_name => 'log';
display text => $text, time => 0, window_name => 'AIM', append => 'top';
display text => $f_top10_list, time => 300, font => 'Times 25 bold',
geometry => '+0+0', width => 72, height => 24;
display "device=alpha $caller";
display "app=bingo $bingo_text";
display app => 'bingo', text => $bingo_text;
If -tk 1 (i.e. Tk is installed and used), the data is displayed in a Tk popup window. If -tk 0 or the data is echoed to the console.
If the data is requested from a web browser, the data is echoed to the browser print_log window. It will be displayed to a local tk window only if the $time parm
is specified.
Use this to run some code after some delay.
Usage:
eval_with_timer $code, $time;
Examples:
eval_with_timer 'print_log "hi from the past"', 60;
eval_with_timer '$Misc{insult}{flag} = 1', 2; # Sets flag after 2 seconds
If you want to do this with an item state, use the set_with_timer
method.
Renames or optionally copies a file to the same name with the "backup1" extension. If the backup1 file already exists, it is renamed to backup2 first, backup2 is renamed to backup3, backup3 is renamed to backup4, and backup4 is deleted.
Examples:
file_backup $log_file, "force";
file_backup $parm_file, "copy";
Normally, this function will only run if the file is older than ten minutes. Use the "force" option if you want to override this behavior. Use the "copy" option if you want to copy the file instead of renaming it. The "copy" option implies "force".
Concatonates data from one file onto another. If an optional 3rd parm of 'top' is specified, the first files is added to the top of the 2nd file. If not, then it is added to the bottom.
Examples:
file_cat $file, $file_total;
file_cat "$config_parms{html_dir}/aprs/week2.html",
"$config_parms{html_dir}/aprs/old/${Year_Month_Now}.html",
'top';
Returns 1 if the specified file has change since last checked. Returns 0 if the file has not changed. Returns undef if we don't know (i.e. first check after MisterHouse was started).
Example:
print_log "File $file has change" if file_changed($file);
Checks to see if a file exists, and if not, returns a default file instead.
Usage:
file_default $file, $default;
Examples:
$f_insult = new File_Item(&check_default_file($config_parms{speak_insult_file},
"$config_parms{data_dir}/remarks/insults1.txt"));
Returns true if the contents of the 2 specified files are different.
Example:
print_log "Files are different" if file_diff($file1, $file2);
```perl
### `file_head`
Returns the first few lines of a file
Example:
```perl
@data = file_head($file, $lines);
If $lines is not specified, the default is 3. If used in a list context, a list is returned, otherwise a string of all the requested lines is returned.
Returns the size of a file, in bytes.
Reads data from a file. If used in a list context, a list is returned, otherwise a string of all the lines.
Examples:
@data = file_read($file);
$data = file_read($file);
Returns a member => full_path hash for all members in all dirs passed to it.
Examples:
my %file_paths = &file_read_dir(@Code_Dirs);
for my $member (keys %file_paths) {
next unless $member =~ /(\S+).menu$/i;
menu_parse file_read $file_paths{$member}, $1;
}
Returns the last few lines of a file
Example:
$data = file_tail($file, $lines);
If $lines
is not specified, the default is 3.
If used in a list context, a list is returned,
otherwise a string of all the requested lines is returned.
Returns 0 if the specified file has change since last checked. Returns 1 if the file has not changed. Returns undef if we don't know (i.e. first check after MisterHouse was started).
Example:
my $watchdog_file = '//dm/d/misterhouse/mh/data/mh.time';
if (file_unchanged $watchdog_file) {
speak "MisterHouse has stopped running on the Nick's box";
set_with_timer $watchdog_light '20%', 5;
}
Writes data into a file. Like logit, except it writes over, rather than appends to, a file.
Examples:
file_write($file, $data);
Returns the given string, with carriage returns and line feeds filtered out
Examples:
print_log filter_cr get "$URL/play?p=$config_parms{mp3_program_password}";
Appends data into a log file. Use file_write to write over a file.
Usage:
logit($log_file, $log_data, $log_format, $head_tail);
$log_format=0 => Data is written as is, no /n, no time_date stamp.
$log_format=## => Every log entry is preceded with a time_date stamp.
## is passed to &time_date_stamp to determine the format.
Also, /r/n is stripped so we get only one record per call.
The default $log_format is 14.
$head_tail => If 1, data is logged to the top of the file, otherwise
it is added to the bottom.
Examples:
logit("$Pgm_Root/data/logs/wx200.$Year_Month_Now.log", $data, 0);
logit("$Pgm_Root/data/phone/logs/callerid.$Year_Month_Now.log", "$cid_number $cid_name");
These functions can be used to manipulate mht files.
Use this to play wave or system sound files. There are 2 modes of calling it:
Simple mode:
play $file_name
Options mode:
play(option => 'value', file => $file_name);
Options are:
address => 'ip_address' Use this to push wav files to
remote computers that are enabled to received
pushed wav files (e.g. Audreys). Configure
with the mh.ini parm voice_text_address_code.
Can be a comma delimited list of addresses.
rooms => 'room_names' You need to code a &Play_pre_add_hook to enable this.
See mh/code/bruce/pa_control for an example.
volume=> dd How loud (dd = 0->100).
time => $time The amount of time to leave the PA speakers on for rooms
mode => $mode $mode can be:
wait : MisterHouse will pause (hang), until wav file finishes
loop : MisterHouse will loop on the wav file
stop : MisterHouse will stop playing the previous file
async : MisterHouse will play wave file asynchronously (in the background). This is the default.
mode => 'unmuted' Forces speech, even in mute and offline mode
nolog => 1 Does not log $file_name to the speech log.
app => 'xyz' This uses the parms defined in the xyz section of
the mh.ini speak_app parm. This allows us to use custom
parms with generic, common code.
You can control the default mode parm with the mh.ini
play_mode
parm.
If $file_name
is a blank or comma delimited list of files, they are played sequentially. If it is a wild-carded file specification (e.g. "movement*.wav"
), then a file is picked at random from the files that match.
If the file does not include a path specification, the file is looked for in the mh/sounds directory
.
If the file starts with System
or with sound_
, the sound file is NOT logged in the speak log.
Here are the names of some of the Windows System sounds. Use the Control Panel Sounds menu to change their associated wav files:
- MenuPopup
- SystemDefault
- SystemAsterisk
- SystemExclamation
- SystemExit
- SystemHand
- SystemQuestion
- SystemStart
Examples:
# Play a random 'garage open/close' wav file
if($state = state_now $garage_door) { # $state will be open or close
play(rooms => 'all', file => "garage_door_" . $state . "*.wav");
}
play(file => 'SystemAsterisk') if $Reload;
play "fun/*.wav" if time_cron '* 9 * * 6';
play address => '192.168.0.82,kitchen', file => '../sounds/hello_from_bruce.wav';
Use these to print to the various logs. These logs are listed in Tk and web frames.
NOTE: These docs refer to MisterHouse versions after pull request #820 when print_log
was renamed to print_log_simple
and the new print_log
was created with the overloaded functionality to provide the ability to substitute your own print_log_private
subroutine and provide a severity
and a source
(see mh/code/examples/print_log_private.pl
). See here for more on logging.
Function | Description |
---|---|
print_log(message, severity, source) |
Used to log messages to a print file or, when combined with a print_log_private subroutine, to customize handling of log messages. Without a print_log_private subroutine the message are logged to a file in the directory pointed to by the mh.ini parameter data_dir ).message the message to print,severity - (optional) one of EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFORMATIONAL, NONE or DEBUG. If NONE is set, the print_log_private should not print anythingsource (optional) - where was the message generated, e.g. my_subroutine If the implementation has defined a print_log_private() subroutine, this will be called with the (message, severity, source) parameters, if not print_log_simple is called with the message concatenated with the severity and source. |
print_log_simple(message) |
Typically not called directly except from a print_log_private subroutine. You can prefix the text with log=my_logfile . For example: print_log_simple 'log=test1.log This message is logged in test1.log'; If you pass multiple arguments to this function, it will print them with a space between, just as the perl print function does. |
print_msg(message) |
Typically used for less frequent, more important messages. This is not currently shown on the default web windows. If you pass multiple arguments to this function, it will print them with a space between, just as the perl print function does. |
print_speaklog(message) |
Called by the speak and play functions, so should not be normally used in user code. If you pass multiple arguments to this function, it will print them with a space between, just as the perl print function does. |
Use this function to round off a number. Usage:
round $number, $digits
If $digits < 10
, $number
is rounded to $digits
to the right of the decimal
If $digits >= 10
, $number
is rounded to $digits
nearest $digits
Examples:
$time_left = round $time_left, 1; Round to nearest tenth
$time_left = round $time_left, 2; Round to nearest hundredth
$rank = round $1, 100; # Round to nearest 100
$rank = round $1, 1000; # Round to nearest 1000
You can use the run function to run a program as a separate process. On Windows, the perl Win32::Process
function is used, and on Unix, the program is forked with &.
If you specify 'inline'
as the first argument, the program will not be a background process/forked. MisterHouse will pause until the program is done.
If you want to track when the process finishes, use a Process_Item instead.
Examples:
run('IR_cmd VCR,3,6,RECORD'); # Start a VCR recording run 'rasdial /disconnect'; # Log off from the net (on Windows) run 'inline', 'some_fast_command_here'; run 'mplayer.exe /play /close c:\win98\media\canyon.mid'; # Play a midi file
You can use this to create events with built in delays without causing MisterHouse to pause
Example:
# After 2 seconds, this evals the print_log string
run_after_delay 2, "print_log 'Ending delay test 1'";
# This runs anonymous subs to print after 2 and 3 seconds.
run_after_delay 2, sub {
print_log "Printed after 2 seconds";
run_after_delay 1, sub {
print_log "Printed after 1 more second seconds";
}
}
You can use this to have one event trigger another voice command event.
Example:
run_voice_cmd 'Get the top10 list' if time_now('6:30 AM');
SendKeys
, WaitForAnyWindow
, SetWindowText
, GetWindowText
, SetFocus
, EnumChildWindows
, sendkeys_find_window
On Windows systems, use these functions to control other programs. Full documentation is mh/lib/site/Win32/setupsup.html
.
SendKeys($window, $keystr, $activate, [$timeout])
WaitForAnyWindow($title, \$window, $timeout, [$refresh])
SetFocus($window)
EnumChildWindows($window, \@childs)
WaitForAnyWindow
will set the window handle for the window that matches the (sub)string specified in $title.
WaitForWindow
is like WaitForWindow
, but requires an exact string match for the window title.
SetWindowText
is useful in changing a generically named window to a specific name that can then be accessed via WaitForAnyWindow. Also, since WaitForAnyWindow
will match the first (left most) part of any title, GetWindowText
allows one to get window specific info that can be used to determine the status of the window application.
SendKeys
sends the keys. Here is an excerpt of the valid key list:
ALT+ alt down ALT- alt up CTRL+ ctrl down CTRL- ctrl up SHIFT+ shift down SHIFT- shift up
TAB tabulator RET return ESC escape BACK backspace DEL delete INS insert HELP help
LEFT arrow left RIGHT arrow right UP arrow up DN arrow down PGUP page up PGDN page down
BEG pos1 END end F1 function 1 ... F12 function 12
NUM0 0 on the num block ... NUM9 9 on the num block
NUM* multiply key on the num block
NUM+ add key on the num block NUM- minus key on the num block NUM/ divide key on the num block
SetFocus
sets the focus to $window
. It does not activate the window (the foreground application will not be changed if $windows
belongs to another application).
EnumChildWindows
enumerates all child windows that belong to $window and returns the handles in the @childsCODE>
array. $window
must be a valid window handle @childs
must be an array reference.
sendkeys_find_window
is a MisterHouse subroutine that calls WaitForAnyWindow
. If the window is not found and $program
is specified, it will start $program
and wait for the window to appear, then return the window handle.
sendkey_find_window($title, [$program]);
Here are a few examples:
# Start winamp, if it is not running
unless (&WaitForAnyWindow('Winamp', \$window, 100,100)) {
print_log "Starting winamp";
run $config_parms{mp3_program};
}
# Send/receive mail, using sendkeys_find_window to start the program
# if it is not already running
if (my $window = &sendkeys_find_window('Outlook', 'D:\msOffice\Office\OUTLOOK.EXE')) {
my $keys = '\\alt+\\tss\\alt-\\'; # For Outlook Express
my $keys = '\\alt\\te\\ret\\'; # For Outlook
&SendKeys($window, $keys, 1, 500);
}
This function can be used to send the resulting text of a command or query to a specified target. By default, valid targets are:
display -> Text is passed to the display function.
email -> Text is passed to net_mail_send
im -> Text is passed to net_im_send
log -> Text is passed to print_log
speak -> Text is passed to speak
tk -> Text is passed to speak (or display if long)
web -> Text is passed to the web browser.
All parms given to respond are passed to the target function. So, for example, you can specify a specific email account using the to parm, like this:
respond target => 'email', to => '[email protected]', text => 'Alarm just went off';
or as with the speak and display functions, you can specify your parms in-line, like this:
respond 'target=im [email protected] pgm=jabber Alarm just went off';
The default respond target it whatever set_by
is, so for example, if a command is run from an im
client, text sent to any respond called by that command will be sent only to that `im client. You can also specify multiple targets. For example:
respond 'target=speak,im,email app=notice The fire alarm just went off';
In this case, the app parm is only recognised by the speak function, and would be ignored by the im
and email functions.
When called with no target, the default is to speak, or display if the text is long.
You can specify new targets, or override the default target response of the above default targets, by creating respond_xyz
functions in your user code. So for example, if we had callerid
code with this:
$caller = "Call from $caller. Call is from $caller.";
respond("app=phone target=callerid $caller");
You could add this function anywhere in your user code to change how it is spoken and to forward the call to your im
client:
sub respond_netcallerid {
my (%parms) = @_;
$parms{text} =~ s/ ?\.[^\.]*$/\./; # Drop the extra 'call from'
&net_im_send(pgm => "AOL', text => $parms{text});
&speak("app=phone $parms{text}");
}
Passes specified text to the TTS program. There are 2 modes of calling it:
Simple mode:
speak 'text to speak';
speak 'option=value text to speak';
Options mode:
speak(option => 'value', text => 'text to speak');
Default options can be specified with mh.ini
parms, using a speak_ prefix
. For example: speak_voice = mike
Options are:
address => 'ip_address' Use this to push TTS synthesized wav files to
remote computers that are enabled to received
pushed wav files (e.g. Audreys). Configure
with the mh.ini parm voice_text_address_code.
Can be a comma delimited list of addresses.
rooms => 'room_names' You need to code a &Speak_pre_add_hook to enable
this. See mh/code/bruce/pa_control for an example.
mode => 'unmuted' Forces speech, even in mute and offline mode
nolog => 1 Does not log the spoken text to the speech log.
app => 'xyz' This uses the speak parms defined in the xyz section of
the mh.ini speak_app parm. This allows us to use custom
speak parms with generic, common code.
These options are for the Unix Festival speech engine (but don't work yet):
rate => '+-nn%' (e.g. +10% or -30%)
voice => 'name'
These are for Unix IBM ViaVoice TTS engine (mh.ini sound_program=vv_tts):
default_volume xyz => default volume when -volume not set
volume xyz => volume setting for both play and voice unless specified
voice_volume xyz => voice volume setting
voice xyz => voice #
nomixer => do not use built in mixer support
play xyz => play's sound file xyz
These options are currently for the windows MS TTS engine only.
mode => any of the following
stop, pause, resume, rewind, fastforward, slow, normal, fast, dd
voice => 'name'
This can be any voice listed in the mh.ini voic_names parm or
any of the following:
random => randomly selects a voice
next => selects the next voice in the voice_names list
all => uses a different voice for each word. Note this was
inspired by dictionaraoke.org, but not all that useful.
Only works with xml enabled engines (MSV5 and NaturalVoice)
volume => dd (dd = 0 -> 100).
rate => fast,normal,slow,dd
For the V4 engine, dd is words per minute.
For the V5 engine, dd is -10 -> 10 for slowest to fastest
pitch => dd (dd = -10 -> 10)
card => d (d = 1,2,3...) Picks which sound card to used (MSV5 only)
d can also be a text string, if you use the mh.ini voice_text_cards option
to define which cards to enable (e.g. voice_text_cards = live,audigy).
To output to more than one card, specify a comma delimited list.
to_file => xyz. Saves speech to file xyz.
With the MS TTS V4 engine, the rate parm effects all subsequent spoken text (volume and voice parms do nothing).
With the MS TTS V5 engine, the volume, rate, and voice parms will effect
only the specified text. If you want to change the default for all text,
specify the parm, but no text (e.g. speak voice => 'Sam'
)
The MS TTS V5 engine also supports embedded XML parms for other controls (e.g. pitch,
silence, pronounce, emphasis). See mh/doc/ms_speech_xml_example.*
for examples.
You can use the mh.ini voice_names
parm to correlate generic voice names to
specific names. For example:
voice_names = female=>Crystal, male=>Rich16, male1=>Rich16, male2=>Mike,
Rich=>Rich16, Mary=>Crystal, Sam=>Mike
Using voice=none will
cause no text NOT to be spoken.
Examples:
$test_voice1 = new Voice_Cmd "Say something with at a volume of [50,100]";
$test_voice2 = new Voice_Cmd "Say something at a [fast,slow,normal] speed";
$test_voice3 = new Voice_Cmd "Say something in voice [male,female]";
speak(volume => $state,
text => "This is an example at a volume of $state") if $state = said $test_voice1;
speak(rate => $state,
text => "This is an example at a rate of $state") if $state = said $test_voice2;
speak(voice => $state,
text => "This is an example of a $state voice") if $state = said $test_voice3;
$Save{mode} = 'mute' if time_cron '0 10-21 * * 1-5';
speak 'mode=unmuted The front door just opened';
speak mode => 'pause';
speak mode => 'resume', rate => 120;
speak "address=bedroom,kitchen Wake up or die!";
speak "Now I am really, <pitch absmiddle='10'/>really excited!"
speak to_file => "$config_parms{data_dir}/test_tts.wav",
text => read_next $house_tagline if $New_Minute;
speak app => 'email', text => 'You have new email';
speak app => 'timer', text => 'The timer has expired';
More examples can be found in mh/code/common/test_speak.pl
Use this to add/delete an offset to a time value, using the same syntax as offsets allowed for in time_now.
Examples:
my $fishtank_light_on_time,$fishtank_light_off_time,$fishtank_light_duration;
if ($Startup) {
$fishtank_light_on_time = time_add "$Time_Sunrise_Twilight+3:00";
$fishtank_light_off_time = time_add "$Time_Sunset_Twilight+4:00";
$fishtank_light_duration = time_add "$fishtank_light_off_time-$fishtank_light_on_time";
}
This function returns the time difference between 2 time values. The roundoff time unit is dependent on how big the difference is between the 2 times. For example, if the time difference is > 5 days, the returned value will be in days.
Examples:
my $diff = time_diff $Moon{time_full}, $Time;
speak "The last full moon was $diff ago";
You can use this function to return a time/date string.
Usage:
time_date_stamp($format, $file_or_time);
$format can be any of the following:
1: Sunday, 12/25/99 01:52 PM
2: Sunday Dec 25 13:52 1999 (seems to be more compatible with javascript parsing)
3: Sunday, Dec 25 at 1 PM
4: 1:52 PM on Sunday, Dec 25
5: 1:52 PM
6: Sun, Dec 25
7: Sun 01:52PM
8: 1:52 (skip the AM PM)
9: 12/25/99 01:52 PM
10: 1999_12 year_month, with leading 0, so log files are sorted ok (e.g. 97_01)
11: 12/25/99
12: 12/25/99 13:52:24
13: 13:52:24
14: Sun 12/25/99 13:52:24
15: Sunday, December 25th
16: 04/14/97 2:28:00 PM
17: 2001-04-09 14:05:16 (POSIX strftime format)
18: YYYYMMDD (e.g. 20011201)
19: Sun, 06 Nov 1994 08:49:37 GMT (RFC 822 format, needed by web servers)
20: YYYYMMDDHHMMSS
21: 12:52 Sun 25 (For short time/date displays)
22: Sun, Dec 25 1:52 PM
23: relative to now (eg, 6 seconds ago, 4 hours from now, yesterday, etc)
The second argument can be either time (in epoch seconds) or a file, where it will use the time that it was last modified. The default is $Time (current time).
$lcd_data{1} = &time_date_stamp(14, $Time);
speak "File was changed today" if time_date_stamp(6, $file) eq time_date_stamp(6);
Note: The mh.ini
time_format and date_format
parms can be used to modify these formats to non-us standards (e.g. no AM/PM, use dd/mm instead of mm/dd).
The cron time format matches the Unix cron format.
Cron Format:
minutes hours day_of_month month day_of_week
minutes: 0-59
hours: 0-23
dom: 1-31 (day of month)
month: 1-12
dow: 0-6 (day of week 0=Sunday 6=Saturday)
You can use a comma delimited list for any of these fields. * matches all values. By default time_cron only operates on the pass when a new minute starts (i.e. $Second == 0). This can be overridden using a 2nd 'second' parameter to specify which second to trigger on. If this is set to '*', it returns true for all passes for the minutes that it matches on. This may be useful if a movement sensor is to trigger different events at different times.
Examples:
# Speak time every 15 minutes, between 7 am and 8:45 am on weekdays only
speak $Time_Now if time_cron '0,15,30,45 7,8 * * 1-5';
# Change PA speaker mode 30 seconds past at 9 pm, every day
pa_sleep_mode('kids', 1) if time_cron('* 21 * * * ', 30);
if (state_now $movement_sensor eq ON and !$Save{woken_up} and
time_cron('* 6-9 * * 1', '*') ) {
speak "It is Monday morning. Remember to put the rubbish out.";
$Save{woken_up} = 1;
}
These return true if the specified time is greater, less than, or equal to the current time. Format can have the same sorts of offsets as described in time_now below. Note unlike time_now
which is only true once, these functions will return a true value for every pass that they are true.
Example:
curtain_on('bedroom', OPEN) if
time_cron('22 6 * * 1-5') and
time_greater_than("$Time_Sunrise + 0:15");
Returns true if the current time is between the 2 specified times.
If the end time happens to be earlier than the start_time, then it tests if the start-time is more than 12 hours in the future. If so, it subtracts 24 hours from the start-time, otherwise it adds 24 hours to the end-time.
Example:
speak 'Who goes there' if
state_now $motion_sensor and
time_between '10 pm', '6 am';
time_now
is evaluate to true for the 1 pass that matches the specified date time. Date is optional. You can specify + or - offset, in hours:minutes:seconds. Time can include AM/PM or be in 24 hour format.
A optional 2nd 'second' parameter can be used to specify which $Second it returns true on (default is on a new minute, $Second == 0). If this is set to '*', it returns true for all passes for the minute that it matches on.
The best way to see how it works is to look the following examples:
Examples:
run_voice_cmd 'close the living room curtains' if time_now $Time_Sunset;
set $backyard_light ON if time_now("$Time_Sunset + 0:15");
set $left_bedroom_light +50 if $Weekday and time_now "$wakeup_time - 0:01";
speak "Remember dentist appointment" if time_now '5/27/98 8:15 AM';
run('min', 'IR_cmd VCR,4,RECORD') if time_now('2/07 17:59', 45);
run('min', 'IR_cmd VCR,STOP') if time_now "$date $stop - 00:01";
Use time_random
to code random events. It uses the same time format as time_cron
, but includes frequency parameter that specifies how often the event should trigger. Frequency is the average number of minutes between occurrences.
Usage:
time_random($cron_spec, $frequency)
Examples:
# Speak something goofy once an hour on weekends
speak(read_next $april_fools) if time_random('* 8-22 * * 0,6', 60);
# Toggle a light on an off randomly every 30 minutes
if (time_random('* 18-22 * * *', 30)) {
$state = (ON eq state $bedroom_light) ? OFF : ON;
set $bedroom_light $state;
}
print 'test value=2' if time_random '* * * * *', 2; # Fires every other minute;
print 'test value=10' if time_random '* * * * *', 10; # Fires every other 10th minute;
print 'test value=1' if time_random '* * * * *', 1; # Fires every minute (not useful)
Use time_random_offset
to code a random time around a time_now formatted time. It takes two arguments. The first is the same as the time_now
function, '6:45 PM' for example. The second is an offset in minutes (60), seconds (:45), or minutes and seconds (2:30). The function returns true at some random time between the time specified and the offset.
The offset can only be positive and if you restart between the time specified and the random offset, it won't fire.
Usage:
time_random_offset($time_now_spec, $offset)
Examples:
speak "random test" if &time_random_offset('1:20 pm', '1:23');
set $light ON if &time_random_offset(&time_add("$Time_Sunset + :15"), 15));
This function will add or edit Misterhouse parameters in the user's ini file. It will make a backup of the ini file, and it doesn't remove any comments in the file. The first argument is a hash of parameters to set. The second (optional) argument is the ini file you want to modify, and the third (optional) argument is set to 1 if you want to log the change.
Examples:
write_mh_opts({"photo_dir" -> $state}, undef, 1);
write_mh_opts(%parms);
These functions are like the $New_Second/Minute/Hour variables, except they can return true only on the nth second/minute/hour.
Examples:
print_log "This occurs every 10th second" if new_second 10;
print_log "This occurs once every even hour" if new_second 2;
If you pass no argument, it defaults to 1 (i.e. the same as the $New_* variables).
The tk widget functions are documented here.
The trigger functions are documented here.
This function will retrieve data from the web (http web pages or ftp files). If the web page is large or the site is slow, you may want to use a Process_Item call to the get_url program, so the request can be done as a separate process and MisterHouse will not get hung up while waiting.
Examples:
my $html = get 'http://marketing.cbs.com/lateshow/topten';
Other examples are in `mh/code/bruce/internet_data.pl`
Returns the numeric IP address of the specified hostname. If hostname is blank, localhost is used. If used in a list context, all associated IP address are returned (e.g. dial up address and local address).
Examples:
print_log "Current IP address " . get_ip_address;
# Echo dynamic IP address to the Tk gui
if ($New_Minute and net_connect_check) {
$Tk_objects{ip_address} = "IP address: " . get_ip_address;
}
tk_label(\$Tk_objects{ip_address});
Un-escapes "%xx"
data back into the original characters. Use on HTML FORM data.
net_domain_name 'address'
, net_domain_name_start 'search_name', 'address'
, net_domain_name_done 'search_name'
These functions will return the domain_name
of the last client to access the specified port. If the mh.ini
DNS_server parm is NOT set, it will return the IP address instead. You can also pass it an IP address, instead of a server port name.
If used in an array context, it returns the full domain name, and a short version of the domain name (e.g. 'www.ibm.com' and 'ibm').
If you call net_domain_name_start
, then check for net_domain_name_done
, it will query the DNS servers as a background task, so MisterHouse will not pause if the DNS server response takes a while. The 'search_name' string must be unique for that part of the code, so that the net_domain_name_done
test gets the correct results.
The data is cached. If the domain has already been searched, net_domain_name_start
will return the same results as net_domain_name_done
.
Examples:
# Run in the foreground
my $domain_name = net_domain_name 'http';
my ($name, $name_short) = net_domain_name 'server_speak';
my ($name, $name_short) = net_domain_name '204.146.18.33';
# Results: $name = 'www.ibm.com', $name_short = 'ibm';
# Run in the background
$v_test_dns2 = new Voice_Cmd 'Run the dns test2';
$v_test_dns2 -> tie_event("net_domain_name_start 'test', '204.146.18.33'");
print_log "Domain=$state" if $state = net_domain_name 'test';
Checks to see if an IP address is available. Returns true if pingable.
Example:
&net_ping($host); # Default protocol is specified in mh.ini
&net_ping($host, $protocol);
Note this may cause my to hang for a while if the target is not pingable. A better way of testing ping-ability to use a Process_Item call. An example is in code/common/internet_connect_check.pl
Used to ftp data to or from an ftp server. There is also a stand alone version of this command in mh/bin/net_ftp
, so you can run this command with a run or a Process_Item
to avoid hanging MisterHouse with long running ftp sessions.
Usage:
net_ftp(option1 => $value1, option2 => value2 ...);
These are the possible options:
server Default is mh.ini parm net_www_server
user Default is mh.ini parm net_www_user
password Default is mh.ini parm net_www_password
dir Default is mh.ini parm net_www_dir
file Name local/remote file to get/put
file_remote Name of remote file (if different from local file)
command get/put/delete.
type ASCII/binary (default is ASCII)
passive Set to 1 to get a passive FTP (sometimes needed for firewalls)
Example:
net_ftp(file => 'index.html', command => 'put', passive => 1);
my $rc = net_ftp(
file => 'c:/junk1.txt', file_remote => 'incoming/junk1.txt',
command => 'put', server => 'misterhouse.net',
user => 'anonymous', password => '[email protected]');
print_log "net_ftp put results: $rc";
$v_test_ftp = new Voice_Cmd 'Test background ftp [get,put]';
$p_test_ftp = new Process_Item;
if ($state = said $v_test_ftp) {
set $p_test_ftp
"net_ftp -file c:\junk1.txt -file_remote incoming/junk1.txt " .
"-command $state -server misterhouse.net " .
"-user anonymous -password bruce\@misterhouse.net";
start $p_test_ftp;
}
print_log "Ftp command done" if done_now $p_test_ftp;
Returns true if connected to the Internet. If the mh.ini
parm net_connect=persistent
, this always returns true.
Returns true if the specified host:port
is avilable, 0 otherwise.
Usage:
net_socket_check($host_port, $protocol);
Examples:
return &net_socket_check("$host:$port");
Used to send and AOL Instant Message, Jabber, or MSN message across the internet.
Information on AIM clients (available for various different platforms) can be found at http://www.aol.com/aim/faq/getstarted.html
. Tik,
a tk based client for use on a Unix os, can be found at http://tarp.linuxos.org/tik
. You can register for an AIM name at http://www.aol.com/aim/faq/registration.html
.
Information on Jabber clients (many open sourced clients are available for different platforms AND the protocol is open) can be found at http://www.jabber.com and http://www.jabbercentral.org
.
Usage:
net_im_send(option => value);
These are the options:
pgm Default aol. Can also be jabber or msn
password Default is mh.ini parm net_jabber_password or net_aim_password
from Default is mh.ini parm net_jabber_name or net_aim_name
to Default is mh.ini parm net_jabber_name_send or net_aim_name_send
server Default is mh.ini parm net_jabber_server (e.g. jaber.com)
resource Default is mh.ini parm net_jabber_resource (this can be left blank)
text Message
file Message. You can use the text and/or file options.
The first time you send a message, MisterHouse will pause for a few seconds while it logs onto a server. Subsequent messages use the same signon, so are sent much faster.
Once you have been logged in, MisterHouse will also display incoming messages. This code has lots of other possibilites that can be added, since jabber is XML based and very flexable.
Example:
net_im_send(pgm => 'jabber', text => "Stock summary\n $Save{stock_data1}\n $Save{stock_data2}")
net_im_send(text => "Internet mail summary for $Date_Now $Time_Now",
file => "$config_parms{data_dir}/get_email2.txt") if time_cron '05 12 * * 1-5';
More examples are in mh/code/common/internet_im.pl
Used to send email. To run commands via email, see FAQ question 2.12: Can do I send MisterHouse commands via email?
There is also a stand alone bin/send_email
command you can use if you find &net_mail_send
causes MisterHouse to pause.
Usage:
net_mail_send(option => value);
These are the options:
server Default is mh.ini parm net_mail_ACCOUNT_server or
parm net_mail_ACCOUNT_server_send
port Default is 25 or parm net_mail_ACCOUNT_server_send_port
from Default is mh.ini parm net_mail_ACCOUNT_address
to Default is mh.ini parm net_mail_ACCOUNT_address
This can be a comma or semicolon delimited list of addresses
account This is the ACCOUNT field used in finding the above parms.
It defaults to the mh.ini parm net_mail_send_account.
subject Default is 'Email from Mister House'
text Body of the message
file File with the body of the message or a file whose
contents you want attached to the note.
Note: You can not use file and text at the same time, as they will be combined.
filename Name to give file attachement. Defaults to file parm.
mime Set to the mime type (used if a file is attached).
Current recognized types are txt,pl,zip,bin,exe,jpg,gif,png, and html.
If not specified, the extention of the file parm is used.
Use bin for an arbitary binary file.
Can also be html_inline if you want the html inline, rather than attached.
baseref If sending html with mime => 'html', use this to set the BASE HREF
priority Can be 1->5 (1 is high, 5 is low). Default is 3.
Example:
net_mail_send(text => "Test email sent at $Time_Now\n\n");
net_mail_send(account => 'Bruce', to => '[email protected]', text => $msg);
net_mail_send to => '[email protected],[email protected]', text => 'hiho';
net_mail_send(subject => 'test an html file attachment',
baseref => 'localhost:8080',
file => '../web/mh4/widgets.html', mime => 'html');
net_mail_send(subject => 'test a gif file attachement',
file => '../web/graphics/goofy.gif');
# Use run to launch a background process
run 'send_email -subject "test" -text "Test background send_email"';
Returns the number of email message on the specified account.
Usage:
net_mail_count(option => value);
These are the options:
server Default is mh.ini parm net_mail_ACCOUNT_server
port Default is 110 or parm net_mail_ACCOUNT_server_port
user Default is mh.ini parm net_mail_ACCOUNT_user
password Default is mh.ini parm net_mail_ACCOUNT_password
account This is the ACCOUNT field used in finding the above parms.
It defaults to the mh.ini parm net_mail_send_account.
Example:
my $count = net_mail_count(account => 'Bruce');
speak "Email account Bruce has $count new email messages";
This returns a pointer to a hash array containing info on mail for a specified email account. Check out the mh/bin/get_email
program for a usage example. Rather than call this with MisterHouse code directly, calling get_email with a Process_Item
, so MisterHouse does not pause while email is being checked. See mh/code/common/internet_mail.pl
for an example.
Returns a list array of pointers to data read from an email account. This is not tested and needs to be documented.
Deletes mail from an account. A dangerous, but requested, function.