Skip to content
ggodart edited this page Feb 4, 2021 · 35 revisions

Table of Contents

Tk widget functions

Trigger functions

Internet functions


set_by_to_target

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, ...

add_sound

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';
    }

browser

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;

convert_k2f and convert_c2f

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

convert_direction

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});

dbm_write =item logit_dbm

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.

dbm_read

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);

dbm_search

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.

display

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.

eval_with_timer

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.

file_backup

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".

file_cat

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';

file_changed (or older name of file_change)

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);

file_default

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"));

file_diff

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.

file_size

Returns the size of a file, in bytes.

file_read

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);

file_read_dir

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;
    }

file_tail

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.

file_unchanged

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;
    }

file_write

Writes data into a file. Like logit, except it writes over, rather than appends to, a file.

Examples:

     file_write($file, $data);

filter_cr

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}";

logit

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");

mht_item_add, mht_item_delete, mht_item_copy, mht_item_write

These functions can be used to manipulate mht files.

play

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';

print_log, print_log_simple, print_msg, print_speaklog

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 anything
source (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.

round

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

run

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

run_after_delay

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";
       }
     }

run_voice_cmd

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);
   }

respond

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 => 'joe@cops.com', 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 to=joe@jabber.com 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}");
  }

speak

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

time_add

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";
    }

time_diff

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";

time_date_stamp

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).

time_cron

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;
    }

time_greater_than, time_greater_or_equal, time_less_than, time_less_or_equal

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");

time_between

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

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";

time_random

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)

time_random_offset

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));

write_mh_opts

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);

new_second, new_minute, new_hour

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).

List of tk widget functions

The tk widget functions are documented here.

List of trigger functions

The trigger functions are documented here.

List of Internet functions

get

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`

get_ip_addresses

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});

html_unescape

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';

net_ping

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

net_ftp

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 => 'bruce@misterhouse.net');
     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;

net_connect_check

Returns true if connected to the Internet. If the mh.ini parm net_connect=persistent, this always returns true.

net_socket_check

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");

net_im_send

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

net_mail_send

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 => 'winter@misterhouse.net', text => $msg);

    net_mail_send to => 'winter@misterhouse.net,santa@claus.net', 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"';

net_mail_count

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";

net_mail_summary

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.

net_mail_read

Returns a list array of pointers to data read from an email account. This is not tested and needs to be documented.

net_mail_delete

Deletes mail from an account. A dangerous, but requested, function.

Clone this wiki locally