Connecting Velux Active KIX 300

@tombox that’s correct. I described above how you can remove the certificate pinning and route the network traffic through a mitm proxy. It’s a bit tricky to setup but I think the only way to get the necessary data.

This is not the issue because the the is no traffic via https is looks like a direct connection between gateway and phone. The Gateway sends a broadcast and the app on the receive the package and generate a hash. This hash will be send to the gateway with a hashed target position. But the decompiled hash algorithm are hard to reproduce.

@nougad:
Finally found the time to go through your howTo and got everything working. Great Kudos!

Is it ok for you if I cut you a PR with some improvement ideas?

Sure, all contributions are welcome. Right now the velux-cli is just an example for accessing the Velux CLI and it works pretty well for me in combination with OpenHab.

Hello there,
I am very interested in this topic, as I was really unhappy that velux-active is such a closed system without any public api. I currently have 8 windows, 2 blackout blinds and 6 sun screens/awning blinds running. As someone said before, the system works perfectly, but the automation features are poor and I want to log the sensor data in openhab.

I tried @nougad’s manual for retrieving the client_id and client_secret - but I’m stuck. I should add that I have no experience with java or android develepement. Maybe someone could give me a hint? :wink:

Current status:

  • I decompiled the app, changed the xml file (2 occurences), built it again
  • signed it with a developer key (using apk signer)
  • installed the apk on an android device
  • changed the proxy settings, but via android ui, not with adb
  • i get http requests of the browser on the android device in mitmproxy ->should work?
  • the app starts, but fails to connect to netatmo-server at login (brief error message at the bottom of the screen).

UPDATE: right after posting this I found my error (it always works…) – I didn’t install the mitm-certs. It works now!

I will test @nougad’s velux-cli in the next few days.

1 Like

Many thanks @nougad for all your reverse engineering! Out of curiosity: Are the KIX 300 APIs the same as the ones of the KLF 200?

A link to the fully documented KLF 200 APIs can be found in the docs of the Velux binding. On that note: Based on my understanding of the API docs, KLF 200 supports more than 5 devices (up to 200 if I get it right).

I could imagine that Velux is using parts of the KLF 200 code base for the KIX 300 (this would mean that the existing integration could be amended without too much effort). And given that Velux documented the KLF 200 APIs I could further imagine that they would eventually do the same thing for the KIX 300.

I will certainly follow this discussion with high interest! I just installed a Somfy Connexoon to control my two Velux roller shutters (the rest of my apartment is KNX), just to find out that things are controlled through the Somfy cloud (which I don’t really like). Setting the Connexoon up with my OpenHAB Raspberry worked like a charm, but I will eventually replace it with a solution with more privacy.

Hey @peter.janes. As far as I know the KIX300 API has nothing to do with the KLF 200 API. The KLF 200 API is a local wire protocol with the hub while the KIX 300 API ist talking with an Cloud-based endpoint. THE KIX 300 API has some overlap with the netatmo API. Therefore the marketing name VELUX ACTIVE with NETAMO - which I personally find quiet a stretch since the the only overlap between the two products is some common terms in an undocumented API. In addition the KIX 300 supports homekit which I personally haven’t tried.

Thanks for your quick feedback @nougad!

