Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Home assistant and more #1

Open
Userfreedu42 opened this issue Jan 15, 2024 · 13 comments
Open

Home assistant and more #1

Userfreedu42 opened this issue Jan 15, 2024 · 13 comments

Comments

@Userfreedu42
Copy link

Hello Thank you for your work, I'm trying to understand and I'd like to know if we can integrate your code into home assistant. I connected the ultimate speed to Home assistant with mqtt and a gateway where the data goes to a topic. But then I block, is it feasible? My connections are on the Net1 as the master, it didn't work on the gateways. Have you made the same connections? Do you speak French? Thanks
Uploading IMG_20240115_080126.jpg…

@bammab
Copy link
Owner

bammab commented Jan 20, 2024

Hi,
I use the esphome API core component to connect directly to homeassistant (without the requirement to use MQTT). I'm really new at the home asstistant and esphome part and never used mqtt - sorry.
But MQTT should work, too. Then an on_value-Action for the mqtt subscriber would be required and you could set the current with the generic number.set Action.

I use Net2, as shown in the manuel, but NET1 should work too (but noch testet). The Gateway-Port is completely useless. This should be for the smart meter gateway, but this port don't have any function at the moment (response of the support).

I don't understand which gateway do you mean ("mqtt and a gateway where the data..). The connection to net1 is working? You mqtt topic got data (you configure mqtt and an sensor of type mqtt_subscribe)? You got any data (see logs of the esp himself)? Otherwise toggle the wires, because rs485 don't work, if the wires are switched.

Here is my complete configuration incl. my automation. Hope it helps?!

Esphome Config

esphome:
  name: wb
  friendly_name: WB

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "..."

ota:
  password: "..."

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "Wb Fallback Hotspot"
    password: "..."

captive_portal:

external_components:
  - source:
      type: local
      path: local_components

uart:
  id: uswb_uart
  rx_pin: GPIO16
  tx_pin: GPIO17
  baud_rate: 4800
  stop_bits: 1

uswb:
  id: uswb_controller
  uart_id: uswb_uart
  send_wait_time: 200ms
  flow_control_pin: 18

sensor:
  - platform: uswb
    id: requested_current
    uswb_id: uswb_controller
    name: "USWB11A1 Requested Current"

number:
  - platform: uswb
    id: allowed_current
    uswb_id: uswb_controller
    name: "USWB11A1 Allowed Current"
    max_current: 16

Automation

Requirements

Requirement are three helper:

  • WB Power Buffer: input_number
    Negative: use grid to
    Positiv: leave this at least as buffer for other devices
  • WB Solar Charging: input_boolean
    Activate the automatic adjustment by the automation
  • WB Solar Charging Force Buffer: input_boolean
    Use the buffer value not just to start charging, but also while charging

And I use a sensor to use the mean power of the smart meter of the last 5min, to prevent to start charging just of a few seconds with enough power available.

sensor:
  - platform: statistics
    name: "Smart Meter Sum Active Power 5m"
    unique_id: smart_meter_sum_power_mean_5m
    entity_id: sensor.smart_meter_sum_active_instantaneous_power
    state_characteristic: mean
    precision: 0
    max_age:
      minutes: 5

Config

alias: USWB11A1 solar charging
description: ""
trigger:
  - platform: state
    entity_id:
      - input_boolean.wb_solar_charging
  - platform: state
    entity_id:
      - input_boolean.wb_solar_charging_force_buffer
  - platform: state
    entity_id:
      - input_number.wb_power_buffer
  - platform: time_pattern
    seconds: "30"
    enabled: true
condition:
  - condition: state
    entity_id: binary_sensor.wallbox_plugged
    state: "on"
    enabled: true
  - condition: state
    entity_id: input_boolean.wb_solar_charging
    state: "on"
    enabled: true
