Smart home with SMA PV and wallbox, Wolf heat pump and LEDA wood oven

Thank you! (Danke :-))

This seems to be the right direction, but i have to admit to be lost how to implement it in HA (as there are scripts with curl (which i dont know) and Homematic).
Are there any specific instructions/help for HA? Would you mind to share some of your knowledge? :slight_smile:
Thanks a lot!

Hello together,
I also have a SMA EV Charger and would like to intigrate it in HA. Therefore, I would also be interested in a tutorial.

Many Thanks

As some others posted before - I just wanted to add I tried implementing this in Home Assistant as well - but failed. I was able to query the information on the command line, but automating this in Home Assistant was a real nightmare.

@tmeringer: if you could post the configuration you used for the EV charger and maybe a few sentences with a short explanation maybe this should be enough to help all of us :slight_smile:

Sure, but keep in mind that I am no php expert at all, so the script provided might not be the best in the universe, plus I am only reading data from the SMA EV Charger (for now) using an Apache webserver that is running on my Home Assistant server, so YMMV.
IOW: my Apache webserver is returning a JSON string that can be consumed by Home Assistant then.

Here’s the php script:

<?php
$SMA_EV_IP = "<ev_charger_ip>";
$SMA_EV_user = "<ev_charger_username>";
$SMA_EV_pass = "<ev_charger_password>";

$URL_EV_token = "http://$SMA_EV_IP/api/v1/token";
$URL_EV_data = "http://$SMA_EV_IP/api/v1/measurements/live/";

// Get data from SMA EV charger
// 1st: get bearer token after authentication
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=password&username=$SMA_EV_user&password=$SMA_EV_pass"); 
curl_setopt($ch, CURLOPT_URL, $URL_EV_token);
$SMA_EV_token = curl_exec($ch);
curl_close($ch);

$SMA_bearer_token = json_decode($SMA_EV_token, true);
$SMA_bearer_access_token = $SMA_bearer_token[access_token];

// 2nd: get live data

$SMA_EV_header = array(
        "Authorization: Bearer $SMA_bearer_access_token"
);
$SMA_EV_data = "[{\"componentId\":\"IGULD:SELF\"}]";


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $URL_EV_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $SMA_EV_header); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
curl_setopt($ch, CURLOPT_POST ,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $SMA_EV_data);

$SMA_EV_return = curl_exec($ch);
curl_close($ch);

echo  $SMA_EV_return;
?>

Thank you very much for the script.

Since I had to do a bit trial and error, for future reference the steps i took in my Debian system:

sudo apt update
sudo apt install apache2
sudo apt-get install php
sudo apt-get install php-curl
service apache2 restart

This gave me a working setup, so I could save your script in /var/www/html and open it in a browser. By the way, since the debugging gave me a warning: I changed the line

$SMA_bearer_access_token = $SMA_bearer_token[access_token];

to

$SMA_bearer_access_token = $SMA_bearer_token['access_token'];

Now my final problem is: how can I process this data in Home Assistant?
I tried something like this in configration.yaml:

rest:
# SMA EV charger
  - resource: http://hass/sma.php
    scan_interval: 30
    sensor:
      - name: Wallbox
        value_template: 'OK'
        json_attributes:
          - Measurement.Metering.GridMs.TotWIn.ChaSta
          - Measurement.Metering.GridMs.TotWhIn.ChaSta

Also tried the other variation I found on https://www.home-assistant.io/integrations/rest/#fetch-multiple-json-values-and-present-them-as-attributes - nothing seems to work. The sensor is there, but only has a value of “friendly_name: Wallbox”. Seems to me the values provided by the script are formatted strangely - the browser only displays everything as plain text, too:


Whereas another JSON request I am using shows a formatted text in the same browser:
grafik

An hint on this? How did you integrate the PHP results into Home Assistant?

Sorry, it took a while.
I decided to go for a Home Assistant only route so that there is no need for an external dependency (using Apache).That caused my some headache, but I finally came up with a solution.

I came across Extracting data from JSON array from rest sensor that is longer than 255 characters - #5 by tmeringer which contains a very useful and clever trick.

So what I did: I am using Command Line - Home Assistant with a bash script.

This is the bash script that’s called from Home Assistant:

#!/bin/sh

IP_EV_Charger='<IP.OF.YOUR.EV22>';

USER='<USERNAME>';
PASSWORD='<SUPERSECRETPASSWORD>';

TOKENREQUEST=$(curl --silent http://$IP_EV_Charger/api/v1/token -d "grant_type=password&username="$USER"&password="$PASSWORD)
bearer_token_string=$(echo $TOKENREQUEST | jq -r .access_token) # -r removes surrounding quotes

SMA_EV_Return=$(curl --silent http://$IP_EV_Charger/api/v1/measurements/live/ -d "[{\"componentId\":\"IGULD:SELF\"}]" -H "Authorization: Bearer $bearer_token_string")

echo "{\"sma_ev_json\":"$SMA_EV_Return"}"

And the sensor being used is

- platform: command_line
  name: SMA EV Charger
  scan_interval: 60
  command_timeout: 30
  command: "/opt/homeassistant/sma-ev-getdata.sh"
  value_template: 'SMA_EV_CHG'
  json_attributes:
    - sma_ev_json

This results in a new sensor that contains the json data from the SMA EV Charger as attributes:

Data can be accessed like this then:

{{ states.sensor.sma_ev_charger.attributes['sma_ev_json'][1]['values'][0]['value'] }}

Result:

1 Like

Thanks a lot! That worked for me, too!
It might also be possible to change values with this method, extending the script a bit - but this version is a beginning and should be enough for what I want to do at the moment.
And even though they announced it quite a while ago and nothing happened until now, maybe SMA will update the wallbox to support modbus in the near future so all will be easier…

That works like a charm! Thank you very much.

The only thing i am missing is the “Car connected to Wallbox”.
But if i am reading this right, the api only returns the data that is presented via the "webui/monitoring/live view (“Momentanwerte” ), right?
Maybe we find a way for the “connected” status sometime.

There might be other endpoints too. I am still waiting for my BEV to arrive, so can’t check the “connected” status at the moment.

I found something here in post #19 - it’s in German, but since SMA does not seem to have huge market shares outside Germany I guess you might understand it :slight_smile:

According to the comments in this script, the connection state is represented by this value:

- channelId: Measurement.Operation.EVeh.ChaStt
  componentId: IGULD:SELF
  values:
    - time: '2022-06-20T19:44:27.350Z'
      value: 200112

… where
200111 = not connected
200112 = connected
200113 = charging

And by the way, in this thread mentioned above there is a link to another forum (also in German) that contains information about how to read and change settings - obviously with the same method, but the URL

[IP]/api/v1/parameters/search/
1 Like

Ah, great, thank you for pointing that out!

I did find this channel exposed via the api (just missed it due to “200111” and not being something readable ;-).
I can now read out the numeric state and convert it to text with a template:

Read out the numeric state:

- name: "sma_wallbox_car_connected"
  unique_id: "sma_wallbox_car_connected"
  state: "{{ states.sensor.sma_ev_charger.attributes['sma_ev_json'][17]['values'][0]['value'] }}"

and convert it into a human readable state (at least for a german) :slight_smile: :

- name: "sma_wallbox_car_status"
  unique_id: "sma_wallbox_car_status"
  state: "{%if states.sensor.sma_wallbox_car_connected.state == '200111' %}nicht angeschlossen
       {% elif states.sensor.sma_wallbox_car_connected.state == '200112' %}angeschlossen
       {% elif states.sensor.sma_wallbox_car_connected.state == '200113' %}lädt
       {% endif %}"

PS: i wonder if one could put these two sensors into one. I like to keep the sensor count as low as possible…

For the ability to change settings: for me the actual readout of

  • connection status (nothing connected, car connected, charging)
  • charging power in kW
  • total value of charged kWh

is enough, as i always (at least at the moment) use spare solar power to charge the battery.
if i have to go “full throttle” on charging i do have to walk to the wallbox and physically flip the switch anyway.

As my scripting abilities tend to be mostly zero, i sadly cannot make much out of the project you pointed out.

A bit off topic, but still my 2 cents: you can also do this by setting a charge limit in the smartphone app, e.g. 40 kWh to be charged in 2 hours. Then it will start charging at full speed. Big advantage of this approach: after the set time limit it will automatically revert to charging with spare solar power. This might be possible using Home Assistant as well, but since my setup seems to be very similar to yours (charging almost exclusively with solar power) that is no big deal.

2 Likes

You’re absolutely right.
I just tried that a few days ago and it seems to work as expected. (although it seems to drop the charging every now and then for no obvious reason - this don’t happen if i physically flip the switch).

Thanks for pointing that out.

I’ve managed to get this into one sensor with attributes for the different measurements:

template:                                                                                                                                                                                                                                                                                                                  
  - sensor:                                                                                                                                                                                                                                                                                                                
      - name: "Wallbox"
        icon: mdi:ev-station                                                                                                                                                                                                                                                                                               
        state: >                                                                                                                                                                                                                                                                                                           
          {% set s = states.sensor.sma_ev_charger.attributes['sma_ev_json'][17]['values'][0]['value'] | int(0) %}                                                                                                                                                                                                          
          {% if   (s == 200111) %} disconnected                                                                                                                                                                                                                                                                            
          {% elif (s == 200112) %} connected                                                                                                                                                                                                                                                                               
          {% elif (s == 200113) %} charging                                                                                                                                                                                                                                                                                
          {% else %} unknown                                                                                                                                                                                                                                                          
          {% endif %}                                                                                                                                                                                                                                                                                                      
        attributes:                                                                                                                                                                                                                                                                                                        
          energy_current_session: "{{ states.sensor.sma_ev_charger.attributes['sma_ev_json'][0]['values'][0]['value']  }}"                                                                                                                                                                                                 
          mode_switch:            "{{ states.sensor.sma_ev_charger.attributes['sma_ev_json'][1]['values'][0]['value']  }}"                                                                                                                                                                                                 
          grid_frequency:         "{{ states.sensor.sma_ev_charger.attributes['sma_ev_json'][5]['values'][0]['value']  }}"                                                                                                                                                                                                 
          power_charging_station: "{{ states.sensor.sma_ev_charger.attributes['sma_ev_json'][14]['values'][0]['value'] }}"                                                                                                                                                                                                 
          total_energy:           "{{ states.sensor.sma_ev_charger.attributes['sma_ev_json'][16]['values'][0]['value'] }}"                                                                                                                                                                                                 
          status:                 "{{ states.sensor.sma_ev_charger.attributes['sma_ev_json'][17]['values'][0]['value'] }}"                                                                                                                                                                                                 
1 Like

Hey,

I am a real noob in this and got some problems with the implementation.

I created the bash script sma-ev-getdata.sh under /config/bash/. In the configuration.yaml i added this:

- platform: command_line
  name: SMA EV Charger
  scan_interval: 60
  command_timeout: 30
  command: "/config/bash/sma-ev-getdata.sh"
  value_template: 'SMA_EV_CHG'
  json_attributes:
    - sma_ev_json

It also creates the sensor but doesn’t get any data as you can see in the image:

The logs show me this:

If i run the script in terminal i get paramters returned like this:

image

Where could be the problem?

Regards
Philipp

Hello Alois,
I am trying to add my STP 20000 to HA. How you did it?
Thanks for helping
alpha

Hi,
I found another solution for the SMA EV Charger just by using the RESTful integration. The idea is to define a sensor to obtain the token in specified intervals.
The other sensors provide the corresponding values. This works better for me as I have full control over each sensor (like the unit of measurement) without the need of any template sensors.
Additional sensors can be added as usual.

rest:
  - resource: "http://<HOST>/api/v1/token"
    method: POST
    payload: "grant_type=password&username=<USERNAME>&password=<PASSWORD>"
    scan_interval: 3000
    headers:
      Content-Type: "application/x-www-form-urlencoded"
    sensor:
      - unique_id: SMA-Token
        name: "SMA EV Charger Token"
        value_template: "OK"
        json_attributes:
          - access_token

  - resource: "http://<HOST>/api/v1/measurements/live"
    method: POST
    payload: "[{\"componentId\":\"IGULD:SELF\"}]"
    scan_interval: 10
    headers:
      Authorization: "Bearer {{ state_attr('sensor.sma_ev_charger_token', 'access_token') }}"
      Content-Type: "application/x-www-form-urlencoded"
    sensor:
      - unique_id: SMA-Measurement.ChaSess.WhIn
        name: "SMA EV Charger Energy Charging"
        value_template: "{{ value_json[0]['values'][0]['value'] | float }}"
        unit_of_measurement: Wh
    
      - unique_id: SMA-Measurement.Chrg.ModSw
        name: "SMA EV Charger Mode Switch"
        value_template: >
          {% set mode=value_json[1]['values'][0]['value'] %}
          {% if mode == 4950 %} Smart charging
          {% elif mode == 4718 %} Fast charging
          {% else %} unknown
          {% endif %}

I have a STP15 which is almost the same. Had to add it with modbus:

modbus:
  # SMA STP 15.0
  - type: tcp
    name: inverter_pv_stp15
    host: 192.168.8.54
    port: 502
    sensors:
      - name: Power_STP15
        address: 30775
        input_type: input
        count: 2
        slave: 3
        unit_of_measurement: W
        data_type: int32
      - name: Total_revenue_STP15
        address: 30529
        input_type: input
        count: 2
        slave: 3
        unit_of_measurement: Wh
        data_type: int32
      - name: Daily_revenue_STP15
        address: 30535
        input_type: input
        count: 2
        slave: 3
        unit_of_measurement: Wh
        data_type: int32
      - name: Temperature_STP15
        address: 30953
        input_type: input
        count: 2
        slave: 3
        unit_of_measurement: °C
        data_type: int32

Thank you very much for sharing. That’s easier and more flexible than using the script provided earlier.
I have to test it on the weekend with my charger, but do I understand correctly that you only read values with this method? It would be especially interesting to also set values, thus being able to program smart charging for dynamic power prices and things like that.

Up to now it’s only for reading values. There are also RESTful Switch and a RESTful Command integrations which should work similar as the sensor but of course with different endpoints. I haven’t tried it yet.
But I guess it will be a little bit more messy in your configuration as you will need to use helpers and templates to achieve a nice user experience.