clementprevot / pyduro

A Pypi library to communicate with Aduro (H1) wood/pellet burner via NBE communication

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

API communication

SpaceTeddy opened this issue · comments

Dear Clement,
in the next weeks I will get my own Aduro Hybrid oven and my plan is to try to integrate this oven in my home automation (fhem). Before I try to reverse engineer the communication or read out the ESP32 Wifi module on the ovens main board, I would like to ask you if you already know the communication between app and oven.
thanks and have a nice weekend :)

chris

Hi @SpaceTeddy.
Yup I have a pretty good understanding of the communication going on between the app and the oven.
I started to write this Python lib to use it to integrate my Aduro oven in HomeAssistant but I haven't had time to work further on it yet.

I hope to be able to work on it pretty soon.

In the meantime I can try to write a small doc on the protocol.

Stick around I'll keep you posted

cool, that sounds good!
Documentation of the communication would be the most interesting part for me that I can start to implement it in fhem. 👍
good job!

dear clement,

I tried to log the commands from the oven or aduro cloud with mitproxy, but unfortunately I does not get any commands from that sides.
It would be very nice, if you can give me some further information of the type of protocol and how to sniff it.
would be great during this hard corona times.

thanks a lot

Hi @SpaceTeddy,

Sorry for not coming back to you earlier.
I haven't had any time to work on this as there was a lot going on recently (I have a todler that is being confined with me and my wife, so finding time to geek is far from easy 😉)

I'll try to summarize what I found here (and I will also push my work in progress right now, but I think that it will be hardly usable).

First of, the frame format that is used to talk with the oven. Here is an example frame (used for discovering oven):

abcdefghijkl041837 \x02000012345678904361465775pad 013NBE Discovery\x04

And here the different part of the frame:

  • abcdefghijkl - appId, 12 alphanumerical (upper and lowercase) characters - Uniquely identify the application that is talking with the oven (you can put here whatever you want)
  • 123456 - controllerId, 6 digits - This is the "Serial number" of your oven (the same as the one you entered in the official Aduro application, you can find it on a sticker on the oven, often inside of the door)
  • ** ** - 1 space character
  • \x02 - startChar, the ASCII character 0x02 (so 1 char, not "\x02" 😉) - This is the separator to identify the beginning of the request
  • 00 - function, 2 digits - Identify the type of request
  • 00 - sequenceNumber, 2 digits - To identify the request when run in sequence (optional, you can leave this at 00 if you don't care about the order of your requests)
  • 1234567890 - pinCode, 10 digit - The password to connect to your oven (the same as the one you entered in the official Aduro application, you can find it on a sticker on the oven, often inside of the door)
  • 4361465775 - time, 10 digits - The timestamp at which the request as been issued ('{:0>10.10}'.format(str(time())) in Python do the trick)
  • **pad ** - literraly the string "pad " - I don't know what is this used for. It looks like some sort of padding. Maybe for taking in account larger timestamps or appId. Don't know 🤷‍♂️
  • 013 - payloadSize, 3 digits - The size of the actual payload of the request (that comes right after this)
  • NBE Discovery - payload, max 495 bytes - The actual payload of the request _(here in the example it's a discovery request).
  • \x04 - endChar, the ASCII character 0x04 (so 1 char, not "\x04" 😉) - This is the separator to identify the end of the payload

Here is what I found regarding the function (the name of the functions are pretty straightforward):

  • discover = 00
  • get_settings = 01
  • get_operating_data = 04
  • get_advanced_data = 05
  • get_consumption_data = 06
  • get_event_log = 08
  • get_info = 09
  • get_sw_versions = 010
  • set = 02

So to communicate with the oven, you first have to issue a "Discovery" frame by broadcasting it in on UDP port 1901 and then listen for a response on UDP port 8483.
In this response you will have information about your oven, including it's IP address and port.

Once you discovered your oven, you can send frames with different function and payload.

I didn't found everything by myself, I heavily relied on https://github.com/motoz/nbetest/.
You will also find more information about data structure when getting/setting information):

root = ('settings', 'operating_data', 'advanced_data', 'consumption_data', 'event_log','sw_versions','info')
settings = ('boiler', 'hot_water', 'regulation', 'weather', 'weather2', 'oxygen', 'cleaning', 'hopper', 'fan', 'auger', 'ignition', 'pump', 'sun', 'vacuum', 'misc', 'alarm', 'manual')
consumption_data = ('total_hours', 'total_days', 'total_months', 'total_years', 'dhw_hours', 'dhw_days', 'dhw_months', 'dhw_years', 'counter')

Otherwise, just using the appropriate get operation without any payload will give you the "menu" of each part of your oven.

Hope this help, and if you want to contribute, don't hesitate!

Happy confining 😉

dear clement,
wow, thats are pretty lot infomation, which I have to study and to try out. That the stove uses UDP with your mentioned ports is a good entry point for me. I saw only that the Aduro communicates with http://stokercloud.dk/ and they are using the mentioned NBE protocol.

Thanks a lot and I'm happy to test something in the future :)

Glad this helps.

I'll close this issue, don't hesitate to reopen it or open a new one if you need it.

dear clement,
I guess I need some help for sending the commands..
Well, discovery works fine and I receive the expected data from the oven. Then I tried to send a "get_info" 09 command without payload and without three payload bytes (or payload bytes 000, it noes not matter) , but I receive only '''...Illegal payload size\04''' or '''...Illegal end character: 0x00\04''' messages.
May you please be so kind and describe which string I may send to send the i.E. get_info function.

thanks a lot

Hi @SpaceTeddy!
Well, I have to admit that I don't remember quite well how I managed to make request without payload work. I know that I had to tinker with it a bit, but that I finally managed to make it work.
Sorry, you will have to try it by yourself.

However, on another note, I saw that after 4 years of no updates, the NBETest repository has been updated yesterday. And one of the most notable update is that adding of a protocol documentation. Maybe it will help you

And by reading this documentation, I'm guessing that you can't send an empty request. You have to pass something in the payload, which is the path you want to read

well,
I'm in contact with motoz (nbetest & PellMon) and nbetest (testbranch for NBE V13) is working with the Aduro Hx stoves. With this tool and wireshark I could log the UDP packages and have a better understanding of the protocol now. Also interesting to learn a bit about the crypto stuff what you need to "set" parameters to the ofen. I can recommend that tool.
I also had some trouble with the python crypto lib under MacOS. I used pyCryptoDome, but the nbetest tool is only working with pycrypto.

If someone does need an simple method to request an Aduro Hybrid Stove he can use the Aduro Cloud website.

This Site is using an https-request for getting details of your sove autenthicated by berer token.

Request URL:
https://adurocloud.com/api/stove/xxxxx (Serial number)

Log in at cloud website and track network activity of the site. You will get a perfect json structure with main informations.

Im Still testing lifetime of bearer token.
Screenshot 2022-03-25 183419