syssi / esphome-soyosource-gtn-virtual-meter

ESPHome component to simulate the current clamp to control the Soyosource GTN1200 limiter
Apache License 2.0
74 stars 20 forks source link

Which version I must install? #175

Closed Giro-S closed 3 weeks ago

Giro-S commented 1 month ago

Hi to all and a very big tank to Syssi and all other for tis great work! I have this inverter 1200W-Grid-Tie-Solar-Inverter-with-WIFI-Sine-Wave-Home-Inverter-with-MPPT-and-Limiter-CE

I use a Wemos D1 Mini, not original wifi stick, but exactly wich version I must install?

I've connected wemos to inverter USB port and installed esp8266-display-wifi-version-limiter-example.yaml All works but not limiter connected directly to inverter I have also connected inverter rs485 to wemos throught adapter (rs485 to serial ttl) but it does not work :/

Can anyone help to configure correctly wemos? Thank you very much

syssi commented 1 month ago

You are on the right track. Could you make a photo of your wiring and provide your YAML configuration? I would like to make sure the RS485 converter is connected to the configured GPIOs etc.

display-port-wifi-version-plus-limiter

Giro-S commented 1 month ago

Tank you syssi! Senza titolo 20240524_074833 20240524_074845

Sorry for "fast draw"

The schema is: inverter USB port to wemos GPIO4 and 5 ...and ground inverter RS485 to converter

tis is the code:

substitutions:
  name: "gestione-inverter-notte"
  device_description: "Monitor and control the Soyosource GTN (WiFi version) via the display port and control the power output on demand via RS485"
  external_components_source: github://syssi/esphome-soyosource-gtn-virtual-meter@main
  # The display port should be connected to these GPIOs using a USB connector (VCC, RX, TX, GND)
  # A optocoupler / optical isolator (f.e. ADUM1201) between the display port and the ESP is recommended if the ESP isn't powered by the display port!
  tx_pin_ttl_wifi: GPIO4
  rx_pin_ttl_wifi: GPIO5
  tx_pin_rs485: GPIO12
  rx_pin_rs485: GPIO14

esphome:
  name: ${name}
  comment: ${device_description}
  project:
    name: "syssi.esphome-soyosource-gtn-virtual-meter"
    version: 2.1.0

esp8266:
  board: d1_mini

external_components:
  - source: ${external_components_source}
    refresh: 0s

logger:
  level: INFO

# If you use Home Assistant please remove this `mqtt` section and uncomment the `api` component!
# The native API has many advantages over MQTT: https://esphome.io/components/api.html#advantages-over-mqtt
mqtt:
  broker: xxxx
  username: xxxxx
  password: xxxxx
  #id: mqtt_client

api:
  encryption:
    key: "xxxx"

ota:

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "xxxxx"
    password: "xxxxx"

uart:
  - id: uart_0
    baud_rate: 9600
    tx_pin: ${tx_pin_ttl_wifi}
    rx_pin: ${rx_pin_ttl_wifi}

  - id: uart_1
    baud_rate: 4800
    tx_pin: ${tx_pin_rs485}
    rx_pin: ${rx_pin_rs485}

soyosource_modbus:
  - id: modbus0
    uart_id: uart_1
    # flow_control_pin: GPIO12

    # Optional settings
    #
    # The name is used as prefix for some log messages and should
    # help to distinguish between different instances/devices
    name: inverter_notte

soyosource_virtual_meter:
  - id: virtualmeter0
    soyosource_modbus_id: modbus0

    # The state of this sensor (instantaneous power in watt) is used as source
    power_id: powermeter0

    # Optional settings
    power_sensor_inactivity_timeout: 20s
    power_demand_calculation: NEGATIVE_MEASUREMENTS_REQUIRED
    min_power_demand: 0
    max_power_demand: 900
    zero_output_on_min_power_demand: true
    # Split/distribute the power demand if you have multiple inverters attached to the same RS485 bus
    power_demand_divider: 1
    # A positive buffer value (10) tries to avoid exporting power to the grid (demand - 10 watts)
    # A negative buffer value (-10) exports power to the grid (demand + 10 watts)
    buffer: 10
    # The operation_status_id sensor is expected here. Passing the operation_status won't work
    # The state is used to suspend the limiter if the operation status of the inverter isn't 0x0 (normal)
    operation_status_id: operation_status_id0

    # The update interval is important and defaults to 3 seconds. If the demand is sent too frequently
    # or rarely the interverter stops. TODO: Identify and validate the lower and upper update limit
    update_interval: 3s

soyosource_display:
  - id: display0
    uart_id: uart_0
    protocol_version: SOYOSOURCE_WIFI_VERSION
    update_interval: 5s

binary_sensor:
  - platform: soyosource_display
    fan_running:
      name: "${name} fan running"
    limiter_connected:
      name: "${name} limiter connected"

button:
  - platform: soyosource_display
    restart:
      name: "${name} restart"

number:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    buffer:
      name: "${name} buffer"
      initial_value: 10
      restore_value: true
    manual_power_demand:
      name: "${name} manual power demand"
      max_value: 900
    max_power_demand:
      name: "${name} max power demand"
      initial_value: 200
      max_value: 900
      restore_value: true
    power_demand_divider:
      name: "${name} power demand divider"
      initial_value: 1
      restore_value: true

  - platform: soyosource_display
    start_voltage:
      name: "${name} start voltage"
    shutdown_voltage:
      name: "${name} shutdown voltage"
    # Maximum output power in limiter mode / Output power in constant power mode
    output_power_limit:
      name: "${name} output power limit"
    start_delay:
      name: "${name} start delay"

select:
  - platform: soyosource_display
    operation_mode:
      name: "${name} operation mode"
      optionsmap:
        1: "PV"
        2: "Battery Constant Power"
        17: "PV Limit"
        18: "Battery Limit"

