Over a million developers have joined DZone.

Interview: Java Heating System Regulator

DZone 's Guide to

Interview: Java Heating System Regulator

· Java Zone ·
Free Resource
GreenFire is an open source Java-based heating system regulator. Adam Bien, its creator, tells us all about it in this interview.

Adam is based in Bavaria, Germany. He is the author of several books, a popular speaker at international conferences, and a Java champion. He is the originator and developer behind GreenFire, the open sourced Java-based heating system regulator, one of the nominees for the upcoming JAX Innovation Awards. GreenFire makes use of a wide variety of technologies and techniques, which Adam outlines in this interview.

Adam, firstly, what is GreenFire?

GreenFire is an open-source Java EE 5 application/platform aimed at managing heating systems in a convenient and intelligent way. Greenfire runs in my house—it is mission critical because... winters are cold in Bavaria.

Greenfire is able to control heating remotely and provides a simple Java API to do so. Every five minutes Greenfire checks all the sensors and the weather forecast and then decides what to do. It then sets the heating mode, "On", "Off", etc.

In the end, it writes all decisions and sensor data to a Java DB database. This is interesting for reports:

Greenfire runs on GlassFish v2, but initially on JBoss. It was built with Eclipse, then migrated to NetBeans IDE. I saved about 10-30% in my home's primary energy consumption. My heating bill decreased as well.

What's its history?

If you get a new heating system, it has to be tuned. The configuration isn't complex, but you have to observe the system for a while. I was unhappy with the default behavior in my home—solar energy wasn't being leveraged to the extent that I had expected. I use a combination of solar energy and wood to heat the house. But, before Greenfire, wood heating provided much of the heat, thus precious solar hours were lost.

I started to change the different modes manually—and it worked. So, for example, I switched off the heating on a nice spring morning, and let the sun do its work. However, this approach was error-prone. From time to time, I forgot to switch it on again—and then the next day we found ourselves with cold water and room temparature. I began to think about automating the whole process.

Around the same time, I had identified an "admin interface" in the heating system. It had a hiden COM interface. I started to "hack" the application. After a weekend of work, I was already able to read the system's basic parameters for the external and internal temparature.

Currently, the system is already about three years (since about 2005/2006) in production. It works really well and I began to think about open sourcing it. That process is still in progress. Some modules are still waiting for refactoring and optimization before check-in.

How did it come to be named "GreenFire"?

Its first name was "ParaControl", a composite of Paradigma (the vendor of my heating system) and Control. Later I didn't like the name because I wanted to provide vendor-neutral functionality and wasn't sure about the legal issues. Then the first candidate was "SunFire". This name would have been perfect—however, it was already heavily used.

What are its main features?

The features were built incrementally. The idea for most of the features was born after the heating and weather data was available:

  • Monitoring of the heating status, external / internal temparature, current solar power, total solar power etc.
  • Reporting of all archived data
  • Remote control (On/Off/Warm Water)
  • Integration with standalone clients via JMS and Shoal
  • Scripting interface for business logic
  • Monitoring Widget (see my blog: http://blog.adam-bien.com)
  • RSS feed for mobile phones—works well with iPhone
However, all the features are just collateral stuff—the main goal is leveraging the highest possible level of C02-neutral resources and so save energy in my home environment.

Can you walk us through a detailed scenario where it is currently used?

There are actually several scenarios:

  • Summer: During the summer, Bavaria has enough solar energy for heating the water. There is even too much sun, so the system could overheat. To protect it, most heating system vendors just set the collectors off. GreenFire uses the superfluous energy and heats the basement with it. It takes several weeks—and the basement becomes several degrees warmer (to about 23°C). This is actually a good way to store energy for autumn. You can leverage serveral hundred kW more with this strategy. The basement remains warm until December/January.
  • Spring/Autumn: On the first day with enough sun, GreenFire sets the heating off, and tries to fully leverage solar energy. When it becomes too cold, it switches back to the default mode and allows the usage of, for example, wood pellets for heating. There are actually about 8 weeks in the year during which GreenFire turns off the main heating. You could achieve the same by controlling the heating manually, however you will have to stay home to do so.
  • Winter: You cannot save much energy during winter by managing the heating in an intelligent way. All of the energy is used for heating. However, if I'm using my wood burning stove GreenFire monitors it and leverages the superfluous energy as well.

Please tell us about its architecture.

I built the whole system in my spare time, so I was really interested in "Time To Market". I started with the integration module, which talked directly to the heating system. It is abstracted by an interface, so you could easily integrate it with any heating system you want. The interface is exposed via RMI to an EJB 3. RMI runs in an isolated JVM, so if it crashes GlassFish will still operate.

Another EJB 3 with a timer service is responsible for the "heartbeat". Every five minutes it gathers data from the integration module and the weather forecast module. Then it passes the data to the broadcaster. The broadcaster sends the data internally via JMS to all the listeners. One particular listener is the "brain"—it is another EJB 3 that downloads a Groovy script from a URL and passes the data to the script. The EJB 3 expects a result that is the suggested "mode" for the heating (On/Off/Auto/Warmwater only, and so on).

Another interesting module is the "bridge". It translates the JMS-messages to XML and uses Shoal to distribute the data in the local LAN. This is really convenient because then you can easily start up a local Swing application which will receive the data every five minutes as well. I've started to work on a JavaFX client too—inspired by the NetBeans Weather Java FX Application.

The other modules, such as RSS and widget are basically "listeners" that participate in the "heartbeat".

Here is an overview:

What's the reason that you chose some of the various technologies you're using?

  • Groovy integration. This was a natural choice. The first algorithms were hardcoded in Java. The unit testing was just easier in Groovy. After that, it was very easy to migrate the working Java code into Groovy. It was actually nothing more than "copy and paste". At the same time, I already had a working sample for the pattern "Fluid Kernel" (http://p4j5.dev.java.net). So the effort to integrate Groovy was almost zero.
  • Shoal integration. I started with JMS Topics. It worked well, however the set up is a little bit more complex. You have to at least provide a jndi.properties file and know the IP adress of the server. Shoal was just more suitable for my purposes. I wasn't really interested in transactional reliability or durable subscription. I had a working example as well. I contributed some code to http://fishfarm.dev.java.net, so I knew it worked.
  • Mobile integration. I wanted to monitor the status of my house in a convenient way. It turned out that an RSS feed works really well, at least on my Nokia Phone and on my wife's iPhone:

  • SunSPOT integration. These are perfectly suitable for my purposes. They already come with temparature sensors and IO-ports. I know nothing comparable. I experimented a little bit with another device, which had to be programmed in C, however it just consumed too much time and GreenFire is a spare time project.

Can you show an example Groovy script?

VERSION = "Version 0.6, 05.11.2006"

tpoShouldHigh = configurationItem.getTPOHigh()
tpoShouldLow = configurationItem.getTPOLow()

twoShouldHigh = configurationItem.getTWOHigh()
twoShouldLow = configurationItem.getTWOLow()
solPowerLow = configurationItem.getSolPowerLow()

tpoIs = heatingStateItem.getTPO()
twoIs = heatingStateItem.getTWO()
tpuIs = heatingStateItem.getTPU()

heatingModeIs = heatingStateItem.getHeatingMode()
solPowerIs = heatingStateItem.getMomentaneLeistung()

OFF = configurationItem.getHeatingModeOff();
ON = configurationItem.getHeatingModeOn();

logger.info("Current TPO: " + tpoIs + " Current TWO: " + twoIs)
logger.info("TPO (should) High: " + tpoShouldHigh + " TWO (should) High: " + twoShouldHigh)
logger.info("TPO (should) Low: " + tpoShouldLow + " TWO (should) High: " + twoShouldLow)

if(heatingModeIs != 0){ // Change only if heating is not in AUTO mode

// the buffer shouldn't be hotter than 72
if(tpoIs > 72 || twoIs > 72){
suggestedMode = ON
logger.info("Too hot (70) suggested change: " + suggestedMode)
if(solPowerIs < solPowerLow){
suggestedMode = OFF
logger.info("The solar power is too low. Suggested change: " + suggestedMode);
if(tpoIs > tpoShouldHigh || twoIs > twoShouldHigh){
suggestedMode = ON
logger.info("Too hot suggested change: " + suggestedMode)
}else if(twoIs < twoShouldLow || tpoIs < tpoShouldLow){
suggestedMode = OFF
logger.info("Too hot suggested change: " + suggestedMode)
suggestedMode = heatingStateItem.getHeatingMode()
logger.info("Nothing to do. Just keeping the current mode: " + suggestedMode)
}else{ // Heating is in the AUTO state. But cooling is needed anyway
if(tpoIs > 68 || twoIs > 68){
suggestedMode = ON
logger.info("Temperature greater than 68: " + suggestedMode)
suggestedMode = heatingModeIs
logger.info("Heating is in AUTO state. Keeping the state.")

So what percentage of GreenFire is Java and what percentage is Groovy?

95% Java, 5% Groovy, BUT the essential business logic was written in Groovy. GreenFire downloads the script from a HTTP (later from an JPA-entity) server every five minutes. So, I'm able to change the algorithm very quickly—without redeploying the application. I can correct potential problems every 5 minutes—it is really robust...

In the beginning of this interview, you said you started with Eclipse and JBoss, but then migrated to NetBeans IDE and GlassFish. Why?

When I started with GreenFire, Java EE 5 was an early draft—and JBoss the first usable container with experimental EJB 3 support. I used Eclipse with Maven to build the modules. I switched to NetBeans IDE because of better integration of:

  • Database (the Explorer)
  • Visual JSF and Swing Designer
  • Java FX demos and support
  • Really good GlassFish integration (monitoring, local and remote deployment)
  • Built-In support for Java EE 5 deployment

I was able to really quickly develop and deploy GreenFire. In my spare time I like to try the "bleeding edge technologies". So I often use the latest IDE, frameworks, etc. This is my way to explore new things. This is not a problem with NetBeans IDE—you can just download the whole bundle every day. If a daily build doesn't work, I just wait another day or use the latest RC. This strategy just isn't applicable with Eclipse—you have to not only install Eclipse, but corresponding plugins as well. You need at least six or seven for GreenFire. This was just too time consuming for a spare time project.

I switched from JBoss to GlassFish just because of the GlassFish administration capabilities. You can easily administer GlassFish using a web interface. Here, for example, is the GlassFish console:

It is not so easy with JBoss...

What kind of developments will GreenFire undergo in the future?

I have too many ideas! I have summarized the most realistic features in the following below:

  • Easier script/profile management. Currently GreenFire runs in winter and summer mode. I need to switch the scripts back and forth. However, I would like to simplify management and provide a user interface for this purpose. In addition, I would like to provide additional profiles, such as vacation, work, and so on.
  • Water pump integration. Every German house has a circulation pump for warm water. The purpose of this device is to provide immediate availability of warm water. However, the pump is controlled by a timer, so it runs whether you need warm water or not. Every time it runs the warm water temparature drops several degrees, which in my case means wasting several kW of energy. I would like to integrate the control of this pump with GreenFire.
  • Further SunSPOT integration. GreenFire determines its actions based on the weather forecast, the current collector power, and the thermos temparature. I would like to integrate the internal temperature, external temparature, as well as the sun's radiation in various rooms as well. I will use SunSPOTs for this purpose.
  • Wood pellet price feed integration. I would like to intercept the price-feeds of several wood pellet providers. Because GreenFire knows how many wood pellets were burned, it should be able to suggest the best price/condition via email.
  • Comparative reporting. I have gathered weather data for about 3 years in Java DB, which happens every five minutes. It would be nice to correlate the data, so that you would be able to see the temparature and energy costs of the current day one or two years ago.
  • Air ventilation integration. My house is actively ventilated. The ventilator runs 24 hours per day. I think this should not be necessary. I would like to control the ventilator as well, with a SunSPOT and some electronic relays.

I'm thinking about decentralizing the whole system into loosely-coupled SunSPOTs. They could communicate in a P2P manner. This would be especially interesting for users without a central server.

Would you like contributions, such as code, from the community?

Sure. A main motivation when participating in open source is learning from others and of course benefitting from code contributions. I underestimated the level of interest in this topic. I gave a session at the OOP 2008 conference in Munich about GreenFire... and the room was overcrowded. I received several e-mails after the session with suggestions/questions.

I would expect some patches and ideas from interested developers first. After this step, I would decide whether commit rights to the repo should be granted or not. This approach works really well in my other open source projects, such as p4j5.dev.java.net and qlb.dev.java.net.

In the long term I imagine I'd be able to provide an open library of scripts and strategies for GreenFire. So, new ideas/strategies could be easier shared and leveraged that way.

How do I get started with it?

For now, about 80% of the code is in the open source repository. You can check out the projects into NetBeans IDE and start working/deploying. I'm thinking about providing a binary (EAR)distribution as well. For this purpose, I will have to mock the heating system, otherwise it will be unusable for most developers.

Finally, it turns out that GreenFire has been nominated for a JAX award. What's your connection with that conference and how did the award come about?

I really like the JAX conference—I've been speaking there since 2001, which was the first JAX conference. This year I will give a workshop about pragmatic architectures and design of Java EE 5 applications. I will try to show as much code as possible. On the Thursday I will give a session about Maintainable RIAs, and explain some Presentation Tier Patterns.

I received an email last week about the nomination. It was a big surprise. GreenFire is competing with many European companies and open source projects. But I'm looking forward to it. And, at the very least, GreenFire is a good contribution to the environment...

Related Resources


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}