How to integrate Daikin Altherma LT heat pump?

Hello George,

I have a BRP069A61 recently installed in my Altherma 3. I have contacted Daikin and they have replied that they only support the APP, and that they do not give any kind of information, since it is a proprietary protocol.
I have tried with
http: // DAIKIN_IP / aircon / get_sensor_info
and

http: // DAIKIN_IP / aircon / get_control_info

But the BRP069A61 replies: Sorry, the requested file does not exist on this server.

I suppose there must be differences between each type of module …
How did you find out how the module works? I say it to be able to do with mine …

Thanks and best regards
Luis

“Man in the middle method”, use a packet sniffer and a port mirror! With Altherma the aircon section might not exist.
Sniff the packets sent between the app and the interface!

Hello,
I have an Altherma LT CB series and a BRP069A2 and want to monitor it like you.

Have you suceeded to make some GET request ? I sniff the packet, but nothing obvious about the sensors values appear…the area of Georges are not accessible too.

Regards

If HTTP GET does not work for you, you need to use websocket. See:

So I found some Pyhthon code in the emoncms code for the BRP069A2 and combined it with the REST API of OpenHab. I wanted to do it as a regular script, but couldn’t figure out how to properly do web sockets. The idea behind the script is that it runs as cron job. I feel like this is a little bit of a hack, but it should do the job and may help some people here.

from websocket import create_connection
import json, urllib, random, string
from urllib import request, parse

def randomString(stringLength=5):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

def postUdpate(item, value):
#Adjust your IP of the OpenHab part here.
    req =  request.Request("http://openhab:8080/rest/items/"+item+"/state", data=str(value).encode('utf-8')) 
    req.add_header('Content-Type', 'text/plain')
    req.get_method = lambda: 'PUT'
    resp = request.urlopen(req)
    if resp.status!=202 :
        print("Response was %s %s" % (resp.status, resp.reason))

def requestValue(ws, item):
    ws.send("{\"m2m:rqp\":{\"op\":2,\"to\":\"/[0]/MNAE/"+item+"/la\",\"fr\":\"/OpenHab\",\"rqi\":\""+randomString()+"\"}}")
    result1 =  json.loads(ws.recv())
    #print("Response was: %s" % result1)
    value = result1["m2m:rsp"]["pc"]["m2m:cin"]["con"]
    return value

#You need to adjust your IP Address here
ws = create_connection("ws://192.168.188.20/mca")

items =	{
  "Heating_TankTemperature": "2/Sensor/TankTemperature",
  "Heating_IndoorTemperature": "1/Sensor/IndoorTemperature",
  "Heating_OutdoorTemperature": "1/Sensor/OutdoorTemperature",
  "Heating_OperationPower": "1/Operation/Power",
  "Heating_OperationMode": "1/Operation/OperationMode",
  "Heating_OperationTargetTemperature": "1/Operation/TargetTemperature",
  "Heating_TankOperationPower": "2/Operation/Power",
  "Heating_TankOperationMode": "2/Operation/OperationMode",
  "Heating_TankOperationTargetTemperature": "2/Operation/TargetTemperature",
  "Heating_TankOperationPowerful": "2/Operation/Powerful",
  "Heating_ErrorState": "0/UnitStatus/ErrorState"
}

for x in items:
  value = requestValue(ws, items[x])
  #print("Received value '%s' for %s" % (value, x))
  postUdpate(x, value)

ws.close()

And of course some items:

Group heating  "Heating"
Number:Temperature     Heating_TankTemperature            "Tank temperature"                             (heating)
Number:Temperature     Heating_IndoorTemperature            "Indoor temperature"                             (heating)
Number:Temperature     Heating_OutdoorTemperature            "Outdoor temperature"                             (heating)
Number:Temperature     Heating_OperationTargetTemperature            "Target temperature"                             (heating)
Number:Temperature     Heating_TankOperationTargetTemperature            "Target tank temperature"                             (heating)
String     Heating_ErrorState            "Error state"                             (heating)
String     Heating_OperationPower            "Operation Power"                             (heating)
String     Heating_OperationMode            "Operation Mode"                             (heating)
String     Heating_TankOperationPowerful            "Operation Powerful"                             (heating)
String     Heating_TankOperationPower            "Operation Power"                             (heating)
String     Heating_TankOperationMode            "Operation Mode"                             (heating)

You may need to run pip3 install websocket websocket-client before it actually works and execute it with python3.

Enjoy!

1 Like

I did a man in the middle capture and found the following end points:

/[0]
/[0]/MNAE/0
/[0]/MNAE/0/DateTime/la
/[0]/MNAE/0/Error/la
/[0]/MNAE/0/UnitProfile/la
/[0]/MNAE/1
/[0]/MNAE/1/ChildLock/LockedState/la
/[0]/MNAE/1/ChildLock/PinCode/la
/[0]/MNAE/1/Consumption/la
/[0]/MNAE/1/Holiday/EndDate/la
/[0]/MNAE/1/Holiday/HolidayState/la
/[0]/MNAE/1/Holiday/StartDate/la
/[0]/MNAE/1/Operation/OperationMode/la
/[0]/MNAE/1/Operation/Power/la
/[0]/MNAE/1/Operation/TargetTemperature/la
/[0]/MNAE/1/Schedule/Next/la
/[0]/MNAE/1/Sensor/IndoorTemperature/la
/[0]/MNAE/1/Sensor/OutdoorTemperature/la
/[0]/MNAE/1/UnitIdentifier/Icon/la
/[0]/MNAE/1/UnitIdentifier/Name/la
/[0]/MNAE/1/UnitProfile/la
/[0]/MNAE/1/UnitStatus/EmergencyState/la
/[0]/MNAE/1/UnitStatus/ErrorState/la
/[0]/MNAE/1/UnitStatus/InstallerState/la
/[0]/MNAE/1/UnitStatus/TargetTemperatureOverruledState/la
/[0]/MNAE/1/UnitStatus/WarningState/la
/[0]/MNAE/2
/[0]/MNAE/2/ChildLock/LockedState/la
/[0]/MNAE/2/ChildLock/PinCode/la
/[0]/MNAE/2/Consumption/la
/[0]/MNAE/2/Holiday/EndDate/la
/[0]/MNAE/2/Holiday/HolidayState/la
/[0]/MNAE/2/Holiday/StartDate/la
/[0]/MNAE/2/Operation/OperationMode/la
/[0]/MNAE/2/Operation/Power/la
/[0]/MNAE/2/Operation/Powerful/la
/[0]/MNAE/2/Operation/TargetTemperature/la
/[0]/MNAE/2/Schedule/Next/la
/[0]/MNAE/2/Sensor/TankTemperature/la
/[0]/MNAE/2/UnitIdentifier/Icon/la
/[0]/MNAE/2/UnitIdentifier/Name/la
/[0]/MNAE/2/UnitInfo/UnitType/la
/[0]/MNAE/2/UnitProfile/la
/[0]/MNAE/2/UnitStatus/EmergencyState/la
/[0]/MNAE/2/UnitStatus/ErrorState/la
/[0]/MNAE/2/UnitStatus/InstallerState/la
/[0]/MNAE/2/UnitStatus/ReheatState/la
/[0]/MNAE/2/UnitStatus/TargetTemperatureOverruledState/la
/[0]/MNAE/2/UnitStatus/WarningState/la
/[0]/MNAE/2/UnitStatus/WeatherDependentState/la
/[0]/MNAE/3
/[0]/MNCSE-node/deviceInfo
/[0]/MNCSE-node/firmware

You can do a discovery of your device by asking for the [0]/MNAE/ and then a number. This will give you a response of what unit you are talking to:

{"m2m:rsp":{"rsc":2000,"rqi":"lcmsd","to":"/S","fr":"/[0]/MNAE/0","pc":{"m2m:cnt":{"rn":"0","ri":"006a","pi":"C0003","ty":3,"ct":"20000000T000000Z","lt":"20000000T000000Z","st":11,"lbl":"function/Adapter"}}}}
{"m2m:rsp":{"rsc":2000,"rqi":"lnjnp","to":"/S","fr":"/[0]/MNAE/2","pc":{"m2m:cnt":{"rn":"2","ri":"003c","pi":"C0003","ty":3,"ct":"20000000T000000Z","lt":"20000000T000000Z","st":13,"lbl":"function/DomesticHotWaterTank"}}}}

A non existing unit will give you a rsc:4004. The next step would then be to request the unit profile: /[0]/MNAE/2/UnitProfile/la which gives you a map of the end points that can be talked to and some information about what answers to expect (only the con part shown here):

{  
   "Sensor":[  
      "IndoorTemperature",
      "OutdoorTemperature"
   ],
   "UnitStatus":[  
      "ErrorState",
      "InstallerState",
      "WarningState",
      "EmergencyState",
      "TargetTemperatureOverruledState"
   ],
   "Operation":{  
      "Power":[  
         "on",
         "standby"
      ],
      "OperationMode":[  
         "heating"
      ],
      "TargetTemperature":{  
         "heating":{  
            "maxValue":30.0000000000000000,
            "minValue":12.0000000000000000,
            "stepValue":1.0000000000000000
         }
      }
   },
   "Schedule":{  
      "Base":"action",
      "defaultScheduleAvailable":"true",
      "NameAdjustable":"false",
      "List":{  
         "heating":[  
            {  
               "StartTime":{  
                  "stepValue":10.0000000000000000,
                  "unit":"minutes"
               },
               "TargetTemperature":{  
                  "heating":{  
                     "maxValue":30.0000000000000000,
                     "minValue":12.0000000000000000,
                     "stepValue":1.0000000000000000
                  }
               },
               "Actions":[  
                  "StartTime",
                  "TargetTemperature"
               ],
               "maxActionsAllowed":6
            },
            [  
               "monday",
               "tuesday",
               "wednesday",
               "thursday",
               "friday",
               "saturday",
               "sunday"
            ],
            [  
               "monday",
               "tuesday",
               "wednesday",
               "thursday",
               "friday",
               "saturday",
               "sunday"
            ],
            [  
               "monday",
               "tuesday",
               "wednesday",
               "thursday",
               "friday",
               "saturday",
               "sunday"
            ],
            [  

            ]
         ]
      }
   },
   "Consumption":{  
      "Electrical":{  
         "unit":"kWh",
         "Heating":{  
            "Daily":{  
               "contentCount":24,
               "resolution":2
            },
            "Weekly":{  
               "contentCount":14,
               "resolution":1
            },
            "Monthly":{  
               "contentCount":24,
               "resolution":1
            }
         }
      }
   }
}{  
   "Sensor":[  
      "TankTemperature"
   ],
   "UnitStatus":[  
      "ErrorState",
      "InstallerState",
      "WeatherDependentState",
      "WarningState",
      "EmergencyState"
   ],
   "Operation":{  
      "Power":[  
         "on",
         "standby"
      ],
      "OperationMode":[  
         "reheat_only"
      ],
      "TargetTemperature":{  
         "reheat_only":{  
            "maxValue":60.0000000000000000,
            "minValue":30.0000000000000000,
            "stepValue":1.0000000000000000
         }
      },
      "powerful":[  
         "0",
         "1"
      ]
   },
   "Schedule":{  

   },
   "Consumption":{  
      "Electrical":{  
         "unit":"kWh",
         "Heating":{  
            "Daily":{  
               "contentCount":24,
               "resolution":2
            },
            "Weekly":{  
               "contentCount":14,
               "resolution":1
            },
            "Monthly":{  
               "contentCount":24,
               "resolution":1
            }
         }
      }
   }
}

Notably interesting is the response to consumption:

{"Electrical":{"Heating":{"D":[0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,3,null],"W":[1,1,2,2,1,0,1,1,2,null,null,null,null,null],"M":[null,null,null,null,null,null,null,null,null,null,null,null,null,0,82,23,100,null,null,null,null,null,null,null]}}}

Unfortunately I don’t have my heating on long enough to get some more interesting data. But I consider writing a proper Daikin adapter bundle as there is some interesting data on these.

1 Like

