esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 34 forks source link

RPi Pico W build fails when using api services #4160

Open THorst92 opened 1 year ago

THorst92 commented 1 year ago

The problem

The build of the RPi Pico W firmware fails as soon as I add the service section in the api section. Without the service section I have no problems. The service section was already successfully tested on an esp8266 and esp32.

Which version of ESPHome has the issue?

2022.12.8

What type of installation are you using?

Home Assistant Add-on

Which version of Home Assistant has the issue?

2023.2.0

What platform are you using?

RP2040

Board

Raspberry Pi Pico W

Component causing the issue

api

Example YAML snippet

esphome:
  name: test-pico

rp2040:
  board: rpipicow
  framework:
    # Required until https://github.com/platformio/platform-raspberrypi/pull/36 is merged
    platform_version: https://github.com/maxgerhardt/platform-raspberrypi.git

#################
# LOG
#################
logger:
  baud_rate: 0
#  level: VERY_VERBOSE

#################
# API
#################
api:
  encryption:
    key: "xxxxxxx"
  services:
    - service: set_textid
      variables:
        new_textid: int
      then:
        - sensor.template.publish:
            id: textid
            state: !lambda return (float)new_textid;
    - service: enroll
      variables:
        finger_id: int
        num_scans: int
      then:
        - fingerprint_grow.enroll:
            finger_id: !lambda 'return finger_id;'
            num_scans: !lambda 'return num_scans;'
    - service: cancel_enroll
      then:
       - fingerprint_grow.cancel_enroll:
    - service: delete
      variables:
        finger_id: int
      then:
        - fingerprint_grow.delete:
            finger_id: !lambda 'return finger_id;'
    - service: delete_all
      then:
        - fingerprint_grow.delete_all:

ota:
  password: "xxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot in case wifi connection fails
  ap:
    ssid: "Test-Pico Fallback Hotspot"
    password: "xxxxxxxx"

#################
# UART
#################
uart:
  id: uart_r503
  rx_pin: GPIO9
  tx_pin: GPIO8
  baud_rate: 57600

#################
# SPI
#################
spi:
  clk_pin: GPIO2
  mosi_pin: GPIO3
  miso_pin: GPIO4

#################
# FONTS
#################
font:
  - file: "/config/www/fonts/RobotoCondensed-Regular.ttf"
    id: robotocondensed_regular_40
    size: 40
  - file: "/config/www/fonts/RobotoCondensed-Regular.ttf"
    id: robotocondensed_regular_10
    size: 10

#################
# IMAGES
#################
image:
  - file: "/config/www/logo_white_small.png"
    id: logo

#################
# DISPLAY
#################
display:
  - platform: waveshare_epaper
    id: display_1
    cs_pin: GPIO6
    dc_pin: GPIO7
    busy_pin: GPIO10
    reset_pin: GPIO11
    model: 1.54inv2
    full_update_every: 1
    update_interval: never
    pages:
      - id: page0
        lambda: |-
          it.image(0, 0, id(logo));
      - id: page1
        lambda: |-
          it.print(100, 40, id(robotocondensed_regular_40), COLOR_ON, TextAlign::CENTER, "Ich");
          it.print(100, 84, id(robotocondensed_regular_40), COLOR_ON, TextAlign::CENTER, "komme");
          it.print(100, 128, id(robotocondensed_regular_40), COLOR_ON, TextAlign::CENTER, "gleich!");
      - id: page2
        lambda: |-
          it.print(100, 84, id(robotocondensed_regular_40), COLOR_ON, TextAlign::CENTER, "Paket bitte");
          it.print(100, 128, id(robotocondensed_regular_40), COLOR_ON, TextAlign::CENTER, "in Kasten!");

#################
# R503
#################  
fingerprint_grow:
  sensing_pin: GPIO16
  uart_id: uart_r503
  on_finger_scan_matched:
#    - homeassistant.event:
#        event: esphome.test_node_finger_scan_matched
#        data:
#          finger_id: !lambda 'return finger_id;'
#          confidence: !lambda 'return confidence;'
    - fingerprint_grow.aura_led_control:
        state: FLASHING
        speed: 200
        color: GREEN
        count: 1
    - fingerprint_grow.aura_led_control:
        state: !lambda |-
          if (id(haus_pico_bewegungsmelder).state) return 1;
          else return 4;
        speed: 200
        color: BLUE
        count: 0
    - logger.log: "R503 Matched"
  on_finger_scan_unmatched:
#    - homeassistant.event:
#        event: esphome.test_node_finger_scan_unmatched
    - fingerprint_grow.aura_led_control:
        state: FLASHING
        speed: 25
        color: RED
        count: 2
    - fingerprint_grow.aura_led_control:
        state: !lambda |-
          if (id(haus_pico_bewegungsmelder).state) return 1;
          else return 4;
        speed: 200
        color: BLUE
        count: 0
    - logger.log: "R503 Unmatched"
  on_enrollment_scan:
#    - homeassistant.event:
#        event: esphome.test_node_enrollment_scan
#        data:
#          finger_id: !lambda 'return finger_id;'
#          scan_num: !lambda 'return scan_num;'
    - fingerprint_grow.aura_led_control:
        state: FLASHING
        speed: 25
        color: BLUE
        count: 2
    - fingerprint_grow.aura_led_control:
        state: ALWAYS_ON
        speed: 0
        color: PURPLE
        count: 0
    - logger.log: "R503 Scan"
  on_enrollment_done:
#    - homeassistant.event:
#        event: esphome.test_node_enrollment_done
#        data:
#          finger_id: !lambda 'return finger_id;'
    - fingerprint_grow.aura_led_control:
        state: BREATHING
        speed: 100
        color: BLUE
        count: 2
    - logger.log: "R503 Done"
  on_enrollment_failed:
#    - homeassistant.event:
#        event: esphome.test_node_enrollment_failed
#        data:
#          finger_id: !lambda 'return finger_id;'
    - fingerprint_grow.aura_led_control:
        state: FLASHING
        speed: 25
        color: RED
        count: 4
    - logger.log: "R503 Failed"

#################
# NFC Leser
#################
rc522_spi:
  cs_pin: GPIO5
  on_tag:
    then:
#      - homeassistant.event:
#          event: esphome.test_node_new_uid
#          data:
#            uid: !lambda 'return x;'
      - fingerprint_grow.aura_led_control:
          state: FLASHING
          speed: 25
          color: PURPLE
          count: 2
      - fingerprint_grow.aura_led_control:
          state: !lambda |-
            if (id(haus_pico_bewegungsmelder).state) return 1;
            else return 4;
          speed: 200
          color: BLUE
          count: 0

#################
# OUTPUT DEF
#################
switch:
  - platform: gpio
    name: "haus_pico_klingel"
    id: haus_pico_klingel
    pin:
      number: GPIO18
      mode:
        output: true
      inverted: false
  - platform: gpio
    name: "haus_pico_wakeupcamera"
    id: haus_pico_wakeupcamera
    pin:
      number: GPIO19
      mode:
        output: true
      inverted: false

#################
# BINARY SENSORS
#################
binary_sensor:
  # Status
  - platform: status
    name: "haus_pico_status"
  # Bewegungsmelder
  - platform: gpio
    name: "haus_pico_bewegungsmelder"
    id: haus_pico_bewegungsmelder
    pin:
      number: GPIO17
      mode:
        input: true
      inverted: false
    filters:
      - delayed_off: 5s
    on_press: 
      then:
        - display.page.show: page1
        - fingerprint_grow.aura_led_control:
            state: BREATHING
            speed: 200
            color: BLUE
            count: 0
#        - switch.turn_on: wakeup
#        - switch.turn_on: klingel
    on_release:      
      then:
        - display.page.show: page0
        - fingerprint_grow.aura_led_control:
            state: ALWAYS_OFF
            speed: 200
            color: BLUE
            count: 0
#        - switch.turn_off: wakeup
#        - switch.turn_off: klingel
  - platform: gpio
    name: "haus_pico_touchsensor"
    id: haus_pico_touchsensor
    pin:
      number: GPIO16
      mode:
        input: true
      inverted: false
    on_press:
      then:
        - fingerprint_grow.aura_led_control:
            state: FLASHING
            speed: 25
            color: YELLOW
            count: 2
        - fingerprint_grow.aura_led_control:
            state: !lambda |-
              if (id(haus_pico_bewegungsmelder).state) return 1;
              else return 4;
            speed: 200
            color: BLUE
            count: 0
        - sensor.template.publish:
            id: textid
            state: !lambda |-
              if ((int)id(textid).state < 4){
                id(textid).publish_state((int)id(textid).state + 1);
              }
              else {
                id(textid).publish_state(1);
              }
              return (int)id(textid).state;
        - switch.turn_on: haus_pico_klingel
        - switch.turn_on: haus_pico_wakeupcamera
        - delay: 1s
        - switch.turn_off: haus_pico_klingel
        - switch.turn_off: haus_pico_wakeupcamera

#################
# SENSORS
#################
sensor:
  # Wifi Signalstärke
  - platform: wifi_signal
    name: "haus_pico_wifisignal"
    update_interval: 60s
  # Text ID
  - platform: template
    name: "haus_pico_textid"
    id: textid
    internal: true
    on_value:
      - display.page.show: !lambda |-
          switch ((int)id(textid).state) {
            case 1:
              return id(page0);
              break;
            case 2:
              return id(page1);
              break;
            case 3:
              return id(page2);
              break;
            default:
              return id(page0);
              break;
          }
      - component.update: display_1

Anything in the logs that might be useful for us?

INFO Reading configuration /config/esphome/test-pico.yaml...
INFO Generating C++ source...
INFO Compiling app...
Processing test-pico (board: rpipicow; framework: arduino; platform: https://github.com/maxgerhardt/platform-raspberrypi.git)
--------------------------------------------------------------------------------
HARDWARE: RP2040 133MHz, 264KB RAM, 2MB Flash
 - framework-arduinopico @ 1.20604.0 (2.6.4) 
 - tool-rp2040tools @ 1.0.2 
Flash size: 2.00MB
Sketch size: 1.00MB
Filesystem size: 1.00MB
Maximium Sketch size: 1044480 EEPROM start: 0x101ff000 Filesystem start: 0x100ff000 Filesystem end: 0x101ff000
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
Dependency Graph
|-- WiFi @ 1.0.0
|   |-- Updater @ 1.0
|   |   |-- MD5Builder @ 1.0.0
|   |   |-- LittleFS @ 0.1.0
|   |   |-- PicoOTA @ 1.0.0
|   |   |   |-- LittleFS @ 0.1.0
|   |-- MD5Builder @ 1.0.0
|   |-- lwIP-Ethernet @ 1
|   |   |-- lwIP_CYW43 @ 1
|   |   |   |-- SPI @ 1.0
|   |   |-- SPI @ 1.0
|   |-- lwIP_CYW43 @ 1
|   |   |-- SPI @ 1.0
|   |-- SPI @ 1.0
|-- LEAmDNS @ 1.2
|   |-- lwIP-Ethernet @ 1
|   |   |-- lwIP_CYW43 @ 1
|   |   |   |-- SPI @ 1.0
|   |   |-- SPI @ 1.0
|   |-- WiFi @ 1.0.0
|   |   |-- Updater @ 1.0
|   |   |   |-- MD5Builder @ 1.0.0
|   |   |   |-- LittleFS @ 0.1.0
|   |   |   |-- PicoOTA @ 1.0.0
|   |   |   |   |-- LittleFS @ 0.1.0
|   |   |-- MD5Builder @ 1.0.0
|   |   |-- lwIP-Ethernet @ 1
|   |   |   |-- lwIP_CYW43 @ 1
|   |   |   |   |-- SPI @ 1.0
|   |   |   |-- SPI @ 1.0
|   |   |-- lwIP_CYW43 @ 1
|   |   |   |-- SPI @ 1.0
|   |   |-- SPI @ 1.0
|-- Updater @ 1.0
|   |-- MD5Builder @ 1.0.0
|   |-- LittleFS @ 0.1.0
|   |-- PicoOTA @ 1.0.0
|   |   |-- LittleFS @ 0.1.0
|-- SPI @ 1.0
|-- noise-c @ 0.1.4
|   |-- libsodium @ 1.10018.1
|-- MD5Builder @ 1.0.0
Compiling /data/test-pico/.pioenvs/test-pico/src/main.cpp.o
Linking /data/test-pico/.pioenvs/test-pico/firmware.elf
/data/cache/platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/10.3.0/../../../../arm-none-eabi/bin/ld: /data/test-pico/.pioenvs/test-pico/src/main.cpp.o: in function `_ZN7esphome3api15UserServiceBaseIJllEE15execute_serviceERKNS0_21ExecuteServiceRequestE':
main.cpp:(.text._ZN7esphome3api15UserServiceBaseIJllEE15execute_serviceERKNS0_21ExecuteServiceRequestE[_ZN7esphome3api15UserServiceBaseIJllEE15execute_serviceERKNS0_21ExecuteServiceRequestE]+0x26): undefined reference to `_ZN7esphome3api21get_execute_arg_valueIlEET_RKNS0_22ExecuteServiceArgumentE'
/data/cache/platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/10.3.0/../../../../arm-none-eabi/bin/ld: main.cpp:(.text._ZN7esphome3api15UserServiceBaseIJllEE15execute_serviceERKNS0_21ExecuteServiceRequestE[_ZN7esphome3api15UserServiceBaseIJllEE15execute_serviceERKNS0_21ExecuteServiceRequestE]+0x30): undefined reference to `_ZN7esphome3api21get_execute_arg_valueIlEET_RKNS0_22ExecuteServiceArgumentE'
/data/cache/platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/10.3.0/../../../../arm-none-eabi/bin/ld: /data/test-pico/.pioenvs/test-pico/src/main.cpp.o: in function `_ZN7esphome3api15UserServiceBaseIJlEE15execute_serviceERKNS0_21ExecuteServiceRequestE':
main.cpp:(.text._ZN7esphome3api15UserServiceBaseIJlEE15execute_serviceERKNS0_21ExecuteServiceRequestE[_ZN7esphome3api15UserServiceBaseIJlEE15execute_serviceERKNS0_21ExecuteServiceRequestE]+0x28): undefined reference to `_ZN7esphome3api21get_execute_arg_valueIlEET_RKNS0_22ExecuteServiceArgumentE'
/data/cache/platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/10.3.0/../../../../arm-none-eabi/bin/ld: /data/test-pico/.pioenvs/test-pico/src/main.cpp.o: in function `_ZN7esphome3api15UserServiceBaseIJllEE28encode_list_service_responseEv':
main.cpp:(.text._ZN7esphome3api15UserServiceBaseIJllEE28encode_list_service_responseEv[_ZN7esphome3api15UserServiceBaseIJllEE28encode_list_service_responseEv]+0x2a): undefined reference to `_ZN7esphome3api19to_service_arg_typeIlEENS0_5enums14ServiceArgTypeEv'
/data/cache/platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/10.3.0/../../../../arm-none-eabi/bin/ld: main.cpp:(.text._ZN7esphome3api15UserServiceBaseIJllEE28encode_list_service_responseEv[_ZN7esphome3api15UserServiceBaseIJllEE28encode_list_service_responseEv]+0x30): undefined reference to `_ZN7esphome3api19to_service_arg_typeIlEENS0_5enums14ServiceArgTypeEv'
/data/cache/platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/10.3.0/../../../../arm-none-eabi/bin/ld: /data/test-pico/.pioenvs/test-pico/src/main.cpp.o: in function `_ZN7esphome3api15UserServiceBaseIJlEE28encode_list_service_responseEv':
main.cpp:(.text._ZN7esphome3api15UserServiceBaseIJlEE28encode_list_service_responseEv[_ZN7esphome3api15UserServiceBaseIJlEE28encode_list_service_responseEv]+0x2a): undefined reference to `_ZN7esphome3api19to_service_arg_typeIlEENS0_5enums14ServiceArgTypeEv'
collect2: error: ld returned 1 exit status
*** [/data/test-pico/.pioenvs/test-pico/firmware.elf] Error 1
========================= [FAILED] Took 25.76 seconds =========================

Additional information

No response

THorst92 commented 1 year ago

Found something: If I use the following configuration

    - service: set_textid
      variables:
        new_textid: int
      then:
        - sensor.template.publish:
            id: textid
            state: !lambda return (float)new_textid;

it is transferred in the main.c into

  api_userservicetrigger = new api::UserServiceTrigger<int32_t>("set_textid", {"new_textid"});
  api_apiserver->register_user_service(api_userservicetrigger);
  automation = new Automation<int32_t>(api_userservicetrigger);

but there seems no template function for int32_t in the user_services.cpp. Example for the function to_service_arg_type:

template<> enums::ServiceArgType to_service_arg_type<bool>() { return enums::SERVICE_ARG_TYPE_BOOL; }
template<> enums::ServiceArgType to_service_arg_type<int>() { return enums::SERVICE_ARG_TYPE_INT; }
template<> enums::ServiceArgType to_service_arg_type<float>() { return enums::SERVICE_ARG_TYPE_FLOAT; }
template<> enums::ServiceArgType to_service_arg_type<std::string>() { return enums::SERVICE_ARG_TYPE_STRING; }
template<> enums::ServiceArgType to_service_arg_type<std::vector<bool>>() { return enums::SERVICE_ARG_TYPE_BOOL_ARRAY; }
template<> enums::ServiceArgType to_service_arg_type<std::vector<int>>() { return enums::SERVICE_ARG_TYPE_INT_ARRAY; }
template<> enums::ServiceArgType to_service_arg_type<std::vector<float>>() {
  return enums::SERVICE_ARG_TYPE_FLOAT_ARRAY;
}
template<> enums::ServiceArgType to_service_arg_type<std::vector<std::string>>() {
  return enums::SERVICE_ARG_TYPE_STRING_ARRAY;
}

When I change it to

    - service: set_textid
      variables:
        new_textid: float
      then:
        - sensor.template.publish:
            id: textid
            state: !lambda return new_textid;

it works fine.

I think that it is dependent on the board if an int has a size of 2 bytes or 4 bytes. Maybe it would be better to exchange all int with int32_t in the user_services.cpp.