sensor:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    power_demand:
      name: "${name} power demand"

  - platform: soyosource_display
    error_bitmask:
      name: "${name} error bitmask"
    operation_mode_id:
      name: "${name} operation mode id"
    operation_status_id:
      name: "${name} operation status id"
      id: operation_status_id0
    battery_voltage:
      name: "${name} battery voltage"
    battery_current:
      name: "${name} battery current"
    battery_power:
      name: "${name} battery power"
    ac_voltage:
      name: "${name} ac voltage"
    ac_frequency:
      name: "${name} ac frequency"
    temperature:
      name: "${name} temperature"
    output_power:
      name: "${name} output power"

  # mqtt subscribe example
#  - id: powermeter0
#    internal: true
#    platform: mqtt_subscribe
#    name: "${name} instantaneous power consumption"
#    topic: "smartmeter/sensor/smartmeter/obis/1-0:16.7.0/255/value"
#    accuracy_decimals: 2
#    unit_of_measurement: W
#    device_class: power
#    filters:
#      - throttle_average: 15s

#   # import smartmeter reading from homeassistant
#   # requires the "api" component see above
  - platform: homeassistant
    id: powermeter0
    name: "${name} smartmeter instantaneous power"
    entity_id: sensor.sonoff_1001553f47_power
    filters:
      - throttle_average: 15s

switch:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    manual_mode:
      name: "${name} manual mode"
      restore_mode: RESTORE_DEFAULT_ON
    emergency_power_off:
      name: "${name} emergency power off"
      restore_mode: RESTORE_DEFAULT_OFF

text_sensor:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    operation_mode:
      name: "${name} limiter operation mode"

  - platform: soyosource_display
    errors:
      name: "${name} errors"
    operation_mode:
      name: "${name} operation mode"
    operation_status:
      name: "${name} operation status"

Battery costant power works well but with limiter I don't understand which are the right parameters. In this case I use this istant meter (not reverse energy) ...but I bought a Tuya dual meter for this scope. images

I would like to use original power meter because I want use 3 inverters on parallel RS485 wires I don't understand the logical under settings. The original power meter is connected to the first, second and third inverter through RS485 ...is ok But how D1 mini is connected? Only through USB? In this case which versione I could use?

Another problem is: where must be place the CT and the inverter over the "house wires"? The istructions tell one thing, but other people tell another one.

In my case the first counter from grid is on long distance from inverters and I will use 2 RS485 to wifi converters (Elfin EW11A) and just tried them but the text string has some "not decoded" chars. (I must study it)

Ok ok very much questions and ....problems :-)

Thank you again!

syssi commented 1 month ago

Does the TX LED of your RS485 module blink periodically?

syssi commented 1 month ago

Battery constant power works well but with limiter I don't understand which are the right parameters.

If "constant power works" does it mean you have used the manual mode of this project to pass a constant power demand to the inverter or did you change the inverter settings to constant power?

syssi commented 1 month ago

In this case I use this istant meter (not reverse energy) ...but I bought a Tuya dual meter for this scope.

Let's try to get this project up and running first and lets discuss the different possible to drive the limiter later on.

Giro-S commented 1 month ago

Does the TX LED of your RS485 module blink periodically?

Yes, TX led blinks

If "constant power works" does it mean you have used the manual mode of this project to pass a constant power demand to the inverter or did you change the inverter settings to constant power? I selected "battery costant mode", I setted only "output power limit" (first item) and "manual mode" switch. It works well!

I have 3 D1 mini for 3 inverters and I've installed on all the same project. If I attach the original power meter to the inverter RS485 port, do I need the RS485 converter? I think no, right? Or do I must connect POWER_METER->RS485_CONVERTER->INVERTER? I don't understant this thing.

Thank you very much again PS: I love this project, if I can offer a beer to you, I'll be happy :)

syssi commented 1 month ago

If I attach the original power meter to the inverter RS485 port, do I need the RS485 converter? I think no, right?

If you use the original current clamp no converter is needed. The clamp should simply measure the current flow on some wire and tries to request this amount of power using RS485 at the inverter.

It's possible the original clamp doesn't do a good job because the clamp is unable to understand the direction of the current flow. For example if you feed 900W into the grid the clamp will measure the same power demand as if you import 900W from the grid.

This project avoids the original current clamp and passes a power demand retrieved using alternative measurement devices to the inverter.

syssi commented 1 month ago

I'm happy about any donation supporting this project:

https://paypal.me/syssi84 https://buymeacoffee.com/syssi

Giro-S commented 1 month ago

I'm happy about any donation supporting this project:

https://paypal.me/syssi84 https://buymeacoffee.com/syssi

OK!

If I attach the original power meter to the inverter RS485 port, do I need the RS485 converter? I think no, right?

If you use the original current clamp no converter is needed. The clamp should simply measure the current flow on some wire and tries to request this amount of power using RS485 at the inverter.

It's possible the original clamp doesn't do a good job because the clamp is unable to understand the direction of the current flow. For example if you feed 900W into the grid the clamp will measure the same power demand as if you import 900W from the grid.

This project avoids the original current clamp and passes a power demand retrieved using alternative measurement devices to the inverter.

Ok, I don't use original CT and Elfin converters, I bought this (next week I should receive it): 51-sW+hjAIL _AC_UF1000,1000_QL80_ Bidirectional meter, I will add through Tuya Local on Home assiatant (one clip of course) I will modify your(my) code with this and I hope that it works.

My goal is: use my 3 inverters in parallel (with 3 different 24V batteries) always on ...2100W max on demand (700x3). I think that need esp32 (D1 mini has poor performace) with RS485 to TTL converter AND connect in parallel to 3 inverters. I think need to add another SwSerial...

