Energy consumption and Arlec Grid Connect (Tuya) smart plug

Alright, ignore the above. It was easier than I thought.

For anyone else trying to get this working:
When you are adding the switch and sensors for the plug in the localtuya setup, just add another entity of type number, set it to id = 9 (details from tuya iot below).

When you have the device and entities in HA, go to the device and you’ll have 2 controls - a switch and a Timer (well a number but I called mine Timer).

Hit the switch THEN set the timer number. If you do it the other way round, the call to flick the switch sets the timer to 0 and it won’t work (it’ll flick the switch, but with no timer).

“unit”:“s”,
“min”:0,
“max”:86400,
“scale”:0,
“step”:1

Back in March I reported here that I converted two of my Arlec PC191HA power switches to ESPHome firmware over-the-air.
Since then I have
(a) added a uptime and Wi-fi Signal fields to ESPHome YAML device definitions, and
(b) discovered that there is a different tuya-local integration (GitHub - make-all/tuya-local: Local support for Tuya devices in Home Assistant), and gave it a try. Using the Device_id and local_key values it detected PC191HA’s as “smartplugv2_energy” (a generic profile based on which DPs are exposed). All DPs were configured, and seem to fit nicely into existing Lovelace panels.

Both the PC191HA units running ESPHome and units under TuyaLocal have been stable, and an improvement. Time to standardise. It would love to remove tuya - but I have other tuya-based devices (particularly the Zemismart blind).

Anyway i just compared devices and found extra fields in the TuyaLocal definition for PC191-HAs.


… compared to ESPHome …

1 Like

I just came here after seeing your comment in the AU thread, so sorry this is late.

The extra entities in the Tuya version could easily be added to the ESPhome version, you just need to update your code a bit.

ie: to add a timer or ‘child lock’ function.

for the light entity in the Tuya version, the reason you don’t see that in the ESPhome version is because your ESPhome code has ‘internal: True’ which prevents the device from exposing this entity to HA.

‘Initial state’ is also configurable in ESPhome, your config lists ‘RESTORE_DEFAUL-OFF’. Now, I’m not sure (since I’ve never tried) as to whether or no this can be made to use a HA selector or not.

1 Like

While I see ESPHome as my preferred platform going forward, I really am still just a beginner with it.

I know that I will have to dive into it (rather than just the brief skims to copy/paste bits of code which i have done so far) for much to stick in my old brain.

I am looking at a small home greenhouse project which I know one of my RasPis will handle easily - however it may be appropriate for ESPHome

FWIW, I noticed that the Arlec PC191HA has not been added to the list of devices on esphome.io, so thought I would have a go at adding it.

UPDATE: it is now available at https://github.com/esphome/esphome-devices/blob/dcd6b471222b5722022446b372b2810e2edfba17/src/docs/devices/Arlec-PC191HA-Plug/index.md

Following the guide I took a lot of the non-essential functionality out of the esphome.io template, and i think the person who did the pull simplified it further. I am now updating my version with some of the simplifications (eg that the “id:” values are only used within the device’s own yaml, and so don’t need to differentiate between multiple devices of the same type).

I guess here is a good place to post my latest version with all the bells and whistles I found and thought useful - but also many of the simplifications:

#
# I have a number of Aulec PC191HA smart plugs with Power Monitoring,  
#     ESPHome guide says to use "name_add_mac_suffix: true" to automatically add the  
#     MAC address to the device name, so you can use a single firmware for all devices.  
# However, while MAC address is definitely unique, it is not at all intuitive,  
#     and since I already use static IP addresses, I append last octet of the device IP Address.  
#
substitutions:
  deviceIP: "109"                   # last octet of the IP Address

  friendly_name: pc191ha-${deviceIP}  # user-friendly devicename:
  device_name:   pc191ha_${deviceIP}       # the device_id as used by HomeAssistant, including IP suffix

  # the parameters used below (for ease of adjusting)
  restore_mode: RESTORE_DEFAULT_ON  # mode for when power is turned on
  update_interval: "30s"            # How often to measure and report energy values

esphome:
  name: $friendly_name

bk72xx:
  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: $friendly_name button
    id:   button
    device_class: window
    # when button is pressed, toggle the switch on/off
    on_press:
      then:
        - switch.toggle: relay  # toggle the relay / switch
    internal: True

light:                # LED in the button  (led1_pin: 26)
  - platform: status_led
    # name: $friendly_name Switch state
    id:   led
    pin: P26
    restore_mode: $restore_mode   # default when power is turned on 
    internal: True

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

#
# PC191HA sensors - power monitoring
#

sensor:
  - platform: wifi_signal         # report wi-fi signal strength from this end
    name: $friendly_name WiFi Signal
    id:   ${device_name}_wifi_signal
    update_interval: "120s"      # how often to report wifi signal strength

  - platform: uptime
    name: $friendly_name Uptime
    id:   ${device_name}_uptime
    update_interval: "120s"

    # PC191HA includes a BL0937 chip for measuring power consumption
    #     and BL0937 is a variation of hlw8012, but using inverted SEL pin functionality
    #     Note that the first value reported should be ignored as inaccurate
  - 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: $update_interval      # How often to measure and report values

    ### Decided that I want Power and Voltage reported each time (not swapping with Current).  
    # I can choose not to keep swapping SEL pin, instead setting change_mode_every to a
    #   sufficiently high value that it will take 4000 years to shange. 
    #   This means I will have to calculate the value for current (as a template) from power / voltage
    initial_mode: "VOLTAGE"           # reports VOLTAGE or CURRENT
    change_mode_every: 4294967295     # how many times to report before swapping

    # Adjust according to the actual resistor values on board to calibrate the specific unit
    voltage_divider:  770       # LOWER VALUE GIVES LOWER VOLTAGE
    current_resistor: 0.001     # HIGHER VALUE GIVES LOWER WATTAGE

    # how the power monitoring values are returned to ESPHome
    voltage:
      name: $friendly_name Voltage
      id:   voltage
      unit_of_measurement: V
      accuracy_decimals: 1
      filters:
        - skip_initial: 1

    power:
      name: $friendly_name Power
      id:   power
      unit_of_measurement: W
      accuracy_decimals: 1
      filters:
        - skip_initial: 1
        - multiply: 0.97
        - lambda: if (x < 0.01) {return 0;} else {return x;}

    energy:
      name: $friendly_name Energy
      unit_of_measurement: Wh
      accuracy_decimals: 1
      filters:
        - skip_initial: 1

# instead of alternating reporting Voltage and Current, I will report Current from a template 
#    current:
#      name: $friendly_name Current
#      unit_of_measurement: A
#      accuracy_decimals: 2
#      filters:
#        - skip_initial: 1
#        - multiply: 0.4250
#        - lambda: if (x < 0.01) {return 0;} else {return x;}
 
  - platform: template  
    name: $friendly_name Current
    unit_of_measurement: A
    accuracy_decimals: 2
    update_interval: $update_interval 
    lambda: |-
      return (id(power).state / id(voltage).state );
    filters:  
      - skip_initial: 2     # give time for data to settle to avoid NaN

2 Likes

I got a Series 2 Arlec Smart Plug with Energy Metering flashed with ESPHome.

My notes:

Product Name: Arlec White Grid Connect Smart Plug in Socket with Energy Meter
Product Code: PC191HA (White) & PC191BKHA (Black). “Series 2” (CB2S module, BK7231N chip)

Product Listing:

  1. White
  2. Black

Cloudcutter Guide Followed: UPDATED How To Guide - Tuya CloudCutter with ESPHome LibreTiny - No soldering | digiblurDIY
LibreTiny Support: CB2S - LibreTiny
LibreTiny Profile (Initial flash): UPK2ESPHome

Initial Impressions:

Pro’s:

  • ESPHome-able (via Cloudcutter and LibreTiny). No need to open to flash.
  • Small form factor (fit 2 side-by-side :white_check_mark:)
  • Power Monitoring
  • I like the button being on the top for access
  • Oz Certified (as opposed to the Athom I moved over to after the Kogan’s and Brilliant’s failed)
  • Dirt cheap at $15 AUD.

Con’s:

  • Possibly “disposable devices” - who knows how long they will last? Based on other cheap devices, maybe not that long. Caps are a common culprit.
  • The end to end flash pipeline is still a little involved even though it’s wireless. Expect a Tuya convert style flash. The instructions are pretty good. When I hit issues it was mainly because I wasn’t following them properly :wink:. After you’ve done one it would be way faster for subsequent devices.

TODO:

  1. More testing
  2. Optimise config.
  3. Long term review

Initial config is below. I copied / merged some stuff from the Athom config and bits from Don too.

# Config for Arlec White Grid Connect Smart Plug in Socket with Energy Meter 
# Product Code: PC191HA (White) & PC191BKHA (Black). “Series 2” (CB2S module, BK7231N chip)
# https://www.bunnings.com.au/arlec-white-grid-connect-smart-plug-in-socket-with-energy-meter_p0273367
# https://upk.libretiny.eu/?profile=arlec-pc191ha-smart-plug-bk7231n-v1.1.8
# Copied some config from Athom: https://github.com/athom-tech/athom-configs/blob/main/athom-smart-plug-v2.yaml

substitutions:
  relay_restore_mode: RESTORE_DEFAULT_OFF         #Adjust as required.
  hlw8012_update_interval: 10s                    #Not sure how this affects lifetime and maybe overheating? 
  
esphome:
  name: arlec-smartplug-1
  friendly_name: Arlec Smartplug 1
  comment: "Arlec Black Grid Connect Smart Plug in Socket with Energy Meter"  
bk72xx:
  board: generic-bk7231n-qfn32-tuya #https://docs.libretiny.eu/boards/cb2s/  
  
wifi:
  ap:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.1.80
    gateway: 192.168.1.1
    subnet: 255.255.255.0
    

logger:
mdns:
api:
  password: ""
ota:
  password: ""

globals:
  - id: total_energy
    type: float
    restore_value: yes
    initial_value: '0.0'
  
sensor:
  - platform: uptime
    name: Uptime
  - platform: wifi_signal
    name: "WiFi Signal"
    update_interval: 60s
    
  - platform: hlw8012
    model: BL0937
    update_interval: ${hlw8012_update_interval}
    change_mode_every: 3
    voltage_divider: 770 #Required changing
    current_resistor: 0.001 ohm
    cf_pin:
      number: P8
      inverted: true
    cf1_pin:
      number: P7
      inverted: true
    sel_pin:
      number: P6
      inverted: true
    current:
      name: Current
      filters:
        - multiply: 0.4250 #https://community.home-assistant.io/t/esphome-install-does-not-update-firmware/544026/10?u=mahko_mahko
        - lambda: if (x < 0.01) {return 0;} else {return x;}
    voltage:
      name: Voltage
    power:
      name: Power
      id: power_sensor
      filters:
        - multiply: 0.97
        - lambda: if (x < 0.01) {return 0;} else {return x;}
    energy:
      name: Energy
      id: energy
      unit_of_measurement: kWh
      filters:
        - multiply: 0.001  # Multiplication factor from W to kW is 0.001
      on_value:
        then:
          - lambda: |-
              static float previous_energy_value = 0.0;
              float current_energy_value = id(energy).state;
              id(total_energy) += current_energy_value - previous_energy_value;
              previous_energy_value = current_energy_value;
              
  - platform: template
    name: "Total Energy"
    unit_of_measurement: kWh
    device_class: "energy"
    state_class: "total_increasing"
    icon: "mdi:lightning-bolt"
    accuracy_decimals: 3
    lambda: |-
      return id(total_energy);
    update_interval: ${hlw8012_update_interval}
    
  - platform: total_daily_energy
    name: "Total Daily Energy"
    restore: true
    power_id: power_sensor
    unit_of_measurement: kWh
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    
output:
  - platform: libretiny_pwm
    id: output_led_1
    pin:
      number: P23
      inverted: true

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_multi_click:
      - timing:
          - ON for at most 1s
          - OFF for at least 0.2s
        then:
          - switch.toggle: switch_1
      - timing:
          - ON for at least 4s
        then:
          - button.press: Reset

