Turn your tuya ev charger dynamic, load balancing or solar controlled

I wanted to share a project of mine, i took inspiration from many contributors, took pieces of code, modified them. you know how it goes. So i thought it would be time to give back a little.

I wrote an automation 2 actually that work together to control a cheap tuya ev charger from home assistant and have it take commands to either load balance, solar charge or shutdown.

The automation relies on a few sensors, a couple of helpers, some simple calculations, a smart socket with power metering and some tuya scenes (i haven’t been able to get the charger into localtuya yet.)

To operate it needs an input_number helper. one automation fills the value of that input number and the other takes that input number and translates it to a command for the charger (if change is needed).

These cheaper tuya ev chargers do not like big swings in power settings (they shut down and don’t start back easily) so the automation steps it up or down depending on the need.

The first script takes commands and sends them out if needed to the charger via a tuya scene:

alias: "Laadamperes regelen "
if:
  - condition: numeric_state
    entity_id: sensor.tesla_lader_hws_vermogen
    above: 100
  - condition: template
    value_template: >
      {% set laadstroom_keuze = states('input_number.echt_amperage') | float %}
      {% set laad_amperage = states('input_number.laad_amperage') | float %} {{
      laadstroom_keuze in [6, 8, 10, 13, 16] and laad_amperage in [6, 8, 10, 13,
      16] }}
then:
  - choose:
      - conditions:
          - condition: template
            value_template: >-
              {{ states('input_number.echt_amperage') | float <
              states('input_number.laad_amperage') | float }}
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ states('input_number.echt_amperage') | float == 6 }}"
                sequence:
                  - entity_id: scene.ev_charger_8a
                    action: scene.turn_on
              - conditions:
                  - condition: template
                    value_template: "{{ states('input_number.echt_amperage') | float == 8 }}"
                sequence:
                  - entity_id: scene.ev_charger_10a
                    action: scene.turn_on
              - conditions:
                  - condition: template
                    value_template: "{{ states('input_number.echt_amperage') | float == 10 }}"
                sequence:
                  - entity_id: scene.ev_charger_13a
                    action: scene.turn_on
              - conditions:
                  - condition: template
                    value_template: "{{ states('input_number.echt_amperage') | float == 13 }}"
                sequence:
                  - entity_id: scene.ev_charger_16a
                    action: scene.turn_on
      - conditions:
          - condition: template
            value_template: >-
              {{ states('input_number.echt_amperage') | float >
              states('input_number.laad_amperage') | float }}
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ states('input_number.echt_amperage') | float == 16 }}"
                sequence:
                  - entity_id: scene.ev_charger_13a
                    action: scene.turn_on
              - conditions:
                  - condition: template
                    value_template: "{{ states('input_number.echt_amperage') | float == 13 }}"
                sequence:
                  - entity_id: scene.ev_charger_10a
                    action: scene.turn_on
              - conditions:
                  - condition: template
                    value_template: "{{ states('input_number.echt_amperage') | float == 10 }}"
                sequence:
                  - entity_id: scene.ev_charger_8a
                    action: scene.turn_on
              - conditions:
                  - condition: template
                    value_template: "{{ states('input_number.echt_amperage') | float == 8 }}"
                sequence:
                  - entity_id: scene.ev_charger_6a
                    action: scene.turn_on
      - conditions:
          - condition: template
            value_template: >-
              {{ states('input_number.echt_amperage') | float ==
              states('input_number.laad_amperage') | float }}
        sequence:
          - entity_id: scene.none
            action: scene.turn_on

The pacing is done by waiting on helper input_number.echt_amperage. This number is generated by taking the power reading of the smart plug (sensor.tesla_lader_hws_vermogen) to which the charger is connected dividing it by the voltage and rounding it off to a set number of options (6 8 10 13 and 16, which are the possibe settings of the charger) to give a rough estimate of the amp draw. (a change in amps towards the setpoint indicates the car received and accepted the order so the charger can continue stepping up or down)
that script looks like this :

alias: laad amperes meting stekker (stap voor stap op/af schalen)
target:
  entity_id: input_number.echt_amperage
data:
  value: >-
    {% set calculated_value = (states('sensor.tesla_lader_hws_vermogen') |
    float(0)) / 240 %}

    {% if calculated_value is not none %}
      {% if calculated_value < 6 %}
        6
      {% elif calculated_value < 8 %}
        8
      {% elif calculated_value < 10 %}
        10
      {% elif calculated_value < 13 %}
        13
      {% elif calculated_value < 16 %}
        16
      {% else %}
        16
      {% endif %}
    {% else %}
      0  # Fallback value if calculation fails
    {% endif %}
action: input_number.set_value
enabled: true

this is triggered every 10 seconds when the charger is on it makes it so the charger controller script steps up or down 1 step from the current setting.

input_number.laad_amperage is what signals the need for a shift up or down. it is the value we want to ā€œstep towardā€ and maintain for the moment.

That is generated by this script for load balancing:

alias: dynamisch naar max
target:
  entity_id: input_number.laad_amperage
data:
  value: >-
    {% set max_belasting_p1 = states('input_number.max_belasting_p1') | float(0)
    %} {% set p1_vermogen = states('sensor.p1_meter_vermogen') | float(0) %} {%
    set tesla_vermogen = states('sensor.tesla_lader_hws_vermogen') | float(0) %}

    {% set calculated_value = ((max_belasting_p1 - p1_vermogen) +
    tesla_vermogen) / 250 %}

    {% if calculated_value is not none %}
      {% if calculated_value < 6 %}
        6
      {% elif calculated_value < 8 %}
        8
      {% elif calculated_value < 10 %}
        10
      {% elif calculated_value < 13 %}
        13
      {% elif calculated_value < 14 %}
        16
      {% else %}
        16
      {% endif %}
    {% else %}
      6  # Fallback value if calculation fails, set to 6A
    {% endif %}
action: input_number.set_value
enabled: true

input_number.max_belasting_p1 is a load limiter, it makes sure that if some big appliance kicks in there’s still room on the main power connection to sustain it while the charger steps down the ev charging. it takes 10 seconds per step so it needs a bit of a buffer. it is set to 6kw in my situation.

solar controlled charging is done by :

alias: Zon laden naar aanbod
target:
  entity_id: input_number.laad_amperage
data:
  value: >-
    {% set calculated_value =
    (states('input_number.beschikbare_solar_voor_thunder') | float(0) - 300) /
    240 %}

    {% if calculated_value is not none %}
      {% if calculated_value < 6 %}
        6
      {% elif calculated_value < 8 %}
        8
      {% elif calculated_value < 10 %}
        10
      {% elif calculated_value < 13 %}
        13
      {% elif calculated_value < 16 %}
        16
      {% else %}
        16
      {% endif %}
    {% else %}
      6  # Fallback value if calculation fails, set to 6A
    {% endif %}
action: input_number.set_value
enabled: true

this input number combines all loads that are controlled by solar and the main meter value. essentially making sure the ev charger will ā€œpush outā€ all other solar controlled functions by hogging the solar. (which causes the other solar functions to step down or turn of). this is off course a choice. you can prioritise is fits your situation. in my case the number generation looks like this:

target:
  entity_id: input_number.beschikbare_solar_voor_thunder
data:
  value: >-
    {% set calculated_value = 0 - (states('sensor.p1_meter_vermogen') |
    float(0)) + (states('sensor.zonne_boiler_hws_vermogen') | float(0)) + 
    (states('sensor.accu_pakket_hws_vermogen') | float(0)) + 
    (states('sensor.tesla_lader_hws_vermogen') | float(0))%} {% set
    clamped_value = [0, [calculated_value, 5000] | min] | max %} {{
    clamped_value | round(0, 'floor') | int }}
action: input_number.set_value
alias: beschikbaar solar voor Thunder (eis alle zonnestroom op)

The solar calculation is done every 3 minutes

The charger order execution (script sending out scenes) is triggered by changes in the input_numbers it relies on.

the other calculations are done every ten seconds

In my case the charging itself gets triggered by an app that selects the best times to charge the car based on power grid demand and my departure time. I get a financial reward for handing over that control.

That makes charging at night cheap and charging during the day profitable. As long as home assistant controls the current (through the tuya ev charger) and the sun is shining I get paid to charge my own car with my own solar energy. A free charge and some spare change for my efforts.

I hope this helps someone, it would have helped me :slight_smile:

4 Likes