For this project I will need your precious help :) Thank you very much again!

syssi commented 1 month ago

This sounds like a good decision. Let me summarize your future setup:

  1. The tuya device will be installed next to your electricity meter to measure the energy imported from the grid.
  2. The tuya device will publish the measurements so they are available in Home Assistant
  3. One ESP will drive three inverters using the same RS485 bus. All inverters will be attached to the same RS485 converter.
  4. The ESP will receive the measurements of the tuya device via Home Assistant. F.e. if the tuya device reports a power demand of 300W the demand will be divided by 3 (because of the power_demand_divider: 3) setting. A power demand of 100W will be reported using RS485. Each attached inverter will ramp up and produce 300W in total.
Giro-S commented 1 month ago

This sounds like a good decision. Let me summarize your future setup:

  1. The tuya device will be installed next to your electricity meter to measure the energy imported from the grid.
  2. The tuya device will publish the measurements so they are available in Home Assistant
  3. One ESP will drive three inverters using the same RS485 bus. All inverters will be attached to the same RS485 converter.
  4. The ESP will receive the measurements of the tuya device via Home Assistant. F.e. if the tuya device reports a power demand of 300W the demand will be divided by 3 (because of the power_demand_divider: 3) setting. A power demand of 100W will be reported using RS485. Each attached inverter will ramp up and produce 300W in total.

Yes! :) Can you check if this configuration is right? I will use ESP32 Mini (dual core, 240 Mhz)

substitutions:
  name: soyosource-gtn-virtual-meter
  device_description: "Monitor multiple Soyosource GTNs and control the power output on demand both via RS485"
  device0: Inverter_0
  device1: Inverter_1
  device2: Inverter_2
  external_components_source: github://syssi/esphome-soyosource-gtn-virtual-meter@main
  tx_pin_ttl_wifi_uart_0: GPIO17
  rx_pin_ttl_wifi_uart_0: GPIO16
  tx_pin_ttl_wifi_uart_1: GPIO32
  rx_pin_ttl_wifi_uart_1: GPIO12
  tx_pin_ttl_wifi_uart_2: GPIO26
  rx_pin_ttl_wifi_uart_2: GPIO13
  tx_pin_rs485_uart_3: GPIO33
  rx_pin_rs485_uart_3: GPIO14

esphome:
  name: ${name}
  comment: ${device_description}
  project:
    name: "syssi.esphome-soyosource-gtn-virtual-meter"
    version: 2.1.0

esp32:
  board: esp32dev
  framework:
    type: arduino

external_components:
  - source: ${external_components_source}
    refresh: 0s

#ethernet:
#  type: LAN8720
#  mdc_pin: GPIO23
#  mdio_pin: GPIO18
#  clk_mode: GPIO17_OUT
#  phy_addr: 0

ota:

logger:
  baud_rate: 0
  level: INFO

# If you use Home Assistant please remove this `mqtt` section and uncomment the `api` component!
# The native API has many advantages over MQTT: https://esphome.io/components/api.html#advantages-over-mqtt
mqtt:
  broker: !secret mqtt_host
  username: !secret mqtt_username
  password: !secret mqtt_password
  id: mqtt_client

api:

uart:
  - id: uart_0
    baud_rate: 9600
    tx_pin: ${tx_pin_ttl_wifi_uart_0}
    rx_pin: ${rx_pin_ttl_wifi_uart_0}
  - id: uart_1
    baud_rate: 9600
    tx_pin: ${tx_pin_ttl_wifi_uart_1}
    rx_pin: ${rx_pin_ttl_wifi_uart_1}
  - id: uart_2
    baud_rate: 9600
    tx_pin: ${tx_pin_ttl_wifi_uart_2}
    rx_pin: ${rx_pin_ttl_wifi_uart_2}
  - id: uart_3
    baud_rate: 4800
    tx_pin: ${tx_pin_rs485_uart_3}
    rx_pin: ${rx_pin_rs485_uart_3}

soyosource_modbus:
  - id: modbus0
    uart_id: uart_3
    # flow_control_pin: GPIO12
    # The name is used as prefix for some log messages and should
    # help to distinguish between different instances/devices
    name: Inverter_0
  - id: modbus1
    uart_id: uart_3
    name: Inverter_1
    # flow_control_pin: GPIO13
  - id: modbus2
    uart_id: uart_3
    name: Inverter_2
    # flow_control_pin: GPIO13

soyosource_inverter:
  - id: inverter0
    soyosource_modbus_id: modbus0
  - id: inverter1
    soyosource_modbus_id: modbus1
  - id: inverter2
    soyosource_modbus_id: modbus2