action:
  - variables:
      wb_phases: 1
      wb_min_current: 6
      wb_max_current: >-
        {%- set wb_buffer = states('input_number.wb_power_buffer') | float -%}

        {%- set wb_sum_power_last_5m =
        states('sensor.smart_meter_sum_active_power_5m') | float -%}

        {%- set wb_sum_power =
        states('sensor.smart_meter_sum_active_instantaneous_power') | float -%}

        {#- Use buffer only to initiate charging OR consume/save it all the time
        -#} {%- set wb_force_buffer =
        states('input_boolean.wb_solar_charging_force_buffer') | bool -%}

        {%- set wb_projected_voltage = 235 | float -%}

        {%- set wb_max_amp = 16 | float -%}

        {%- set wb_used_amp =
        [states('sensor.wb_uswb11a1_requested_current')|int,
        states('number.wb_uswb11a1_allowed_current')|int] | min -%}

        {%- set wb_used_watts = wb_used_amp * wb_phases * wb_projected_voltage
        -%}

        {%- set wb_is_charging = wb_used_amp > 0 -%}

        {%- set effective_charge_power = wb_sum_power + wb_buffer -
        wb_used_watts -%}

        {%- set effective_charge_power_5m = wb_sum_power_last_5m + wb_buffer -
        wb_used_watts -%}

        {%- if effective_charge_power < 0 -%}
            {%- set wb_max_charge_5m = ((effective_charge_power_5m / wb_projected_voltage) ) | abs | round(0) -%}
            {%- set wb_max_charge_with_buf = ((effective_charge_power / wb_projected_voltage) ) | abs | round(0) -%}
            {%- set wb_max_charge_wo_buf = (((effective_charge_power - wb_buffer) / wb_projected_voltage) ) | abs | round(0) -%}
            {%- set wb_max_charge_use = wb_max_charge_with_buf if wb_force_buffer else wb_max_charge_wo_buf -%}
            {#- Activate only, if min. current reached for at least 5m! -#}
            {%- if not wb_is_charging and wb_max_charge_5m < wb_min_current -%}
                0
            {%- elif wb_max_charge_use <= wb_min_current -%}
                {{ wb_min_current }}
            {%- elif wb_max_charge_use >= wb_max_amp -%}
                {{ wb_max_amp }}
            {%- else -%}
                {{ wb_max_charge_use }}
            {%- endif -%}
        {%- else -%}
            {#- Could not deactivate if already running! -#}
            {%- if wb_is_charging -%}
                {{ wb_min_current }}
            {%- else -%}
                0
            {%- endif -%}
        {%- endif -%}
  - condition: template
    value_template: >-
      {{ wb_max_current|int != states('number.wb_uswb11a1_allowed_current')|int
      }}
  - service: number.set_value
    data:
      value: "{{ wb_max_current }}"
    target:
      entity_id: number.wb_uswb11a1_allowed_current
mode: single

@Userfreedu42
Copy link
Author

Hi,
The connection to net1 is working. My mqtt topic got data
Screenshot_2024-01-20-21-37-33-93_f8348633b3cc54ccc0ae923fa7a5486e
But how do you translate it into home assistant? Can your code be adapted in home assistant?

@bammab
Copy link
Owner

bammab commented Jan 21, 2024

Okay - you just passthrough the rs485 communication to mqtt.
If you do not do it for testing purpose - your wallbox is in master mode. You need to setup in slave mode to control it.
But my code is not usable in home assistant directly, as it is programmed in C and home assistant use python. I've a proof of concept code in the repo, which is python.

You need to create a custom component for HA or try to implement the required function with an automation based on the mqtt events. I never made a custom component for HA and using a automation would not be easy, due to the crc.
Just as an idea of an automation:

  • Intervall as triger (every 10s)
  • Mqtt send message for target slave_id (your rs485 to mqtt device must send this data to the rs485 port)
    This would be 5a a5 07 00 SLAVE_ID 02 01 ALLOWED_CURRENT TWO_BYTE_MODEBUS_CRC
    Calculate all possible CRCs and use a lookup table, because it is not possible to calculate it in jinja, as some function are missing (or create a custom filter which exports the pymodbus.utilities.compute_crc function).
  • Gateway device send back the response of the wallbox to another topic
  • Get the required current from the response (third byte from the end) as sensor data to calculate the new allowed current

To calculate the complete message something like this could be possible with jinja templates?! But don't know how to use it with mqtt, because I never used it. But seems you could use it as payload_template of the mqtt.publish service. But there I could ne help anymore - sorry.

{% set crc16_modbus_table = [
[0x85, 0xE8],
[0x44, 0x28],
[0x04, 0x29],
[0xC5, 0xE9],
[0x84, 0x2B],
[0x45, 0xEB],
[0x05, 0xEA],
[0xC4, 0x2A],
[0x84, 0x2E],
[0x45, 0xEE],
[0x05, 0xEF],
[0xC4, 0x2F],
[0x85, 0xED],
[0x44, 0x2D],
[0x04, 0x2C],
[0xC5, 0xEC],
[0x84, 0x24],
[0x45, 0xE4],
[0x05, 0xE5],
[0xC4, 0x25],
[0x85, 0xE7],
[0x44, 0x27],
[0x04, 0x26],
[0xC5, 0xE6],
[0x85, 0xE2],
[0x44, 0x22],
[0x04, 0x23],
[0xC5, 0xE3],
[0x84, 0x21],
[0x45, 0xE1],
[0x05, 0xE0],
[0xC4, 0x20]] %}
{% set allowed_current = 0 %}

{{ [0x5a, 0xa5, 0x07, 0x00, 0x02, 0x02, 0x01] + [allowed_current] + crc16_modbus_table[allowed_current]
{#    5a    a5    07    00  SLAVE_ID 02   01     current  crc    <<<<<<---- COMMENT LINE ONYL!!! #}

@bammab
Copy link
Owner

bammab commented Feb 8, 2024

Hi,
as explained in the readme, this component could only be used with the recvision A1 (11 or 22 kW). Your link show the revision A2 which use another protocol. The manual of the A2 explain the new protocol (no need to reverse engineer like me for A1).
But I could not implement it, because I could not test it.

@valsenlis
Copy link

Hello,
I have attempted recently to make this component work with the USWB22A2. It turns out that the protocol does not seem to have changed compared to revision A1, despite what is described in the manual. During my tests, I observed that I could transfer an allowed current to the EVSE and get a requested current back from it through the ESP32, with the current code made for the A1 revision. However, because of practical issues, I could not yet test the whole chain until doing a controlled charging with an EV, so this compatibility assessment has to be taken with a grain of salt.

@Userfreedu42
Copy link
Author

Userfreedu42 commented Mar 16, 2024

I bought an esp32 with this
On my A2 I connected to the NET2 A and B, in slave 1 and I entered the following code according to this website
I have uswb11a2_requested_current, when I manually change the power on the wallbox, the value also changes.

But when I want to change it via Home assistant it doesn't work an idea ?

Here is my configuration:

captive_portal:

binary_sensor:
#Etat de la connection
  - platform: status
    name: "Etat de la connection"

sensor:
   # Qualité du signal
     - platform: wifi_signal
       name: "Qualite du signal Wifi"
       update_interval: 60s
   # Temps de fonctionnement
     - platform: uptime
       name: "Allumé depuis (s)"
       id: uptime_sec
     - platform: uswb
       id: requested_current
       uswb_id: uswb_controller
       name: "USWB11A2 Requested Current"
       
switch:
   # Bouton de redémarrage
     - platform: restart
       name: "Redémarrage"

   # Transformation des secondes en jours
text_sensor:
    - platform: wifi_info
      ip_address:
        name: "ESP IP Address"
    - platform: template
      name: "Allumé depuis (j)"
      lambda: |-
        int seconds = (id(uptime_sec).state);
        int days = seconds / (24 * 3600);
        seconds = seconds % (24 * 3600); 
        int hours = seconds / 3600;
        seconds = seconds % 3600;
        int minutes = seconds /  60;
        seconds = seconds % 60;
        return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };          
      icon: mdi:clock-start
      update_interval: 60s

external_components:
  - source: github://bammab/custom_components_for_esphome

  # - source:
  #     type: git
  #     url: https://INTERNAL_GIT/USER/custom_components_for_esphome
  #     ref: dev_uswb11a1
  #     # username: OPTIONAL_USER
  #     # password: OPTIONAL_PWD
  #   components: [ uswb ]

  # - source:
  #     type: local
  #     path: local_components

uart:
  id: uswb_uart
  rx_pin: GPIO22
  tx_pin: GPIO23
  baud_rate: 4800
  stop_bits: 1

uswb:
  id: uswb_controller
  uart_id: uswb_uart
  send_wait_time: 200ms
  # address: 2
  # update_interval: 10s
  # revision: A1
  flow_control_pin: 18

number:
    - platform: uswb
      id: allowed_current
      uswb_id: uswb_controller
      name: "USWB11A2 Allowed Current"
      max_current: 32

image

@bammab
Copy link
Owner

bammab commented Mar 23, 2024

Hi @Userfreedu42,

It works as expected when you change the value on the wallbox and the requested current changed, but not when you change it with the number component.

The wallbox will request always the maximum they will use (min(allowed from display, allowed from car)). So this value will not change, until the car will change the maximum current (or you change it at the wallbox, which is not possible while charging).
The ESP just act as a master/loadbalancer and response the request with the set current (wallbox want 9A, but we say to use just 7A).

The revision A1 don't have any registers I could read to get the currently used current, I only get the request. Sorry, but this is how it works. I have also trouble after long standby. Then the wallbox sometimes ignores the loadbalancing and I could not really see anything in HA. Only the calculated consumtion and the real one do not match. This could only be fixed by stopping and starting (tap 5s on the button of the display or completly unplug/plug the charger).

@Userfreedu42
Copy link
Author

Userfreedu42 commented Apr 2, 2024

Hi @bammab,

I've done it, I can control my wallbox

With your equipment, I can change the load power (min 6 A, 7, 8, ... up to 32 A)

I set USWB22A2 Requested Current to 32 A and I modify USWB22A2 Allowed Current according to the production of electricity without stopping the load and the current sent by the wallbox is well that of USWB22A2 Allowed Current.

Thank you very much for your help and your work.

@Maarten69
Copy link

@Userfreedu42 Can you please share all your code and wiring please? I have a 22 kW USWB 22 A2
Thanks!

@Userfreedu42
Copy link
Author

Userfreedu42 commented Apr 5, 2024

sensor:
  - platform: uswb
    id: requested_current
    uswb_id: uswb_controller
    name: "USWB22A2 Requested Current"
       

external_components:
  - source: github://bammab/custom_components_for_esphome

  # - source:
  #     type: git
  #     url: https://INTERNAL_GIT/USER/custom_components_for_esphome
  #     ref: dev_uswb11a1
  #     # username: OPTIONAL_USER
  #     # password: OPTIONAL_PWD
  #   components: [ uswb ]

  # - source:
  #     type: local
  #     path: local_components

uart:
  id: uswb_uart
  rx_pin: GPIO3
  tx_pin: GPIO1
  baud_rate: 4800
  stop_bits: 1

uswb:
  id: uswb_controller
  uart_id: uswb_uart
  send_wait_time: 200ms
  # address: 2
  # update_interval: 10s
  # revision: A1
  flow_control_pin: 4

number:
  - platform: uswb
    id: allowed_current
    uswb_id: uswb_controller
    name: "USWB22A2 Allowed Current"
    max_current: 32

#select:
#   - platform: uswb
#     id: allow_current_2
#     uswb_id: uswb_controller
#     name: "USWB11A2 Allowed Current b"
#     max_current: 32

SCHEMA

@Maarten69
Copy link

Maarten69 commented Apr 5, 2024

Thanks @Userfreedu42
I find it difficult, because I'm using a different setup.
I connected an USB RS485 adapter to my laptop running the script "com_test.py" from @bammab.

I set the Wallbox to MASTER (1) and connected A+ to NET2 485A and B+ to NET2 485B. (the wallbox limit is set to 16A)
(The image schema you drawed shows A+ to B+ and B+ to A+ I assume that's by mistake...)

Running the script with an small adjustment (not lowering max current) I get this output:

2024-04-05 20:29:00,186 - INFO - Logger setup successful
2024-04-05 20:29:00,214 - INFO - Opened serial port
2024-04-05 20:29:00,214 - INFO - Start SLAVE mode (id: 2)
2024-04-05 20:29:00,618 - DEBUG - <- recv: 0x5A 0xA5 0x07 0x00 0x02 0x02 0x01 0x10 0x84 0x24
2024-04-05 20:29:00,618 - INFO - Got allowed current: 16/9
2024-04-05 20:29:00,618 - DEBUG - -> send: 0x5A 0xA5 0x07 0x00 0x02 0x02 0x02 0x09 0x45 0x1E
2024-04-05 20:29:02,263 - DEBUG - <- recv: 0x5A 0xA5 0x07 0x00 0x02 0x02 0x01 0x10 0x84 0x24
2024-04-05 20:29:02,263 - INFO - Got allowed current: 16/9
2024-04-05 20:29:02,263 - DEBUG - -> send: 0x5A 0xA5 0x07 0x00 0x02 0x02 0x02 0x09 0x45 0x1E
2024-04-05 20:29:03,893 - DEBUG - <- recv: 0x5A 0xA5 0x07 0x00 0x02 0x02 0x01 0x10 0x84 0x24

When I switch the Wallbox to SLAVE 2 I'm getting an Error 20: "RS485 slave error, connection with the charger is lost" even without running the script.

My goal is to control the Wallbox via python (as part of Home Assistant) on an intel nuc running Debian.

Could you put my in the right direction or do you think I should give up and go the ESP32 way?

@Userfreedu42
Copy link
Author

I understand, I control the Wallbox via an esp32 (as part of Home Assistant) on an pi4

Perhaps this can be done using python but I don't know how, sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants