Rowenta vacuum cleaner HT component

Hello everyone,
I bought a Rowenta model vacuum cleaner with IOT remote control, I was wondering if any of you know how to integrate it to home assistant, or if there is an API in python to be able to control it.
Thank you!

1 Like

Hello there,

You have this working on youā€™re home assistant?

Hi @dadaloop82 ,

Did you ever got this working on home assistant?

Appologies for bumping this topic but iā€™ve taken a look into this,
for what i can tell itā€™s not possible.

i did a MITM attack and could see it settings up a connection to ā€˜https://account.groupeseb.com/services/oauth2/tokenā€™ to get the user account information and an API key. From then it gets itā€™s information of ā€œhttps://sebplatform.api.groupe-seb.com:443ā€

I can read the https payloads as long as it goes about the user information, but when I send a vacuum request like ā€˜localizeā€™ or ā€˜startā€™ then it receives 3 RSA public keys from ā€˜https://account.groupeseb.com/id/keysā€™ and they encrypt the payload before sending it over a websocket to a MQTT server of AWS.

https://(ENDPOINT)-ats.iot.eu-west-1.amazonaws.com:443/mqtt?

more info
(Device communication protocols - AWS IoT Core)
MQTT over WSS wss://iot-endpoint/mqtt

there is no internal traffic registered between the app and the vacuum, it all goes through the cloud MQTT server. Itā€™s a closed api and as long as we donā€™t have the private key we wonā€™t be able to decrypt those payloads.

2 Likes

Hi @luwidgiani

First of all, thanks for doing this research,
I was looking also into getting this to work with HA, but it seems its not possibleā€¦

ā€˜Luckilyā€™ I work at GroupeSeb, but not on the HQ, where they do those decisionsā€¦
Iā€™ll try to find the department that manages this and ask for support on this matter, but i am keeping my expectations lowā€¦
Even with Amazon/Alexa the functionality is very very poorā€¦

3 Likes

Bump,
Did you mean to control a rowenta vacuum robot via home assistant?
I got a rowenta series 80 and found it exposes a ā€œrobeyeā€ interface on port 8080. This page contains multiple buttons that send http requests for certain actions. eg: ā€œ192.168.x.x:8080/set/stopā€ to stop cleaning. You can view alot of info about the device on this page, including the generated maps of your home. and all sensor data can be read from ā€œhttp://192.168.x.x:8080/get/sensor_valuesā€

I have not looked further into it at the moment but this shouldnā€™t be to hard to control using home assistantā€¦ maybe if I have some more free time I would look into making a simple HA integrationā€¦

If anyone is looking into this as well, let me know.

4 Likes

Hi @dadaloop82, thanks for starting this thread, I have the same question as you.

@luwidgiani, thanks for trying to untangle the API. I have emailed Rowenta asking them if they will provide access to the API. Iā€™ll let you know if I get a reply.

@raggadust, any luck at GroupeSeb?

@peejee, nice find, but sadly I am not able to access my sensor data in that way with my robots ip. ERR_CONNECTION_REFUSED which robot are you using? I have a rowenta x-plorer 60 series.

I would hope Rowenta will be willing to support Home Assistant given they already support Google Home and Apple Homekit aside from their own appā€¦

HI,
Local API not working for me neither (rowenta xplorer 75).

I can work on the HA integration if you get the API documentation from rowenta.

same, no internal api on the rowenta xplorer 45

@peejee what is robeye, google is not giving me any hits

@mennosmit & @vipial1 have you tried doing a nmap scan of the ip that your vacuum is on? There might be another open port on that deviceā€¦ or maybe I got send a device that had issues and they forgot to put developer mode off :man_shrugging: Only have the 1 device

@luwidgiani RobeyeĀ® | Recognition Robotics is used on my Rowenta series 80

Capture dā€™Ć©cran 2022-12-11 105639

My Rowenta Smart Force Cyclonic Connect is probably a robart vaccum cleaner (robart.ai). It seems to be very similar to the previous descriptions, and I was able to do something

In my case, with nmap :
Not shown: 998 closed ports
PORT STATE SERVICE
443/tcp open https
10009/tcp open swdtp-sv

There is a workaround now, cause itā€™s possible to add it in google home.

I ran map on my rowenta xplore 60 series and it returned 4 filtered ports, which means we might need to spoof the origin of requests to it.
here is the result :
PORT STATE SERVICE
17322/tcp filtered unknown
35336/tcp filtered unknown
53972/tcp filtered unknown
65163/tcp filtered unknown

Hi guys,
it seems that there is a difference between the series. For the older models I found the post in different thread (Robot Vacuum recommendation - #30 by VNRARA) that its just Tuay devices, so you should be able to add them through Tuay/Smar life app and use the Tuya integration with HA.
For new devices the situation is different. I have device Rowenta Explorer 130 series and there it seems that its their own product.

Fornunetly the integration should be easy to create.

Thanks for @peje66 message I have discovered that vacuum cleaner have the own app RobEye publicly accessible through the local network on port 8080

So far, I get investigation for the API, and it looks like it using simplified REST api just with GETs.

For exaple

Stop command GET 192.168.X.X:8080/set/stop
Home command GET 192.168.X.X:8080/set/go_home
Clean all  GET 192.168.X.X:8080/set/clean_all?cleaning_parameter_set=0&cleaning_strategy_mode=4&pump_volume=none

We can get also the information about the areas with

GET 192.168.X.X:8080/get/areas

hi,

the rowenta 130 is using similar api to romy, you can get it here:
https://www.romyrobot.com/de-AT/romy-robot-interface-protocol

theoretically there are plugins as merge request, which could work for S130 too:

and openhab(only 2 links allowed to post as new user here)
github DOT com /openhab/openhab-addons/pull/15738

yours,
xeniter

Thank you, I will definetly give a try, but in the mean time I did some research and have prepared a manual configuration for myself. I am in the state that I am able to control my vacuum cleaner Rowenta Explorer 130 from HA without any direct integration, using just the vacuum template and REST integration.

If someone is interest in the details, you can add the following code into your configuration.yaml to do a same thing

First of all you will need to get just few details from the RobEey app (which is runing on port 8080 of your vacuum cleaner IP)

# This is the configuration part
input_text:
  vacuum_cleaner_ip:
    name: "Vacuum cleaner IP"
    # You need to set your local IP
    initial: "192.168.X.X"
  vacuum_cleaner_map_id:
    name: "Vacuum cleaner map ID"
    # You need to set Map ID from RobEye app
    initial: "3"

# This is the are mapping with human names and internal IDs from RobEey app
input_select:
  vacuum_cleaner_area:
    icon: mdi:map-marker
    options:
      - Bed room-1
      - Kitchen-3
      - Bathroom-6
      - Living room-10
      - Hall-11
      - Toilet-14
      - Hall and Bathroom-11,6

You can get your Map ID from here
image

And then from the image of the map you can get the ID of the areas:

Then you can just add prepared configuration like I did, and make sure to restart the whole HA inside the devloper tools menu.

# APIs for the sensors values
rest:
  resource_template: http://{{states('input_text.vacuum_cleaner_ip')}}:8080/get/status
  sensor:
    - name: Vacuum battery level
      value_template: "{{ value_json.battery_level | int }}"
      unit_of_measurement: "%"
      icon: mdi:battery
    - name: Vacuum mode
      value_template: "{{ value_json.mode }}"
      icon: mdi:robot-vacuum
    - name: Vacuum charging
      value_template: "{{ value_json.charging }}"
      icon: mdi:battery-charging
    - name: Vacuum fan speed
      value_template: "{{ value_json.cleaning_parameter_set }}"
      icon: mdi:speedometer 

# Commands to control the Vacuum cleaner
rest_command:
  rowenta_return_to_base:
    url: "http://{{states('input_text.vacuum_cleaner_ip')}}:8080/set/go_home"
  rowenta_stop:
    url: "http://{{states('input_text.vacuum_cleaner_ip')}}:8080/set/stop"
  rowenta_clean_all:
    url: "http://{{states('input_text.vacuum_cleaner_ip')}}:8080/set/clean_all?cleaning_parameter_set={{cleaning_parameter_set}}&cleaning_strategy_mode=1&pump_volume=none"
  rowenta_clean_spot:
    url: "http://{{states('input_text.vacuum_cleaner_ip')}}:8080/set/clean_map?map_id={{states('input_text.vacuum_cleaner_map_id')}}&area_ids={{area_ids}}&cleaning_parameter_set={{cleaning_parameter_set}}&cleaning_strategy_mode=1&pump_volume=none"
  rowenta_set_fan_speed:
    url: "http://{{states('input_text.vacuum_cleaner_ip')}}:8080/set/switch_cleaning_parameter_set?cleaning_parameter_set={{cleaning_parameter_set}}"
  rowenta_status:
    url: "http://{{states('input_text.vacuum_cleaner_ip')}}:8080/get/status"

# Vacuum template
vacuum:
  - platform: template
    vacuums:
      rowenta_vacuum:
        # Change to yours SN
        unique_id: "aicu-123345909090"
        friendly_name: "Vacuum cleaner"
        battery_level_template: "{{states('sensor.vacuum_battery_level')}}"
        fan_speed_template: "{{states('sensor.vacuum_fan_speed')}}"
        value_template: >-
          {% if states('sensor.vacuum_mode') == "cleaning" %}
            cleaning
          {% elif states('sensor.vacuum_mode') == "ready" and ( states('sensor.vacuum_charging') == "charging" or states('sensor.vacuum_charging') == "connected" ) %}  
            docked
          {% elif states('sensor.vacuum_mode') == "ready" and states('sensor.vacuum_charging') == "unconnected" %}  
            paused  
          {% elif states('sensor.vacuum_mode') == "go_home" %}  
            returning  
          {% else %}
            error
          {% endif %}
        attribute_templates:
          cleaning_area: >-
            {% set parts = states('input_select.vacuum_cleaner_area').split('-') %}
            {{ parts[0] }}
        start:
          service: rest_command.rowenta_clean_all
          data:
            cleaning_parameter_set: >-
              {% set fan_speed_reverse_map = { 'Normal':'1', 'Eco':'2',  'High':'3', 'Silent': '4' } %}
              {{ fan_speed_reverse_map[states('input_select.vacuum_cleaner_fan_speed')] }}
        stop:
          service: rest_command.rowenta_stop
        return_to_base:
          service: rest_command.rowenta_return_to_base
        clean_spot:
          service: rest_command.rowenta_clean_spot
          data:
            area_ids: >-
              {% set parts = states('input_select.vacuum_cleaner_area').split('-') %}
              {{ parts[1] }}
            cleaning_parameter_set: >-
              {% set fan_speed_reverse_map = { 'Normal':'1', 'Eco':'2',  'High':'3', 'Silent': '4' } %}
              {{ fan_speed_reverse_map[states('input_select.vacuum_cleaner_fan_speed')] }}
        set_fan_speed:
          - service: rest_command.rowenta_set_fan_speed
            data:
              cleaning_parameter_set: >-
                {% set fan_speed_reverse_map = { 'Normal':'1', 'Eco':'2',  'High':'3', 'Silent': '4' } %}
                {{ fan_speed_reverse_map[fan_speed] }}
          - service: input_select.select_option
            data:
              option: "{{ fan_speed }}"
            target:
              entity_id: input_select.vacuum_cleaner_fan_speed
        fan_speeds:
          - Normal
          - Eco
          - High
          - Silent

#Helper input select with fan speed
input_select:
  vacuum_cleaner_fan_speed:
    icon: mdi:speedometer
    options:
      - Normal
      - Eco
      - High
      - Silent

# Helper button to start area cleaning
input_button:
  vacuum_cleaner_start_area_cleaning:
    name: Start area cleaning
    icon: mdi:vacuum   

# Automation to start the spot cleaning 
automation:
  - id: '1700602293259'
    alias: Vacuum start area cleaning
    description: ''
    trigger:
    - platform: state
      entity_id:
      - input_button.vacuum_cleaner_start_area_cleaning
    condition: []
    action:
    - service: vacuum.clean_spot
      data: {}
      target:
        entity_id: vacuum.rowenta_vacuum

You can also create a shortcut buttons for clean a specific room like this:

# Helper button to start kitchen cleaning
input_button:
  vacuum_cleaner_start_kitcheb_cleaning:
    name: Start kitchen cleaning
    icon: mdi:vacuum   

automation:
  - id: '1700636942173'
    alias: 'Clean kitchen '
    description: ''
    trigger:
    - platform: state
      entity_id:
      - input_button.clean_kitchen
    condition: []
    action:
    - service: input_select.select_option
      data:
        # You need to specify the option from the area-ids mapping selector
        option: Kitchen-3
      target:
        entity_id: input_select.vacuum_cleaner_area
    - service: vacuum.clean_spot
      data: {}
      target:
        entity_id: vacuum.rowenta_vacuum
    mode: single

And here is my example dashboard card configuration, which looks like this:
image

type: entities
entities:
  - entity: vacuum.rowenta_vacuum
  - entity: sensor.vacuum_battery_level
    name: Battery
  - entity: input_select.vacuum_cleaner_area
    name: Area
    icon: mdi:map-marker
  - entity: input_select.vacuum_cleaner_fan_speed
    name: Cleaning mode
    icon: mdi:speedometer
  - entity: input_button.vacuum_cleaner_start_area_cleaning
title: Vacuum cleaner
footer:
  type: buttons
  entities:
    - entity: input_button.clean_kitchen
      show_icon: true
      show_name: true
3 Likes

I integrated your snippets with my Rowenta 80 Explorer series and it worked great! One thing that had me scratching my head for a moment is that declaring multiple input_select options in the configuration.yaml as separate blocks wouldnā€™t work for me. This should be turned into a real integration with how smooth it works.

romy support is now merged supported by HA (: