MAX! system installation and configuration walktrough

I thought i’d document my implementation of my MAX! system in openHAB. I hope it’s useful to someone.
Questions and comments are welcome.

Installation

The installation of the Max! addon is quite straight ahead:
In Paper UI, go to the “Addons” section, and select to install the MAX! Binding (make sure you don’t use the MAX! CUL Binding).

After that, you should find a new thing in your Inbox:
2
Go to the “Inbox” section, and select to Add the MAX! Cube LAN Gateway:


After doing so, you’ll find all MAX! devices in your Inbox. Add them all.

Configuration

After openHAB “knows” your devices, you can start to configure them as items.

Groups

I use groups in “two dimensions”: First, all devices in one room make up a group. Second, all attributes (like temperyture, valve etc) make up othe groups.
Using this, you can easily use rules looping though all groups to set all thermostats to manual mode or do other things.

//=====================================================================================================================
// Gruppe für alles
Group gMax               "Max! Heizungssystem"        <temperature>

// Gruppen für die einzelnen Räume
Group gMaxWohnzimmer     "Thermostat Wohnzimmer"      <temperature>   (gMax)   ["Thermostat"]
Group gMaxKueche         "Thermostat Küche"           <temperature>   (gMax)   ["Thermostat"]
Group gMaxKinderzimmer   "Thermostat Kinderzimmer"    <temperature>   (gMax)   ["Thermostat"]
Group gMaxArbeitszimmer  "Thermostat Arbeitszimmer"   <temperature>   (gMax)   ["Thermostat"]
Group gMaxSchlafzimmer   "Thermostat Schlafzimmer "   <temperature>   (gMax)   ["Thermostat"]
Group gMaxBad            "Thermostat Bad"             <temperature>   (gMax)   ["Thermostat"]

// Gruppen für die einzelnen Aspekte
Group                         gMaxMode        "Modus"                             <temperature>   
Group                         gMaxSetTemp     "Wunschtemperatur"                  <temperature>
Group                         gMaxActualTemp  "Raumemperatur"                     <temperature>
Group:Switch:OR(ON,OFF)       gMaxBatLow      "Batteriestatus [MAP(max.map):%s]"  <battery> 
Group                         gMaxValve       "Ventilstellungen"                  <max_valve>
Group:Contact:OR(OPEN,CLOSED) gMaxWindow      "Fenster [MAP(max.map):%s]"         <window> 
Group:Contact:OR(CLOSED,OPEN) gMaxLock        "Bediensperre [MAP(max.map):%s]"    <lock>   

// Gruppen für die Automatik bei Anwesenheit ("alle" außer Schlafzimmer)
Group gMaxAutoTemp
Group gMaxAutoMode

Explanation

gMax is the “Master” group that includes all other items.

Second, there are groups for my rooms. Each has a label, uses the “temperature” item, belongs to the master group “gMax”, and is tagged “Themostat” so it can be controlled using Alexa.

Third, there are groups for mode, setpoint, actual temperature etc.

And lastt, there are some groups I use in rules

Using logic to sum up individual states

Three of these groups sum up the individual states.
gMaxBatLow should be “on” (= battery low) when any of the individual states is “on”.
gMaxWindow should be “open” when any of the windows is “open”.
gMaxLock works just the other way 'round, it should be “closed” when any of the themostats is locked.

Using transformations for labels

These groups are using a transformation for displaying a label. To use this, you have to activate the “Map Transformation” in Paper UI, and create a .map file containing the mappings:

ON=niedrig
OFF=ausreichend
OPEN=geöffnet
CLOSED=geschlossen

The first thermostat


//=====================================================================================================================
// Kueche
String  maxModeKueche                 "Modus"                                                  <max_mode>  (gMaxKueche, gMaxMode, gMaxAutoMode)                                  {channel="max:thermostat:JEQ0438859:KEQ0335349:mode"}
Number  maxSetTempKueche              "Wunschtemperatur [%.1f °C]"                             <max_temp>  (gMaxKueche, gMaxSetTemp, gMaxAutoTemp)        ["TargetTemperature"]  {channel="max:thermostat:JEQ0438859:KEQ0335349:set_temp"} 
Number  maxActualTempKueche           "Raumtemperatur [%.1f °C]"                               <max_temp>  (gMaxKueche, gMaxActualTemp)                   ["CurrentTemperature"] {channel="max:thermostat:JEQ0438859:KEQ0335349:actual_temp"}
Switch  maxBatLowKueche               "Batteriestatus Küche [MAP(max.map):%s]"                 <battery>   (gMaxKueche, gMaxBatLow)                                              {channel="max:thermostat:JEQ0438859:KEQ0335349:battery_low"}
Number  maxValveKueche                "Ventilstellung [%d %%]"                                 <max_valve> (gMaxKueche, gMaxValve)                                               {channel="max:thermostat:JEQ0438859:KEQ0335349:valve"}
Contact maxLockedKueche               "Bediensperre [MAP(max.map):%s]"                         <lock>      (gMaxKueche, gMaxLock)                                                {channel="max:thermostat:JEQ0438859:KEQ0335349:locked"}

You see here all aspects of a MAX! thermostat: mode, set temperature, current temperature, battery low state, valve setting and lock state. I use labels with a reasonable formatting of values (temperature as °C with one decimal, valve as integer percent). I created some SVG graphics (max_mode, max_temp, max_valve) to visualize the states. In the next column, the items are added to the respective groups.
maxSetTempKueche and maxActualTempKueche are tagged for the Alexa skill.
The last column are the channels. You find the channel name (and the type) in Paper UI:

A room with window sensor

This is an example of a room with a window sensor:

//=====================================================================================================================
// Arbeitszimmer
String  maxModeArbeitszimmer          "Modus"                                                  <max_mode>  (gMaxArbeitszimmer, gMaxMode, gMaxAutoMode)                           {channel="max:thermostat:JEQ0438859:JHA0008545:mode"}
Number  maxSetTempArbeitszimmer       "Wunschtemperatur [%.1f °C]"                             <max_temp>  (gMaxArbeitszimmer, gMaxSetTemp, gMaxAutoTemp) ["TargetTemperature"]  {channel="max:thermostat:JEQ0438859:JHA0008545:set_temp"} 
Number  maxActualTempArbeitszimmer    "Raumtemperatur [%.1f °C]"                               <max_temp>  (gMaxArbeitszimmer, gMaxActualTemp)            ["CurrentTemperature"] {channel="max:thermostat:JEQ0438859:JHA0008545:actual_temp"}
Switch  maxBatLowArbeitszimmer        "Batteriestatus Arbeitszimmer [MAP(max.map):%s]"         <battery>   (gMaxArbeitszimmer, gMaxBatLow)                                       {channel="max:thermostat:JEQ0438859:JHA0008545:battery_low"}
Number  maxValveArbeitszimmer         "Ventilstellung [%d %%]"                                 <max_valve> (gMaxArbeitszimmer, gMaxValve)                                        {channel="max:thermostat:JEQ0438859:JHA0008545:valve"}
Contact maxLockedArbeitszimmer        "Bediensperre [MAP(max.map):%s]"                         <lock>      (gMaxArbeitszimmer, gMaxLock)                                         {channel="max:thermostat:JEQ0438859:JHA0008545:locked"}

Contact maxFensterArbeitszimmer       "Fenster Arbeitszimmer [MAP(max.map):%s]"                <window>    (gMaxArbeitszimmer, gMaxWindow)                                       {channel="max:shuttercontact:JEQ0438859:OEQ0417571:contact_state"}
Switch  maxBatLowFensterArbeitszimmer "Batteriestatus Fenster Arbeitszimmer [MAP(max.map):%s]" <battery>   (gMaxArbeitszimmer, gMaxBatLow)                                       {channel="max:shuttercontact:JEQ0438859:OEQ0417571:battery_low"}

A room with a wall thermostat

Im my living room, there are two heatings and a wall mounted thermostat:

//=====================================================================================================================
// Wohnzimmer
String  maxModeWohnzimmer             "Modus"                                                  <max_mode>  (gMaxWohnzimmer, gMaxMode, gMaxAutoMode)                              {channel="max:wallthermostat:JEQ0438859:MEQ0854379:mode"}
Number  maxSetTempWohnzimmer          "Wunschtemperatur [%.1f °C]"                             <max_temp>  (gMaxWohnzimmer, gMaxSetTemp, gMaxAutoTemp)    ["TargetTemperature"]  {channel="max:wallthermostat:JEQ0438859:MEQ0854379:set_temp"} 
Number  maxActualTempWohnzimmer       "Raumtemperatur [%.1f °C]"                               <max_temp>  (gMaxWohnzimmer, gMaxActualTemp)               ["CurrentTemperature"] {channel="max:wallthermostat:JEQ0438859:MEQ0854379:actual_temp"}
Switch  maxBatLowWohnzimmer           "Batteriestatus Wandthermostat [MAP(max.map):%s]"        <battery>   (gMaxWohnzimmer, gMaxBatLow)                                          {channel="max:wallthermostat:JEQ0438859:MEQ0854379:battery_low"}
Contact maxLockedWohnzimmer           "Bediensperre [MAP(max.map):%s]"                         <lock>      (gMaxWohnzimmer, gMaxLock)                                            {channel="max:wallthermostat:JEQ0438859:MEQ0854379:locked"}

