Vent-axia Svara (App controlled extractor fan)

Does anyone know if this will work with the Vent-Axia PureAir Sense?

I’ve taken my fan apart and cannot see any mac/pin code so not sure how to get these (been trying to see it on esprence but after multiple times turning it off and on I cannot seem to get it)

Works in my app fine by bluetooth

Yes, you will need a Bluetooth dongle. I had my HA on my Sinology in the past and it should work fine. Just expose your usb dongle to the VM.

The MAC address and PIN code is on the blades part of the fan. Just pull it out and it’s on a sticker on the small board.

You also need to have a bluetooth dongle, if your pi doesn’t have Bluetooth. Also make sure it’s in range as some adapters don’t work very far.

I’m not sure about that model. This one is particularly for the Svara model as it’s the same as the PAX.

I got the integration installed and works like a charm!

But I was wondering how you others are controlling the fan. How do you turn it off for example? I disabled all light, humidity sensor and trickling but the fan still runs.

Anyone made a neat node red flow for controlling the fan, would be highly appreciated if you would share :slight_smile:

same here. I can view stats which aren’t always up to date tbh. I just need to be able to control it via HA as the humidity and light sensor fan activation isn’t the most reliable

I have managed to achieve basic control of mine using an ESP home bluetooth proxy. It runs on an M5 Atom Lite that cost about £9.

To boost the fan it takes a few BLE commands:

  • Connect
  • Write PIN
  • Write boost cancel (otherwise the next command is ignored if already boosted)
  • Write boost
  • Disconnect

I added it as a ‘button’ type entity and can ‘Press’ it in HA.

I use it with a HA automation for running the fan when my bathroom light has been on for 70% of the past 10 minutes.

It’s also more or less the same steps to control my Vent-Axia PureSense fan.

If anyone’s interested I can share the scripts.

3 Likes

if you could post a tutorial of how you acheived this it would be awesome :slight_smile:

I’m interested too!

Probably late in the game, but here’s an idea.
If you’re absolutely sure your device’s address/pin was right, you might have encountered something similar to me: My MAC on the device sticker had a typo!

I mounted 2 Svara devices today. One has synchronized based on the sticker data, just as described in pax_ble, the other one just refused to do so after taking identical steps. It made me double check the fan id config. I knew pin was correct based on the successful sync with Ventaxia app, so MAC was the only option, confirmed in the logs.

The way I double-checked the BT fan MAC was through my Android phone BT sync UI: afaik, in any modern phone, a synchronized BT device panel will print its physical address. I synced with the fan as a generic BT device, it is intuitively discoverable under “Vent-Axia Svara” alias, and discovered a printed “2” is actually a “3”. It’s not an unclear, misread print, but a genuine mistake.

Note that I still could not tap in the fan through HA integration until I disconnected it from my phone. There are probably less hacky ways to discover a BT device’s physical address.

Have you had any luck with this my friend? Just installed one and desperately would love to pair it with HA if unsuccessful I’ll just wire esp board and use digital inputs on the board.

I was able to decompile/read the source code and found a pin number 10135097 … however… my Extractor is now installed and too far from my HA/Pi to try pairing… and to be pair, the mobile app confirms how terrible the BT range is (its about 1m :confounded:)

And yeah, I’m trying to use an ESP32 on the Digital/analog inputs instead…

Hi how did you add the pure sense to home assistant. I cant find my MAC address of the fan

Thanks

I managed to do this quite easily today for my Pure Sense using the BLE Device Tracker Bluetooth LE Tracker - Home Assistant it creates the file known_devices and it will find Pure Sense and give you the MAC ID. I just used 0000 as password and it connected, well… did it? It says it’s discovered and it comes up with the device and a load of entities, but most of them are “unknown”. I took the fan apart and cannot see MAC or PIN. So I think I have it integrated, but I’m unsure whether I can do anything at all with it.

@Paul_Crouch if you pull the fan out you’ll see a sticker on the control board with the MAC address

This is a great integration!

It’s worth noting older Svara’s might not work. I had a Svara that I bought back in 2017, and it would not connect, even when entering the MAC and PIN manually.

It died last week, so I connected Vent-Axia customer services. They sent me a new unit under warranty even though I bought it nearly 7.5 years ago. Big up Vent-Axia customer services!

The new unit wasn’t recognised automatically, but connected straight away when entering the MAC and PIN manually.

We are interested in the scripts… please share!

Apologies for the delay, I had spent a while writing out a tutorial on how to get going with ESPHome etc. but was unable to finish it. When I came back to it my draft message was gone so I gave up.

I’ll make this one brief.

I’m using an M5 Stack Atom Lite and here is my ESPHome yaml for it with MACs, PINs and keys partially redacted using “XX”:

# Define reusable constants here
substitutions:
  name: "iot-atom-ble-proxy-30XXXX"
  friendly_name: Bluetooth Proxy 30XXXX
  tv_mount_mac_address: 34:15:13:DA:XX:XX
  kitchen_extractor_mac_address: 4C:96:2D:12:XX:XX
  bathroom_extractor_mac_address: 58:2b:db:01:XX:XX
  shower_extractor_mac_address: 58:2b:db:01:XX:XX

# The core firmware to build on
packages:
  esphome.bluetooth-proxy: github://esphome/firmware/bluetooth-proxy/m5stack-atom-lite.yaml@main

# Name this node/Atom Lite
esphome:
  name: ${name}
  name_add_mac_suffix: false
  friendly_name: ${friendly_name}

# The encryption key to authenticate this node
api:
  encryption:
    key: XXXX/LOlXzS+XXXXXXXXXXXXXXXXX=

# Wifi credentials
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Maximum 3 active BLE clients on the Atom Lite (it struggles with 4+)
ble_client:
  # Vent Axia PureAir Sense
  - mac_address: ${kitchen_extractor_mac_address}
    id: KITCHEN_EXTRACTOR
    auto_connect: false
    # Debug logging, shown in the node logs
    on_connect:
      then:
        - lambda: |-
            ESP_LOGD("ble_client_lambda", "Connected to Kitchen Extractor");
    # Debug logging, shown in the node logs
    on_disconnect:
      then:
        - lambda: |-
            ESP_LOGD("ble_client_lambda", "Disconnected from Kitchen Extractor");
  # Vent Axia Svara
  - mac_address: ${bathroom_extractor_mac_address}
    id: BATHROOM_EXTRACTOR
    auto_connect: false
    on_connect:
      then:
        - lambda: |-
            ESP_LOGD("ble_client_lambda", "Connected to Bathroom Extractor");
    on_disconnect:
      then:
        - lambda: |-
            ESP_LOGD("ble_client_lambda", "Disconnected from Bathroom Extractor");
  # Vogels Motion Mount (unrelated to extractors)
  - mac_address: ${tv_mount_mac_address}
    id: TV_MOUNT
    auto_connect: false
    on_connect:
      then:
        - lambda: |-
            ESP_LOGD("ble_client_lambda", "Connected to TV mount");
    on_disconnect:
      then:
        - lambda: |-
            ESP_LOGD("ble_client_lambda", "Disconnected from TV mount");
  # Commented out due to 3 client limit, also a Vent Axia Svara
  #- mac_address: ${shower_extractor_mac_address}
  #  id: SHOWER_EXTRACTOR
  #  auto_connect: false
  #  on_connect:
  #    then:
  #      - lambda: |-
  #          ESP_LOGD("ble_client_lambda", "Connected to Shower Extractor");
  #  on_disconnect:
  #    then:
  #      - lambda: |-
  #          ESP_LOGD("ble_client_lambda", "Disconnected from Shower Extractor");

# Add the sensors that will be discovered by Home Assistant
sensor:
  - platform: ble_rssi
    name: kitchen_extractor_rssi
    mac_address: ${kitchen_extractor_mac_address}
  - platform: ble_rssi
    name: bathroom_extractor_rssi
    mac_address: ${bathroom_extractor_mac_address}
  - platform: ble_rssi
    name: tv_mount_rssi
    mac_address: ${tv_mount_mac_address}

