Rademacher Homepilot in Home Assistant

Haven’t looked into the UI’s source code, but makes sense.
Some people are using the DuoFern USB stick to directly communicate with the devices (pyduofern IIRC), don’t know what the state of that is :thinking:

Me neither. F12 in Crome / network tab and you see what happens.

Acrually it would be worth to have a “Real” HomePilot integration. But the learning curve to make that is a bit to steep (for me), especially if you have it actually running…

So, I’m fine with the rest based version. If someone makes a “central dynamic polling” like i did in node red directly in scripts - i guess i would switch to that. Otherwise I’m ok with it for now.

Before i stumbled about this thread, i was using only input numbers, and did send updates to the blinds once UI changes the numbers. But this “a -> b ; b-> a” update logic caused strange effects. So, I’m really happy with the cover template now. :slight_smile:

Hi, I’m currently working on a Rademacher HomePilot integration for Home Assistant. At the time it only supports Blinds and ignores the “inverted” flag since the first pull request should be as minimal as possible.
If you want to try it out you can download the homepilot folder from my repo and place it in your custom_components folder (https://downgit.github.io/#/home?url=https://github.com/Nico0302/core/tree/homepilot/homeassistant/components/homepilot).
After restarting Home Assistant you should be able to add the integration via the integration panel in the setting UI.

The integration uses a custom python library to communicate with the HomePillot Hub or Smart2Smart bridge: https://github.com/Nico0302/pyhomepilot.

6 Likes

Wow, first of all welcome and thank you! Sounds great, I’ll look into it later :partying_face:

Thanks and good work!
I just tested it with the starterkit and it looks promising.

Hallo zusammen ,
Kann mir einer bitte jemand den kompletten curl Befehl für den 2 fach Aktor zum ein und ausschalten nennen.
Z.b.
Http://192.168.2.4/devices/xxxxxxx ???

In Chrome Tracing steht Turn Off und on.
Ich weiß aber nicht wie der komplette Befehl lautet.
Gruß Thomas

Will you add your custom integration to HACS?

Hab selbst leider keinen 2 fach Aktor, aber folgendes im React Frontend gefunden:

{
  name: "CURR_SWITCH_POS_CFG",
  value: "TURN_ON_CMD" oder "TURN_OFF_CMD"
}

Zum anschalten also einfach diesen Befehl ausführen:

curl -XPOST -H "Content-type: application/json" -d '{
 "name": "CURR_SWITCH_POS_CFG",
 "value": "TURN_ON_CMD"
}' 'http://host/devices/{deviceId}'

(bin mir nicht ganz sicher, ob das auch für den 2 fach Aktor funktioniert, da dort nur von “switch” die Rede ist)

I’m currently adding some more unit tests so I can integrate it directly into Home Assistant.

1 Like

@fedot
Thank you very much for your work. I received my DuoFern belt winders today and with your code I had them up and running in HA in around 15 minutes. :+1: :smiley:

Works great, now I have to find out why the belt winder reports mysterious states itself. The states in HA are the same as the Rademacher bridge reports, but they are wrong in the first place. My blinds are up around 15 centimeters and get reported as 50%… :grimacing: :thinking:

But nonetheless it was a very pleasant surprise how easy it was thanks to your work. :slight_smile: I copied all three parts into one package file, replaced the did with a !secret and that was it. :slight_smile:

Thanks!

The did is the device ID and just an ascending number, there’s nothing secret about it, so you don’t need to do that.
Read the instructions on how to set the endpoints correctly on the belt winders, then they’ll report the correct state.

I know, but !secret was the only way (I know) to combine the IP and the device into one place. I just have to add more devices in one place and then copy and paste the sensor and the template. :wink:

# blinds_package.yaml
sensor:
  - platform: rest
    name: 'Livingroom Window Blind'
    resource: !secret host_livingroom_window_blind
    value_template: >-
      {% for item in value_json.payload.device.capabilities %}
        {%- if item.name == "CURR_POS_CFG" -%}
          {{ 100 - float(item.value) }}
        {%- endif -%}
      {% endfor %}
    scan_interval: 20

cover:
  - platform: template
    covers:
      livingroom_window_blind:
        device_class: blind
        friendly_name: "Rollo Wohnzimmerfenster"
        position_template: "{{ states('sensor.livingroom_window_blind') }}"
        open_cover:
          - service: rest_command.belt_winder_up
            data:
              device_ip_id: !secret host_livingroom_window_blind
        close_cover:
          - service: rest_command.belt_winder_down
            data:
              device_ip_id: !secret host_livingroom_window_blind
        stop_cover:
          - service: rest_command.belt_winder_stop
            data:
              device_ip_id: !secret host_livingroom_window_blind
        set_cover_position:
          - service: rest_command.belt_winder_set_position
            data_template:
              device_ip_id: !secret host_livingroom_window_blind
              position: "{{position}}"

