Help with i2c Custom Component

Hi All,

I’ve trying many different approaches but have had no luck. I have replicated the ifan02 from the cookbook in the way that suits me (d1 mini and a 4-way relay board)and it works fantastically, now I’m trying to do the same but instead of running directly off the d1 mini I am trying to use an MCP23017 which means using the i2c in the custom component. By doing this I hope to control many fans from just 1 d1 mini.

Is anyone able to help me?

The code I’m trying at the moment looks like this:

esphome:
  name: expansion_fan_test
  platform: ESP8266
  board: d1_mini
  includes:
    - ifan02test.h 

wifi:
  ssid: "****"
  password: "****"

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

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

i2c:
  sda: D5
  scl: D6
  scan: True
  id: bus_a
  
mcp23017:
  - id: 'mcp23017_hub'
    address: 0x20

output:
  - platform: custom
    type: float
    outputs:
      id: fanoutput
    lambda: |-
      auto test_fan = new FanOutput();
      App.register_component(test_fan);
      return {test_fan};
      
fan:
  - platform: speed
    output: fanoutput
    id: test_fan
    name: "i2c Fan"      

and the custom_component.h (ifan02test.h) file:

#include "esphome.h"
using namespace esphome;

class FanOutput : public Component, public FloatOutput {
  public:
	void write_state(float state) override {
	
      if (state < 0.3) {
        // OFF
		Wire.beginTransmission(0x20); //address of MCP23017
        Wire.write(0x12); // port a
        Wire.write(0xFF); // write all pins high
		Wire.endTransmission();
      } else if (state < 0.6) {
        // HIGH speed
		Wire.beginTransmission(0x20); //address of MCP23017
        Wire.write(0x12); // port a
        Wire.write(0xFB); // write pin 3 low
		Wire.endTransmission();
      } else if (state < 0.9) {
        // medium speed
		Wire.beginTransmission(0x20); //address of MCP23017
        Wire.write(0x12); // port a
        Wire.write(0xFD); // write pin 2 low
		Wire.endTransmission();
      } else {
        // LOW speed
		Wire.beginTransmission(0x20); //address of MCP23017
        Wire.write(0x12); // port a
        Wire.write(0xFE); // write pin 1 low
		Wire.endTransmission();
      }
    }
};

everything compiles fine with no errors however nothing happens on the i2c or 4-way relay board.

I have tried something similar with arduino on an arduino uno and managed to get it to work.

I literally changed nothing and it started working today, go figure. However I ran into my next problem which was reading the states of the pins on the expansion board so the correct values could be assigned. I did overcome this with some complex template binary sensor coding and now I’ve managed to get it working. I’ll tidy the code up and upload for people to see.