Fireplace interface & scripting

I’ve got a Flare fireplace with a Maxitrol controller that has this automation workflow:

What’s neat about this is I can do more than just turn it on and off, but that does present some complications.

I’m currently thinking that a 4 channel Sonoff pro controller will be my best best for handling the hardware side of things.

On the UX side, I’m thinking a basic on/off + “brightness” should handle all my needs.

What I need to figure out is:

  • Which firmware I should run? (this will be my first sonoff)
  • Should I handle the logic at the sonoff or within home assistant? (I’m not afraid to program)
  • Is there an existing device type that would fit this or should I look into creating a new device type?
1 Like

Hi there @Tuckie,

Did you end up making any progress on this?

I had some luck automating my fireplace in a smiple way, by simulating the Mertik Maxitrol remote, I managed to get this working using OpenMQTTGateway, running on an ESP8266 NodeMCU, with a cheap 433MHz transmitter for sending codes to my fireplace. All for less than $10,

In Home Assistant, I then created two switches. One is for power on/off and the other is for flame up/down. I created buttons for these in the Lovelace UI. All working quite nicely.

  - platform: mqtt
    name: Fireplace Power
    command_topic: "home/OpenMQTTGateway/commands/MQTTto433"
    payload_on: '{ "protocol": 31, "delay": 400, "length": 12, "repeat": 150, "value": 1267 }'
    payload_off: '{ "protocol": 31, "delay": 400, "length": 12, "repeat": 10, "value": 1271 }'
    optimistic: false
    retain: false

  - platform: mqtt
    name: Fireplace Flame
    command_topic: "home/OpenMQTTGateway/commands/MQTTto433"
    payload_on: '{ "protocol": 31, "delay": 400, "length": 12, "repeat": 10, "value": 1275 }'
    payload_off: '{ "protocol": 31, "delay": 400, "length": 12, "repeat": 10, "value": 1277 }'
    optimistic: false
    retain: false

I recently got a Mertik Maxitrol. But this operates at 868Mhz. Do you know this is possible as well with OMG ?

@JensVanhooydonck I have no idea about 868MHz. Best is to ask on @1technophile.

Hello, did you find some 868mhz hardware receivers and emitters ?

I ordered an cyc1101, if I find some time I will try to add that to OMG

1 Like

Nice. It would be great if you could add a gateway dedicated to cc1101 based maybe on this :

I’ve been trying to home automate the fireplace in all different ways… Even almost bought the Wifi addition in the hope I could capture those commands… But using those pins to control the fireplace with a Sonoff is by far the best idea ever… I feel pretty dumb that I never thought of this :slight_smile:.

Did you manage to get this working? I can’t wait to start working on this. Where did you find that screenshot of the documentation?

I did get a basic codebase working, but there is definitely room for improvement. I can share what I have in a few days.

I just ordered a double relay and I have 2 NodeMCU laying around, it is not the most compact solution but it seems to be doable with OpenMQTTGateway. Anybody got this working allready?

I can share my rough code, however I never did get it working very reliably without some form of feedback from the controller (due to on/off cool-down times and other weirdness with the standard fireplace controller in general)… and looking up on this thread I never did that the first time… :blush:

Here is fireplace.h

    using namespace esphome;
    static const char *TAG = "debug";
    const int BLUE_LED = 13;     // wifi signal led
    const int MASTER_RELAY = 12; // relay 1, setup inline with the others as a master disconnect switch
    const int CONTACT_1 = 5;     // relay 2
    const int CONTACT_2 = 4;     // relay 3
    const int CONTACT_3 = 15;    // relay 4
   

    // for automating a Flare fireplace with a Maxitrol controller
    // documentation from the manufacturer can be viewed here: https://i.imgur.com/iPU1glv.png

    class FireplaceOutput : public Component, public output::FloatOutput {
    protected:
      float fire_level_{0.0};
      bool currently_changing_level_{false};
    public:
    void setup() override {
        // This will be called by App.setup()
        pinMode(BLUE_LED, OUTPUT);
        pinMode(MASTER_RELAY, OUTPUT);
        pinMode(CONTACT_1, OUTPUT);
        pinMode(CONTACT_2, OUTPUT);
        pinMode(CONTACT_3, OUTPUT);
        // blue led blink on boot just to let me know it has rebooted/started
        digitalWrite(BLUE_LED, LOW); 
        // make sure the fireplace is off on boot
        fireplace_off();
        digitalWrite(BLUE_LED, HIGH);
    }

    void connect(){
        ESP_LOGD(TAG, "Starting Fireplace change...");
        this->currently_changing_level_ = true;
        digitalWrite(MASTER_RELAY, HIGH);
    }

    void disconnect() {
        ESP_LOGD(TAG, "... Ending Fireplace change");
        digitalWrite(MASTER_RELAY, LOW);
        this->currently_changing_level_ = false;
    }

    void contacts_off(){
        digitalWrite(CONTACT_1, HIGH);
        digitalWrite(CONTACT_2, HIGH);
        digitalWrite(CONTACT_3, HIGH);
    }

    void fireplace_off() {
        ESP_LOGD(TAG, "Fireplace off");
        connect();
        digitalWrite(CONTACT_1, LOW);
        digitalWrite(CONTACT_2, LOW);
        digitalWrite(CONTACT_3, LOW);
        this->set_timeout("turning-off", 2000, [this]() { this->contacts_off(); });
        // takes a while to turn off, and doesn't respond to any other signals during this period
        this->set_timeout("powering-down", 14000, [this]() { this->disconnect(); this->fire_level_ = 0.0;});
    }

    void fireplace_on() {
        ESP_LOGD(TAG, "Fireplace on");
        connect();
        digitalWrite(CONTACT_1, LOW);
        digitalWrite(CONTACT_2, HIGH);
        digitalWrite(CONTACT_3, LOW);
        this->set_timeout("turning-on", 2000, [this]() { this->contacts_off(); });
        // takes a while to turn on, and doesn't respond to any other signals during this period
        this->set_timeout("booting-up", 30000, [this]() { this->disconnect(); this->fire_level_ = 1.0;});
    }
    

    void turn_up_fireplace() {
        digitalWrite(CONTACT_1, LOW);
        digitalWrite(CONTACT_2, HIGH);
        digitalWrite(CONTACT_3, HIGH);
    }

    void turn_down_fireplace() {
        digitalWrite(CONTACT_1, HIGH);
        digitalWrite(CONTACT_2, HIGH);
        digitalWrite(CONTACT_3, LOW);
    }

    void set_fireplace(float set_level){
        ESP_LOGD(TAG, "Setting fireplace to: %.2f", set_level);
        float difference = 0.0;
        if (set_level == this->fire_level_) {
            return;
        }
        else if (set_level > this->fire_level_) {
            connect();
            difference = set_level - this->fire_level_;
            turn_up_fireplace();
        }
        else if (set_level < this->fire_level_) {
            connect();
            difference = this->fire_level_ - set_level;
            turn_down_fireplace();
        }
        float ramp_time = 12000 * difference;
        this->set_timeout("changing-level", ramp_time, [this, set_level]() { this->disconnect(); this->fire_level_ = set_level;});
    }

    void write_state(float state) override {
        if (this->currently_changing_level_ == true) {
            //what to do here? Is there any way to report back the previous setting? Queue the requested setting?
        }
        else {
            if (state == 0.0) {
                fireplace_off();
            }
            else {
                if (this->fire_level_ == 0.0) {
                    fireplace_on();
                    this->set_timeout("waiting-to-set-level", 30100, [this, state] () { this->set_fireplace(state); } );
                }
                else {
                    set_fireplace(state);
                }
            }
        }
    }
    };

and my yaml:

output:
- platform: custom
  type: float
  lambda: |-
    auto my_custom_float_output = new FireplaceOutput();
    App.register_component(my_custom_float_output);
    return {my_custom_float_output};
  outputs:
    id: fireplace
fan:
  - platform: speed
    output: fireplace
    name: "Fireplace"
    speed:
      low: 0.7
      medium: 0.75
      high: 1.0

My fireplace is also equipped with a GV60 burner and a Mertik Maxitrol B6R ECOMAX electronic ignition and control receiver, ref. B6R-R8U.

Unfortunately, this particular receiver is not compatible with the Mertik Wi-Fi box, so no myFire app.

As for RF control, the fireplace is remotely controlled with a 868 MHz (915 MHz in US/Canada) remote. As a side note, I think that nobody will manage to make some custom RF home automation system work at these frequencies, because unlink previous 433 MHz freq, there is now a pairing sequence between remote control and the receiver inside the fireplace, which uses a random key among 65,000 possibles values.

There is only one option remaining to automate the fireplace: use the three contacts like in Tuckie’ picture shown in the first post of this thread.

Most of my setup at home uses Z-wave. So I thought about using a Fibaro Smart Implant FGBS-222:


Being quite small, it can also and on the top of it, act as a dry contact switch. Actually I’d need a couple, since each smart implant is able to output two different closed states at the same time, and one needs three switches for such a system.

How to do this with HA?

My idea at first is to create a virtual dimmer and assign each possible brightness_pct value (brightness percentage, from 0 to 100%, so a hundred values + zero aka off position) to a specific duration in milliseconds. For example: going from O to 100% flame height takes 12 seconds (12000 milliseconds). Going from there (100%) to 50% flame height takes half this value so 6000 ms, and so on.

One thing to note : after each ignition when the fireplace has been previously switched off, the flame always initially goes to 100% height, so the motor automatically turns for 12 seconds to completely open the gas valve. From there, you can choose to keep the fire as is, or reduce the flame.

