Device Controller

Note: This project is part of our on-going smart home software development and is continually being updated and improved, as we learn more about our smart home and want to improve the way thinsg work. Whilst this is essentially a project about technology and software, the main objective of this project is to make it very easy to configure our smart home to work exactly the way we want it. This project simply aims to enable a great user experience.

This project documents the Java software we have been using for several years and some more recent updates as part of our Home Control System (HCS). The software controller described here is a generic and re-usable Java class created to provide automatic and intelligent control, based on real-time events, along with adaptive scheduled control of devices and services in our home. It is used to control things like the central heating, hot water and security and convenience lighting.

We don't expose the underlying technology discussed here in normal use. The use of controllers and the configuration of these controllers would be part of another project to model our smart home configuration in JSON and we plan to have a nice graphical tool to enable this. This tool would then allow anyone to automate and configure the behaviour of their home, assuming they used our Home Control System (HCS) and our technology abstraction.


A single instance of a Controllers class exists and this scans a specified folder for JSON configuration files. For each JSON file found, an instance of the Controller class is created. At any time we can send a 'reload' command to our Home Control System (HCS) and it will reload all of these JSON configuration files, and reset all of the controllers. This latter feature makes it really easy to develop and test without having to restart our Home Control System (HCS). Given that we are innovating really quickly and makign daily updates and improvements, this is really important.

The "rules" described in these configuration files are designed to use any of the 240+ objects (sensors and devices) in our smart home or any of their attributes as the basis of the rules. This is also true for all of the zones modelled in our smart home. This makes them incredibly powerful and flexible, whilst also being really simple to configure.

The main things the controller does are:

  • Be a single point of decision making for each item being managed by a controller.
  • Ensure they are no conflicts between all of the rules and inputs behind the control decision.
  • Ensure the best decision is made with 'whole home context' and very low latency.

Java Implementation

The constructor creates the controller object and calls the Load() method (which loads the configuration file). The configuration file (examples) has a device name (which is used to load the configuration file), the zone for this device (used to filter events) and a default value. If the conditions mean that no rules match, then this default value is used as the target output.

Class Methods

The Check(event) method passes an event to the controller, which then checks its target output value. To make this function as fast as possible, it runs some test to see if it needs to do anything at all, e.g. is the event zone relevant or are any conditions satisfied.

The Load() method causes the controller to load/reload its configuration file from the associated XML file. If the load fails the controller is marked as inactive and generates a warning when the Check() function is called. To make the class more efficient and faster, the XML file is processed and cached into a number of arrays.

The Extend(duration) method extends the timer by the defined number of minutes.

Schedules, Rules, Timers & Timer Extensions

The controller schedule is configured using a set of simple rules, that determine the target value at any given time. The rules are loaded from a configuration file and validated on loading. We currently generate these files manually but, the plan is that a nice graphical tool will generate them in XML in the future.

The rules are processed in order to work out the current target value. The target value is in 'free text' format and is validated for the device to which it relates. For a device like the 'Hot Water Heater' the target will be either 'On' or 'Off'. For devices like 'Bathroom Heating' the target value will be a temperature (in ºC).

The rules are basically a house status (for which this rule applies or a wildcard), start date/time, end date/time and a target value (comma separated). The start and end can be based on a specific dates, or days of the week and always includes a time in the 24-hour format, e.g. 16:00:00. Rules using days of the week are specified in a string of the form SMTWTFS, e.g. S----F- equates to Sunday and Friday only.

The time element can also have one of the following values: Sunrise, Sunset, Dawn or Dusk. These have time values set by the wider and retrieved from the database. We also plan to implement delays on these values, e.g. 15 minutes after sunset. This would be done in the form: Dusk+00:15:00.

Each rule has one or more associated house status values of 'In', 'Out' or 'Away', to enable different target values for each status. If this is set to '*', then it is not checked. This is not the value stored in the database (which also may have the value of 'Auto') but, the calculated value returned by a Status class. This is because this class also handles the 'Auto' value and takes thus into account detected presence.


