Guide - Medify MA-112 with ESPHome

This is my second guide following the guide for the MA-40. I had some asking for the MA-112 guide so here it is to the best of my writing abilities.

Note: This guide removes the connection for the factory IO board, making the MA-112 only controllable by the ESPHome interface. Performing these steps will leave the MA-112 with no permanent modifications, and restoring to factory operation is just re-opening the unit, removing the ESP32 module, and re-connecting the control board to the front IO panel.

The control board for the MA-112 is located in the front of the unit, requiring the removal of the large plastic housing panel that makes up the entire front of the unit. You’re on your own for this part though, it’s been about a year since I opened it up. @cwe5590 has noted in the MA-40 thread that the MA-112 requires a tri-wing bit to open.

Open the Control Board Box in the front of the unit to expose the Control Board.

Unplug the cable connecting the Interface Panel and Control Board from the Control Board. We will be using the following pins on this header (thanks again to @cwe5590 for confirming the pin functions):

+5V - ESP32 Dev Board Power
GND - ESP32 Dev Board GND
VSP- Fan Control (Analog Input ranging from 1.58V (1% On) to 2V (100% On))
FG - Speed Feedback for Motor (pulse)
ION - DIO for ION control
FG - Speed Feedback for Motor (pulse)
PC - Power Control

Plug Jumper Cables into this header for the listed pins:

Lastly, close up the Control Board Box and plug these cables into the ESP32 Dev Board using the following pins:

gpio26 to VSP
gpio25 to FG
gpio33 to PC
gpio27 to ION
5V to +5V
GND to GND

Use the following code for ESPHome (you might need to mess with the lambda expression for fan speed to fine tune the voltages for your ESP32 and MA-112):

esphome:
  name: esphome-ma-112
  friendly_name: MA-112

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret encryption_key

ota:
  password: !secret ota_password

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "MA-112"
    password: 

captive_portal:

globals:
  - id: filter_time
    type: int
    restore_value: yes
    initial_value: '0'

interval:
- interval: 1min
  then:
    if:
      condition:
        fan.is_on: ma112
      then:
      - lambda: |-
          id(filter_time) += 1;

sensor:
  - platform: pulse_counter
    pin: 25
    name: "Motor RPM"
    update_interval: 1s
  - platform: template
    name: Filter On Time
    id: filter_time_disp
    unit_of_measurement: "minutes"
    device_class: "duration"
    state_class: "measurement"
    accuracy_decimals: 0
    lambda: |-
      return id(filter_time);

binary_sensor:
  - platform: template
    name: "Filter End of Life"
    lambda: |-
      if (id(filter_time) > 180000){
        return true;
      } else {
        return false;
      }

button:
  - platform: template
    name: "Reset Filter Life"
    on_press:
      lambda: |-
        id(filter_time) = 0;

switch:
  - platform: gpio
    pin: 27
    name: "Ion"
    id: ion
  - platform: gpio
    pin: 33
    name: "Power"
    id: power
    internal: true

output:
  - platform: esp32_dac
    pin: 26
    id: fanspeed
  - platform: template
    id: custom_fan
    type: float 
    write_action:
      - if:
          condition:
            lambda: return ((state == 0));
          then:
            # action for off
            - switch.turn_off: power
            - output.turn_off: fanspeed
            - switch.turn_off: ion

      - if:
          condition:
            lambda: return ((state > 0));
          then:
            # action for on
            - switch.turn_on: power
            - output.turn_on: fanspeed
            - output.set_level:
                id: fanspeed
                level: !lambda return (0.48 + (state * 0.13));

fan:
  - platform: speed
    id: ma112
    output: custom_fan
    name: "Fan"
    speed_count: 100

Home Assistant dashboard should look similar to the following if all is right!

2 Likes

@stevo32792, I will be trying it this weekend and will report back here! Thank you!

@stevo32792 I got everything to work using your guide - THANK YOU!

A few notes below for anyone else doing it:

  1. You do need the Tri-wing bit, specifically for 3 screws on the very bottom of the front panel. There are 5 Philips head screws on either side, as well as 2 on top as well. You should remove a total of 15 screws to remove the front panel.

  2. Be careful since there are some short wires connecting the front panel. You can gently disconnect the terminals.

  3. I found the fan on the unit to be slightly lower than what I would have expected (for example in Home Assistant set fan to 20% and see what it sounds like). I might tune the numbers in Stevo’s YAML a little bit as he mentioned in his post as well.

  4. I was able to get the whole ESP32 including 3d printed case into the main control box.

Big thanks again for this guide!!!

Matt




In case it’s helpful, I talked with Medify customer support for a while to obtain the RPM ranges for the 112:

RPM for speed 1(r/min) 450 and RPM for speed 4 (r/min) 880.

If that’s helpful at all @stevo32792 or revises your arithmetic for the fan speeds, let me know and I will update mine as well.

Matt

@matthewcbyington I certainly hadn’t considered a calibration function for the fan control. I might actually attempt to implement that as it would be useful for both motor life (to operate within the same range as Medify’s controller) and for my C535 Air Purifiers as well. I’ll see what I can come up with. I’ll need to figure out what the steps are on the encoder to translate pulses to rotations.

1 Like

@stevo32792 sounds good sir. No rush of course and no pressure. I just figured I’d pass the info along.

I don’t know how to convert the RPM that they sent me to the pulses/min that we get in HA with the ESP code.

The reason is that I do not know how many pulses per revolution. (edit: ah you stated this as well, yep)

I suspect you are way better at this than me.

Anecdotally, and this is not empirical but rather just my gut feeling, is that when I set the fan to 40%, it is actually running lower than 40% (compared to what it was without the ESP32) - closer to 20-25%. Just in case it’s helpful.

Matt