# Add buttons to perform simple trigger actions in Home Assistant
button:
  - platform: template
    name: Boost Kitchen Extractor
    on_press:
        then:
        # Stop the background BLE scanning
        - esp32_ble_tracker.stop_scan:
        # Connect to the PureAir Sense
        - ble_client.connect: KITCHEN_EXTRACTOR
        # Authenticate with PIN (change the value to match yours)
        - ble_client.ble_write:
            id: KITCHEN_EXTRACTOR
            service_uuid: e6834e4b-7b3a-48e6-91e4-f1d005f564d3
            characteristic_uuid: 4cad343a-209a-40b7-b911-4d9b3df569b2
            value: [0xXX, 0x58, 0x82, 0x01]
        # Cancel any current boost time remaining
        - ble_client.ble_write:
            id: KITCHEN_EXTRACTOR
            service_uuid: c119e858-0531-4681-9674-5a11f0e53bb4
            characteristic_uuid: 7c4adc07-2f33-11e7-93ae-92361f002671
            value: [0x00, 0x00, 0x00, 0x00, 0x00]
        # Send the boost command
        - ble_client.ble_write:
            id: KITCHEN_EXTRACTOR
            service_uuid: c119e858-0531-4681-9674-5a11f0e53bb4
            characteristic_uuid: 7c4adc07-2f33-11e7-93ae-92361f002671
            value: [0x01, 0xC4, 0x09, 0x58, 0x02]
        # Disconnect from the Pure Sense
        - ble_client.disconnect: KITCHEN_EXTRACTOR
        # Restart the background BLE scanning
        - esp32_ble_tracker.start_scan:
        # Debug logging, shown in the node logs
        - logger.log: Boost Kitchen Extractor button finished
  - platform: template
    name: Boost Bathroom Extractor
    on_press:
        then:
        # Stop the background BLE scanning
        - esp32_ble_tracker.stop_scan:
        # Connect to the Svara
        - ble_client.connect: BATHROOM_EXTRACTOR
        # Authenticate with PIN (change the value to match yours)
        - ble_client.ble_write:
            id: BATHROOM_EXTRACTOR
            service_uuid: e6834e4b-7b3a-48e6-91e4-f1d005f564d3
            characteristic_uuid: 4cad343a-209a-40b7-b911-4d9b3df569b2
            value: [0xXX, 0x14, 0xf7, 0x01]
        # Cancel any current boost time remaining
        - ble_client.ble_write:
            id: BATHROOM_EXTRACTOR
            service_uuid: c119e858-0531-4681-9674-5a11f0e53bb4
            characteristic_uuid: 118c949c-28c8-4139-b0b3-36657fd055a9
            value: [0x00, 0x00, 0x00, 0x00, 0x00]
        # Send the boost command
        - ble_client.ble_write:
            id: BATHROOM_EXTRACTOR
            service_uuid: c119e858-0531-4681-9674-5a11f0e53bb4
            characteristic_uuid: 118c949c-28c8-4139-b0b3-36657fd055a9
            value: [0x01, 0x60, 0x09, 0x2C, 0x01]
        # Disconnect from the Svara
        - ble_client.disconnect: BATHROOM_EXTRACTOR
        # Restart the background BLE scanning
        - esp32_ble_tracker.start_scan:
        # Debug logging, shown in the node logs
        - logger.log: Boost Bathroom Extractor button finished
  - platform: template
    name: Extend TV Mount
    on_press:
        then:
        - esp32_ble_tracker.stop_scan:
        - ble_client.connect: TV_MOUNT
        - ble_client.ble_write:
            id: TV_MOUNT
            service_uuid: 3e6fe65d-ed78-11e4-895e-00026fd5c52c
            characteristic_uuid: c005fa00-0651-4800-b000-000000000000
            value: [0x00, 0x64]
        - ble_client.disconnect: TV_MOUNT
        - esp32_ble_tracker.start_scan:
        - logger.log: Extend TV Mount button finished
  - platform: template
    name: Retract TV Mount
    on_press:
        then:
        - esp32_ble_tracker.stop_scan:
        - ble_client.connect: TV_MOUNT
        - ble_client.ble_write:
            id: TV_MOUNT
            service_uuid: 3e6fe65d-ed78-11e4-895e-00026fd5c52c
            characteristic_uuid: c005fa00-0651-4800-b000-000000000000
            value: [0x00, 0x00]
        - ble_client.disconnect: TV_MOUNT
        - esp32_ble_tracker.start_scan:
        - logger.log: Retract TV Mount button finished
2 Likes

To achieve this, I use the History Stats integration:

In my configuration.yaml I added the sensor:

sensor:
  - platform: history_stats
    name: Bathroom Light ON 10 mins
    entity_id: light.bathroom_main
    state: "on"
    type: ratio
    end: "{{ now() }}"
    duration:
      minutes: 10

And the automation looks like this:

alias: "Fan: Boost the bathroom extractor"
description: ""
mode: single
triggers:
  - entity_id: sensor.bathroom_light_on_10_mins
    above: "70"
    trigger: numeric_state
conditions: []
actions:
  - repeat:
      while:
        - condition: numeric_state
          entity_id: sensor.bathroom_light_on_10_mins
          above: "70"
      sequence:
        - metadata: {}
          data: {}
          target:
            entity_id: button.iot_atom_ble_proxy_30XXXX_boost_bathroom_extractor
          action: button.press
        - delay:
            hours: 0
            minutes: 1
            seconds: 0
            milliseconds: 0
1 Like