Orcon MVS Ventilation System

@wietse1
Here’s the setup I use:

esphome:
  name: mvcontroller
  platform: ESP8266
  board: d1_mini


captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "<USETHEONEHACAMEUPWITHONINSTALATION>"

ota:
  password: "<HAWILLSUGGESTONEONINSTALATION>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Mvcontroller Fallback Hotspot"
    password: "<APASSWORDYOUDECIDE"
i2c:

output:
  - platform: esp8266_pwm
    pin: D6
    frequency: 1000 Hz
    id: orcon_mv_pwm_out
    inverted: true
  - platform: template
    id: dummy
    type: float
    write_action:
      - logger.log: "Something was written to dummy."

switch:
  - platform: gpio
    id: bypass
    name: "Orcon speed bypass"
    pin: 
      number: D8
      inverted: False

fan:
  - name: "Orcon"
    id: "orcon"
    icon: "mdi:hvac"
    platform: speed  # sliding output
    output: dummy

    restore_mode: ALWAYS_ON

    on_turn_on:
      - logger.log: "Turning on Orcon"
    on_turn_off:
      - logger.log: "Turning off Orcon"
      - lambda: "id(orcon).speed = 1;"
    on_speed_set:
      - logger.log: "Speed changed."
      - lambda: |-

            // Set a little margin so we don't keep toggling the relay if
            // the requested and set speeds are very similar.
            int margin = 5;

            // Contains requested speed by the machine (0-100)
            int req = int(id(orcon_mv_requested_speed).state);
            // Contains requested speed by the user (0-100)
            int now = int(id(orcon).speed);
    
            // ESP_LOGD("req", "%d", req);
            // ESP_LOGD("now", "%d", now);

            if (now > (req - margin)) {
                id(bypass).turn_on();

                id(orcon_mv_pwm_out).set_level(
                    float(now / 100.0)
                );

            } else {
                id(bypass).turn_off();
                id(orcon_mv_pwm_out).set_level(0.0);
            }

sensor:
  - platform: pulse_counter
    pin: D5
    name: Orcon Tachometer
    id: orcon_mv_tachometer
    update_interval: 5s
    accuracy_decimals: 0
    internal_filter: 250us
    unit_of_measurement: rpm
  - platform: duty_cycle
    name: "Orcon MV Requested speed"
    id: orcon_mv_requested_speed
    internal: true
    unit_of_measurement: "%"
    accuracy_decimals: 0
    pin:
      number: D7
      mode: INPUT_PULLUP
      inverted: no
    update_interval: 20s
    filters:
      lambda: "return int(x);"

    on_value:
      - lambda: |-
            // Hacky way to trigger the original code instead of duplicating.
            if (id(orcon).state) {
                auto call = id(orcon).turn_on();
                call.set_speed(id(orcon).speed);
                call.perform();
            }
  

and for the automation to turn it on when the humidity rises in the bathroom:

alias: Bathroom - ventilation on
description: ""
trigger:
  - platform: numeric_state
    entity_id:
      - sensor.humidity_temp_1_humidity
    for:
      hours: 0
      minutes: 1
      seconds: 0
    above: 72
condition: []
action:
  - service: fan.turn_on
    metadata: {}
    data:
      percentage: 100
    target:
      entity_id: fan.orcon
mode: single

and off again on a certain level:

alias: Bathroom - ventilation back to auto
description: ""
trigger:
  - platform: numeric_state
    entity_id:
      - sensor.humidity_temp_1_humidity
    for:
      hours: 0
      minutes: 1
      seconds: 0
    below: 65
condition: []
action:
  - service: fan.turn_off
    data: {}
    target:
      entity_id: fan.orcon
mode: single
1 Like

Thank you! I just had this ventilation system installed a few months ago and thought it was broken because it kept running even during the day. Your comment made me realize it’s probably because it’s been raining so much lately.