Integration of Heatpump Ochsner Tronic Smart Services (OTS) via Modbus

Hello and welcome abraxas_son!

Thank you so much for the info on undocumented modbus registers. I tried immediately and still have to look into it in detail. My first comments are:

  • 203 (Hot water temperature Scale 0.1) is now identical to 029 (after undocumented change from scale 1 to sclae 0.1)
  • 219 (Hot Water Setpoint): To me it seems to be the hot water setpoint for reduced. values corresponds to Values changed in OTS-App.
  • 246 (Power Consumption): Questio is on whether thisis the total Power Consumption or just L1. Actually L2, L3 are auxilary heater, thus they might be in seperate registers in order to compute “power demand” as shown in the app.
  • 213: also 1542 for me

How about other addresses ? Did you try to read other addresses as well ?

I will keep those entities and check which values they get and whether I can relate them to a functionality.

Hi Alfred,

I already tried all registers up to 247 but besides the few registers I listed above (and a few I added now below), I couldn’t find any other meaningful registers. Some were just duplicates of documented registers and all the others were returning 0. Perhaps some of the registers with 0 values might have meantingful readings at specific times, but I just checked briefly with ModbusMaster and didn’t observe for a longer period of time.

For address 246 (power consumption), I had not the chance yet to validate if its L1 only or total of all phases. Since the auxiliary heating element is barely in use (only when it’s really freezing outside), it might take until winter to find out.

For me I could confirm address 219 to hold the active warmwater setpoint, as it changes between “reduced” setpoint and “normal” setpoint based on the schedule defined in “comfort mode” (the one I use). And when the anti-legionella program is active, it matches the setpoint specified for the anti-legionella program.

Register 202 shows following pattern, but I have no idea what this could be :thinking:.

In the meantime, I could find out Register 229 is just a duplicate of 49 (heatpump status) :unamused:

Some other registered I found filled with values I can’t explain.

  • 30 (so far only 1, 2, 4, 11, 12, 31, perhaps a status code?)
  • 32 (so far only seen 450, 550, and 0)
  • 53 (values between 642-646)

Hi abraxas_son!

ad 219: I was mistaken - you are absolutely right, it is the setpoint of hot water temperature depending on schedule and mode.

ad 202: it somehow relates to heatpump operating status, but has a lot more values. Also trying to relate to power consumption did not help.

ad:229: as stated by you already, 229 is a copy of heatpump status

ad 246: this was supposed to hold the value of the power consumption. In order to check whether this covers just L1 oder L1+L2+L3 I switched off heatpump, swirched on auxilary heater and turned temperature up for hot water. However I cannot explain the results out of this action. Register 246 shows at the maximum register about 1840 W while my shelly for L2 shows more than 2500 W. For power of the heatpump during hot water heating the values of register 246 and shelly have been equal.


Registers for precise temperature values of hot water and room temperature.

I did contact Ochsner because of the breaking change of hot water temperature done may 1st (scale 0.1). According to Ochsners answer this was a mistake and as of today it is scale 1 as before and as documented. Addionally I got the information, that upon requets by users now additional registers are available holding precise temperature (scale 0.1) which will be officially documented soon.

  • register 147: precise_hot_water_temperature (scale 0.1)
  • register 153: precise_room_temperature_heating_circuit_1 (scale 0.1)
  • register 154: precise_room_temperature_heating_circuit_2 (scale 0.1)
  • register 154: precise_room_temperature_heating_circuit_3 (scale 0.1)
  • register 155: precise_room_temperature_heating_circuit_4 (scale 0.1)

I will try to keep in contact with ochsner regarding values reengineered by abraxas_son and my questions in particular regarding power consumption.
Also the yaml definition in this post will be updated to V0.93 to reflect these new registers.

1 Like

Hi Alfred,

first of all thank you for your great work.
I’m already reading my Ochsner Heatpump (Air Hawk 518 - has got the exakt same Modbus Registers) via NodeRed and saving the values to an influxdb for over 2 years by now.
Now I was looking for a way to transfer the values to Home Assistant as well and found your way to integrate it directly - awesome!