(Owning a Daikin Altherma LT 16 kW ( EHVH16S26CB9W, ERLQ016CAW1)

I was Googling to find information about how to connect a Daikin Altherma LT with a modbus interface and found this thread; at first I was disappointed to read that only the HT versions were suited for the RTD-W:

But now I found the RTD-LT/CA. Maybe that one was not available in 2016.

https://www.daikin.eu/en_us/products/RTD-LT-CA.html
http://www.alphabms.com/wp-content/uploads/2018/04/Daikin-RTD-Range.pdf

Product Features

RTD-LT

  • Modbus interface for monitoring and control of Daikin Altherma low temperature (EHVH(X)-C / EHBH(X)-C)
  • Voltage and resistance control
  • Photovoltaic operation signal for energy saving

Using the RTD-LT seems to be the most flexible way of remotely managing low temperature heat pumps.

For reference, here is a detailed installation manual that documents the device quite well.
http://www.dacnw.ru/extranet/01.%20Daikin/06.%20СИСТЕМЫ%20УПРАВЛЕНИЯ%20И%20ОПЦИИ/ЦЕНТРАЛЬНЫЕ%20ПУЛЬТЫ%20И%20ШЛЮЗЫ/MODBUS%20GATEWAY%20(EKMBDXA_RTD)/RTD/(IM-OM)%20RTD-LT-CA_rus.pdf

Hey, I continued to investigate this API a bit and the consumption works as following:
For the daily row every even hour a new value is provided for the past 2 hours. Here is an example at 23h:

[0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,null]

One hour later at 0:01

[0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,null,null,null,null,null,null,null,null,null]

So the last value is essentially never written.
For the weekly this is the same on Sunday it looks like this:

"W":[7,8,4,9,1,3,3,1,3,3,8,1,4,null]

on Monday then:

"W":[1,3,3,8,1,4,2,null,null,null,null,null,null,null]

What I am not quite sure yet is what this consumption entails. I have 2 smartmeter (one for heating, the other for the rest of the house) and the numbers that I collect there during the heating phases are smaller, but not as much as I would expect for an air heat pump. I guess I should check the front panel of my unit to see as it reports both consumed and generated energy.

Date Measured Reported
2019-06-17 2,6 7
2019-06-18 2,8 8
2019-06-19 2 4
2019-06-20 3,2 9
2019-06-21 1 1
2019-06-22 1,6 3
2019-06-23 1,2 3
2019-06-24 1,3 1
2019-06-25 1,5 3
2019-06-26 1,3 3
2019-06-27 3,1 8
2019-06-28 0,8 1
2019-06-29 1,4 4

So here is my updated script now which works quite well:

from websocket import create_connection
import json, datetime, time, urllib
from urllib import request, parse
import random
import string

def randomString(stringLength=5):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

def postUdpate(item, value):
    if value is None:
        print("Not posting None value for "+item)
        return
    req =  request.Request("http://openhab:8080/rest/items/"+item+"/state", data=str(value).encode('utf-8')) # this will make the method "POST"
    req.add_header('Content-Type', 'text/plain')
    req.get_method = lambda: 'PUT'
    resp = request.urlopen(req)
    if resp.status!=202 :
        print("Response was %s %s" % (resp.status, resp.reason))

def requestValue(ws, item):
    ws.send("{\"m2m:rqp\":{\"op\":2,\"to\":\"/[0]/MNAE/"+item+"/la\",\"fr\":\"/OpenHab\",\"rqi\":\""+randomString()+"\"}}")
    result1 =  json.loads(ws.recv())
    #print("Response was: %s" % result1)
    value = result1["m2m:rsp"]["pc"]["m2m:cin"]["con"]
    return value

def requestYesterdaysConsumption(unitNumber):
    consumption=requestValue(ws, str(unitNumber)+"/Consumption")
    cj = json.loads(consumption)
    now = datetime.datetime.now()
    weeklyIndex=(now.weekday()-1)+7
    dailyUsage=cj["Electrical"]["Heating"]["W"][weeklyIndex]
    print("Received electrical weekly usage value '%s' for unit %s" % (dailyUsage, unitNumber))
    if dailyUsage is not None: #This may occur if your local time is more advanced
        return dailyUsage*1000 # than the heating unit.
    return None

def requestLast2HoursConsumption(unitNumber):
    consumption=requestValue(ws, str(unitNumber)+"/Consumption")
    cj = json.loads(consumption)
    now = datetime.datetime.now()
    hourlyIndex=((now.hour-2)//2)+12
    biHourly=cj["Electrical"]["Heating"]["D"][hourlyIndex]
    print("Received electrical daily usage value '%s' for unit %s" % (biHourly, unitNumber))
    if biHourly is not None:
        return biHourly*1000
    return None

ts = time.time()
timestamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')

ws = create_connection("ws://192.168.188.20/mca")

items =	{
  "Heating_TankTemperature": "2/Sensor/TankTemperature",
  "Heating_IndoorTemperature": "1/Sensor/IndoorTemperature",
  "Heating_OutdoorTemperature": "1/Sensor/OutdoorTemperature",
  "Heating_OperationPower": "1/Operation/Power",
  "Heating_OperationMode": "1/Operation/OperationMode",
  "Heating_OperationTargetTemperature": "1/Operation/TargetTemperature",
  "Heating_TankOperationPower": "2/Operation/Power",
  "Heating_TankOperationMode": "2/Operation/OperationMode",
  "Heating_TankOperationTargetTemperature": "2/Operation/TargetTemperature",
  "Heating_TankOperationPowerful": "2/Operation/Powerful",
  "Heating_ErrorState": "0/UnitStatus/ErrorState"
}

for x in items:
  value = requestValue(ws, items[x])
  print("Received value '%s' for %s" % (value, x))
  postUdpate(x, value)

postUdpate("Heating_BiHourlyEnergyHeat", requestLast2HoursConsumption(1))
postUdpate("Heating_BiHourlyEnergyWater", requestLast2HoursConsumption(2))
postUdpate("Heating_DailyEnergyHeat", requestYesterdaysConsumption(1))
postUdpate("Heating_DailyEnergyWater", requestYesterdaysConsumption(2))
ws.close()

I also captured some write packages, but apparently forgot to store them :wink: But what I recall is that OP is set to 1 for writing. I will re-check when I am back at home.

Ah, I did find the responses for switching something:

{"m2m:rqp":{"op":1,"to":"/[0]/MNAE/1/Operation/Power","fr":"/S","rqi":"qwxxl","ty":4,"pc":{"m2m:cin":{"con":"on","cnf":"text/plain:0"}}}}
{"m2m:rsp":{"rsc":2001,"rqi":"qwxxl","to":"/S","fr":"/[0]/MNAE/1/Operation/Power"}}
{"m2m:rqp":{"op":1,"to":"/[0]/MNAE/2/Operation/Powerful","fr":"/S","rqi":"spcxt","ty":4,"pc":{"m2m:cin":{"con":1,"cnf":"text/plain:0"}}}}
{"m2m:rsp":{"rsc":2001,"rqi":"spcxt","to":"/S","fr":"/[0]/MNAE/2/Operation/Powerful"}}
{"m2m:rqp":{"op":1,"to":"/[0]/MNAE/2/Operation/Powerful","fr":"/S","rqi":"olpcx","ty":4,"pc":{"m2m:cin":{"con":0,"cnf":"text/plain:0"}}}}
{"m2m:rsp":{"rsc":2001,"rqi":"olpcx","to":"/S","fr":"/[0]/MNAE/2/Operation/Powerful"}}

Great work. Thanks for this! I am able to run your script and update my items in OH. But I’m wondering how it works the other way. Meaning, how can I change for example the target temperature from OH? Not sure if I understand your last post with the responses for switching something. Thanks.

To give you some idea I quickly wrote this code for you to do some testing. I am currently not at home, so I have no way of checking if it works like that. In particular I have never seen the setting of a target temperature, so no idea if that is the correct way of doing it. It is simply a guess from my side.

def setValue(ws, item, value):
    ws.send("{\"m2m:rqp\":{\"op\":1,\"to\":\"/[0]/MNAE/"+item+"\",\"fr\":\"/OpenHab\",\"rqi\":\""+randomString()+"\",\"ty\":4,\"pc\":{\"m2m:cin\":{\"con\":"+value+",\"cnf\":\"text/plain:0\"}}}}")
    result1 =  json.loads(ws.recv())
    #print("Response was: %s" % result1)
    value = result1["m2m:rsp"]["rsc"]
    if (value==2001):
        print("Success")
    return value

#Switch on the heating unit (1 is my central heating, 2 is warmwater)
setValue(ws, "1/Operation/Power", "\"on\"")
#Switch on the temporary boost
setValue(ws, "2/Operation/Powerful", "1")
#Change temperature 
setValue(ws, "2/Operation/TargetTemperature", "15")

On the good news side: I am currently developing a binding and if you want to beta test it, I will be happy to provide it to you once I am mildly confident that it does work in general. What would be helpful is if you could send me your output of:

print(requestValue("0/UnitProfile"))
print(requestValue("1/UnitProfile"))
print(requestValue("2/UnitProfile"))
print(requestValue("3/UnitProfile"))
print(requestValue("4/UnitProfile"))

Hi Karsten, many thanks! Your code, after some initial tests, seems to work. Sure, I like to help out and do some beta testing for the binding. I have a Daikin Altherma hybrid heat pump and I’m using the BRP069A62 LAN adapter.

For some reason, I can only request the unit profiles 0 and 1. My thermostat shows more information like the energy consumption, so I am bit in the dark why I can’t see it in the app or via the API. Here are the response messages:
UnitProfile0.json (115 Bytes)
UnitProfile1.json (3.1 KB)
Is there anything else you would like to know?

Ah, that is the same Adapter I have. It is odd that it does not appear to export the same values. A friend of me has the same adapter and it also does not report the consumption. The thermostat is probably directly attached to the P1P2 bus and thus has access to all registers (which in theory the adapter should also have). From the Man in the middle capture I could also see that some other registers can be accessed that are not in the UnitProfile.
Thanks for your profile!

Ok, I did some disassembly of of the APK file from the Android store and did find a few more strings that one can query. Like:

print(requestValue(ws, "1/ChildLock/LockedState/la"))
print(requestValue(ws, "1/ChildLock/PinCode/la"))

print(requestValue(ws, "1/ConnectionTest"))

print(requestValue(ws, "1/Holiday/EndDate/la"))
print(requestValue(ws, "1/Holiday/HolidayState/la"))
print(requestValue(ws, "1/Holiday/StartDate/la"))

print(requestValue(ws, "1/Operation/ComfortMode/la"))
print(requestValue(ws, "1/Operation/OperationMode/la"))

print(requestValue(ws, "1/Operation/ReheatTargetTemperature/la"))
print(requestValue(ws, "1/Operation/TargetTemperature/la"))

#Points to the active Schedule (returns 1/Schedule/List/Heating/la for example)
print(requestValue(ws, "1/Schedule/Active/la"))
print(requestValue(ws, "1/Schedule/Default/la"))
print(requestValue(ws, "1/Schedule/List/Cooling/la"))
print(requestValue(ws, "1/Schedule/List/Heating/la"))
#Not sure why they are included, maybe an earlier version had a typo
print(requestValue(ws, "1/schedule/List/Cooling/la"))
print(requestValue(ws, "1/schedule/List/Heating/la"))
#What will happen next the temperature probably refers to the mode 
print(requestValue(ws, "1/Schedule/Next/la"))

#Returns an index to the icon, you can find the icons in the APK android file
print(requestValue(ws, "1/UnitIdentifier/Icon/la"))
#Appears to be null
print(requestValue(ws, "1/UnitIdentifier/Name/la"))

#Some information about the units
print(requestValue(ws, "1/UnitInfo/ModelNumber/la"))
print(requestValue(ws, "1/UnitInfo/UnitType/la"))
print(requestValue(ws, "1/UnitInfo/Version/IndoorSettings/la"))
print(requestValue(ws, "1/UnitInfo/Version/IndoorSoftware/la"))
print(requestValue(ws, "1/UnitInfo/Version/OutdoorSoftware/la"))
print(requestValue(ws, "1/UnitInfo/Version/RemoconSettings/la"))
print(requestValue(ws, "1/UnitInfo/Version/RemoconSoftware/la"))

print(requestValue(ws, "1/UnitStatus/ActiveState/la"))
print(requestValue(ws, "1/UnitStatus/ControlModeState/la"))
print(requestValue(ws, "1/UnitStatus/EmergencyState/la"))
print(requestValue(ws, "1/UnitStatus/ErrorState/la"))
print(requestValue(ws, "1/UnitStatus/InstallerState/la"))
print(requestValue(ws, "1/UnitStatus/ReheatState/la"))
print(requestValue(ws, "1/UnitStatus/TargetTemperatureOverruledState/la"))
print(requestValue(ws, "1/UnitStatus/WarningState/la"))
print(requestValue(ws, "1/UnitStatus/WeatherDependentState/la"))

#Didn't try that one ;)
print(requestValue(ws, "1/Reboot"))

As I am currently developing the binding I need some orientation on what you’re interested on:

How important is it for you to see and or modify the schedule?

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

0 voters

How important is it for you to see the consumption?

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

0 voters

Hello,
Look at this, you may be interested …


1 Like

In case someone didn’t know how to get the IP o the pump

from zeroconf import ServiceBrowser, Zeroconf
import ipaddress

class MyListener:

    def remove_service(self, zeroconf, type, name):
        print("Service %s removed" % (name,))

    def add_service(self, zeroconf, type, name):
        info = zeroconf.get_service_info(type, name)
        ip = ipaddress.IPv4Address(info.address)
        print("%s: Service %s added, service info: %s" % (ip, name, info))


zeroconf = Zeroconf()
listener = MyListener()
browser = ServiceBrowser(zeroconf, "_daikin._tcp.local.", listener)
try:
    input("Press enter to exit...\n\n")
finally:
    zeroconf.close()

Hi All,

Since a week or 2 I have the same adapter BRP069A62
And I am poking around this device. What I have found is that upon reboot, port 80 and 23 are open for about 30 min or so, I have not been able to guess a password for the telnet connection. And port 80 only does basic functions on the page like setting the IP address and reset.

For now I am able to read a lot of info, and change the temp and turn on / off. But am stuck trying to change anything of the schedule. The nested json is a bit of a pain.

Current output

User chosen schedule ID: 3
Next schedule change: Monday, Time: 2200, temp will be set to: 18.0
Complete schedule: $NULL|1|1700,200;2200,180;,;,;,;,;1700,200;2200,180;,;,;,;,;1700,200;2200,180;,;,;,;,;1700,200;2200,180;,;,;,;,;1700,200;2200,180;,;,;,;,;1000,200;1300,180;1700,200;2200,180;,;,;1000,200;1300,180;1700,200;2200,180;,;,
=====================================================
Connected to Daikin on: 192.168.1.247
Device function: function/SpaceHeating
The device is currently: on, and the operation is: heating
Brand: Daikin, LAN adapter Model: BRP069A62, Duty: HVAC controller, Firmware: 17003900, Software: 436DD123000, SerialNR: XXXXXXX
Given name by user: Central heating
=====================================================
Indoor unit model: EHYHBH08AAV3, software: ID9051, EEPROM: AS1706433-11A
Outdoor unit Softare: ID3904, User EEPROM: AS1705847-01F, User interface software: AS1705847-01F
=====================================================
Current Errors: 0, Current Warmings: 0, Emergency state: 0,  Installer state: 0
Reported Errors:
=====================================================
Did we manually override the scheduled temp: NO
Current indoor temp: 20.0
Current outdoor temp: 11.0
Current water temp: 46.5
Current target temp: 21.0
=====================================================
Water temp is calculated based on: WeatherDependent
=====================================================
Is child lock active: NO, Current pin is: 1234
=====================================================
Holiday start: 2020-03-06, Holiday End: 2020-03-06, Holiday mode active?: NO
=====================================================

Any one have a Idea to on how to change the schedule?

This is based upon changing the temp / on/off but does not seem to work:

{
	"m2m:rqp": {
		"op": 1,
		"to": "/[0]/MNAE/1/Schedule/Active",
		"fr": "/S",
		"rqi": "",
		"ty": 4,
		"pc": {
			"m2m:cin": {
				"con": "{"data":{"path":"/mn-cse-LONG_ID_STRING/MNAE/1/schedule/List/Heating/la","id":2}}",
				"cnf": "text/plain:0"
			}
		}
	}
}

changing: "cnf": "text/plain:0" to "cnf": "application/json:0" does not help either. The daiking heating app is a mess with cariables named every letter of the alphabet and not a decent name. All the values in a long variable… those devs…

My code is far from pretty as it is highly repetitive at the moment having all the URLS + their JSON key figured out, and some even nested JSON.

My indoor unit is the hvac+gas hybrid pump. And does not readout consumption as it is not connected to the lan module only the p1/p2 bus is. (which might be a next step to figure out on how to enable such things.)

Alos worthy of note:

  • The Random strings are not actually needed it seems.
  • The Url in the send JSON under fr, Also can be just a /
  • Which would reduce the code to: "{\"m2m:rqp\":{\"op\":2,\"to\":\"/[0]/MNAE/1/Schedule/List/Heating/la\",\"fr\":\"/\",\"rqi\":\""\"}}"

Cheers!

I’m looking to get a DAIKIN Altherma R Hybrid 8kW. Would that work with your REST sniffer based works ?

Did your plans to go for a binding succeed ? Or did your Python script mature ?

I’d like to instruct my heat pump to do its work when I have excess electric power from my solar system (SG ready function)
Can I do that via OpenHAB/REST or would I need the BRP069A61 ? (it has electrical inputs for that in addition to what the BRP069A62 can do).

Hey Markus,
I am currently in the process of switching everything over to a Homie/MQTT based architecture. I was just developing some code today. I guess by Monday I should have something to at least read the values and provide it to MQTT.
I think you could use the 2/Operation/Powerful feature to produce hot-water on demand, but I am not sure if there is a smarter/better way of doing that.

I will let you know when I have some public code.

Karsten