libretiny-eu / libretiny

PlatformIO development platform for IoT modules
http://docs.libretiny.eu/
MIT License
382 stars 55 forks source link

ESPHome: missing uart.write_array for std::vector #208

Closed szupi-ipuzs closed 7 months ago

szupi-ipuzs commented 7 months ago

ESPHome API states that there is a variant of write_array method in UARTDevice class that accepts a vector, but when trying to use this with libretiny (1.4.1) uart, I get this error:

/config/tuya-ht-1.yaml: In lambda function:
/config/tuya-ht-1.yaml:104:52: error: no matching function for call to 'esphome::uart::LibreTinyUARTComponent::write_array(const std::vector<unsigned char>&)'
  104 |                id(tuya_uart).write_array(WIFI_RESET_RESPONSE);
      |                                                    ^
In file included from src/esphome.h:59,
                 from src/main.cpp:3:
src/esphome/components/uart/uart_component_libretiny.h:20:8: note: candidate: 'virtual void esphome::uart::LibreTinyUARTComponent::write_array(const uint8_t*, size_t)'
   20 |   void write_array(const uint8_t *data, size_t len) override;
      |        ^~~~~~~~~~~
src/esphome/components/uart/uart_component_libretiny.h:20:8: note:   candidate expects 2 arguments, 1 provided

The appropriate part of yaml is as follows:

uart:
  - id: tuya_uart
    rx_pin: RX1
    tx_pin: TX1
    baud_rate: 9600
    debug:
      direction: BOTH
      dummy_receiver: true
      sequence:
        - lambda: UARTDebug::log_hex(direction, bytes, ' ');
        - lambda: !lambda |-
            static const std::vector<uint8_t> WIFI_RESET_COMMAND = { 0x55, 0xAA, 0x00, 0x04, 0x00, 0x01, 0x01, 0x05 };
            static const std::vector<uint8_t> WIFI_RESET_RESPONSE = { 0x55, 0xAA, 0x00, 0x04, 0x00, 0x00, 0x03 };
            if ((direction == uart::UART_DIRECTION_RX) && (bytes == WIFI_RESET_COMMAND))
            {
               id(tuya_uart).write_array(WIFI_RESET_RESPONSE);
            }

I know that it's not a big deal, I can use the other variant, still I think this should be consistent with esphome API description.

kuba2k2 commented 7 months ago

The linked documentation is for UARTDevice, while the error originates from UARTComponent.

The LibreTiny implementation is the same as in all other platforms. The write_array() function is defined and implemented in uart_component.h, which is not LibreTiny-specific. That error is caused by something else, not missing implementation.

Can you try adding #undef uint8_t right before the static const array declarations?

szupi-ipuzs commented 7 months ago

Nope, it didn't help. I can see in the code that UARTDevice blindly calls matching method on the underlying parent (ie. UARTComponent):

  void write_array(const uint8_t *data, size_t len) { this->parent_->write_array(data, len); }
  void write_array(const std::vector<uint8_t> &data) { this->parent_->write_array(data); }
  template<size_t N> void write_array(const std::array<uint8_t, N> &data) {
    this->parent_->write_array(data.data(), data.size());
  }
szupi-ipuzs commented 7 months ago

Looks like the UARTComponent::write_array() for vector is not virtual, so you should re-define it in libretiny_uart. As soon as I learn how to use my own fork, I can test this and create a pull request.

Btw. I'm a bit confused where I should post the issues and pull requests now when libretiny is merged with main esphome branch:

kuba2k2 commented 7 months ago

It depends whether the issue is LibreTiny related (such as "crashes on bk7231"), or if it applies to all platforms (such as "custom component problems"). The old fork repository doesn't have issues enabled.

Yes, the function is not virtual, because it's inline. It's implemented right in uart_component.h:

void write_array(const std::vector<uint8_t> &data) { this->write_array(&data[0], data.size()); }

Neither of the implemented platforms (re)implement this function.

szupi-ipuzs commented 7 months ago

You're correct... That would mean the same problem should occur with other boards (eg. ESP8266). If so, this would be an esphome issue. Will try that now.

Cossid commented 7 months ago

Yeah, this looks like an ESPHome bug. I think components\uart\uart.h line 22 should be void write_array(const std::vector<uint8_t> &data) { this->parent_->write_array(data, data.size()); } which would match uart_component.h

szupi-ipuzs commented 7 months ago

Yes, I've got the same result with ESP8266:

/config/h801.yaml: In lambda function:
/config/h801.yaml:37:53: error: no matching function for call to 'esphome::uart::ESP8266UartComponent::write_array(const std::vector<unsigned char>&)'
   37 |               id(test_uart).write_array(WIFI_RESET_RESPONSE);
      |                                                     ^
In file included from src/esphome.h:66,
                 from src/main.cpp:3:
src/esphome/components/uart/uart_component_esp8266.h:56:8: note: candidate: 'virtual void esphome::uart::ESP8266UartComponent::write_array(const uint8_t*, size_t)'
   56 |   void write_array(const uint8_t *data, size_t len) override;
      |        ^~~~~~~~~~~
src/esphome/components/uart/uart_component_esp8266.h:56:8: note:   candidate expects 2 arguments, 1 provided
*** [.pioenvs/h801/src/main.cpp.o] Error 1

Can we transfer this issue to esphome issues?

Cossid commented 7 months ago

Nope can't transfer to different orgs. You'll need to create a new issue there.