Great work, David. Thanks a lot For sharing.

hi
I have two 11kw (almost) stupid chargers, one inside and one outside the garage… i wanted to buy one a little less stupid… a smart one… in my electrical panel I recently put a three-phase tuya meter, the tuya easem-e pc473. in your opinion is it possible to (buy and) connect a smart tuya charger with the pc473 device and with this set regulate the charging current so that it charges my car only with the sun?

I think that could work, i think any reading of your power meter and wifi controlled ev charger can work if home assistant can read the data and send commands.

I got mine to connect locally through local tuya, i read the ev charger sensors through local tuya too. So maybe have a look at supported devices in local tuya see if the one you are looking at is on the list ?

Hello, I’m new to HA and also have a Tuya EV Portable Charger (VEVOR Portable EV Charger Type 2, 16A).
The script you created is exactly what I want to achieve with this charger, so it’s great to see that it’s possible!
I’ve already been able to add the charger to HA with ā€œTuya Localā€ and can control it.
I’ve noticed that I can use all amperages between 6 and 16, including 7A, for example, so there’s no need to jump between 6, 8, 10, 13, and 16?

Unfortunately, I don’t know much about scripts and automations yet.
My other car already charges automatically via EVCC, which works perfectly, but this doesn’t work for my hybrid car, so I’m forced to use this charger, which unfortunately doesn’t work with EVCC.

Would it be possible to explain this step by step and what exactly needs to be changed in the script to make it work for me?
My P1 meter and solar inverter are also connected to HA so I also have sensors for this.

I also speak Dutch, but I think only English is allowed here?

Thanks in advance and thanks for sharing these scripts with everyone already!

I’ve now tested the EV charger while it’s charging, but once charging has started, it’s no longer possible to adjust the charging amperages.
This can only be adjusted when charging isn’t in progress.
Is this the case with your charger too, @DavidH ?
Or are you using a different EV Tuya charger than I am?

Thanks

Hi,
before few days, I bought this charger from Amazon:
https://www.amazon.de/dp/B0DQP6JY3R?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1
This charger can change charging amperages also while charging is in progress (from Tuya android apk, I tested today: in afternoon I switched from 20A to 16 then 13 and 10, 8,6A all manually by myself).
Will test it more in near future.
As I see, this charger refuses if I choose 12A or some other ā€˜unsupported amperage’… in that case, charger switches to first step below of:
6-8-10-13-16-20-24-32A

Sorry for the late response, I was a bit distracted.

Did you figure it out or can you still use some help ?

My charger allows me to change amperage while charging, BUT: only to the selected amperages, if i try values in between it will refuse to take it. Tuya local doesn’t take that into account, it’s baked in the charger firmware not the Tuya integration.

Stepping down should be done gently to prevent the charger from tripping (overcurrent alarm)

Let me know if I can be of assistance or if you need my most recent script for inspiration. Not sure about the forum language etiquette, best stick to English.

David

Hi, no problem, thanks for your reply.
Which specific charger are you using?
Unfortunately, my Tuya EV Portable Charger (VEVOR Portable EV Charger Type 2, 16A) can’t adjust the speed while charging.

i use the AFEEV 3.5/7KW Draagbare EV-oplader Type2 IEC62196-2

https://nl.aliexpress.com/item/1005008263098071.html?spm=a2g0o.order_list.order_list_main.209.76d479d2Ewoqwn&gatewayAdapt=glo2nld

It works well with tuya local, i built the original automation to work with teslemetry, the first redesign was done to work with the tuya charger through tuya scenes still has elements in it from that automation.

The latest version (local tuya control) mostly uses entities from the charger itself (which became accesible after getting the charger into tuya local)

1 Like

Could it be that you have the 7kW (32A) model?
My charger is a 16A version (with a Schuko plug), and I suspect that only the 32A Tuya chargers (without a Schuko plug) can adjust the charging speed during charging.
Because in the reviews of your charger, I still see people mentioning that the charging speed can’t be adjusted while charging.
Thanks for your reply!

no, it’s the 16 amp…

Very nice work! I have the same charger in 32a guise. Very unsure about shutting down charge current remotely (charger side) as I see it lacks the communication cable to the car and triggers a charge error message in the car. I suppose you charge to 100 percent every time you trigger the charger?