From my research I’m happy to be able to contribute at least a little piece to solve the “undocumented”-riddle:
Register 220 is the target temperature for the heating (Vorlauf_Soll). :slight_smile:

Hi, can anyone help me, to integrate and control this in HA. How have i config the sensor/switches. Ochsner Air Hawk 518
The Sensors for reading ar perfect working.

Thanks so much

Actually OTS supports 3 modes of “Integration” See “ZBH-Modbus OTS-EN03”

As far as I understand you would have to use the mode " Control via building management" - which means you would be soley responsible for controlling the heatpump.

What I and most probably you as well are seeking would be to read and set all values which can be read or set by the OTS application and keeping control under OTS according those values. This would allow to autoamte a timing plan, modify setpoint of temperature of heating and/or hot water, … track values for settings, … The later would be of use to correlate values of heating curve wiht outside temperature in order to optimize hte curve. Or take weather forecast inot account (Currently average temperature of past 10 hours is taken for control, in combination of the delay of underfloor heating).

I my opinion the mart home integration of Ochsner is quite poor, first in terms of usability to leave the user alone with modbus and even more importand with functionallity crippled to a minimum.

If a find time, I will again contact ochsner, so far I was not sucessful at all.
Maybe if others aks for better integration they will wake up.

Sorry guys to bother you. I just started with Home Assistant two days ago and would like to add my Ochsner Air Hawk 208 with the given yaml code.

Unfortunately, I always get a configuration warning when adding the code (and modifying the IP accordingly):
Konfigurationswarnungen

Invalid config for ‘modbus’ at configuration.yaml, line 12: ‘modbus’ is an invalid option for ‘modbus’, check: modbus->0->modbus Invalid config for ‘modbus’ at configuration.yaml, line 12: ‘sensor’ is an invalid option for ‘modbus’, check: modbus->0->sensor Invalid config for ‘modbus’ at configuration.yaml, line 12: required key ‘baudrate’ not provided Invalid config for ‘modbus’ at configuration.yaml, line 12: required key ‘bytesize’ not provided Invalid config for ‘modbus’ at configuration.yaml, line 12: required key ‘method’ not provided Invalid config for ‘modbus’ at configuration.yaml, line 12: required key ‘parity’ not provided Invalid config for ‘modbus’ at configuration.yaml, line 12: required key ‘port’ not provided Invalid config for ‘modbus’ at configuration.yaml, line 12: required key ‘stopbits’ not provided Invalid config for ‘modbus’ at configuration.yaml, line 12: required key ‘type’ not provided

Any idea what can be done to fix this? :confused:
Thanks in advance!

Actually, I don’t know what did go wrong. However, I updated my yaml code (Integration of Heatpump Ochsner Tronic Smart Services (OTS) via Modbus - #3 by Alfred99). Only an additional register is defined, which has nothing to do with your problem. Anyway you can give it a try, maybe something was wrong when the previous yaml file v0.93.

in case I find enough time and help, I will provide a Github integration which would be easier to integrate and have all entities as one device.

1 Like

My bad! Your code is working fine when using in configuration.yaml. I tied excluding it in a seperate file which obviously causes strange errors. :slight_smile: Thanks so much!
Just need to wait for the Ochsner support to active modbus…

Hi there and thanks @Alfred99 for your documentation!
Was anybody succesfully to write Data to the Ochsner Air Hawk?
I have tested it to send on Register Adress 1 with Value 0/1, (& Read out the changes) but the Heating Pump doesn’t change its Operating Mode.

hi,
I think this works only in case you request such mode at Ochsner.
Reading in the “OTS MODBUS INTERFACE” on Top of page 6 “INTEGRATION” with its three described "scenarieos (they name it “questions”). This sounds pretty much not in the spirit of smart home, but rather in the spirit of a Building manangement system alternatively to private use in smart home.

In my understanding, a smarthome integration should be allowed to read everything the OTS application is allowed to read and write everything the OTS application is allowed to write, but not at the cost of passing full controlto the user, but stay responsible liek the OTS app does
.
From time to time I am in contact with Ochsner, but asking about smart home they tell that they are disvussing internally. Maybe some I find time to write a more detailed proposal what I as a smarthome user is expecting and add some hints how the could be accomplished by them.

Currently I am even missing data I would like to read

  • power (it delivers just energy), in order to compute COP and other values resp show graphs. An external powermeter is necessary
  • settings: I would read my settings like heating and cooling curve in order to relative to measurements of room temperature and optimize

Some screenshorts of my Ochsner heatpump integration:

  1. my overview: I have added badges for Heatpump operation mode and power, actual COP (Performance), Flow temperature, Boiler temp,…

    2.) In a heatppumpt view I show mode dependend information. Here you see Cooling mode with some data like power and COP and graph of room temperature Flow Temperature, Return Temperature and Dewpoint.
    All of this depends of external Powermeter in addition to modbus data from Ochsner
  2. Screenshort shows temperature increase during mode hot water - it shows electric power and thermal power (computed). This ratio is the COP (Performance factor)

    4.) Screenshot shows reported faults - actually I notify home assistant and my smartphone as well in case of a fault.

Good Visualisation and Ideas from your Side @Alfred99!

I have contacted Ochsner also if they can explain me why sending Value 1/0 at Adress 1 takes no impact to the Heatpump itself.
I hope they can answer it.
Because its also able to read all values from this Table.

@Alfred99 Here you can see the power consumption in W, i have done an Helper to calculate the actual COP

      - name: OTS_246_power_consumption
        slave: 1
        address: 246
        input_type: holding
        data_type: uint16
        unit_of_measurement: W
        state_class: measurement
        device_class: power
        scan_interval: 30
        unique_id: ots_246_power_consumption

Thanks
I am quite interested in Ochsners answer!

Regarding Reg 246. Actually this is a “newer” one and I think not yet officially documented. Ochsner did answer my question regarding 246 a couple of month ago:
relevant are in particular registers available in the documentation. All others are partially used internal may change or be deleted. (Translated)

Furthermore 246 show 10 - 40 W less than my Shelly PM. Shelly measures all three phases which allows in particular look at auxilary heating / hot water .

Actually such a difference will result in significant difference in COP.

1 Like

Hi @Alfred99 Ochsner has anwered my Questions about the Modbus Case.
Modbus TCP is only for reading - if we want to write, we have to activate Modbus RTU. But this is only possible on site possible.

So… after a few years of reading values via Modbus with the Script above (Thank you, by the way), I really wanted a way to also control settings like buffer temperature in order to be able to automatically heat the water hotter than required when there is excess PV energy and use it throughout the day.
But apparently, since the Modbus interface doesn’t allow us to write anything that seems like a pipe dream, right?

Well not anymore!

Presenting the newest Vibecode slop I’ve cooked up over the holidays:
OTS-HomeAssistant

If anyone cares, here’s the story:

The root of my investigation was a simple train of thought:
If the Modbus Interface can’t control the settings remotely, then how does the App do it?

About a year back I attempted to find any possible other interface to access the heat pump and realized that if you connect a browser to its IP address, you get a http login prompt. Declining that prompt gives you the interesting nugget of knowledge which is the manufacturer:
Siemens Building Technologies Climatix WEB Server V1.00, 2008

So apparently Ochsner just rebrands Siemens Heatpumps (or at least the controllers)? Fitting.

Either way, a bit of googling revealed a default user and PW for the web interface for Siemens Climatix - sadly that just leads to an empty web page.

Yesterday I got thinking again, and on a hunch attempted to decompile the apk for the Ochsner app, and wouldn’t you know it, it’s entirely obfuscated.