In another forum article (#11) I read that Velux Active can be operated without the Velux cloud (only HomeKit local) - so I would assume there must be locally available APIs, at least for HomeKit.

Did you compare your reverse engineered APIs with the KLF 200 documentation?

Yes, as I mentioned the KIX 300 has HomeKit support which I didn’t tried. Above Connecting Velux Active KIX 300 mentioned HomeKit simulators/bridges which probably work completely local.

The API I use is the cloud-based-Netatmo-like-API which is also used in the Velux APP.

And then again there is the KLF200 which has absolutely nothing to do with the KLX 200 (neither netatmo cloud nor homekit API)

Thanks for the clarifications, @nougad! I will certainly continue to follow this conversation.

Hi guys,

I see that Velux Active now supports Google Home / Assistant since few months ago.

I have configured it with my KIX300 and it works, it is still buggy, but I believe that they will fix this with future versions.

So, here is the question; does this mean that they opened some api? Would it be possible now to use this for OH-KIX300 binding?

This is wonderful! Thanks a lot @nougad for your work and @Polo for your help, I can now store the sensor values and build graphs :grinning:

@nougad here’s the traffic for windows:

#################################################

Open window to 47% 

POST https://app.velux-active.com/syncapi/v1/setstate                                                                                                                                                                                   [m:auto]{
    "app_version": "1106200",
    "home": {
        "id": "YOUR_HOME_ID",
        "modules": [
            {
                "bridge": "BRIDGE_MAC_ADDRESS",
                "hash_target_position": "...",
                "id": "YOUR_WINDOW_ID",
                "nonce": 0,
                "sign_key_id": "VERY_SECRET_KEY_FOR_END_2_END",
                "target_position": 47,
                "timestamp": 1584558106
            }
        ],
        "timezone": "Europe/Vienna"
    }
}


#################################################

Close Window

POST https://app.velux-active.com/syncapi/v1/setstate
{
    "app_version": "1106200",
    "home": {
        "id": "YOUR_HOME_ID",
        "modules": [
            {
                "bridge": "BRIDGE_MAC_ADDRESS",
                "id": "YOUR_WINDOW_ID",
                "target_position": 0
            }
        ],
        "timezone": "Europe/Vienna"
    }
}


#################################################

Open Window completely (100%)

https://app.velux-active.com/syncapi/v1/setstate
{
    "app_version": "1106200",
    "home": {
        "id": "YOUR_HOME_ID",
        "modules": [
            {
                "bridge": "BRIDGE_MAC_ADDRESS",
                "hash_target_position": "...",
                "id": "YOUR_WINDOW_ID",
                "nonce": 0,
                "sign_key_id": "VERY_SECRET_KEY_FOR_END_2_END",
                "target_position": 100,
                "timestamp": 1584558276
            }
        ],
        "timezone": "Europe/Vienna"
    }
}


#################################################

Stop all movements currently going on

POST https://app.velux-active.com/syncapi/v1/setstate
{
    "app_version": "1106200",
    "home": {
        "id": "YOUR_HOME_ID",
        "modules": [
            {
                "id": "BRIDGE_MAC_ADDRESS",
                "stop_movements": "all"
            }
        ],
        "timezone": "Europe/Vienna"
    }
}


#################################################
1 Like

Found a much better way of how to interact with KIX-300, the answer is HomeKit.
It has several advantages over the reverse engineered solution used by velux-cli:

  • easier to setup
  • future proof as it uses a standard protocol to interact with the KIX-300
  • works locally, no cloud
  • works with windows as well
  • get all values from sensors

