psvanstrom / esphome-p1reader

ESPHome custom component for reading P1 data from electricity meters.
MIT License
251 stars 106 forks source link

Compile Error with esp-idf Framework #72

Open 314159-r opened 1 year ago

314159-r commented 1 year ago

Compiling p1reader for a SeeedStudio XIAO ESP32C3 with the "esp-idf" framework fails.

I recently got a Wemos D1 device up and running fine with your p1eader. Very nice... But I want a device with external antenna, so I wanted to try to make this work with a XIAO ESP32C3. I got this error when compiling using the "esp-idf" framework. I first tried to compile with the default arduino framework, but it it doesn't seem to support the UART component for ESP32C3.

I get the following error when compiling: (log file attached)

In file included from src/main.cpp:54:
src/p1reader.h: In member function 'void P1Reader::readP1Message()':
src/p1reader.h:262:21: error: 'Serial' was not declared in this scope
           int len = Serial.readBytesUntil('\n', buffer, BUF_SIZE);
                     ^~~~~~
src/p1reader.h:262:21: note: suggested alternative: 'erfl'
           int len = Serial.readBytesUntil('\n', buffer, BUF_SIZE);
                     ^~~~~~

The essential parts of my config: (yaml file attached)

esphome:
  name: ${device_name}
  includes:
    - p1reader.h    
esp32:
  board: esp32-c3-devkitm-1
  variant: esp32c3
  framework:
    type: esp-idf

uart:
  id: uart_bus
  baud_rate: 115200
  rx_pin:
    number: 20  # GPIO20, D7, RX
    inverted: true

I'm running this with ESPhome "stand alone", without Home Assistant on a Debian 11 system. My Home Assistant is running on a raspberry Pi 3b+, and it has issues with incompatible compiler for ESP32C3 in the "esp-idf" framework (riscv32-esp-elf-gcc -- broken)

Compiling with just the UART component but without p1reader.h, works fine.

log-esp32c3-p1reader_esp-idf.txt elmataren_yaml.txt

314159-r commented 1 year ago

Meanwhile, I have at least verified that the XIAO ESP32C3 devise is "physically" suited for this task. I wired it up to my Sagemcom T211 meter, powered from the P1 port. And uploaded a test-config that reads the UART and reports to the debug output. - Works like a charm... :)

It's a really minimalistic setup, with just one pull-up resistor for RX, and one capacitor at the power input. And the ESP itself of course...

DSC_0437

esp32c3-test.yaml.txt log-esp32c3-uart_debug.txt

314159-r commented 1 year ago

This issue is not really related to the ESP32C3 device. I get the same compile error for a Wemos D32 device, with the esp-idf framework. I have no insight in whether a custom component like this, can be compatible with both frameworks or not. Or if a different variant of p1reader would be necessary to work with esp-idf. However, Seeed Studio have shown that working with UART in custom components, XIAO ESP32C3 and esp-idf framework is possible in this demo. XIAO ESP32C3 accesses Home Assistant via ESPHome service

The good news is that we don't need esp-idf (I don't...). I was diverted into trying esp-idf because I got errors compiling with arduino. Reading a lot of comments about poor support for these "new" -C3 devices, I decided to try with esp-idf instead...

Lack of success led me back to the arduino framework, and I have found a config that successfully compiles p1reade for the Seeed Studio XIAO ESP32C3 - with the arduino framework. :)

The trick was not to use the dedicated name for the board: seeed_xiao_esp32c3 Instead we must use the "generic" esp32-c3-devkitm-1

p1reader.yaml (sorry for sensor names in Swedish...)

substitutions:
  device_name: "elmataren"
  friendly_name: "Elmätaren"
  device_description: "Ellevios el-mätare för hela huset. (SeeedStudio XIAO esp32c3)"

esphome:
  name: ${device_name}
  friendly_name: ${friendly_name}
  comment: "${device_description}"
  includes:
    - p1reader.h    

esp32:
  board: esp32-c3-devkitm-1
  variant: esp32c3
  framework:
    type: arduino

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "1xUW/G1DHc+ToRQm17Qw3Na1LjM/8yG18lIBgxbGPpg="

ota:
  password: "44906a5cd9292211d5b64204659e507f"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  domain: .lan
  fast_connect: True
  power_save_mode: none

  # Enable fallback hotspot (captive portal) in case wifi connection fails
#  ap:
#    ssid: ${device_name}
#    password: !secret fallback_ap_password
#
#captive_portal:    # Kräver Arduino framework

uart:
  id: uart_bus
  baud_rate: 115200
  rx_pin:
    number: 20  # GPIO20, D7, RX
    inverted: true

sensor:
- platform: custom
  lambda: |-
    auto meter_sensor = new P1Reader(id(uart_bus));
    App.register_component(meter_sensor);
    return {
      meter_sensor->cumulativeActiveImport,
      meter_sensor->cumulativeActiveExport,
      meter_sensor->cumulativeReactiveImport,
      meter_sensor->cumulativeReactiveExport,
      meter_sensor->momentaryActiveImport,
      meter_sensor->momentaryActiveExport,
      meter_sensor->momentaryReactiveImport,
      meter_sensor->momentaryReactiveExport,
      meter_sensor->momentaryActiveImportL1,
      meter_sensor->momentaryActiveExportL1,
      meter_sensor->momentaryActiveImportL2,
      meter_sensor->momentaryActiveExportL2,
      meter_sensor->momentaryActiveImportL3,
      meter_sensor->momentaryActiveExportL3,
      meter_sensor->momentaryReactiveImportL1,
      meter_sensor->momentaryReactiveExportL1,
      meter_sensor->momentaryReactiveImportL2,
      meter_sensor->momentaryReactiveExportL2,
      meter_sensor->momentaryReactiveImportL3,
      meter_sensor->momentaryReactiveExportL3,
      meter_sensor->voltageL1,
      meter_sensor->voltageL2,
      meter_sensor->voltageL3,
      meter_sensor->currentL1,
      meter_sensor->currentL2,
      meter_sensor->currentL3
    };
  sensors:
  - name: "Energi"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    state_class: "total_increasing"
    device_class: "energy"
  - name: "Energi Export"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    state_class: "total_increasing"
    device_class: "energy"
  - name: "Energi Reaktiv"
    unit_of_measurement: kvarh
    accuracy_decimals: 3
  - name: "Energi Export Reaktiv"
    unit_of_measurement: kvarh
    accuracy_decimals: 3
  - name: "Effekt"
    unit_of_measurement: kW
    accuracy_decimals: 3
    state_class: "measurement"
    device_class: "power"
  - name: "Effekt Export"
    unit_of_measurement: kW
    accuracy_decimals: 3
    state_class: "measurement"
    device_class: "power"
  - name: "Effekt Reaktiv"
    unit_of_measurement: kvar
    accuracy_decimals: 3
  - name: "Effekt Export Reaktiv"
    unit_of_measurement: kvar
    accuracy_decimals: 3
  - name: "Effekt L1"
    unit_of_measurement: kW
    accuracy_decimals: 3
    state_class: "measurement"
    device_class: "power"
  - name: "Effekt Export L1"
    unit_of_measurement: kW
    accuracy_decimals: 3
    state_class: "measurement"
    device_class: "power"
  - name: "Effekt L2"
    unit_of_measurement: kW
    accuracy_decimals: 3
    state_class: "measurement"
    device_class: "power"
  - name: "Effekt Export L2"
    unit_of_measurement: kW
    accuracy_decimals: 3
    state_class: "measurement"
    device_class: "power"
  - name: "Effekt L3"
    unit_of_measurement: kW
    accuracy_decimals: 3
    state_class: "measurement"
    device_class: "power"
  - name: "Effekt Export L3"
    unit_of_measurement: kW
    accuracy_decimals: 3
    state_class: "measurement"
    device_class: "power"
  - name: "Effekt Reaktiv L1"
    unit_of_measurement: kvar
    accuracy_decimals: 3
  - name: "Effekt Export Reaktiv L1"
    unit_of_measurement: kvar
    accuracy_decimals: 3
  - name: "Effekt Reaktiv L2"
    unit_of_measurement: kvar
    accuracy_decimals: 3
  - name: "Effekt Export Reaktiv L2"
    unit_of_measurement: kvar
    accuracy_decimals: 3
  - name: "Effekt Reaktiv L3"
    unit_of_measurement: kvar
    accuracy_decimals: 3
  - name: "Effekt Export Reaktiv L3"
    unit_of_measurement: kvar
    accuracy_decimals: 3
  - name: "Spänning L1"
    unit_of_measurement: V
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "voltage"
  - name: "Spänning L2"
    unit_of_measurement: V
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "voltage"
  - name: "Spänning L3"
    unit_of_measurement: V
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "voltage"
  - name: "Ström L1"
    unit_of_measurement: A
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "current"
  - name: "Ström L2"
    unit_of_measurement: A
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "current"
  - name: "Ström L3"
    unit_of_measurement: A
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "current"

- platform: uptime
  name: "Uptime"
- platform: wifi_signal
  name: "WiFi Signal dB"
  id: wifi_signal_db
  update_interval: 60s
- platform: copy    #   Reports the WiFi signal strength in %
  source_id: wifi_signal_db
  name: "WiFi Signal"
  filters:    #   Konvertera -85dB...-45dB -> 0...100 %
    - lambda: return min(max(2.5 * (x + 85.0), 0.0), 100.0);
  unit_of_measurement: "%"
  entity_category: "diagnostic"

text_sensor:
  - platform: wifi_info
    ip_address:
      name: "IP Address"
    ssid:
      name: "WiFi SSID"
    bssid:
      name: "WiFi BSSID"
  - platform: version
    name: "ESPHome Version"
    hide_timestamp: false