The tricky part is that, when setting a certain percentage of such “dimmer” in the interface, one has to first recover the current value of the flame height, and compare it with the new aim value, in order to know if the motor should increase (contact #1) or on the contrary decrease (contact #3) the flame, or do nothing (current and new values are the same). But I don’t know how to do this in a script. Any idea?

Hi, I have a Mertik Maxitrol GV60 and would like to add this device to Home Assistant via the RFXCOM module. However, I am not able to find a manual for this on the internet. I would like to know if anybody succeeded with this. Thanks in advance for your reaction.

For what its worth, I was able to reverse engineer the signal upto a high degree. I documented my findings in a public place:

So the next step for me would be to repeat these signals with a transmitter to see if the fireplace would pick them up, but I do not possess such a device. I might want to get back to this project of hacking my fireplace in the future and spend some money on a software controlled radio transmitter.

What device did you use to capture the signal?

A RTL2832 (DVB-T / RTL SDR) dongle

Wouldn’t this do the trick?

I have ordered the hardware but can you give me some tips how to proceed wich software should hi upload to the ESP8266 NodeMCU and how to connect it to Wifi

There seem to be others who have succesfully integrated this fireplace into their (home assistant) home automation system recently. See the following guide for more details: Bellfire home automation project - PieterBrinkman.com

1 Like

Hi @joostvanmourik - rather than emulating the remote control as others here have done, I went the route of using ESPhome and an ESP8266 board with 4x dry relay board to interface with our fireplace gas log with Maxitrol controller. As I was already running a cable (some spare cat5e in this case) to the firebox to the controller, I also ran 5V DC +/- to power the controller externally, rather than swapping controller AA batteries annually, which is a nice extra bonus for this project.

This probably isn’t the most elegant software solution, but this works for me - I control the gas log via individual scripts which send various relay commands, all controlled through a virtual thermostat using an occupancy/motion sensor in the room which can also sense temperature. It will also turn off the fireplace if there’s no motion in the room for > 60 minutes.

On each script, I reset the relays first:

sequence:
  - type: turn_off
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_1
    domain: switch
  - type: turn_off
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_2
    domain: switch
  - type: turn_off
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_3
    domain: switch
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
mode: single
alias: Reset Fireplace Relays
icon: mdi:electric-switch

Fireplace ignition (creates spark to ignite the pilot light):

alias: Fireplace Ignition
sequence:
  - service: script.reset_fireplace_relays
    data: {}
  - type: turn_on
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_1
    domain: switch
  - type: turn_on
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_3
    domain: switch
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
  - type: turn_off
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_1
    domain: switch
  - type: turn_off
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_3
    domain: switch
  - service: climate.turn_on
    target:
      entity_id: climate.living_room_fireplace
    data: {}
mode: single
icon: mdi:fireplace

Low flame - this requires first turning the flame all the way up, then backing it down a specific amount of time to where the flame is at its lowest point before going out and only the pilot light is lit:

alias: Fireplace Low Flame
sequence:
  - service: script.reset_fireplace_relays
    data: {}
  - type: turn_on
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_1
    domain: switch
  - delay:
      hours: 0
      minutes: 0
      seconds: 12
      milliseconds: 0
  - type: turn_off
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_1
    domain: switch
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
  - type: turn_on
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_3
    domain: switch
  - delay:
      hours: 0
      minutes: 0
      seconds: 6
      milliseconds: 0
  - type: turn_off
    device_id: cd8f3e24c395179b5ab4d2ffbd33d2ed
    entity_id: switch.contact_3
    domain: switch
  - service: climate.turn_on
    target:
      entity_id: climate.living_room_fireplace
    data: {}
mode: single
icon: mdi:fireplace

Here’s the virtual thermostat:

  - platform: generic_thermostat
    name: Living Room Fireplace
    heater: input_boolean.fireplace_gas_log
    target_sensor: sensor.dining_room_occupancy_temperature
    cold_tolerance: 1
    hot_tolerance: 1
    min_temp: 65
    max_temp: 75
    away_temp: 60
    target_temp: 72
    precision: 1.0
    ac_mode: false
    min_cycle_duration: 10

EDIT - Here’s the ESPhome YAML:

esphome:
  name: gas-log
  platform: ESP8266
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "changeme"

wifi:
  ssid: "mySSID"
  password: "changeme"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Fireplace Fallback Hotspot"
    password: "changeme"

captive_portal:

switch:
 - platform: gpio
   pin: GPIO5
   name: "Contact #1"
   id: contact1
   icon: "mdi:electric-switch"
   inverted: true
   restore_mode: ALWAYS_OFF
 
 - platform: gpio
   pin: 4
   name: "Contact #2"
   id: contact2
   icon: "mdi:electric-switch"
   inverted: true
   restore_mode: ALWAYS_OFF

 - platform: gpio
   pin: 14
   name: "Contact #3"
   id: contact3
   icon: "mdi:electric-switch"
   inverted: true
   restore_mode: ALWAYS_OFF

sensor:
 - platform: wifi_signal
   name: "Fireplace Wi-Fi RSSI"
   update_interval: 300s

What I’m working on today (and what made me find this thread) is a more intellegant method of automagically controlling flame height, based on the delta between current and target room temperature. For example, in the morning when the room temperature is 55ºF (we have a cold house during winter overnights) and the target temperature is 70ºF, I want the flame set to high. However, as the room tempature approaches 70ºF, say around 68ºF, the flame should lower. Working on that logic now, any pointers would be helpful. :slight_smile:

2 Likes