libretiny-eu / libretiny

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

compile error - Using raw pin numbers is ambiguous. Use either D1, A1 or P1 #84

Closed donburch888 closed 1 year ago

donburch888 commented 1 year ago

Pretty new to ESPHome, setting my my first ESPHome configuration file, for a Arlec PC191HA power plug. It has a profile on Blakadder (https://templates.blakadder.com/arlec_PC191HA.html) which includes a list of GPIO numbers, and the instruction to replace the WB2S module. Instead i have run cloudcutter for this device, and also used it to load an initial basic LibreTuya-esphome configuration. So far so good ...

Now I have assembled a configuration from components on esphome.io website which I hope will duplicate the original functionality:

esphome:
  name: "pc191ha-109"

libretuya:
  board: wb2s
  framework:
    version: dev

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "HgoRlyg+sp+PXuiZ0h8fcSCxq+HxVp9hvmCAPwzMnW8="

ota:
#  password: "eb9494d8b9ac189def0a76bc22bb638b"
  password: ""

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Pc191 Fallback Hotspot"
    password: "v8ag08b0GTNj"

captive_portal:

web_server:
  port: 80

# Example configuration entry
binary_sensor:
  - platform: gpio
    pin: 01
    name: "pc191ha-109_button"
    device_class: window

# Example configuration entry
light:
  - platform: status_led
    name: "Switch state"
    pin: 14

# Example configuration entry
switch:
  - platform: gpio
    pin: 13
    name: "pc191ha-109_switch"

# Example configuration entry for device BL0937 using inverted SEL pin functionality
sensor:
  - platform: hlw8012
    model: BL0937
    sel_pin:
      number: GPIO12
      inverted: true
    cf_pin: GPIO04
    cf1_pin: GPIO05
    current:
      name: "BL0937 Current"
    voltage:
      name: "BL0937 Voltage"
    power:
      name: "BL0937 Power"
    update_interval: 60s

Problem is that when I use the libreTuya-esphome HA add-on to install, I get errors about the pin numbers.

With numeric pin numbers I get

INFO Reading configuration /config/libretuya-esphome/pc191ha-109.yaml... 
Failed config 

binary_sensor.gpio: [source /config/libretuya-esphome/pc191ha-109.yaml:38] 
    platform: gpio 

    Using raw pin numbers is ambiguous. Use either D1, A1 or P1 - all these are different pins! Refer to the docs for details. 
    pin: 1 
    name: pc191ha-109_button 
    device_class: window 
light.status_led: [source /config/libretuya-esphome/pc191ha-109.yaml:45] 
    platform: status_led 
    name: Switch state 

    Using raw pin numbers is ambiguous. Use either D14, A14 or P14 - all these are different pins! Refer to the docs for details. 
    pin: 14 switch.gpio: [source /config/libretuya-esphome/pc191ha-109.yaml:51] 
    platform: gpio 

Using raw pin numbers is ambiguous. Use either D13, A13 or P13 - all these are different pins! Refer to the docs for details. 
    pin: 13 
    name: pc191ha-109_switch 

however all the docs I have found so far seem to use GPIO pin numbers, most often without an D, A or P prefix !!! Which doc is this referring to ?

If I prefix them all with "GPIO" I get

Compiling /data/pc191ha-109/.pioenvs/pc191ha-109/src/main.cpp.o 
src/main.cpp: In function 'void setup()': 
src/main.cpp:214:45: error: 'PIN_FUNCTION_P01' was not declared in this scope 
    libretuya_arduinointernalgpiopin->set_pin(PIN_FUNCTION_P01); 
                             ^ 
src/main.cpp:237:47: error: 'PIN_FUNCTION_P14' was not declared in this scope 
    libretuya_arduinointernalgpiopin_2->set_pin(PIN_FUNCTION_P14); 
                            ^ 
src/main.cpp:276:47: error: 'PIN_FUNCTION_P13' was not declared in this scope
    libretuya_arduinointernalgpiopin_3->set_pin(PIN_FUNCTION_P13); 
                            ^ 
src/main.cpp:351:47: error: 'PIN_FUNCTION_P12' was not declared in this scope   libretuya_arduinointernalgpiopin_4->set_pin(PIN_FUNCTION_P12); 
                            ^ 
src/main.cpp:356:47: error: 'PIN_FUNCTION_P04' was not declared in this scope   libretuya_arduinointernalgpiopin_5->set_pin(PIN_FUNCTION_P04); 
                            ^ 
src/main.cpp:361:47: error: 'PIN_FUNCTION_P05' was not declared in this scope   libretuya_arduinointernalgpiopin_6->set_pin(PIN_FUNCTION_P05); 
                            ^ 
*** [/data/pc191ha-109/.pioenvs/pc191ha-109/src/main.cpp.o] Error 1 
========================= [FAILED] Took 18.15 seconds ========================= 

Not sure whether the issue comes from ESPHome or libretuya-esphome. I've googled for "Using raw pin numbers is ambiguous", but no results which suggests it might be a recent change of policy ?

One of the documentation pages (can't remember which one) says that ESPHome has a table of GPIO to actual physical pin numbers - maybe this hasn't been setup in libleTuya-esphome for the new modules ?

Cossid commented 1 year ago

GPIO is based on the type of chip on the module. They may be in the same physical location, but ESP and Beken do not use the same GPIO numbers.

You need to look at the physical location of the known GPIO from the ESP device and take what GPIO is at that same location on the Beken module

https://developer.tuya.com/en/docs/iot/wifie2smodule?id=K9605u79tgxug and https://developer.tuya.com/en/docs/iot/wb2s-module-datasheet?id=K9ghecl7kc479

For example, GPIO13 on ESP/TYWE2S is PWM0 (which is also GPIO6) on WB2S, alternately, you can use the "Pin" prefixed with D, so pin 6 is D6 on both.

That is all provided they didn't change trace mapping when they changed modules, which they also sometimes do.

donburch888 commented 1 year ago

So ... you're saying I have to open every device, and be an Electrical Engineer (to "just know" all these unwritten assumptions, where to find, and how to interpret this "documentation") ... in order to be able to turn a switch on/off through Home Assistant ?

I am picking up picking up knowledge, but not as quick as I used to be; and I have learnt to focus on the goal.

I started down this path after finding https://www.elektroda.com/rtvforum/topic3944452.html, where jesse has taken one of these devices apart. He even has listed what I assume is the pin-out - but this doesn't seem to match with the Tuya wb2s datasheet you referred to ... so after thinking it was falling into place, I'm back to being confused again ;-(

Cossid commented 1 year ago

When installing 3rd party firmware, yes, you need to have some knowledge of the device in order to configure it, the firmware is designed to be configurable, not for specific devices. Whether that is you discovering it, or finding the data in an established database, it's still a discovery process to some degree. Sometimes that is the price you must pay for the ultimate control of the device.

That being said, CloudCutter extracts some of the data from the devices where available. In the case of this device, some of the pin data is in the device_configuration for this device found here: https://github.com/tuya-cloudcutter/tuya-cloudcutter.github.io/blob/master/devices/arlec-pc191ha-smart-plug.json search for _pin and you can use those numbers prefixed with GPIO or P in esphome (for example, rlpin:6 you could use GPIO6 or P6). Then you need to decode some of Tuya's prefixes, like rl is relay, bt is button, netled is for the LEDs to display network traffic or status, etc. Then there are more advanced things like ele and sel which are related to power monitoring. https://docs.libretuya.ml/docs/resources/tuya-pin-config/ is a reference that is still work in progress.

This is why CloudCutter by default cuts, because it leaves the device fully configured as it came from the factory. 3rd party firmwares will always involve more work.

donburch888 commented 1 year ago

Thanks for your reply Cossid, it gives me a couple of avenues to explore.

Is the "Using raw pin numbers is ambiguous. Use either D1, A1 or P1" a libretuya-esphome thing ? ESPHome clearly states that they use GPIO pin numbers ... but from your explanation I can see an argument for making the user double-check and explicitly state which pins to use for these newer modules.

kuba2k2 commented 1 year ago

Because LibreTuya is Arduino-compatible, it also has D# pin designations. Usage of these used to be enforced, but we've made it so that raw GPIO numbers could also be used. Using just a number like "16" is ambiguous, because it might refer to D16 or P16 - which are different.

You've chosen WB2S as your board name, so you should refer to the WB2S docs on LibreTuya docs page. There's a pinout diagram which shows which physical pin is which P#/D#/PWM# etc. You can match this diagram to ESP12 pinout, and to the data from blakadder templates.

The error you're getting after prefixing with GPIO means that WB2S doesn't have these pins physically.

donburch888 commented 1 year ago

so you should refer to the WB2S docs on LibreTuya docs page.

Ah, so that's the docs which the error message is referring to ! Actually I did look at it, but the only bit that made sense to me at the time was the 4 lines of ESPHome YAML code.

I'm sure I won't be the first and last person who sees a device listed in Blakadder and hopes to convert it to ESPHome. I can see writing a tutorial for this in my future, and probably additions to the docs.LibreTuya.ml documentation - how should I submit my LibreTuya docs suggestions for review and hopefully incorporation ?

But first I have to work out how to match up the bits of information to determine the flow from blakadder style list of GPIOs to the physical pins for inclusion in the libretuya-esphome yaml. And of course to test it ;-)

I do thank you both for persisting with helping a newbie, and for putting up with my frustrated rants.

kuba2k2 commented 1 year ago

All the docs are in the main LT repository, so if you want to change something, you just fork the repo and make a PR on GitHub.

donburch888 commented 1 year ago

You need to look at the physical location of the known GPIO from the ESP device and take what GPIO is at that same location on the Beken module

https://developer.tuya.com/en/docs/iot/wifie2smodule?id=K9605u79tgxug and https://developer.tuya.com/en/docs/iot/wb2s-module-datasheet?id=K9ghecl7kc479

For example, GPIO13 on ESP/TYWE2S is PWM0 (which is also GPIO6) on WB2S, alternately, you can use the "Pin" prefixed with D, so pin 6 is D6 on both.

OK, for the "known GPIO" as you said. I have matched the Blakadder GPIO# to the TYWE2S Symbol, which gives the module edge connector pin; and from WB2S edge connector to the IC pin number.

What about the UNknown GPIOs ? I see no TYWE2S pin function for GPIO01, which is used for Button 1

catalin2402 commented 1 year ago

GPIO1 on Esp chips is the TX pin and GPIO3 is the RX pin. In your case, the GPIO1 on the TYWE2S corresponds with TX pin on WB2S. TX pin on WB2s is GPIO11

donburch888 commented 1 year ago

Thank you all. Your posts have enabled me to join the dots, and I have now got 2 of my devices using ESPHome in Home Assistant :grin: I can turn the relay and LED on and off, but getting only zero values from the 3 electrical sensors - but that is a different issue.

Cossid commented 1 year ago

We've generally found for the Beken platform, you need to invert all pins for energy monitoring (SEL/CF/CF1). Try that and see if you start seeing values.

junkman690 commented 1 year ago

@donburch888, are you able to post the corrected ESPHOME yaml?

donburch888 commented 1 year ago

I’ve taken a couple of goes at this, and got a workable setup ... but I'm sure it could be better.

INFO Starting log output from 192.168.1.108 using esphome API INFO Successfully connected to 192.168.1.108 [15:00:55][I][app:102]: ESPHome version 2023.5.0-dev compiled on Jun 4 2023, 13:48:42 [15:00:55][C][status_led:064]: Status Led Light:

Turn power off at the wall socket for about 10 minutes, then when the device comes back online it will be running the latest firmware.

And so herewith is my current yaml file for Arlec PC191HA power switch:

substitutions:
  deviceIP: "108"                   # last octet of the IP Address
  devicename: pc191ha-$deviceIP
  deviceID: pc191ha_$deviceIP
  # the parameters used below (for ease of adjusting)
  restore_mode: RESTORE_DEFAULT_ON  # mode for when power is turned on
  wifi_update_interval: "60s"       # how often to report wifi signal strength
  # hlw8012 does the power monitoring and reporting
  hlw8012_update_interval:    "10s"  # How often to measure and report values
  ### Decided that I want Power and Voltage reported each time (not swapping with Current).
  hlw8012_initial_mode: "VOLTAGE"    # reports VOLTAGE or CURRENT
  hlw8012_change_mode_every: "4294967295"  # do NOT swap between reporting Volts or Amps
  # Adjust according to the actual resistor values on board to calibrate the specific unit
  hlw8012_voltage_divider:   "769"
  hlw8012_current_resistor:  "0.0009"  

esphome:
  name: $devicename

libretiny:
  board: wb2s
  framework:
    version: dev

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret esphome_api_encryption

ota:
  password: !secret esphome_ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  use_address: 192.168.1.$deviceIP
  fast_connect: True

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "pc191ha Fallback Hotspot"
    password: !secret wifi_ap_password

captive_portal:

web_server:
  port: 80

#
# PC191HA basic switch operation - button, relay and LED
#
    # button is momentary on - shows "on" in HA except for the moment the button is being pressed
    # LED should have same on/off state as the relay 
    #   so no point exposing these to HA - use internal: true option
    # there is also a wifi_LED, but it is not seen from outside the case

binary_sensor:        # button   (bt1_pin: 11)
  - platform: gpio
    pin: P11
    name: $devicename button
    id:   ${deviceID}_button
    device_class: window
    # when button is pressed, toggle the switch on/off
    on_press:
      then:
        - switch.toggle: ${deviceID}_relay  # toggle the relay / switch
    internal: True

light:                # LED in the button  (led1_pin: 26)
  - platform: status_led
    name: $devicename Switch state
    id:   ${deviceID}_led
    pin: P26
    restore_mode: $restore_mode 
    internal: True

switch:              # relay    (rl1_pin: 6)
  - platform: gpio
    pin: P6
    name: $devicename relay
    id:   ${deviceID}_relay
    restore_mode: $restore_mode   # default when power is turned on
    # synchronise the LED with the relay
    on_turn_on:
      then:
        - light.turn_on: ${deviceID}_led
    on_turn_off:
      then:
        - light.turn_off: ${deviceID}_led
  - platform: restart
    name: $devicename Restart

#
# PC191HA sensors - power monitoring
#
sensor:
  - platform: wifi_signal         # report wi-fi signal strength from this end
    name: $devicename WiFi Signal
    id:   ${deviceID}_wifi_signal
    update_interval: $wifi_update_interval    # how often to report wifi signal strength

    # PC191HA includes a BL0937 chip for measuring power consumption
    #     and BL0937 is a variation of hlw8012, but using inverted SEL pin functionality
  - platform: hlw8012
    model: BL0937     # note that the model must be specified to use special calculation parameters
    sel_pin:          # I believe that cf_pin reports either Voltage or Current depending on this select pin
      inverted: true  # determine whether true reports Voltage
      number: P24
    cf_pin:           # current or voltage (ele_pin: 7)
      inverted: true  # the logic of BL0937 is opposite from HLW8012
      number: P7
    cf1_pin:          #  Power (vi_pin: 8)
      inverted: true  # the logic of BL0937 is opposite from HLW8012
      number: P8

    update_interval: $hlw8012_update_interval      # How often to measure and report values

    # PC191HA measures and returns Voltage OR Current according to the value of sel_pin, 
    #   but it can change the value of sel_pin periodically 
    initial_mode: $hlw8012_initial_mode             # reports VOLTAGE or CURRENT
    change_mode_every: $hlw8012_change_mode_every   # how many times to report before swapping between
        #   reporting Voltage or Current. Note that the first value reported should be ignored as inaccurate

    # Adjust according to the actual resistor values on board to calibrate the specific unit
    voltage_divider:  $hlw8012_voltage_divider     # LOWER VALUE GIVES LOWER VOLTAGE
    current_resistor: $hlw8012_current_resistor    # HIGHER VALUE GIVES LOWER WATTAGE
    # power is simply current x voltage, so needs no separate calibration
  ### except that the pc191ha doesn't follow that formula.
  ### Setting current_resistor to give an accurate Amperage does NOT also give the correct Wattage
  ###

    # how the power monitoring values are returned to ESPHome
    current:
      name: $devicename Current
      id:   ${deviceID}_current
      unit_of_measurement: A
      accuracy_decimals: 4
    voltage:
      name: $devicename Voltage
      id:   ${deviceID}_voltage
      unit_of_measurement: V
      accuracy_decimals: 1
    power:
      name: $devicename Power
      id:   ${deviceID}_power
      unit_of_measurement: W
      accuracy_decimals: 4
tbgoose commented 1 year ago

Hey

I have a similar outdoor version of this plug I am trying to flash with esphome - https://www.bunnings.com.au/arlec-grid-connect-smart-ip44-heavy-duty-timer_p0273373

There is talk of it here - https://www.elektroda.com/rtvforum/topic3980140.html

Using the work you have done and the info on the above page I have created the following esphome yaml, but it's not really correct. Can anyone help figure out what I am doing wrong?

EDIT: I should mention that I am mainly using this plug to monitor power use of my pool pump + filter. I very rarely use the switch. It does turn the device on and off from the web-portal, but not from the button. Power monitoring is completely wrong as logs here show

13:46:19 | [D] | [hlw8012:082] | Got power=2.7W, voltage=0.7V
13:46:19 | [D] | [sensor:093] | 'Voltage': Sending state 0.65699 V with 1 decimals of accuracy
13:46:19 | [D] | [sensor:093] | 'Power': Sending state 2.65077 W with 1 decimals of accuracy
13:46:19 | [D] | [sensor:093] | 'Daily Consumption': Sending state 0.00109 kWh with 3 decimals of accuracy

esphome yaml


substitutions:
  device_name: pool_pump_socket
  device_friendly_name: "Pool Pump Socket"
  device_ip: 192.168.1.183
  outlet_icon: mdi:power-socket-au
  switch_restore: ALWAYS_ON

  # Higher value gives lower watt readout
  current_res: "0.0009 ohm"
  # Lower value gives lower voltage readout
  voltage_div: "769"

esphome:
  name: ${device_name}
  friendly_name: ${device_friendly_name}
  #name_add_mac_suffix: true

libretiny:
  board: wb2s
  framework:
    version: dev

logger:

web_server:
  port: 80

api:
  reboot_timeout: 15min
  encryption:
    key: !secret api_key_pool_pump

ota:
  password: !secret ota_password

captive_portal:

mdns:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: ${device_ip}
    gateway: 192.168.1.1
    subnet: 255.255.255.0
    dns1: 192.168.1.1
  ap:
    password: !secret ap_password

button:
  - platform: restart
    name: Restart

debug:
  update_interval: 30s

sensor:
  - platform: uptime
    name: Uptime
  - platform: hlw8012
    model: BL0937
    cf_pin:
      number: P7
      inverted: true
    cf1_pin:
      number: P8
      inverted: true
    sel_pin:
      number: P24
      inverted: true
    current:
      name: Current
      #unit_of_measurement: A
    voltage:
      name: Voltage
      #unit_of_measurement: V
    power:
      id: ${device_name}_power
      name: Power
      #unit_of_measurement: W
    current_resistor: ${current_res}
    voltage_divider: ${voltage_div}
    change_mode_every: 8
    update_interval: 15s
  - platform: total_daily_energy
    name: "Daily Consumption"
    power_id: ${device_name}_power
    filters:
      - multiply: 0.001
    unit_of_measurement: kWh

  - platform: wifi_signal
    name: RSSI
    update_interval: 5min

  - platform: uptime
    id: uptime_sec
    name: Uptime
    update_interval: 5min

text_sensor:
  - platform: debug
    reset_reason:
      name: "Reset Reason"
  - platform: libretiny
    version:
      name: "Libretiny Version"
  - platform: template
    name: "Up Format"
    lambda: |-
      uint32_t dur = id(uptime_sec).state;
      int dys = 0;
      int hrs = 0;
      int mnts = 0;
      if (dur > 86399) {
        dys = trunc(dur / 86400);
        dur = dur - (dys * 86400);
      }
      if (dur > 3599) {
        hrs = trunc(dur / 3600);
        dur = dur - (hrs * 3600);
      }
      if (dur > 59) {
        mnts = trunc(dur / 60);
        dur = dur - (mnts * 60);
      }
      char buffer[17];
      sprintf(buffer, "%ud %02uh %02um %02us", dys, hrs, mnts, dur);
      return {buffer};
    icon: mdi:clock-start
    update_interval: 5min
  - platform: wifi_info
    ip_address:
      name: "IP Address"
      disabled_by_default: false

output:
  - platform: ledc
    id: output_led_1
    pin: P11

light:
  - platform: monochromatic
    id: light_switch_1
    output: output_led_1

binary_sensor:
  - platform: gpio
    id: binary_switch_1
    pin:
      number: P10
      inverted: true
      mode: INPUT_PULLUP
    on_press:
      then:
        - switch.toggle: outlet

switch:
  - platform: gpio
    id: outlet
    name: None
    pin: P26
    icon: ${outlet_icon}
    on_turn_on:
      - light.turn_on: light_switch_1
    on_turn_off:
      - light.turn_off: light_switch_1
    restore_mode: ${switch_restore}
    device_class: outlet

status_led:
  pin: P6

time:
  - platform: homeassistant
    id: homeassistant_time