Basic Ports

There are four basic ports in openhatd: Digital, Analog, Dial and Select ports. The Analog port is rarely used. All more complex port types inherit their properties from these ports.

The basic properties of all types of ports are:

  • A unique ID which is a text string preferably without blanks and special characters, for example "Window1".
  • A hidden flag which decides whether to display this port on a user interface or not.
  • An optional label and icon specification to display on a user interface (if the port is not hidden).
  • An optional unit specification which determines value conversions, formatting etc. See Unit Specifications for more details.
  • A readonly flag which decides whether a user may change this port's value or not.
  • A persistent flag which decides whether the state of this port is stored permanently in an external file. See Persistent Settings for more details.
  • An optional group ID (ports can be ordered into hierarchical groups). See Groups for more details.
  • A refresh mode that decides how changes in the port's state affect the connected user interfaces.
  • An order number that specifies the ordering of ports on a GUI.
  • A notification mechanism that consists of lists of Digital ports that are changed to High when the value of this port changes.
  • A log verbosity that determines the amount of log output generated by this port.
  • Freely assignable tag values.
  • A work delay value that can be used for performance optimization.

All ports are required to have a unique ID. In most cases their ID will be the same as the configuration section name the port is defined in, for example:

[DigitalPort1]
Type = DigitalPort

This section will create a Digital port with the ID DigitalPort1. Internally created ports will have automatically generated IDs.

Port IDs should contain only upper- and lowercase characters, digits, and the underscore. They should not start with a digit. The technical reason for this is that port IDs can be referred to from within expression formulas and other constructs which use a certain syntax. Using special characters in port IDs might interfere with this syntax. Additionally, port IDs are case sensitive in some contexts but may not be in others. For this reason (and for readability) it is strongly discouraged to rely on port ID case sensitivity.

Settings

You can apply these settings to most ports in an openhatd configuration. It is up to the port implementations which settings they allow to be changed.

Hidden

Optional boolean (True or False) that decides whether the port should be displayed on a GUI. The default depends on the port type.

Label

Optional string that identifies this port on a GUI. This value has no internal use. Most ports chose the ID as default label.

Icon

An icon specification that tells a GUI how to render this port. It is up to a GUI whether and how this property is supported. Icon specifications are a string that uniquely identifies an icon in the system. There is a set of pre-defined icons (TODO: create list of icons).

Unit

A unit specifications that tells a GUI how a port's value can be rendered, converted and formatted for presentation to a user (TODO: create list of units). It is up to a GUI whether and how this property is supported.

Readonly

Optional boolean (True or False) that decides whether the port can be changed by a user or not. The default depends on the port type. This setting only affects user actions. A port's value can always be changed by internal functions.

Persistent

Optional boolean (True or False) that controls whether the port saves its state to a persistent file. Using this property requires the definition of a persistent file in the configuration. The default is false. See Persistent Settings for more details.

WorkDelay

Optional positive numeric value that specifies the minimum delay between two calls of the doWork method of this port. This value can be used to improve the performance of the application. The default is 0 meaning that there should be no delay; in this case, the speed of the doWork calls depends on the TargetFPS value of the main configuration (if the platform supports it). This value can be used to minimize the CPU impact of ports that do a lot of work that is not required to be done all the time; for example, an Expression port that evaluates a complicated formula perhaps only needs to run once a second. In this case WorkDelay should be set to 1000 to decrease the time that is unnecessarily spent for such evaluations.

Group

An optional group ID that allows the logical grouping of ports. GUIs may interpret this value to display hierarchical menus of ports. A group ID that is used here must be defined in the configuration as a node of type Group. See Groups for more details.

RefreshMode

An optional value of either Off, Auto or Periodic. Determines when a GUI is asked to request the current port value from the openhatd slave system. The default value is Auto. In Auto mode refreshes are performed as necessary, i. e. whenever the port's state, history or error state change. In Periodic mode refreshes are performed according to the required RefreshTime setting. Port refreshes that happen too often are suppressed in order to avoid congesting communication channels; the minimum time is one second between refreshes.

Port refreshes happen by sending a refresh message for the port to the GUI. The GUI then needs to query the current port state. It may chose to delay for some time or ignore the refresh message altogether. It is important to understand that for this reason the actually displayed value may differ from the value at the time the refresh has been requested.

RefreshTime

If RefreshMode is Periodic, a required positive integer value that specifies the time between refresh requests in milliseconds.

OrderID

An optional numeric value that specifies the internal ordering of ports. This will usually correspond with the order that ports are presented on a GUI; however, GUIs may chose to implement their own ordering. The default order is the order that ports are enumerated from the configuration file.

The order ID also affects the sequence of port preparation after ports have been configured. It is rarely required to use this setting.

OnChangeInt

An optional port list specification for Digital ports whose Line value is set to High if the state of this port is changed by an internal function (not by a user action). The source of the change (internal) is propagated to the target ports.

OnChangeUser

An optional port list specification for Digital ports whose Line value is set to High if the state of this port is changed by a user action (not by an internal function). The source of the change (user) is propagated to the target ports.

LogVerbosity

An optional value of either Quiet, Normal, Verbose, Debug or Extreme. If this value is set it overrides the log verbosity setting of the configuration file and the command line flag, if specified. It allows you to selectively increase or decrease the log level of messages generated by this port which is especially useful for debugging. For normal operation it is recommended to omit this setting. See Log Verbosity for more information.

Digital Port

The Digital port is the most elementary port type. A Digital port has a Mode and a Line state. Modes can be Input and Output, and the line can be either Low or High. Mode and Line default to Input and Low. A Digital port roughly corresponds with the concept of a Boolean variable.

The Digital port is modeled after a digital I/O pin of a microcontroller. The important thing here is that a Digital port's state is always known, and it is either Low or High. Basically, the Digital port models a switch. In openhatd it is used for "things that can be on or off", no matter whether the state of these things is controlled directly by a user or by internal functions, or whether the Digital port is a physical actor, an internal variable or behavioral component or reflects the state of some outside sensor (by reading its state from some driver).

Typical examples of Digital ports are LEDs or relays (output only), and switches or buttons (input only). However, most higher-level functions in openhatd are also modeled as Digital ports, thus giving you the ability to switch these functions on or off. For example, a Pulse port can periodically change the state of one or more Digital ports (its "outputs"). The Pulse port itself is again a Digital port, and it will only be active if its Line state is High. Thus, you can switch the Pulse port on or off using a user interface, or the Pulse port can again be controlled by any other port that accepts a Digital port as an output. In this way you can connect elementary blocks together to form complex behavior.

Settings

In addition to the basic port settings described above, a Digital port accepts the following settings:

Type

Fixed value DigitalPort.

Mode

An optional value of either Input or Output. This setting defines how the port is displayed on a GUI and whether it can be changed by the user. For internal changes this distinction is irrelevant. The default for a basic Digital port is Input. Some port types may define Output as default or restrict the ability to change this setting.

Line

An optional value of either Low or High. The default for a basic Digital port is Low. Some port types may define High as default or restrict the ability to change this setting.

Analog Port

The Analog port is modeled after the the properties of an A/D or D/A port of a microcontroller. Its value ranges from 0 to 2^n - 1, with n being a value between 8 and 12 inclusively. The Analog port also has a Reference setting (internal/external), and a Mode (input/output). The Analog port is less useful in an openhatd automation context because it is modeled so close to the metal. In most cases it is better to use a Dial port instead.

Settings

In addition to the basic port settings described above, an Analog port accepts the following settings:

Type

Fixed value AnalogPort.

Mode

An optional value of either Input or Output. This setting defines how the port is displayed on a GUI and whether it can be changed by the user. For internal changes this distinction is irrelevant. The default for a basic Analog port is Input. Some port types may define Output as default or restrict the ability to change this setting.

Resolution

An optional resolution in bits. The default resolution is 12 bits.

Value

The initial value of the Analog port. This value must be within the range 0..(2^Resolution-1).

Dial Port

The Dial port is the most versatile and flexible port. It represents a 64 bit signed integer value referred to as Position. There's a Minimum, Maximum and a Step setting which limit the possible values of a Dial port to a meaningful range; for example, to represent an ambient temperature in degrees Celsius you could limit the range to -50..50. The defaults are 0, 100 and 1 for Minimum, Maximum and Step.

openhatd does not do floating point arithmetics internally. You therefore cannot store fractional values in ports. This is not a problem in practice, though; if you need to represent for example tenths of degrees Celsius you could specify the above range as -500..500 and divide the value by 10 for all internal calculations. If the value has to be presented to a user the conversion happens in the UI component; the port's unit specification tells the UI what the value is exactly and what options there are for converting and formatting the value. This also helps with localizing the UI; for example, even though the value is processed internally as tenths of degrees Celsius the UI might choose to display it as degrees Fahrenheit, by means of a conversion routine specified for this unit. The most important thing here is to remember what the internal value actually means for a specific Dial port.

Dial ports can represent numeric information as well as dates and times. As usual with openhatd ports, the value of a Dial port might be set by a user, or it might be the result of an internal calculation, or it might reflect the state of some hardware or other external component (like the content of a file). The best way to initially think about a Dial port is as of a universal numeric variable.

Settings

In addition to the basic port settings described above, a Dial port accepts the following settings:

Type

Fixed value DialPort.

Minimum

The smallest possible value that this Dial port can contain. The default is 0.

Maximum

The greatest possible value that this Dial port can contain. The default is 100.

Step

The interval of the positions of the Dial port. If a value is assigned it is automatically adjusted to the nearest possible position according to this setting. The default is 1.

Position

The positional value of the Dial port.

Select Port

The Select port represents a set of distinct labeled options. The currently selected option number is referred to as position, starting with 0. Its most useful application is to present the user with a choice; however, the Select port can also have internal uses. The most important difference to the Digital port is that the Select port can represent things that do not necessarily have a known state. Take, for example, a radio controlled power socket. The radio control is one-way only in most cases, so there is no way to know whether the power socket is actually on or off; its state is essentially unknown. Such a device can not be modeled with a Digital port as a Digital port must have a known state. It can, however, be conveniently modeled using a Select port with three options: Unknown, Off, and On. If the user selects Off or On the command is sent to the socket via radio, but the Select port's state will not reflect the user's choice but instead remain Unknown.

A Select port supports up to 65535 different labels (or positions), but for practical purposes it is recommended to keep this number as low as possible.

Settings

Type

Fixed value SelectPort.

Position

The positional value of the Select port, i. e. the number of its selected label, starting from 0.

[portID.Labels]

This section contains the labels of the Select port, in the format

<label_text> = <sort position>

The sort positions are non-negative integer numbers. They need not be unique. The labels are sorted in ascending sequence of these numbers; it is important to keep in mind that these numbers do not represent the internal position numbers for the labels; these always start from 0 and are consecutively numbered whereas the sort positions are arbitrary.