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… 
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