soyosource_virtual_meter:
  - id: virtualmeter0
    soyosource_modbus_id: modbus0
    update_interval: 3s

    # the state of this sensor (instantaneous power in watt) is used as source
    power_id: powermeter0
    power_sensor_inactivity_timeout: 20s
    power_demand_calculation: NEGATIVE_MEASUREMENTS_REQUIRED
    min_power_demand: 0
    max_power_demand: 900
    zero_output_on_min_power_demand: true
    # A positive buffer value (10) tries to avoid exporting power to the grid (demand - 10 watts)
    # A negative buffer value (-10) exports power to the grid (demand + 10 watts)
    buffer: 10
    # The operation_status_id sensor is expected here. Passing the operation_status won't work
    # The state is used to suspend the limiter if the operation status of the inverter isn't 0x0 (normal)
    # operation_status_id: operation_status_id0

  - id: virtualmeter1
    soyosource_modbus_id: modbus1
    update_interval: 3s
    # the state of this sensor (instantaneous power in watt) is used as source
    power_id: powermeter1
    power_sensor_inactivity_timeout: 20s
    power_demand_calculation: NEGATIVE_MEASUREMENTS_REQUIRED
    min_power_demand: 0
    max_power_demand: 900
    zero_output_on_min_power_demand: true
    # A positive buffer value (10) tries to avoid exporting power to the grid (demand - 10 watts)
    # A negative buffer value (-10) exports power to the grid (demand + 10 watts)
    buffer: 10
    # The operation_status_id sensor is expected here. Passing the operation_status won't work
    # The state is used to suspend the limiter if the operation status of the inverter isn't 0x0 (normal)
    # operation_status_id: operation_status_id1

  - id: virtualmeter2
    soyosource_modbus_id: modbus2
    update_interval: 3s
    # the state of this sensor (instantaneous power in watt) is used as source
    power_id: powermeter2 
    power_sensor_inactivity_timeout: 20s
    power_demand_calculation: NEGATIVE_MEASUREMENTS_REQUIRED
    min_power_demand: 0
    max_power_demand: 900
    zero_output_on_min_power_demand: true
    # A positive buffer value (10) tries to avoid exporting power to the grid (demand - 10 watts)
    # A negative buffer value (-10) exports power to the grid (demand + 10 watts)
    buffer: 10
    # The operation_status_id sensor is expected here. Passing the operation_status won't work
    # The state is used to suspend the limiter if the operation status of the inverter isn't 0x0 (normal)
    # operation_status_id: operation_status_id1

binary_sensor:
  - platform: soyosource_inverter
    soyosource_inverter_id: inverter0
    fan_running:
      name: "${device0} fan running"
  - platform: soyosource_inverter
    soyosource_inverter_id: inverter1
    fan_running:
      name: "${device1} fan running"
  - platform: soyosource_inverter
    soyosource_inverter_id: inverter2
    fan_running:
      name: "${device2} fan running"

number:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    buffer:
      name: "${device0} buffer"
      initial_value: 10
      restore_value: true
    manual_power_demand:
      name: "${device0} manual power demand"
    max_power_demand:
      name: "${device0} max power demand"
      initial_value: 600
      restore_value: true
    power_demand_divider:
      name: "${device0} power demand divider"
      initial_value: 3
      restore_value: true

  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter1
    buffer:
      name: "${device1} buffer"
      initial_value: 10
      restore_value: true
    manual_power_demand:
      name: "${device1} manual power demand"
    max_power_demand:
      name: "${device1} max power demand"
      initial_value: 600
      restore_value: true
    power_demand_divider:
      name: "${device1} power demand divider"
      initial_value: 3
      restore_value: true

  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter2
    buffer:
      name: "${device2} buffer"
      initial_value: 10
      restore_value: true
    manual_power_demand:
      name: "${device2} manual power demand"
    max_power_demand:
      name: "${device2} max power demand"
      initial_value: 600
      restore_value: true
    power_demand_divider:
      name: "${device2} power demand divider"
      initial_value: 3
      restore_value: true

sensor:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    power_demand:
      name: "${device0} power demand"
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter1
    power_demand:
      name: "${device1} power demand"
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter2
    power_demand:
      name: "${device2} power demand"

  - platform: soyosource_inverter
    soyosource_inverter_id: inverter0
    operation_status_id:
      name: "${device0} operation status id"
      id: operation_status_id0
    battery_voltage:
      name: "${device0} battery voltage"
    battery_current:
      name: "${device0} battery current"
    battery_power:
      name: "${device0} battery power"
    ac_voltage:
      name: "${device0} ac voltage"
    ac_frequency:
      name: "${device0} ac frequency"
    temperature:
      name: "${device0} temperature"
  - platform: soyosource_inverter
    soyosource_inverter_id: inverter1
    operation_status_id:
      name: "${device1} operation status id"
      id: operation_status_id1
    battery_voltage:
      name: "${device1} battery voltage"
    battery_current:
      name: "${device1} battery current"
    battery_power:
      name: "${device1} battery power"
    ac_voltage:
      name: "${device1} ac voltage"
    ac_frequency:
      name: "${device1} ac frequency"
    temperature:
      name: "${device1} temperature"
  - platform: soyosource_inverter
    soyosource_inverter_id: inverter2
    operation_status_id:
      name: "${device2} operation status id"
      id: operation_status_id1
    battery_voltage:
      name: "${device2} battery voltage"
    battery_current:
      name: "${device2} battery current"
    battery_power:
      name: "${device2} battery power"
    ac_voltage:
      name: "${device2} ac voltage"
    ac_frequency:
      name: "${device2} ac frequency"
    temperature:
      name: "${device2} temperature"

  # mqtt subscribe example
  #- id: powermeter0
  #  internal: true
  #  platform: mqtt_subscribe
  #  name: "${device0} instantaneous power consumption"
  #  topic: "smartmeter/sensor/firstfloor/obis/1-0:16.7.0/255/value"
  #  accuracy_decimals: 2
  #  unit_of_measurement: W
  #  device_class: power
  #  filters:
  #    - throttle_average: 15s

  #- id: powermeter1
  #  internal: true
  #  platform: mqtt_subscribe
  #  name: "${device1} instantaneous power consumption"
  #  topic: "smartmeter/sensor/groundfloor/obis/1-0:16.7.0/255/value"
  #  accuracy_decimals: 2
  #  unit_of_measurement: W
  #  device_class: power
  #  filters:
  #    - throttle_average: 15s

   # import smartmeter reading from homeassistant f.e.
   # requires the "api" component see above
   - platform: homeassistant
    id: powermeter0
    name: "${device0} smartmeter instantaneous power"
    entity_id: sensor.to_define_local_tuya_same_as_power_meter_1_and_2

  - platform: homeassistant
    id: powermeter1
    name: "${device1} smartmeter instantaneous power"
    entity_id: sensor.to_define_local_tuya_same_as_power_meter_0_and_2

  - platform: homeassistant
    id: powermeter2
    name: "${device2} smartmeter instantaneous power"
    entity_id: sensor.to_define_local_tuya_same_as_power_meter_0_and_1

