Custom component that outputs different sensor types

I’m trying to make a custom component (my first one also) that will read a device state through UART and parse the data to create different binary_sensor and sensor to Home Assistant.

For the moment, I’ve been able to create the custom component, read from UART, parse it and create a binary sensor.
The problem is when I want to publish another sensor type. Logger shows the new value published but there’s nothing updated to Home Assistant.

Any idea to get this working ?

Here’s what I have in the ESPHome yaml file for this:

uart:
  - id: uart_bus
    tx_pin: TX
    rx_pin: RX
    baud_rate: 9600

binary_sensor:
- platform: custom
  lambda: |-
    auto binary_sensor_ac = new lecture_ac_uart(id(uart_bus));
    App.register_component(binary_sensor_ac);
    return {binary_sensor_ac->led1_sensor};
  binary_sensors:
    name: "Mode Auto"

sensor:
- platform: custom
  lambda: |-
    auto sensor_ac = new lecture_ac_uart(id(uart_bus));
    App.register_component(sensor_ac);
    return {sensor_ac->temperature_sensor};
  sensors:
    name: "Temperature"

And here’s the relevant part of lecture_ac_uart.h

class lecture_ac_uart : public PollingComponent, public UARTDevice {
 public:
  lecture_ac_uart(UARTComponent *parent) : PollingComponent(500), UARTDevice(parent) {}
  Sensor *temperature_sensor = new Sensor();
  BinarySensor *led1_sensor = new BinarySensor();

/*
Data processing part in loop()
*/

  void update() override {
    if(led1 != led1_last) {
      led1_sensor->publish_state(led1);
      led1_last = led1;
    }
    if(temperature != temperature_last) {
      temperature_sensor->publish_state(temperature);
      temperature_last = temperature;
    }
  }
};

I know it’s an old question, but in case the OP or others are still trying, one possible solution is to make the sensors in YAML as template sensors, giving each one an ID. Then, make a custom component and pass the template sensors you created as parameters to your component constructor, like this:

class lecture_ac_uart : publich PollingComponent, public UARTDevice {
 private:
   BinarySensor* led1_sensor;
   Sensor *temperature_sensor
 public:
  lecture_ac_uart(UARTComponent *parent, BinarySensor *led1_sensor, Sensor *temperature_sensor) : PollingComponent(500) {
    this->led1_sensor = led1_sensor;
    this->temperature_sensor = temperature sensor;
  }
  . . .
binary_sensor:
  - platform: template
    name: Mode Auto
    id: mode

sensor:
  - platform: template
    name: Temperature
    id: temperature

custom_component:
  - lambda: |-
      auto ac_uart = new lecture_ac_uart(id(uart_bus), id(mode), id(temperature));
      return {ac_uart};
    components:
      - id: ac_uart

I too am looking for a more elegant solution, but this one works (It’s possible you need to make the update frequency tests in the loop function inside your class instead).

Is there any other way to achieve this, or is this still the only way to return sensors of different types?