So this is what I did:

  1. install https://github.com/jlusiardi/homekit_python#installation
  2. create pairing file
  3. run discovery (within the same network!)
  4. run pairing (you find the pairing code of the KIX-300 on the backside of the gateway) - use ``velux` as alias
  5. list accessories with python3 -m homekit.get_accessories -f pairing.json -a velux
  6. get characteristics or put characteristics

Basically it’s just following the instructions from the link above :wink:

Example how to open a window (11.10 is the characteristic id you get from list accessories):

python3 -m homekit.put_characteristic -f pairing.json -a velux -c 11.10 50

Have fun!

3 Likes

Hi Bernhard
I just implemented your homekit solution. It works perfectly!! Thanks so much!

Is there a nice way to link the python commands directly to openhab?

Kind regards
Jens

did you implemented an binding module?

Hi Rafael,
i just followed the steps described by Bernhard. The commands via console work fine so far.
But I’m not sure how to make items and things from the python commands.

Kind regards
Jens

hi,

i’ve created following protoype. (i didn’t test the UP/DOWN/STOP commands for the blinds, could be that they are inverted and that the stop command doesn’t work at all). Using a slider for the blinds works pretty well.

you need to adjust the id’s (e.g. 5.10) and the path to the paring file (this file need’s to be owned by the openhab user, (not the openhabian user))

velux.things

Thing exec:command:velux [command="python3 -m homekit.get_characteristic -f /openhab/conf/homekit.json -a velux -c 5.10 -c 5.13 -c 5.17 -c 2.10 -c 3.10 -c 4.10", interval=30, timeout=20]

velux.items

String VeluxExec "velux status update" {channel="exec:command:velux:output"}

Number Flur_temperatur "Temperature [%.1f °C]" <temperature> 
Number Flur_Co2 "CO2 [%.1f]"
Number Flur_luftfeuchtigkeit "Luftfeuchtigkeit [%d]"
Number Flur_luftquali "Luft Qualität [%d]"
Number Flur_lux "Lux [%d]"

Group veluxshutters <rollershutter>
Rollershutter Galerie_Rolladen (veluxshutters)
Rollershutter Badezimmer_Rolladen (veluxshutters)
Rollershutter Galerie_Fenster <window> (veluxshutters)

velux.rules

rule "velux item update"
when
   Item VeluxExec changed
then
  val jsonstate = triggeringItem.state.toString
  //logInfo("Received Json", jsonstate)


  val temp = transform("JSONPATH", "$['5.10']['value']", jsonstate)
  Flur_temperatur.postUpdate(temp)

  val co = transform("JSONPATH", "$['5.17']['value']", jsonstate)
  Flur_Co2.postUpdate(co)

  val humidity = transform("JSONPATH", "$['5.13']['value']", jsonstate)
  Flur_luftfeuchtigkeit.postUpdate(humidity)

  val prozent = Integer::parseInt(transform("JSONPATH", "$['3.10']['value']", jsonstate).toString())
  Galerie_Rolladen.postUpdate(100 - prozent)

  prozent = Integer::parseInt(transform("JSONPATH", "$['4.10']['value']", jsonstate).toString())
  Badezimmer_Rolladen.postUpdate(100 - prozent)

  prozent = Integer::parseInt(transform("JSONPATH", "$['2.10']['value']", jsonstate).toString())
  Galerie_Fenster.postUpdate(100 - prozent)
end

rule "shutters command"
when
  Member of veluxshutters received command
then
  logInfo("shutters", triggeringItem.name + ": " + triggeringItem.state.toString + " - " + receivedCommand)


  var String veluxShutter
  switch (triggeringItem) {
    case Galerie_Rolladen: veluxShutter = '3.11'
    case Badezimmer_Rolladen: veluxShutter = '4.11'
    case Galerie_Fenster: veluxShutter = '2.11'
  }


  var int position
  if (receivedCommand == UP) {
    position = 0
  } else if (receivedCommand == DOWN) {
    position = 100
  } else if (receivedCommand == STOP) {
    val StringBuilder readCommand = new StringBuilder
    readCommand.append("python3@@-m@@homekit.get_characteristic@@-f@@/openhab/conf/homekit.json@@-a@@velux@@-c@@" + veluxShutter)
    val String result = executeCommandLine(readCommand.toString, 10000)
    position = transform("JSONPATH", "$.['" + veluxShutter + "'].value", result)
  } else if (receivedCommand instanceof Number) {
    position = 100 - receivedCommand.intValue
  }


  logInfo("shutters",  "moving " + veluxShutter + " to " + position)


  val StringBuilder myCommand = new StringBuilder
  myCommand.append("python3@@-m@@homekit.put_characteristic@@-f@@/openhab/conf/homekit.json@@-a@@velux@@-c@@" + veluxShutter + "@@" +  position)

  logInfo("shutters", myCommand.toString, 1000)

  val String Answer = executeCommandLine(myCommand.toString, 10000)
  logInfo("shutters", "Result:" + Answer)
  
end
1 Like

hi all,

i did already something with openhub and it went so far so good.

But with this i have a problem in creating the “pairing file”.
what information are needed and where can i find it?

I followd the link and installed the homekit_pyton and i can discover the bridge.
But thats it…

thanks for support

chris

hi all,

i found a good step by step guide


no it is working perfect for me

thanks
chris

1 Like