MisterHouse : Setting up “modes”

MisterHouse is a fantastic home automation software with an impressive out-of-the-box feature set, and it only gets better if you know a bit of Perl.

You can conveniently set “modes”, which are settings with states you can define and use. You can then fire events upon state change, and so are they very useful to define some sort of macros.

A few examples :

  • the “Security” mode could be “on” or “off” : setting it “on” would close the shutters and activate the alarm system; setting it “off” would do the opposite;
  • the “Heating” mode could be “day”, “night”, “frost protection only” : setting it on “day” would set the target temperature to 20⁰C, “night” to 15⁰C and “frost protection only” to 7⁰C
  • the “Cinema” mode could be “on” or “off” : setting it to “on” would close the blinds and dim the lights; “off” would bring those back to their former states.

This post will show how to setup a mode, we’ll use the “Heating” mode described above as an example.

Coding a mode

The first thing to know is that a mode is nothing but a Generic_Item. By convention, it’s simpler to use an identifier starting by “mode_”.
Here’s the sample code for the “Heating” mode (click to expand):

$mode_heating = new Generic_Item;
$mode_heating->set_states('day', 'night', 'off');

if (state_changed $mode_heating) {
        my $heating_mode_state;
        $heating_mode_state = state $mode_heating;
        main::print_log "Mode = ", $heating_mode_state;
        if ($heating_mode_state eq "day") {
                $thermostat_bureau->setTarget(18);
                $thermostat_living->setTarget(20);
        }

        if ($heating_mode_state eq "night") {
                $thermostat_bureau->setTarget(13);
                $thermostat_living->setTarget(15);
        }

        if ($heating_mode_state eq "off") {
                $thermostat_bureau->setTarget(7);
                $thermostat_living->setTarget(7);
        }
}

set $mode_heating "night"       if time_cron '00 20 * * *';
set $mode_heating "day"         if time_cron '00 06 * * *';

This code is pretty simple : MisterHouse will take all variable definitions and object creations and will execute them, then put everything else in its main event loop. So here the mode is created and then, in the main event loop, actions will be taken if the state of the mode is changed.
It will also switch the state of the heating mode to day at 6am and to night at 8pm as defined with the “time_cron” functionnality.

Integrating the mode within the web interface

To have this mode show up in the web interface, you’ll need to alter the mh/web/ia5/modes/main.shtml and add the following row at the end of the “table” tag :


    

If the GD graphics library is installed on your system, is supporting JPEG files and you enabled its use by MisterHouse (gd = 1 in mh.private.ini), then MisterHouse will generate and display a graphical button with the current state of the mode. If not you’ll get a text link. No matter what, you can cycle through the different states defined for the mode by simply clicking on it.

If you’d like to have your own graphical buttons, simply place them into the “data” dir (data_dir configuration item of the mh.private.ini) and name them following the convention “modename_item_state.jpg”. For my example modename = mode_heating, and state are “day”, “night” and “frost”, so I’d need the files “mode_heating_item_day.jpg”, “mode_heating_item_night.jpg” and “mode_heating_item_frost.jpg”.

References

  • mh/code/common/mh_control.pl : definition of core MisterHouse modes like mode_mh (normal/mute/offline), mode_vacation (on/off), mode_security (armed/unarmed), mode_sleep (awake/sleeping parents/sleeping kids). You can use those as working examples for your own modes.
  • mh/web/ia5/modes directory : html files for the “modes” menu web page.
  • mh/web/bin/button.pl : script which returns the path to the file for a button and generate it if needed.
  • mh/web/bin/button_toggle.pl : script which generates a link which will toggle an object upon click