rest_command:
  belt_winder_up:
    url: '{{ device_ip_id }}'
    method: PUT
    payload: '{"name":"POS_UP_CMD"}'
  belt_winder_down:
    url: '{{ device_ip_id }}'
    method: PUT
    payload: '{"name":"POS_DOWN_CMD"}'
  belt_winder_stop:
    url: '{{ device_ip_id }}'
    method: PUT
    payload: '{"name":"STOP_CMD"}'
  belt_winder_set_position:
    url: '{{ device_ip_id }}'
    method: PUT
    payload: '{"name":"GOTO_POS_CMD","value":"{{ 100 - float(position)|int }}"}'
# secrets.yaml
host_livingroom_window_blind: 'http://10.0.0.10/devices/1'
host_diningroom_window_blind: 'http://10.0.0.10/devices/2'

This way I have just one place (secrets.yaml) where I have to set the IP and id. :slight_smile: It’s just a convinience function, not a secret. :slight_smile:

I have set both endpoints, they do work, but the %-positions are very weird. The window is at least 1,2m in height, but lifted for around 15cm shows 35%, lifted up to 30cm / 35cm shows 50%… I will have to investigate that, but for now I’m happy all is working, automations are set up, just great! :slight_smile:

@Nico0302 Great!
I see that Rademacher has 2 types of controllers… HomePilot and Bridge:
https://service.rademacher.de/hc/en-us/articles/360015767739-What-is-the-difference-between-the-Bridge-and-the-HomePilot-
From the application point of view seems the same, the bridge has less features and third party systems support. Is your integration compatible with both?

Yes it is, I’m running the code from this thread (slightly changed) without any problems for six days. :slight_smile:

EDIT: To clarify, if this code runs with both (HomePilot and bridge), the code from Nico0302 will run on both as well.

Hi @Nico0302 ,

Please keep in mind that the version information is currently missing from the manifest file which might cause that new users will run into problems loading the addon after 2021.06 is live and these users are not aware of what to change manually in the file…

Hi @kauthmbt,

what exactly needs to be changed in the manifest?
Thx

Hi @mattt ,
it should look something like this now to present the version for custom integrations:

{
  "domain": "homepilot",
  "version": "0.0.2",
  "name": "Rademacher HomePilot"

Source

1 Like

Geil ich kann jetzt schon mal die Homebridge Verknüpfung lösen und direkt einbinden, zumindest die Rollos.
Allerdings macht der Wettersensor Probleme, ich habe da ja einen Aktor integriert dieser läuft auf ID 25 und der Wettersensor auf 26. Dazu habe ich noch den binary sensor (Regen) wie oben beschrieben hinzugefügt. Allerdings kriege ich folgende Fehlermeldungen:

self.environment.handle_exception()
  File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 925, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "
TypeError: unsupported operand type(s) for -: 'int' and 'str'
2021-06-28 17:52:10 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'dict object' has no attribute 'RAIN_DETECTION_MEA' when rendering '{{ value_json["payload"]["device"]["capabilities"][71]["RAIN_DETECTION_MEA"] }}'
2021-06-28 17:52:12 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.markise fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 350, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 558, in async_device_update
    raise exc
  File "/usr/src/homeassistant/homeassistant/components/rest/entity.py", line 85, in async_update
    self._update_from_rest_data()
  File "/usr/src/homeassistant/homeassistant/components/rest/sensor.py", line 184, in _update_from_rest_data
    value = self._value_template.async_render_with_possible_json_value(
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 552, in async_render_with_possible_json_value
    return _render_with_context(
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1358, in _render_with_context
    return template.render(**kwargs)
  File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 1304, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 925, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "
TypeError: unsupported operand type(s) for -: 'int' and 'str'

Der Regensensor ist mir eigentlich wurst und wird auch wieder raus gehauen, allerdings würde ich gerne die Markise steuern können :confused: ich hab die genauso wie die Rollos versucht einzubinden welche ja Funktionieren. Aber der aktualisiert nicht und läd sich tod.

Any Ideas?

Thx

Und die config Einträge…? :wink: Ohne die wird’s eher ein Ratespiel. :slight_smile:

Sorry :smiley: glatt vergessen anbei die Configurator für den Wettersensor und der Markise.
Allerdings kopiere ich das übers Handy, ich hoffe da stimmt dir Formatierung :slight_smile: Und bitte das # teils davor weg denken, sind aktuell nur deaktiviert.
Falls es nicht klappt, dann poste ich die Config nachher nochmal über den PC.
Wisst ihr ob die Markise eine andere Device Class hat als die Rollos?

Merci

sensor:
  - platform: rest
    name: 'Temperatur'
    resource: 'http://192.168.178.32/devices/26'
    value_template: '{{ float(value_json["payload"]["device"]["capabilities"][24]["value"]) }}'
    scan_interval: 20
    device_class: temperature
  - platform: rest
    name: 'Markise'
    resource: 'http://192.168.178.32/devices/25'
    value_template: '{{ 100 - float(value_json["payload"]["device"]["capabilities"][32]["value"]) }}'
    scan_interval: 20
  - platform: rest
    name: 'Markise Position'
    resource: 'http://192.168.178.32/devices/25'
    value_template: >-
      {% for item in value_json.payload.device.capabilities %}
        {%- if item.name == "CURR_POS_CFG" -%}
          {{ 100 - float(item.value) }}
        {%- endif -%}
      {% endfor %}
    scan_interval: 20
  - platform: rest
    name: 'Wettersensor Position'
    resource: 'http://192.168.178.32/devices/26'
    value_template: >-
      {% for item in value_json.payload.device.capabilities %}
        {%- if item.name == "CURR_POS_CFG" -%}
          {{ 100 - float(item.value) }}
        {%- endif -%}
      {% endfor %}
    scan_interval: 20
  - platform: rest
    name: 'Wettersensor'
    resource: 'http://192.168.178.32/devices/26'
    value_template: '{{ 100 - float(value_json["payload"]["device"]["capabilities"][32]["value"]) }}'
    scan_interval: 20

binary_sensor:
  - platform: rest
    name: 'Regensensor'
    resource: 'http://192.168.178.32/devices/26'
    value_template: '{{ value_json["payload"]["device"]["capabilities"][71]["RAIN_DETECTION_MEA"] }'
    scan_interval: 20
    device_class: moisture

rest_command:
 belt_winder_up:
   url: 'http://192.168.178.32/devices/{{ did }}'
   method: PUT
   payload: '{"name":"POS_UP_CMD"}'
 belt_winder_down:
   url: 'http://192.168.178.32/devices/{{ did }}'
   method: PUT
   payload: '{"name":"POS_DOWN_CMD"}'
 belt_winder_stop:
   url: 'http://192.168.178.32/devices/{{ did }}'
   method: PUT
   payload: '{"name":"STOP_CMD"}'
 belt_winder_set_position:
   url: 'http://192.168.178.32/devices/{{ did }}'
   method: PUT
   payload: '{"name":"GOTO_POS_CMD","value":"{{ 100 - float(position)|int }}"}'

cover:
    markise:
      device_class: shutter
      friendly_name: "Markise"
      position_template: "{{ states('sensor.markise_position') }}"
      close_cover:
        - service: rest_command.belt_winder_down
          data:
            did: 25
      stop_cover:
        - service: rest_command.belt_winder_stop
          data:
            did: 25
      set_cover_position:
        - service: rest_command.belt_winder_set_position
          data_template:
            did: 25
            position: "{{position}}"
      open_cover:
        - service: rest_command.belt_winder_up
          data:
            did: 25
    wettersensor:
      device_class: shutter
      friendly_name: "Wettersensor"
      position_template: "{{ states('sensor.wettersensor_position') }}"
      close_cover:
        - service: rest_command.belt_winder_down
          data:
            did: 26
      stop_cover:
        - service: rest_command.belt_winder_stop
          data:
            did: 26
      set_cover_position:
        - service: rest_command.belt_winder_set_position
          data_template:
            did: 26
            position: "{{position}}"
      open_cover:
        - service: rest_command.belt_winder_up
          data:
            did: 26

So ich hab mal die Formatierung etwas angepasst, weiterhin krieg ich Fehlermeldungen zum Markisen Sensor. Die Temperatur sowie der Regensensor haben überhaupt nicht funktioniert. Der “Umweltsensor” von Rademacher ist erreichbar und wirft auch entsprechende Daten aus.

Logger: homeassistant.helpers.entity
Source: helpers/template.py:1358
First occurred: 11:25:24 (236 occurrences)
Last logged: 12:43:45

Update for sensor.markise fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 350, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 558, in async_device_update
    raise exc
  File "/usr/src/homeassistant/homeassistant/components/rest/entity.py", line 85, in async_update
    self._update_from_rest_data()
  File "/usr/src/homeassistant/homeassistant/components/rest/sensor.py", line 184, in _update_from_rest_data
    value = self._value_template.async_render_with_possible_json_value(
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 552, in async_render_with_possible_json_value
    return _render_with_context(
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1358, in _render_with_context
    return template.render(**kwargs)
  File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 1304, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 925, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<template>", line 1, in top-level template code
TypeError: unsupported operand type(s) for -: 'int' and 'str'