switch:
  - platform: gpio
    id: switch_1
    name: Relay 1
    pin: P24
    on_turn_on:
      - light.turn_on: light_switch_1
    on_turn_off:
      - light.turn_off: light_switch_1
    restore_mode: ${relay_restore_mode}

status_led:
  pin:
    number: P26
    inverted: true
    
text_sensor:
  - platform: libretiny
    version:
      name: LibreTiny Version
  - platform: wifi_info
    ip_address:
      name: "IP Address"
    ssid:
      name: "Connected SSID"
    mac_address:
      name: "Mac Address"
      
button:
  - platform: factory_reset
    name: "Restart with Factory Default Settings"
    id: Reset

  - platform: safe_mode
    name: "Safe Mode"
    internal: false
    
time:
  - platform: sntp
    id: sntp_time
5 Likes

I reckon these features are probably defined at the software level and can be implemented on any smart plug running ESPHome?

Yeah. After a year I have had three of the Arlec IP44 versions die recently (only one of which was outside). All with same symptoms - they start to cycle on/off rapidly, which is not great for anything that might be connected to them plus caused a Tuya based device that was plugged into one of them to reset. Part of me is thinking about pulling them apart and working out what has gone to silicon heaven, but the other part of me is planning to just bin them.

1 Like

It’s worth popping one open and seeing if you can spot bulged capacitors:

In converting these devices to TuyaLocal I listed the dp_ids, which included a couple I didn’t implement:

  • dp_id 9 is countdown (toggle the switch after x minutes ?). This could be useful, but I am already doing that in my Node-RED automations. This seems to map to LocalTuya’s timer attribute.
  • dp_id 26 is fault, with valid values ov_cr, ov_vol, ov_pwr, ls_cr, ls_vol, and ls_pow. I think this maps to LocalTuya’s error and currently returns “off”, but not sure what I would actually do with a different value - after all I would only be looking at it when I know it’s not working :wink:

In LocalTuya HA integration (for the devices i haven’t upgraded yet)

  • child_lock is showing “unknown”, and well, I have no children
  • overcharge_cutoff (battery charging has finished ?) is showing “unknown”

On the other hand, I found ESPHome’s uptime, wifi_signal, restart and firmware to be relevant and useful :wink:

1 Like

Good point - I admit I was being lazy. Just cracked one PC44HA open, and all the caps were visually ok ie no bulges etc. If I can be bothered I’ll take out the capacitors and test them one at a time - assumption being if I find a bad one, it will be common on all the switches.

1 Like

Where did you source this from BTW? Some kind of calibration I take it?

Yes … good question … but from where …
Found it over at Esphome install does not update firmware - #10 by Ellcon said

Of course I don’t know how much variation there may be between individual units … but personally I only want to know whether my chest freezer is running or not.


Personally I would like to standardise on zigbee for any future device purchases, and so I haven’t bought a PC191HA v2 unit yet … but I do agree the Pro’s you mention are compelling - and nothing in zigbee that comes close :frowning:

I am interested to compare your configuration, and try out any differences … though of course they are likely to be added functionality in the CB2S chip.

1 Like