Randomly searching through the code gave me at least a rough picture of what was going on, even if I had no idea how it actually worked in detail.

Apparently, the App you can download on Android is the exact same app that is running on the display of the Heat Pump, too. As in: the same APK, with all the code to locally access the heatpump that should only run inside the heatpump locally included in the whole play store app.

Except I had no idea how to interpret the gordian knot that is obfuscated java code to understand exactly HOW to control the device. Luckily, apparently Github copilot + chatgpt 5.2 actually can do this pretty well.

The local interface is a json interface that is entirely undocumented, but can be accessed with hardcoded credentials (the same ones I found via google, but different user name). The interface accepts IDs which can either be read or written. These IDs don’t appear anywhere else, and I found no way to list or identify them locally. However, with a bit more reverse engineering I found the api that the app uses to download the entire configuration bundle from ochsner - you just need your ochsner user and pw to call the api. from the bundle json, you can then look through all possible values and attempt to find the ones you want to locally read / control.

I compiled it all into a script that can:

  • Log into OTS cloud with your account to get access key and download the config bundle
  • search the bundle for names / heating circuits
  • attempt to read the current values to identify the correct ones
  • write single values to see if they affect the right change in the app

Finally, I made a small home assistant custom integration where you can configure your Heat Pump IP address plus all the identified value Ids you want to read / control.

I’ve tested this with an AirHawk 518 and it works pretty well, it even updates the values visible in the app within a few seconds. You can even programmatically set the Minimum Buffer Temperature to force the heat pump to store up heat when there is excess energy!

Let me know if it works for you, and also tread with caution when setting random values so you don’t accidentally brick your device (there don’t seem to be any of the safeguards here as there are with Modbus and you can change a lot more than what is visible in the app)


2 Likes

This sounds pretty cool! Thank you!
Not sure I’m able to understand all steps but I’ll have a look :grin:

Feel free to ask questions. The python script has a bunch of parameters and features that the AI generated that may or may not be necessary, I just summarized a few of them that I used to get the ids required.

Mainly all you want to do is download the bundle.json from ochsner, then use the tool to search through the json for all the values you want to track / control by their name (same or similar name as in the app), and find the “genericId” for those values. Then you add those values with their respective ids into the home assistant config.

Also I have no idea if the solution I outlined using the genericIds will work for every single heatpump, or just for the modern ones.

Future Reference for anyone attempting to reverse engineer some part of this themselves:
There are several ways to control the heat pump in the source code that seem to automatically be selected depending on the version of the controller. The (older?) version uses the normal ids and the /json.html path, where the newer one that I used uses the generic ids and the /jsongen.html path, which does seem to work for everything I tried. The python script to search the bundle and run test queries technically supports both the normal and the generic ids, but the home assistant integration for now only works with generic Ids since while my heat pump has the /json.html interface too, I couldn’t get it to work for me, and only ever received Json error codes when I tried to use that interface.

1 Like

A bit further investigation and I might have found a possible reason why Ochsner was so reluctant to allow users to programmatically change settings: The settings are saved in the Siemens Climatix controller device inside the heat pump, and that uses Flash memory.

From the Technical Documentation of one of these Devices from Siemens:

Lifecycle of flash for ApplicationSave

After ApplicationSave is triggered, all object parameters are written to flash. 
Consider the flash’s lifecycle*) to avoid the flash damage upon ApplicationSave.
*) A flash chip typically has 100,000 erase/program cycles. 
Consequently, the number of executed ApplicationSave command must be 
balanced with the flash chip’s lifecycle. The table below shows a typical controller 
lifecycle with different ApplicationSave scenarios.

Now I don’t know which of the settings would trigger an immediate Flashing every time, or which would only save in longer intervals like certain counters do. However, if you do automate changing any settings like temperature or mode - try to calculate how often that would be called over the course of a day / year, and sum it up for how long you want the heat pump to last–and stay at around 100.000 in total just to be on the safe side. An average of 10 writes per day should last you 30 years for example.

2 Likes