HAI Programming for Programmers

Home Automation, Inc. (HAI) makes the Omni series of home automation controllers. These controllers are a good value and support a variety of sensors and controls. They are programmable by the homeowner as well as the installer. The programming language is event-driven and makes it easy to handle simple scenarios such as "when the front door is opened, turn on the hallway light". However, it has a number of ideosyncrasies, and neither the owner's manual nor the programming class notes are completely clear about all of the issues.

Having learned much about the HAI language the hard way, I wish to share what knowledge I have gained. What follows supplements the information in the owner's manual, and is targeted for the professional programmer.

The HAI can be programmed from the console, but it's far easier to use their PC Access software. There are two versions: Dealer PC Access and End User PC Access. I believe the latter is available to anyone.

Another resource is the HAI Developer Support program. To quote HAI: "This program is generally available to anyone, including homeowners, that does programming. It does not matter if the developer works at a professional level or a hobby level."


Zones are inputs to the controller (or to a connected hardwire expander or expansion enclosure). They can be tested for Secure or Not Ready. When a zone changes state from Secure to Not Ready or vice versa, an event is generated. See appendix C of the OmniPro II installation manual for a complete list of zones and their corresponding inputs.


A Unit is one of the following:

Flags can be used in programming like other units, but have no associated output. Flags are like variables in other programming languages. They can hold values from 0 through 255, but they can only be tested for ON (nonzero) or OFF (zero). The number of flags is quite limited; 119 in the OmniPro II. You can also use other outputs as flags if they are unconfigured or unused.

There is a timer for each unit. Its state is just the amount of time remaining. When the time expires, the controller changes the state of the unit (ON to OFF or OFF to ON). A Unit On/Off command that changes the state of the unit (for example from Off to On) sets the timer according to the command. A Unit On/Off command that does not change the state (for example Off when already Off) sets the timer to the maximum of the time specified by the command and the time that was remaining (if any). Set Unit without a timeout clears the timer (I think).

Turning a unit ON or OFF always generates an event, even if it was already in that state. For example, if a unit is OFF, turning it OFF generates a Unit OFF event.

Setting a flag to a value does not generate an event (even if the value changes from zero to nonzero or vice versa). It cancels any timer.

HAI documentation sometimes uses the term "control" to mean unit (as in When Control or Command Control).

See appendix C of the OmniPro II installation manual for a complete list of Units and their corresponding outputs.


Buttons do not have state; they are simply "activated". A button activation is an event. Buttons can be activated from a console, the telephone (menu function #3), or in program commands. In the OmniPro II there are 128 buttons.

Use buttons if you want the user to be able to initiate a command (from the console or telephone) and there isn't an appropriate zone for this.

HAI documentation often confuses buttons with other events.


The text of a message is its name, which can be up to 15 characters. Receipt of a message on a serial port configured for Pro-Link generates an event. In the OmniPro II there are 128 messages.

Each message has a binary flag that says whether it is displayed on the console. Show Message and Clear Message control this flag.

The text of a message can also be:

The voice associated with a message can be:


An Event is anything that can be tested in the WHEN clause of programs. The complete list of events is:

Program Logic

The WHEN clause of a program line tests for an event. It is important to realize that the line is executed only once when the event occurs. Consider:

WHEN Door NOT READY &IF Dark: Light ON

If the door is opened in the daytime, and remains open as it becomes dark, the light will not be turned on. The Door NOT READY event only occurs at the time the door is opened, so that is the only time this line will be executed.

When an event occurs, the controller executes all lines triggered by that event in order. For example:

WHEN SomeEvent &IF Flag1 OFF: Flag1 ON
WHEN SomeEvent &IF Flag1 ON: Flag1 OFF

This does not toggle Flag1; it always leaves it OFF. If Flag1 was initially ON, the first line does nothing, and the second line turns it OFF. If Flag1 was initially OFF, the first line turns it ON, and the second line then turns it OFF. If you want to toggle Flag1, copy it to a temporary flag first:

WHEN SomeEvent &IF Flag1 OFF: TempFlag OFF
WHEN SomeEvent &IF Flag1 ON: TempFlag ON
WHEN SomeEvent &IF TempFlag OFF: Flag1 ON
WHEN SomeEvent &IF TempFlag ON: Flag1 OFF

While commands are executed when encountered, the processing of triggered events is queued. In the above example, the lines for SomeEvent are executed, then any lines for WHEN Flag1 OFF and possibly WHEN Flag1 ON (I don't know the order of these).

Note, as of firmware version 2.9, there is now a command to toggle a unit.

This page was last updated on 31 October 2008.

Written by Charles R. Landau. Copyright (c) 2005, 2008, 2009. All rights reserved.