All the extra’s I’ve added shouldn’t depend on the CB2S (most of it I pinched from the Anthom config which is another chip altogether (ESP8266). It’s all ESPHome level stuff.
You might like to look over adopting the “Total Energy” and “Total Daily Energy” for example.

I’ve also updated my config to include some of those calibrations and other bits.

I looked into Tuya’s dp_id 17 add_ele and discovered that it reports incremental power used since the last time it was reported … so particularly dependent on frequency of reporting (when my devices were dropping off my wi-fi) and that all values are captured and database updated (at the time I was getting ingress errors in my log).

And the history from one of my TP-Link HS110’s using TP-Link KASA integration (looks similar to Tuya) doesn’t inspire confidence…

However I have nothing to loose by trying out the ESPHome / PC191HA Energy values :smiley: thanks

Wow, the firmware might be the same, but your CB2S chip’s pin numbering is way different from my WB2S chip !
Also I’m not seeing where status_led is used

Compiled with only one section commented out - I’ll come back to that later.
Installed, and device rebooted with firmware compiled 2 days ago … so no change to the unwritten “power off for a random time to get PC191HA to activate the uploaded firmware”. Further testing tomorrow…

1 Like

Not entirely sure myself but seem to recall both red and blue led flashes when I was in the initial flashing process.
So probably the blue one is used for regular state indications and the red one for “warnings”. This could possibly be specific to my plug version.

I understand that the version 1 of PC191HA has 2 LEDs - the one we can see in the button, and apparently another inside the case which the factory uses to indicates the wi-fi status. Since I don’t want to open any up (at least while still under warranty) I never bothered programming it - what is the point of giving a visual indication that can’t be seen ?

My guess is that the “status_led” may refer to that internal LED, and so it doesn’t matter if nothing is using it. Of course assuming that v2 is the same as v1 :wink:

1 Like

I got another 4 of these flashed without much drama. Much easier and faster after you’ve done your first.

There’s an opportunity to use these things as ble scanners (or bluetooth proxies?).

But I know those things are memory intensive, so maybe not a good idea.

I had a go at using a common config using include.

In the devices yaml (arlec-smartplug-3.yaml)

<<: !include .arlec-smartplug-common.yaml
  
esphome:
  name: arlec-smartplug-3
  friendly_name: Arlec Smartplug 3
  comment: "Arlec White Grid Connect Smart Plug in Socket with Energy Meter"  
 
wifi:
  ap:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.1.131
    gateway: 192.168.1.1
    subnet: 255.255.255.0

in .arlec-smartplug-common.yaml

# Config for Arlec White Grid Connect Smart Plug in Socket with Energy Meter 
# Product Code: PC191HA (White) & PC191BKHA (Black). “Series 2” (CB2S module, BK7231N chip)
# https://www.bunnings.com.au/arlec-white-grid-connect-smart-plug-in-socket-with-energy-meter_p0273367
# https://upk.libretiny.eu/?profile=arlec-pc191ha-smart-plug-bk7231n-v1.1.8
# Copied some config from Athom: https://github.com/athom-tech/athom-configs/blob/e9d1218fe0d8b4631cda211d204dd3ff5ac698be/athom-smart-plug-v2.yaml

substitutions:
  relay_restore_mode: RESTORE_DEFAULT_OFF         #Adjust as required.
  hlw8012_update_interval: 30s                    #Not sure how this affects lifetime and maybe overheating? 
  

bk72xx:
  board: generic-bk7231n-qfn32-tuya #https://docs.libretiny.eu/boards/cb2s/  

logger:
mdns:
api:
  password: ""
ota:
  password: ""

globals:
  - id: total_energy
    type: float
    restore_value: yes
    initial_value: '0.0'
  
sensor:
  - platform: uptime
    name: Uptime
  - platform: wifi_signal
    name: "WiFi Signal"
    update_interval: 60s
    
  - platform: hlw8012
    model: BL0937
    update_interval: ${hlw8012_update_interval}
    change_mode_every: 3
    voltage_divider: 770 #Required changing
    current_resistor: 0.001 ohm
    cf_pin:
      number: P8
      inverted: true
    cf1_pin:
      number: P7
      inverted: true
    sel_pin:
      number: P6
      inverted: true
    current:
      name: Current
      filters:
        - multiply: 0.4250 #https://community.home-assistant.io/t/esphome-install-does-not-update-firmware/544026/10?u=mahko_mahko
        - lambda: if (x < 0.01) {return 0;} else {return x;}
    voltage:
      name: Voltage
    power:
      name: Power
      id: power_sensor
      filters:
        - multiply: 0.97
        - lambda: if (x < 0.01) {return 0;} else {return x;}
    energy:
      name: Energy
      id: energy
      unit_of_measurement: kWh
      filters:
        - multiply: 0.001  # Multiplication factor from W to kW is 0.001
      on_value:
        then:
          - lambda: |-
              static float previous_energy_value = 0.0;
              float current_energy_value = id(energy).state;
              id(total_energy) += current_energy_value - previous_energy_value;
              previous_energy_value = current_energy_value;
              
  - platform: template
    name: "Total Energy"
    unit_of_measurement: kWh
    device_class: "energy"
    state_class: "total_increasing"
    icon: "mdi:lightning-bolt"
    accuracy_decimals: 3
    lambda: |-
      return id(total_energy);
    update_interval: ${hlw8012_update_interval}
    
  - platform: total_daily_energy
    name: "Total Daily Energy"
    restore: true
    power_id: power_sensor
    unit_of_measurement: kWh
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    
output:
  - platform: libretiny_pwm
    id: output_led_1
    pin:
      number: P23
      inverted: true

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_multi_click:
      - timing:
          - ON for at most 1s
          - OFF for at least 0.2s
        then:
          - switch.toggle: switch_1
      - timing:
          - ON for at least 4s
        then:
          - button.press: Reset

switch:
  - platform: gpio
    id: switch_1
    name: Relay 1
    pin: P24
    on_turn_on:
      - light.turn_on: light_switch_1
    on_turn_off:
      - light.turn_off: light_switch_1
    restore_mode: ${relay_restore_mode}

status_led:
  pin:
    number: P26
    inverted: true
    
text_sensor:
  - platform: libretiny
    version:
      name: LibreTiny Version
  - platform: wifi_info
    ip_address:
      name: "IP Address"
    ssid:
      name: "Connected SSID"
    mac_address:
      name: "Mac Address"
      
button:
  - platform: factory_reset
    name: "Restart with Factory Default Settings"
    id: Reset

  - platform: safe_mode
    name: "Safe Mode"
    internal: false
    
time:
  - platform: sntp
    id: sntp_time

I just bought a 4-pack of the PC191HA version 2, and can confirm that the Blue LED is used to indicate the switch’s ON/OFF state, and a Red LED blinks fast or slow to indicate that it is pairing.

I also found that all 4 of my devices took at least 3 attempts before they paired. Curiously the device’s LED would often stop blinking at about 1:50 on the countdown, but most often the Grid Connect app would simply time out. The MAC addresses were not consecutive, and all have firmware 1.3.5

I did have a go at this before, but didn’t get it to work. Thank you for showing the correct split between include and device.yaml. YES, working nicely … except that the v1 and v2 devices use different pin numbers … maybe i can nest includes.

I recall mine were a bit fiddly too.

I think putting them in pairing mode was a bit confusing.

Not sure if I even connected mine to an app. I don’t think so. Or maybe just the first one.

I got my include streamlined a bit further actually.

For each device:

E.g
arlec-smartplug-2.yaml

substitutions:
  static_ip_last_3chars: "130"
  plug_number: "2"
  plug_colour:  "White"

packages:
  device_base: !include common/.arlec-smartplug-common.yaml

in .arlec-smartplug-common.yaml

# Config for Arlec White Grid Connect Smart Plug in Socket with Energy Meter 
# Product Code: PC191HA (White) & PC191BKHA (Black). “Series 2” (CB2S module, BK7231N chip)
# https://www.bunnings.com.au/arlec-white-grid-connect-smart-plug-in-socket-with-energy-meter_p0273367
# https://upk.libretiny.eu/?profile=arlec-pc191ha-smart-plug-bk7231n-v1.1.8
# Copied some config from Athom: https://github.com/athom-tech/athom-configs/blob/babced13aaa8462361d6f4100430cf8be95f193a/athom-smart-plug-v2.yaml

substitutions:
  relay_restore_mode: RESTORE_DEFAULT_OFF         #Adjust as required.
  hlw8012_update_interval: 30s                    #Not sure how this affects lifetime and maybe overheating? 
  static_ip_last_3chars: "xxx"
  plug_number: "xxx"
  plug_colour:  "xxx"


esphome:
  name: arlec-smartplug-${plug_number}
  friendly_name: Arlec Smartplug ${plug_number}
  comment: Arlec ${plug_colour} Grid Connect Smart Plug in Socket with Energy Meter 
  
wifi:
  ap:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.1.${static_ip_last_3chars}
    gateway: 192.168.1.1
    subnet: 255.255.255.0


bk72xx:
  board: generic-bk7231n-qfn32-tuya #https://docs.libretiny.eu/boards/cb2s/  

logger:
mdns:
api:
  password: ""
ota:
  password: ""

globals:
  - id: total_energy
    type: float
    restore_value: yes
    initial_value: '0.0'
  
sensor:
  - platform: uptime
    name: Uptime
  - platform: wifi_signal
    name: "WiFi Signal"
    update_interval: 60s
    
  - platform: hlw8012
    model: BL0937
    update_interval: ${hlw8012_update_interval}
    change_mode_every: 3
    voltage_divider: 770 #Required changing
    current_resistor: 0.001 ohm
    cf_pin:
      number: P8
      inverted: true
    cf1_pin:
      number: P7
      inverted: true
    sel_pin:
      number: P6
      inverted: true
    current:
      name: Current
      filters:
        - multiply: 0.4250 #https://community.home-assistant.io/t/esphome-install-does-not-update-firmware/544026/10?u=mahko_mahko
        - lambda: if (x < 0.01) {return 0;} else {return x;}
    voltage:
      name: Voltage
    power:
      name: Power
      id: power_sensor
      filters:
        - multiply: 0.97
        - lambda: if (x < 0.01) {return 0;} else {return x;}
    energy:
      name: Energy
      id: energy
      unit_of_measurement: kWh
      filters:
        - multiply: 0.001  # Multiplication factor from W to kW is 0.001
      on_value:
        then:
          - lambda: |-
              static float previous_energy_value = 0.0;
              float current_energy_value = id(energy).state;
              id(total_energy) += current_energy_value - previous_energy_value;
              previous_energy_value = current_energy_value;
              
  - platform: template
    name: "Total Energy"
    unit_of_measurement: kWh
    device_class: "energy"
    state_class: "total_increasing"
    icon: "mdi:lightning-bolt"
    accuracy_decimals: 3
    lambda: |-
      return id(total_energy);
    update_interval: ${hlw8012_update_interval}
    
  - platform: total_daily_energy
    name: "Total Daily Energy"
    restore: true
    power_id: power_sensor
    unit_of_measurement: kWh
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    
output:
  - platform: libretiny_pwm
    id: output_led_1
    pin:
      number: P23
      inverted: true

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_multi_click:
      - timing:
          - ON for at most 1s
          - OFF for at least 0.2s
        then:
          - switch.toggle: switch_1
      - timing:
          - ON for at least 4s
        then:
          - button.press: Reset

switch:
  - platform: gpio
    id: switch_1
    name: Relay 1
    pin: P24
    on_turn_on:
      - light.turn_on: light_switch_1
    on_turn_off:
      - light.turn_off: light_switch_1
    restore_mode: ${relay_restore_mode}

status_led:
  pin:
    number: P26
    inverted: true
    
text_sensor:
  - platform: libretiny
    version:
      name: LibreTiny Version
  - platform: wifi_info
    ip_address:
      name: "IP Address"
    ssid:
      name: "Connected SSID"
    mac_address:
      name: "Mac Address"
      
button:
  - platform: factory_reset
    name: "Restart with Factory Default Settings"
    id: Reset

  - platform: safe_mode
    name: "Safe Mode"
    internal: false
    
time:
  - platform: sntp
    id: sntp_time