switch:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    manual_mode:
      name: "${device0} manual mode"
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter1
    manual_mode:
      name: "${device1} manual mode"
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter2
    manual_mode:
      name: "${device2} manual mode"

text_sensor:
  - platform: soyosource_inverter
    soyosource_inverter_id: inverter0
    operation_status:
      name: "${device0} operation status"
  - platform: soyosource_inverter
    soyosource_inverter_id: inverter1
    operation_status:
      name: "${device1} operation status"
  - platform: soyosource_inverter
    soyosource_inverter_id: inverter2
    operation_status:
      name: "${device2} operation status"

  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    operation_mode:
      name: "${device0} limiter operation mode"
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter1
    operation_mode:
      name: "${device1} limiter operation mode"
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter2
    operation_mode:
      name: "${device2} limiter operation mode"

Thank you again

syssi commented 1 month ago
esp32:
  board: esp32dev
  framework:
    type: arduino

I prefer the ESP-IDF framework over arduino. It adds less overhead to the project.

uart:
  - id: uart_0
    baud_rate: 9600
    tx_pin: ${tx_pin_ttl_wifi_uart_0}
    rx_pin: ${rx_pin_ttl_wifi_uart_0}
  - id: uart_1
    baud_rate: 9600
    tx_pin: ${tx_pin_ttl_wifi_uart_1}
    rx_pin: ${rx_pin_ttl_wifi_uart_1}
  - id: uart_2
    baud_rate: 9600
    tx_pin: ${tx_pin_ttl_wifi_uart_2}
    rx_pin: ${rx_pin_ttl_wifi_uart_2}
  - id: uart_3
    baud_rate: 4800
    tx_pin: ${tx_pin_rs485_uart_3}
    rx_pin: ${rx_pin_rs485_uart_3}

A ESP32 supports 3 hardware UARTs in total. SoftwareSerial isn't available here. Using 4 UARTs won't be possible AFAIK.

soyosource_virtual_meter:
  - id: virtualmeter0
    soyosource_modbus_id: modbus0
    update_interval: 3s

    # the state of this sensor (instantaneous power in watt) is used as source
    power_id: powermeter0
    power_sensor_inactivity_timeout: 20s
    power_demand_calculation: NEGATIVE_MEASUREMENTS_REQUIRED
    min_power_demand: 0
    max_power_demand: 900
    zero_output_on_min_power_demand: true
    # A positive buffer value (10) tries to avoid exporting power to the grid (demand - 10 watts)
    # A negative buffer value (-10) exports power to the grid (demand + 10 watts)
    buffer: 10
    # The operation_status_id sensor is expected here. Passing the operation_status won't work
    # The state is used to suspend the limiter if the operation status of the inverter isn't 0x0 (normal)
    # operation_status_id: operation_status_id0

Please use a single soyosource_virtual_meter instance because you want to drive all three inverters simultaneously.

Giro-S commented 1 month ago

I prefer the ESP-IDF framework over arduino. It adds less overhead to the project.

How to do this? I've installed ESPHome with usb cable and adopt in home assistant, that is an automatic written

A ESP32 supports 3 hardware UARTs in total. SoftwareSerial isn't available here. Using 4 UARTs won't be possible AFAIK.