String  maxModeWohnzimmerl            "Modus"                                                  <max_mode>  (gMaxWohnzimmer)                                                      {channel="max:thermostat:JEQ0438859:JEQ0616861:mode"}
Number  maxSetTempWohnzimmerl         "Wunschtemperatur [%.1f °C]"                             <max_temp>  (gMaxWohnzimmer)                               ["TargetTemperature"]  {channel="max:thermostat:JEQ0438859:JEQ0616861:set_temp"}
Switch  maxBatLowWohnzimmerl          "Batteriestatus Wohnzimmer links [MAP(max.map):%s]"      <battery>   (gMaxWohnzimmer, gMaxBatLow)                                          {channel="max:thermostat:JEQ0438859:JEQ0616861:battery_low"}
Number  maxValveWohnzimmerl           "Ventilstellung links [%d %%]"                           <max_valve> (gMaxWohnzimmer, gMaxValve)                                           {channel="max:thermostat:JEQ0438859:JEQ0616861:valve"}
Contact maxLockedWohnzimmerl          "Bediensperre links [MAP(max.map):%s]"                   <lock>      (gMaxWohnzimmer, gMaxLock)                                            {channel="max:thermostat:JEQ0438859:JEQ0616861:locked"}

String  maxModeWohnzimmerr            "Modus"                                                  <max_mode>  (gMaxWohnzimmer)                                                      {channel="max:thermostat:JEQ0438859:JEQ0617410:mode"}
Number  maxSetTempWohnzimmerr         "Wunschtemperatur [%.1f °C]"                             <max_temp>  (gMaxWohnzimmer)                               ["TargetTemperature"]  {channel="max:thermostat:JEQ0438859:JEQ0617410:set_temp"}
Switch  maxBatLowWohnzimmerr          "Batteriestatus Wohnzimmer rechts [MAP(max.map):%s]"     <battery>   (gMaxWohnzimmer, gMaxBatLow)                                          {channel="max:thermostat:JEQ0438859:JEQ0617410:battery_low"}
Number  maxValveWohnzimmerr           "Ventilstellung rechts [%d %%]"                          <max_valve> (gMaxWohnzimmer, gMaxValve)                                           {channel="max:thermostat:JEQ0438859:JEQ0616861:valve"}
Contact maxLockedWohnzimmerr          "Bediensperre rechts [MAP(max.map):%s]"                  <lock>      (gMaxWohnzimmer, gMaxLock)                                            {channel="max:thermostat:JEQ0438859:JEQ0616861:locked"}

Sitemap

To test the configuration, you can use an simple sitemap:

sitemap max label="Heizungssteuerung" {
        Group item=gMax
}

This will show you all your rooms, and all devices in this room:

However, you can’t set the desired temperature, and all in all it’s not very user friendly. So here is my complete sitemap:

sitemap max label="Heizungssteuerung" {
	
	Frame label="Wichtige Informationen" visibility=[gMaxBatLow==ON] {
		Group item=gMaxBatLow visibility=[gMaxBatLow==ON] {
			Text item=maxBatLowWohnzimmer            visibility=[maxBatLowWohnzimmer==ON]
			Text item=maxBatLowWohnzimmerl           visibility=[maxBatLowWohnzimmerl==ON]
			Text item=maxBatLowWohnzimmerr           visibility=[maxBatLowWohnzimmerr==ON]
			Text item=maxBatLowKueche                visibility=[maxBatLowKueche==ON]
			Text item=maxBatLowKinderzimmer          visibility=[maxBatLowKinderzimmer==ON]
			Text item=maxBatLowArbeitszimmer         visibility=[maxBatLowArbeitszimmer==ON]
			Text item=maxBatLowSchlafzimmer          visibility=[maxBatLowSchlafzimmer==ON]
			Text item=maxBatLowBad                   visibility=[maxBatLowBad==ON]
			Text item=maxBatLowTaster                visibility=[maxBatLowTaster==ON]
			Text item=maxBatLowFensterKinderzimmer   visibility=[maxBatLowFensterKinderzimmer==ON]
			Text item=maxBatLowFensterArbeitszimmer  visibility=[maxBatLowFensterArbeitszimmer==ON]
		}
	}	
	
	Frame label="Bediensperre" visibility=[gMaxLock==CLOSED] {
		Group item=gMaxLock visibility=[gMaxLock==CLOSED] {
			Text item=maxLockedWohnzimmer            visibility=[maxLockedWohnzimmer==CLOSED]
			Text item=maxLockedWohnzimmerl           visibility=[maxLockedWohnzimmerl==CLOSED]
			Text item=maxLockedWohnzimmerr           visibility=[maxLockedWohnzimmerr==CLOSED]
			Text item=maxLockedKueche                visibility=[maxLockedKueche==CLOSED]
			Text item=maxLockedKinderzimmer          visibility=[maxLockedKinderzimmer==CLOSED]
			Text item=maxLockedArbeitszimmer         visibility=[maxLockedArbeitszimmer==CLOSED]
			Text item=maxLockedSchlafzimmer          visibility=[maxLockedSchlafzimmer==CLOSED]
			Text item=maxLockedBad                   visibility=[maxLockedBad==CLOSED]
		}
	}	

	Frame label="Fenster" visibility=[gMaxWindow==OPEN] {
		Group item=gMaxWindow visibility=[gMaxWindow==OPEN] {
			Text item=maxFensterKinderzimmer         visibility=[maxFensterKinderzimmer==OPEN]
			Text item=maxFensterArbeitszimmer        visibility=[maxFensterArbeitszimmer==OPEN]
		}
	}

	Frame label="Wohnzimmer" {
		Text       item=maxActualTempWohnzimmer  
		Setpoint   item=maxSetTempWohnzimmer     minValue=4.5 maxValue=25 step=0.5
		Selection  item=maxModeWohnzimmer        mappings=[AUTOMATIC=Auto, MANUAL=Manu, BOOST=Boost] 
	}
	
	Frame label="Küche" {
		Text       item=maxActualTempKueche
		Setpoint   item=maxSetTempKueche         minValue=4.5 maxValue=25 step=0.5 
		Selection  item=maxModeKueche            mappings=[AUTOMATIC=Auto, MANUAL=Manu, BOOST=Boost]
	}
	
	Frame label="Arbeitszimmer" {
		Text       item=maxActualTempArbeitszimmer
		Setpoint   item=maxSetTempArbeitszimmer  minValue=4.5 maxValue=25 step=0.5 
		Selection  item=maxModeArbeitszimmer     mappings=[AUTOMATIC=Auto, MANUAL=Manu, BOOST=Boost]
		Text       item=maxFensterArbeitszimmer
}

The first three frames only show up when there is a battery low, a thermostat locked or a window open. That is the reason why the respective groups are defined using the logic.
In these groups, only the probematic items are shown. Here is an example what happens if there are two batteries low:

Usage in rules

As said above, you can use the groups in rules.
To set all thermostats to a specifix temperature, use

        // Temperatur absenken
        gMaxAutoTemp.members.forEach[item | item.sendCommand(11)]
        gMaxAutoMode.members.forEach[item | item.sendCommand("MANUAL")]

To return to automatic mode, use

        gMaxAutoMode.members.forEach[item | item.sendCommand("AUTOMATIC")]

18 Likes

Thanks for the great tutorial!

Hi Pekka,

thanks for the great tutorial, I’m just building something similar.

Where did you find the icon for the mode?

Hendrik,

I made them myself - feel free to use them :wink:

max_mode.svg: max_mode
max_mode-automatic.svg: max_mode-automatic
max_mode-manual.svg: max_mode-manual

3 Likes

I have something to contribute. I want to keep basic configuration in cfg files, and the example thing definition in the documentation throws up warnings in the log. I found the following syntax to be working without warnings in the logs.

Bridge max:bridge:JEQ0341220 "MAX! Cube LAN Gateway" [ ipAddress="192.168.189.23", serialNumber="JEQ0341220"] {
    Thing ecoswitch JEQ0301258      "Eco Taster"                        [ serialNumber="JEQ0301258" ]
    Thing shuttercontact JEQ0318859 "Fenster Badezimmer Sensor"         [ serialNumber="JEQ0318859" ]
    Thing shuttercontact JEQ0318809 "Balkontür Schlafzimmer Sensor"     [ serialNumber="JEQ0318809" ]
    Thing shuttercontact JEQ0320423 "Balkontür Wohnzimmer Sensor"       [ serialNumber="JEQ0320423" ]
    Thing thermostat JEQ0424354     "Heizkörperregler Kinderzimmer"     [ serialNumber="JEQ0424354" ]
    Thing thermostat JEQ0424374     "Heizkörperregler Wohnzimmer Klein" [ serialNumber="JEQ0424374" ]
    Thing thermostat JEQ0424309     "Heizkörperregler Schlafzimmer"     [ serialNumber="JEQ0424309" ]
    Thing thermostat JEQ0424424     "Heizkörperregler Badezimmer"       [ serialNumber="JEQ0424424" ]
    Thing thermostat JEQ0424464     "Heizkörperregler Wohnzimmer Gross" [ serialNumber="JEQ0424464" ]
    Thing wallthermostat IEQ0492172 "Wandthermostat Schlafzimmer"       [ serialNumber="IEQ0492172" ]
    Thing wallthermostat JEQ0654349 "Temperatur Balkon"                 [ serialNumber="JEQ0654349" ]
    Thing wallthermostat JEQ0656854 "Wandthermostat Wohnzimmer"         [ serialNumber="JEQ0656854" ]
    Thing wallthermostat NEQ0086617 "Wandthermostat Kinderzimmer"       [ serialNumber="NEQ0086617" ]
    }   
2 Likes

Continuing the discussion from MAX! system installation and configuration walktrough:

Hi Pekka,
Thank for this great tutorial!
I’m looking for a heating system room-by-room and Max seems the ideal candidate. And cheap :slight_smile:
As I understand Max is made for homes with central heating, but in my case I have to turn on the boiler.
Is it possible to use OH and adapt Max to my needs?
I was thinking of using a rule like that

rule "valve to boiler"
when
        Item maxValve01 changed

then
        if (maxValve01.state == ON) {
       switchBoiler.sendCommand(ON)
        }
        else
       if (maxValve01.state == OFF) {
        switchBoiler.sendCommand(OFF)
        }
end

to give a command to a relay that turns on the boiler.
Note: I think is important to use valve state (on/off or open/close) and not a thermostat temperature value.
Has anyone already tried it or seem good this way?
Thank you
Stefan

I don’t know if that works, but it might.
I would refrain from using Max!, as it is a one-purpose-system. I’d rather recommend momematic from the same vendor, much more flexible.

You could by using the valve valve. If the max system thinks it is cold, it starts opening valves. That would be your cue to switch on the boiler. Please note that max doesn’t have a switch for that

Ok, thank you guys.
I’ll try this winter :wink:

Hi all,

short @Pekka: is this working for all MAX! thermostats (Basic, normal, +)?

I am currently looking for the right thermostat and MAX! seems to be the best from price performance point of view.

Kindly,
Woogi

@Woogi, yes, this is for the Max! system.
However, I would recommend to choose the (more expensive) Homematic. I have the feeling that that system is more supported by the vendor, eq3 - and you haveone system when it comes to other devices.

thanks for your reply. So it works for all MAX! Thermostats (Basic, normal and the + Version). Great.

Is a deeper support needed by the vendor which explains the need to buy the double price higher homematic system?

Well, with homematic you have all options, while Max! is just a heating control…

A great tutorial! Thanks for your work! I like the way you’re managing all the components.
I’ve stared with OpenHab a few days ago and i’m wondering if there is any magic behind the scenes or what is the best practice to handle the logic.
Do i have to bind all components “the manufacturer way” and then “add” them to OpenHab or do i add all components unconfigured as things and handle the logic with rules?
You set the temperature for the living room only to the wallthermostat, but i can’t see anything in the configurations above which could be responsible for delegating this to the radiator thermostats and i wonder if you paired the wallthermostat with the two radiator thermostats with the learning mode outside openHab or if you have any rules which handle this.

I asked myself the same question. Have you already found a solution?

You configure the Max! system like it’s standalone, and after that you add it to OpenHab.

What you set the wall thermostat’s temperature, it gets inherited to the heating thermostats by Max!, so you only need to set one temperature for the whole room.

Thank you very much for your extremely helpful walkthrough!

However, it left me with a question regarding this:

According to the docs:

Sending a command to a Group causes the command to be sent to all Group members.

So I’ve tried to do it this way, and it seems to work perfectly well:

    // Temperatur absenken
    gMaxAutoTemp.sendCommand(11)]
    gMaxAutoMode.sendCommand("MANUAL")]

This appears much simpler to me. Have I overlooked something?

I had some reasons for not doing it that way - however, I don’ remember them. So maybe I was wrong, or someone else may point us to the reasons…

Regarding setup of the cube itself:

The max cube has an own program to control.
How is the best way to disable that in the web interface of the cube?

Why would you like to do that?