Triggers are events that cause a timer extension, e.g. a PIR detection event in a room. Each trigger has an associated delay used to extend the timer. We have implemented this such that all trigger target values are the same.

One limitation in our implementation so far is that triggers need to be global or come from objects in the same zone as the device being controlled. This allows us to massively simplify things and reduce the number of events each controller has to process. We plan to remove this limitation though and monitor the impact of doing this as it restricts things too much.


Conditions are name-value pairs that are checked before the controller checks the rules and is thus able to change the target value. Typically these are a device and value to be tested (e.g. 'Heating' = 'On') but, they could also be an environmental variable (e.g. 'Twilight' = 'Dusk'). The house status is not considered a valid condition, because it is also a condition required for each rule. Conditions can test for a positive (true) match (the default) or a negative (false) match (using a <match>false</match> element).

It should be possible to have conditions per trigger and this will enable a basic state machine capability but, we don't see a need for this (yet).

Something else we are looking at is, extending the <match> element to support >, >=, < and <=. This enables much more powerful control based on numeric values. For example we could heat the water until the hot water capacity equals 100%.


Everything discussed up till now is about determining the 'target' output value but, this in itself doesn't activate a device to turn on (for example) a heater or air-conditioning unit. We are merely setting the target temperature to be reached. For heating and cooling controllers, we also need to have something that converts this into a binary (on/off) or analogue (0-100%) action.

The actions in the XML configuration file determine how this happens. For some devices this will be simply a matter of using the new target value as the device output value (e.g. Safety Lights = On).

Another possible action is to generate an event, so that other parts of our Home Control System (HCS) can be 'informed' about changes. We are testing this within our status project.

We currently use a <actions>O>/actions> element where 'O' is one of a number of action flags.

  • E = send this new target value as an event, back into the HCS.
  • O = output this value to the device


These are some early example implementations used in our home. We have now migrated to a JSON format:

Conservatory Light

This is a really simple example, which has two rules to provide different switch off times depending on the day of the week.

An example XML configuration file.

Kitchen Worktop Lighting

Our kitchen worktop lights are an example of convenience lighting that are currently driven by this software controller. They are also an example of a controller that doesn't have any scheduled 'On' time. The lights are basically off all the time, apart from when they are triggered by the 'Kitchen PIR' = 'On' or 'Kitchen Door' = 'Open' events. Through testing we have found the optimum timer delay to be 6 minutes. They have a single condition associated with them, which is 'Twilight' = 'Dusk', to ensure they only come when it is dark outside. During the winter, this means that they also come on in the morning as well as at night time.

An example XML configuration file.

Study Temperature

This is still being documented and tested.

The default value is set to the minimum temperature we want the room reach if we were 'Away' (e.g. 16°C). Most of the year, this would mean the heating won't be switched on in this room and thus use no energy.

We then define a comfortable background temperature for the 'In' status, which we want at night time (e.g. 20°C). This is then followed by a rule that sets a target temperature (e.g. 22°C) for use in the normal day time hours (e.g. 08:30 to 21:00). We then have a rule for when we are 'Out', which is a lower target (e.g. 18°C).

There is no point in putting conditions in to ensure these values are used only when the 'Heating' = 'On', these are target temperatures only and the heating and cooling can be switched on and off independently.

House Status & Presence

We are using an instance of this Controller class within our status projectkitchen worktop lighting, safety lighting, security lighting, garden lighting and Christmas tree lighting.

This approach works very well with manual controls and interactions. For example, it is very easy to have a '+30min' switch next to a heated towel rail, which triggers the towel rail to come on for 30 minutes. The same approach could be used to add a '+1hr' button for the hot water heating. It could also be used to provide simple 'on' and 'off' buttons. Similarly, the approach can be used with HTML/AJAX web interfaces (hosted on our LAN).

On a related note, we also have a hardware project to do something very similar.

This project only really works because we have used technology abstraction in our Home Control System (HCS). There are no dependencies here on specific home automation technology or the addressing of technology and devices. Each device in our home has a friendly, human-readable name, which is also used through-out our Home Control System (HCS).

Share ...
We are on ...
Facebook Twitter
YouTube Flickr Follow us on Pinterest