Noooo, just now I read this, SWSerial is avaible only on esp8266 :/ Three option remaining: 1-use D1mini with GPIO 1,3 4,5 14,12 13,15 (will it work? don't know) 2-use Esp8266 NodeMCU with more GPIOs 3-use Esp32 with this https://esphome.io/components/weikai.html DFR0627

Please use a single soyosource_virtual_meter instance because you want to drive all three inverters simultaneously.

Ok!

syssi commented 1 month ago

1-use D1mini with GPIO 1,3 4,5 14,12 13,15 (will it work? don't know)

You have to make sure to disable the logger on GPIO1/3 by setting the baud_rate to 0.

2-use Esp8266 NodeMCU with more GPIOs

The number of GPIOs aren't the limiting factor probably. Maintaining 3 SoftwareSerial interfaces is heavy for a ESP8266.

3-use Esp32 with this

This looks like a good choice. I've no experience with this specific board. It looks like the component does expose the additional UARTs as regular UartDevice istances so it should work out of the box.

syssi commented 1 month ago

Just use

esp32:
  board: esp32dev
  framework:
    type: esp-idf

instead of

esp32:
  board: esp32dev
  framework:
    type: arduino

to change the framework + compile & flash again as always.

Giro-S commented 1 month ago

You have to make sure to disable the logger on GPIO1/3 by setting the baud_rate to 0.

Yes, logger must be disabled

The number of GPIOs aren't the limiting factor probably. Maintaining 3 SoftwareSerial interfaces is heavy for a ESP8266.

I think so too, but some GPIOs on D1mini do not react as you expect, I will try with this board and old nodemcu that I have somewhere

This looks like a good choice. I've no experience with this specific board. It looks like the component does expose the additional UARTs as regular UartDevice istances so it should work out of the box.

I've just bought 2 modules :) (hope next week will be here) Thank for to change framework and all

Sorry for another question:

Please use a single soyosource_virtual_meter instance because you want to drive all three inverters simultaneously.

If I use single virtual meter I can't drive each inverter, right? With three virtual meter If I want drive all three inverters simultaneously AND drive each one separately I can set auto on two inverters and manual on third and all other combinations (f.e. if third battery is down) ...or is this another thing?

syssi commented 1 month ago

If I use single virtual meter I can't drive each inverter, right? With three virtual meter If I want drive all three inverters simultaneously AND drive each one separately I can set auto on > two inverters and manual on third and all other combinations (f.e. if third battery is down) ...or is this another thing?

If you attach all inverters to the same RS485 bus all devices gets the same instructions. The inverters cannot be addressed using device addresses or something. It's more like a broadcast. The ESP broadcasts "please produce 100W". If a single inverter is attached to the bus 100W will be produced. If three inverteres will receive the message each inverter will produce 100W and you will receive 300W in total.

If you attach three RS485 converters to the ESP to have 3 independent busses you can drive each inverter individually using a virtual meter instance per device.

Giro-S commented 1 month ago

Thank, I understood you but look this scenario:

esp32/8266 -->TTL --> inverter0
          |    |----> inverter1
          |    |----> inverter2
          |
          |-------->RS485-->inverter0-->inverter1-->inverter2

With one virtual meter I have only one item for three inverters for: buffer manual power demand max power demand power demand divider power demand manual mode limiter operation mode

With three virtual meter I can: -set inverter0 and inverter1 on Auto and Battery limit, they will receive commands through RS485 -set inverter2 on Manual and battery costant power, it will not receive any command through RS485

I'm right?

Sorry for questions

syssi commented 1 month ago

With one virtual meter I have only one item for three inverters for

Correct because the virtual meter is like a small guy which checks your energy meter all the time. As soon there is some energy imported from the grid the guy decides what needs to be broadcasted via RS485. Because of the power demand divider: 3 the power demand gets devided by 3.

With three virtual meter I can: -set inverter0 and inverter1 on Auto and Battery limit, they will receive commands through RS485

Correct. But you will need a RS485 bus per inverter (additional UARTs and RS485 converters!).

-set inverter2 on Manual and battery costant power, it will not receive any command through RS485

If you use the manual mode switch a constant power demand is requested via RS485 periodically. F.e. if you set the manual power demand to 500W the ESP will transmit this demand once per second via RS485.

Giro-S commented 1 month ago

Correct. But you will need a RS485 bus per inverter (additional UARTs and RS485 converters!).

Ahhhh ok ok A wrong think was: use n-virtual meter with one converter

If you use the manual mode switch a constant power demand is requested via RS485 periodically. F.e. if you set the manual power demand to 500W the ESP will transmit this demand once per second via RS485.

for now I use "manual mode" and "battery constant power", it works without attached power meter on inverter RS485 plug. I set only "output power limit" to n-W, "Manual power demand" is set to 0W. Output power on esphome is 0W but I can check through L line CT and tasmota+pzem-004T. It works because I think that the command is received from USB (TTL) port and not from RS485.

Thank you so much for patience with me. At this point I must decide what I want to do. ahahahah :)

syssi commented 1 month ago

Output power on esphome is 0W but I can check through L line CT and tasmota+pzem-004T. It works because I think that the command is received from USB (TTL) port and not from RS485.

The "output power limit" is a config setting of the inverter. You could remove the ESP and the inverter will continue to output the constant power. The "manual mode" is just a static power demand passed periodically via RS485. This should be used for automations. If you are using the "battery constant power" mode you haven't proved yet the RS485 connection is working in general.

Giro-S commented 1 month ago

Hello syssi and all oter users, I'm here again :)

With three virtual meter I can: -set inverter0 and inverter1 on Auto and Battery limit, they will receive commands through RS485

Correct. But you will need a RS485 bus per inverter (additional UARTs and RS485 converters!).

In this scenario: I have 3 inverters with 3 original wifi stick, I use 1 CT clamp and set on it 3 devices and connect it in parallel mode on the 3 inverters through rs485. I use original android application, what happen? Can I drive all 3 inverters separately? I will have 3 devices on my application and I can decide if "auto/manual" or "operation mode" for each one. Am I wrong?

PS: i2c to dual uart module converter is here :)

Always a big thank you

syssi commented 1 month ago

I have 3 inverters with 3 original wifi stick, I use 1 CT clamp and set on it 3 devices and connect it in parallel mode on the 3 inverters through rs485. I use original android application, what happen? Can I drive all 3 inverters separately?

The current clamp has some buttons. You can set the number of attached inverters here. This settings acts like the power demand divider: 3 setting of this project.

syssi commented 1 month ago

I use original android application, what happen? Can I drive all 3 inverters separately?

It looks like your understanding of your inverter features and the additional feature of this project aren't pretty clear yet.

  1. Imagine your inverter would have a display and some buttons (the OEM wifi dongle is just a replacement/alternative for the display). You can use the button to navigation, open the inverter settings menu and change the operation mode of the inverter from "limiter mode" to "constant power mode". There is a second option to set the maximum output power. In limiter mode this is the upper limit (f.e. if the power demand is 2000W requested via RS485 and the maximum output power is set to 300W the inverter will output 300W only!). In "constant power mode" the maximum output power is the constant power the inverter will provide permanently.

You shouldn't change the inverter settings multiple times per day because they are written into an EEPROM or flash storage which will be worn out pretty fast.

Let's call these features "inverter firmware settings/features" in future. These inverter firmware settings/feature can be changed/controlled using this project individually as soon a ESP is connected to the display port of the inverter.

  1. The soyosource_virtual_meter component of this project expects the inverter is always in limiter mode. The inverter is able to receive a single message via RS485 this is the so called "power demand" (in words: "Dear inverter, please provide 300W now!"). The soyosource_virtual_meter component provides two controls called "manual power mode" and "manual power demand". If you enable the manual power mode the manual power demand value will be passed periodically to the inverter via RS485. If the value of the manual power demand is set to 150W (using Home Assistant or MQTT) the soyosource_virtual_meter will send the power demand of 150W periodically to the inverter using RS485.

Let's call the features of the soyosource_virtual_meter in future project features.

Could you rephrase your question:

I use original android application, what happen? Can I drive all 3 inverters separately?

Are you talking about inverter firmware settings?

Giro-S commented 1 month ago

It looks like your understanding of your inverter features and the additional feature of this project aren't pretty clear yet.

Yes, I dont understand yet the logic, I'm very sorry.

I use original android application, what happen? Can I drive all 3 inverters separately?

Are you talking about inverter firmware settings?

I mean: with original application, original wifi stick and original CT connected on parallel to 3 inverters, Can I set f.e. the first and second inverters on auto - battery limit and the third one on manual - costant power? I've used "all original" for two days because I don't like it, I don't know if that settings are applicable.

For now I have 2 inverters always on (for third inverter I haven't yet the battery and it off for now), 2 wemos d1mini, 2 rs485 converters. Each inverter is connected with the own (your "Monitor and control the Soyosource GTN (WiFi version) via the display port and control the power output on demand via RS485"_) module. The settings are the same on the two modules: Output power limit 700 manual mode OFF manual power demand 0 max power demand 1800 divider 2

If the first battery is under 20% of charge I tell to home assistant to switch "manual mode - ON" and if the "manual power demand" is set to 0, the inverter stop the AC output (1 or 2 watts only). When the state of charge is over f.e. 40% I tell to home assistant to switch again to "manual mode - OFF" ...and so on.

In the same time the second battery is on 50%, second inverter is always in "manual mode - OFF" and his output will be the double because the first inverter is in manual and power demand is 0.

Problem: in this scenario when the first inverter switch to auto again, his output is some watts (f.e. 5/10/40) because the output of second inverter remain f.e. to 300W, they are not synched. Solution 1: power on microwave (1500W), the two inverters go to max power, power off microwave, the two inverter are "more or less" synched (f.e. the first output is 130W and the second is 170W if my house power demand is 300W) Solution 2: turn on "manual mode" togheter inverters, turn off manual mode and to hope that they sync togheter , if not try again. Solution 3: use one module that drive 2 (or more) inverters togheter with 1 power meter that always sync the two output power. Is it possible this thing?

Thank you for patience

Giro-S commented 1 month ago

This is an example: Actual Power from grid of my house Immagine 2024-06-01 163424

Outpout power from 2 inverters (2 tasmota d1 mini + pzem-004 with clips put on output L line of each inverter) Immagine 2024-06-01 163350

Output power through this project from Inverter 1 Immagine 2024-06-01 163521

Output power through this project from Inverter 2 Immagine 2024-06-01 163533

As you can see the output of 2 inverter are not the same. Is there any configuration that I can to do to sync them?

1 esp32 with 2 ttl interface (3 in future) and 1 rs485 that drive 2 inverters, could to solve the sync? If yes and if I can't set "manual mode" on each inverter, I can switch OFF a channell where is attached that inverter if the battery is under 20%. I have this, directly connected with inverters fro each channel sonoff-4ch-pro-e-sonoff-4ch-pro-r2 But I don't know if is good remove AC from inverter, can it damage?

Another think: with only one "virtual meter" the esp32 does not to know which inverter I want to set on manual mode. I'm right? This is because there is not address to set for individual inverter. I'm right?

Giro-S commented 3 weeks ago

Hello to all :) I made the first version: control 2 inverters (3 in the next future) with one virtual meter, it works and the outputs are synced.

substitutions:
  name: soyosource-gtn-display
  device_description: "Monitor and control multi Soyosource GTN (WiFi version) via the display port and control the power output on demand via RS485"
  external_components_source: github://syssi/esphome-soyosource-gtn-virtual-meter@main
  # The display port should be connected to these GPIOs using a USB connector (VCC, RX, TX, GND)
  # A optocoupler / optical isolator (f.e. ADUM1201) between the display port and the ESP is recommended if the ESP isn't powered by the display port!
  device0: Inverter 0
  device1: Inverter 1
  tx_pin_rs485_uart_0: GPIO1
  rx_pin_rs485_uart_0: GPIO3

esphome:
  name: ${name}
  comment: ${device_description}
  project:
    name: "syssi.esphome-soyosource-gtn-virtual-meter"
    version: 2.1.0

esp32:
  board: wemos_d1_mini32
  framework:
    type: esp-idf

external_components:
  - source: ${external_components_source}
    refresh: 0s

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

ota:

logger:
  level: INFO

# If you use Home Assistant please remove this `mqtt` section and uncomment the `api` component!
# The native API has many advantages over MQTT: https://esphome.io/components/api.html#advantages-over-mqtt
mqtt:
  broker: 10.110.24.230
  username: mqtt_user
  password: 3zeri3uno@
  #id: mqtt_client

api:

# Allow provisioning Wi-Fi via serial
improv_serial:

i2c:
  sda: GPIO21
  scl: GPIO22
  scan: true
  id: bus_a

wk2132_i2c:
  - address: 0x70
    id: wk2168_bridge_i2c
    uart:
      - id: i2c_uart_0
        channel: 0
        baud_rate: 9600
        parity: none
      - id: i2c_uart_1
        channel: 1
        baud_rate: 9600        
        parity: none

uart:
  - id: uart_0
    baud_rate: 4800
    tx_pin: ${tx_pin_rs485_uart_0}
    rx_pin: ${rx_pin_rs485_uart_0}

soyosource_modbus:
  - id: modbus0
    uart_id: uart_0
    name: Inverter

soyosource_virtual_meter:
  - id: virtualmeter0
    soyosource_modbus_id: modbus0
    # The state of this sensor (instantaneous power in watt) is used as source
    power_id: powermeter0

    # Optional settings
    power_sensor_inactivity_timeout: 20s
    power_demand_calculation: NEGATIVE_MEASUREMENTS_REQUIRED
    min_power_demand: 0
    max_power_demand: 1800
    zero_output_on_min_power_demand: true
    # Split/distribute the power demand if you have multiple inverters attached to the same RS485 bus
    power_demand_divider: 2
    # A positive buffer value (10) tries to avoid exporting power to the grid (demand - 10 watts)
    # A negative buffer value (-10) exports power to the grid (demand + 10 watts)
    buffer: 10
    # The operation_status_id sensor is expected here. Passing the operation_status won't work
    # The state is used to suspend the limiter if the operation status of the inverter isn't 0x0 (normal)
    #operation_status_id: operation_status_id0

    # The update interval is important and defaults to 3 seconds. If the demand is sent too frequently
    # or rarely the interverter stops. TODO: Identify and validate the lower and upper update limit
    update_interval: 3s

soyosource_display:
  - id: display0
    uart_id: i2c_uart_0
    protocol_version: SOYOSOURCE_WIFI_VERSION
    update_interval: 5s
  - id: display1
    uart_id: i2c_uart_1
    protocol_version: SOYOSOURCE_WIFI_VERSION
    update_interval: 5s

binary_sensor:
  - platform: soyosource_display
    soyosource_display_id: display0
    fan_running:
      name: "${device0} fan running"
    limiter_connected:
      name: "${device0} limiter connected"
  - platform: soyosource_display
    soyosource_display_id: display1
    fan_running:
      name: "${device1} fan running"
    limiter_connected:
      name: "${device1} limiter connected"

button:
  - platform: soyosource_display
    soyosource_display_id: display0
    restart:
      name: "${device0} restart"
  - platform: soyosource_display
    soyosource_display_id: display1
    restart:
      name: "${device1} restart"

number:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    buffer:
      name: "${name} buffer"
      initial_value: 10
      restore_value: true
    manual_power_demand:
      name: "${name} manual power demand"
      max_value: 1800
    max_power_demand:
      name: "${name} max power demand"
      initial_value: 0
      max_value: 1800
      restore_value: true
    power_demand_divider:
      name: "${name} power demand divider"
      initial_value: 2
      restore_value: true

  - platform: soyosource_display
    soyosource_display_id: display0
    start_voltage:
      name: "${device0} start voltage"
    shutdown_voltage:
      name: "${device0} shutdown voltage"
    # Maximum output power in limiter mode / Output power in constant power mode
    output_power_limit:
      name: "${device0} output power limit"
    start_delay:
      name: "${device0} start delay"
  - platform: soyosource_display
    soyosource_display_id: display1
    start_voltage:
      name: "${device1} start voltage"
    shutdown_voltage:
      name: "${device1} shutdown voltage"
    # Maximum output power in limiter mode / Output power in constant power mode
    output_power_limit:
      name: "${device1} output power limit"
    start_delay:
      name: "${device1} start delay"

select:
  - platform: soyosource_display
    soyosource_display_id: display0
    operation_mode:
      name: "${device0} operation mode"
      optionsmap:
        1: "PV"
        2: "Battery Constant Power"
        17: "PV Limit"
        18: "Battery Limit"
  - platform: soyosource_display
    soyosource_display_id: display1
    operation_mode:
      name: "${device1} operation mode"
      optionsmap:
        1: "PV"
        2: "Battery Constant Power"
        17: "PV Limit"
        18: "Battery Limit"

sensor:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    power_demand:
      name: "${name} power demand"

  - platform: soyosource_display
    soyosource_display_id: display0
    error_bitmask:
      name: "${device0} error bitmask"
    operation_mode_id:
      name: "${device0} operation mode id"
#    operation_status_id:
#      name: "${device0} operation status id"
#      id: operation_status_id0
    battery_voltage:
      name: "${device0} battery voltage"
    battery_current:
      name: "${device0} battery current"
    battery_power:
      name: "${device0} battery power"
    ac_voltage:
      name: "${device0} ac voltage"
    ac_frequency:
      name: "${device0} ac frequency"
    temperature:
      name: "${device0} temperature"
    output_power:
      name: "${device0} output power"
  - platform: soyosource_display
    soyosource_display_id: display1
    error_bitmask:
      name: "${device1} error bitmask"
    operation_mode_id:
      name: "${device1} operation mode id"
#    operation_status_id:
#      name: "${device1} operation status id"
#      id: operation_status_id0
    battery_voltage:
      name: "${device1} battery voltage"
    battery_current:
      name: "${device1} battery current"
    battery_power:
      name: "${device1} battery power"
    ac_voltage:
      name: "${device1} ac voltage"
    ac_frequency:
      name: "${device1} ac frequency"
    temperature:
      name: "${device1} temperature"
    output_power:
      name: "${device1} output power"

  - platform: homeassistant
    id: powermeter0
    name: "${name} smartmeter instantaneous power"
    entity_id: sensor.total_power

switch:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    manual_mode:
      name: "${name} manual mode"
      restore_mode: RESTORE_DEFAULT_ON
    emergency_power_off:
      name: "${name} emergency power off"
      restore_mode: RESTORE_DEFAULT_OFF

text_sensor:
  - platform: soyosource_virtual_meter
    soyosource_virtual_meter_id: virtualmeter0
    operation_mode:
      name: "${name} limiter operation mode"

  - platform: soyosource_display
    soyosource_display_id: display0
    errors:
      name: "${device0} errors"
    operation_mode:
      name: "${device0} operation mode"
    operation_status:
      name: "${device0} operation status"
  - platform: soyosource_display
    soyosource_display_id: display1
    errors:
      name: "${device1} errors"
    operation_mode:
      name: "${device1} operation mode"
    operation_status:
      name: "${device1} operation status"

this is the hardware: 20240601_213249

The third inverter will be attached to serial 2 on esp32. The suggestions for improvement are welcome :)

Thank you Syssi and all other :)