I don’t know much about it. But i use sunnyportal.com to look online. And local I just go to my ipadres.
I have a Sunny Boy 3.0 1AV-40 and I live in Belgium. I use HA on my synology
I don’t know much about it. But i use sunnyportal.com to look online. And local I just go to my ipadres.
I have a Sunny Boy 3.0 1AV-40 and I live in Belgium. I use HA on my synology
Thanks for the reply. That probably explains it then. My inverter is about 5 years old, you have one of the newest models with the network interface built in… They obviously have changed the interface.
Sorry i can’t help you with the problem. That was the only problem I’ve got
Hi. Did you solve this in the meantime? I have the same problem.
I have been unable to connect to my 5000TL-21 with the additional WebConnect module.
Spoke to SMA Australia, and apparently this model will only connect with Sunny Portal or Sunny Explorer - no internal web interface.
I wonder if this is the same issue a few others have encountered. Using Sunny Explorer I could connect via bluetooth and see that the WebConnect module had an IP and was happily sending data to Sunny Portal - but could not access via browser on the LAN.
for old Sma inverters with web connect you can enable modbus over tcp…
i have these set in configuration.yaml:
modbus:
- type: tcp
host: {ip_of_inverter}
port: 502
sensor:
- platform: modbus
scan_interval: 60 #time in seconds for getting values
registers:
- name: SMA_Power_AC
unit_of_measurement: W
slave: 3
register: 30775
count: 2
data_type: int
- name: PV Daily Yield
unit_of_measurement: kWh
slave: 3
register: 30517
scale: 0.001
precision: 3
count: 4
data_type: uint
- name: PV Total Production
unit_of_measurement: MWh
slave: 3
register: 30513
scale: 0.000001
precision: 3
count: 4
- name: Grid Voltage
unit_of_measurement: V
slave: 3
register: 30783
count: 2
scale: 0.01
precision: 2
data_type: uint
- name: Grid frequency
unit_of_measurement: Hz
slave: 3
register: 30803
count: 2
scale: 0.01
precision: 2
data_type: uint
- name: SMA_temp
unit_of_measurement: °C
slave: 3
register: 30953
count: 2
scale: 0.1
precision: 1
data_type: int
- name: SMA_status
slave: 3
register: 30201
count: 2
- name: SMA_grid
slave: 3
register: 30217
count: 2
- name: Insulation
slave: 3
register: 30225
count: 2
scale: 0.001
unit_of_measurement: kOhms
- name: SMA_Residual_current
slave: 3
register: 31247
count: 2
scale: 1
unit_of_measurement: mA
- name: Apparent Power
unit_of_measurement: VA
slave: 3
register: 30813
scale: 1
precision: 0
count: 2
data_type: int
- name: Reactive Power
unit_of_measurement: VAr
slave: 3
register: 30805
scale: 1
precision: 0
count: 2
data_type: int
- platform: template
sensors:
modbus_sma_pv_power:
entity_id: sensor.sma_power_ac
friendly_name: 'Power Output'
value_template: >-
{% if states('sensor.sma_power_ac')|float < 0 or states('sensor.sma_power_ac')|float > 10000 %}
0
{% else %}
{{ states('sensor.sma_power_ac') }}
{% endif %}
unit_of_measurement: "W"
icon_template: mdi:flash-circle
modbus_sma_pv_apparent_power:
entity_id: sensor.apparent_power
friendly_name: 'Apparent Power'
value_template: >-
{% if states('sensor.apparent_power')|float < 0 or states('sensor.apparent_power')|float > 10000 %}
0
{% else %}
{{ states('sensor.apparent_power') }}
{% endif %}
unit_of_measurement: "VA"
icon_template: mdi:flash-circle
modbus_sma_pv_reactive_power:
entity_id: sensor.reactive_power
friendly_name: 'Reactive Power'
value_template: >-
{% if states('sensor.reactive_power')|float < 0 or states('sensor.reactive_power')|float > 10000 %}
0
{% else %}
{{ states('sensor.reactive_power') }}
{% endif %}
unit_of_measurement: "VAr"
icon_template: mdi:flash-circle
modbus_sma_pv_residual:
entity_id: sensor.sma_residual_current
friendly_name: 'Residual Current'
value_template: >-
{% if states('sensor.sma_residual_current')|float < 0 or states('sensor.sma_residual_current')|float > 10000 %}
0
{% else %}
{{ states('sensor.sma_residual_current') }}
{% endif %}
unit_of_measurement: "mA"
icon_template: mdi:flash-circle
modbus_sma_temperature:
entity_id: sensor.sma_temp
friendly_name: 'Inverter Temp'
value_template: >-
{% if states('sensor.sma_temp')|float < 0 or states('sensor.sma_temp')|float > 100 %}
0
{% else %}
{{ states('sensor.sma_temp') }}
{% endif %}
unit_of_measurement: "°C"
modbus_grid_frequency:
entity_id: sensor.grid_frequency
friendly_name: 'Grid Frequency'
value_template: >-
{% if states('sensor.grid_frequency')|float < 30 or states('sensor.grid_frequency')|float > 100 %}
Not Measured
{% else %}
{{ states('sensor.grid_frequency') }}
{% endif %}
unit_of_measurement: "Hz"
modbus_grid_voltage:
entity_id: sensor.grid_voltage
friendly_name: 'Grid Voltage'
value_template: >-
{% if states('sensor.grid_voltage')|float < 180 or states('sensor.grid_voltage')|float > 300 %}
Not Measured
{% else %}
{{ states('sensor.grid_voltage') }}
{% endif %}
unit_of_measurement: "V"
modbus_inverter_status:
entity_id: sensor.sma_status
friendly_name: 'Inverter Status'
value_template: >-
{% if is_state('sensor.sma_status', '307' ) %}
OK
{% elif is_state('sensor.sma_status', '303' ) %}
Off
{% elif is_state('sensor.sma_status', '455' ) %}
Warning
{% elif is_state('sensor.sma_status', '35' ) %}
Fault
{% endif %}
modbus_grid_contactor:
entity_id: sensor.sma_grid
friendly_name: 'Grid contactor'
value_template: >-
{% if is_state('sensor.sma_grid', '51' ) %}
Closed
{% else %}
Open
{% endif %}
and lovelace a vertical stack which hides most of the values when inverter is not connected to grid:
cards:
- entities:
- entity: sensor.modbus_inverter_status
- entity: sensor.modbus_grid_contactor
show_header_toggle: false
title: PV Inverter
type: entities
- card:
entities:
- entity: sensor.modbus_sma_pv_power
- entity: sensor.modbus_sma_pv_apparent_power
- entity: sensor.modbus_sma_pv_reactive_power
- entity: sensor.pv_daily_yield
- entity: sensor.pv_total_production
- entity: sensor.modbus_sma_temperature
- entity: sensor.modbus_grid_voltage
- entity: sensor.modbus_grid_frequency
- entity: sensor.insulation
- entity: sensor.modbus_sma_pv_residual
show_header_toggle: false
type: entities
conditions:
- entity: sensor.sma_grid
state: '51'
type: conditional
type: vertical-stack
Thanks for sharing mamra.
But i’ve tried to connect via the modbus, i can’t reach my device.
Error:
Connection to (192.168.1.175, 502) failed: timed out
code from configuration.yaml:
modbus:
I’m sure that the right IP from my SMA STP 6000TL, because i can read it from my local Sunny Explored connected trough speedwire.
Any idea’s?
Found it…
In the Sunny portal i had to turn on tcp server.
Hello MatijnB,
We bought an second hand inverter with an Webconnect unit. I cant connect by http and my modbus isn’t working to. Can you explain me where you turned on the tcp server?
I can’t login to an HTTP web interface,
but if i look in the Sunny Explorer there isn’t an option to turn it on. The only option i am seeing is Webconnect : on/off
I am using the SB 3000TLST-21 408 in combination with an SWDM-10 connected to my router.
I have also a WebConnect with only the “SMA Portal”. I don’t have the right to enable Mobius so I looked on how to extract the data directly from SMA Portal as my feed to there is working fine.
I have this under test right now. This is a python script to be executed under “AppDaemon” integration.
Don’t forget to replace xxxxxx & yyyyyy with your credential.
Probably still some debugging needed (I don’t know yet how long I can keep active my session, I try a check every 5 min and a logon once per hour.
from bs4 import BeautifulSoup
import requests
import json
import time
from datetime import datetime
import appdaemon.plugins.hass.hassapi as hass
class sma_bridge(hass.Hass):
def initialize(self):
self.log("Initialize sma_bridge")
self._loginskip = 0
self._handler5 = None
self.run_at_sunset( self.sunset, offset = -30 * 60)
self.run_at_sunrise(self.sunrise, offset = 30 * 60)
if self.sun_up():
self.sunrise("")
else:
self.set_state("sensor.sma_power",state = 0)
self.log("End sma_bridge")
def sunrise(self, kwargs):
self.log("sma_bridge: Sunrise")
tickstart = datetime.now()
if self._handler5 == None:
self._handler5 = self.run_every(self.run_every_c, tickstart, 5 * 60)
def sunset(self,kwargs):
self.log("sma_bridge: Sunset")
if self._handler5 != None:
self.cancel_timer(self._handler5)
self._handler5 = None
self.set_state("sensor.sma_power",state = 0)
def run_every_c(self, kwargs):
myj = self.getSMAData()
power = str(myj["PV"])
if power.isnumeric():
old_state = self.get_state(entity="sensor.sma_power")
if old_state != power:
self.set_state("sensor.sma_power",state = power, attributes = myj)
else:
self._session = None
# For login: logout https://www.sunnyportal.com/Templates/Start.aspx?logout=true
# To Fetch data: https://www.sunnyportal.com/Dashboard
# Example 1: {"__type":"LiveDataUI","Timestamp":{"__type":"DateTime","DateTime":"2020-04-10T09:27:00","Kind":"Unspecified"},"PV":2688,"FeedIn":null,"GridConsumption":null,"DirectConsumption":null,"SelfConsumption":null,"SelfSupply":null,"TotalConsumption":null,"DirectConsumptionQuote":null,"SelfConsumptionQuote":null,"AutarkyQuote":null,"BatteryIn":null,"BatteryOut":null,"BatteryChargeStatus":null,"OperationHealth":{"__type":"StateOfHealth","Ok":1,"Warning":0,"Error":0,"Unknown":0},"BatteryStateOfHealth":null,"ModuleTemperature":null,"EnvironmentTemperature":null,"WindSpeed":null,"Insolation":null,"BatteryMode":null,"InfoMessages":[],"WarningMessages":[],"ErrorMessages":[],"Info":{}}
# Example 2: {"__type":"LiveDataUI","Timestamp":{"__type":"DateTime","DateTime":"2020-04-10T09:47:04","Kind":"Unspecified"},"PV":null,"FeedIn":null,"GridConsumption":null,"DirectConsumption":null,"SelfConsumption":null,"SelfSupply":null,"TotalConsumption":null,"DirectConsumptionQuote":null,"SelfConsumptionQuote":null,"AutarkyQuote":null,"BatteryIn":null,"BatteryOut":null,"BatteryChargeStatus":null,"OperationHealth":null,"BatteryStateOfHealth":null,"ModuleTemperature":null,"EnvironmentTemperature":null,"WindSpeed":null,"Insolation":null,"BatteryMode":null,"InfoMessages":[],"WarningMessages":[],"ErrorMessages":[],"Info":{}}
#############################
#
# SMA Portal
#
#############################
def _Login(self):
if self._loginskip > 0 and self._session != None:
self._loginskip -=1
else:
self._loginskip = 12
session = requests.session()
url ="https://www.sunnyportal.com/Templates/Start.aspx?logout=true&ReturnUrl=%2fFixedPages%2fDashboard.aspx"
response = session.get(url)
myhtml = response.content
soup = BeautifulSoup(myhtml,'html.parser')
x = soup.find("input", {"id" : "__VIEWSTATE"} )
viewstate = x['value']
x = soup.find("input", {"id" : "__VIEWSTATEGENERATOR"} )
viewstategenerator = x['value']
parameters= {
'__EVENTTARGET':'',
'__EVENTARGUMENT':'',
'__VIEWSTATE':viewstate,
'__VIEWSTATEGENERATOR':viewstategenerator,
'ctl00$ContentPlaceHolder1$Logincontrol1$txtUserName':'[email protected]',
'ctl00$ContentPlaceHolder1$Logincontrol1$txtPassword':'yyyyyyyyyyyyyyyyy',
'ctl00$ContentPlaceHolder1$Logincontrol1$LoginBtn':'Login',
'ctl00$ContentPlaceHolder1$Logincontrol1$RedirectURL':'',
'ctl00$ContentPlaceHolder1$Logincontrol1$RedirectPlant':'',
'ctl00$ContentPlaceHolder1$Logincontrol1$RedirectPage':'',
'ctl00$ContentPlaceHolder1$Logincontrol1$RedirectDevice':'',
'ctl00$ContentPlaceHolder1$Logincontrol1$RedirectOther':'',
'ctl00$ContentPlaceHolder1$Logincontrol1$PlantIdentifier':'',
'ctl00$ContentPlaceHolder1$Logincontrol1$ServiceAccess':'true',
'ctl00$ContentPlaceHolder1$Logincontrol1$MemorizePassword':'on',
'ClientScreenWidth':2048,
'ClientScreenHeight':1152,
'ClientScreenAvailWidth':2048,
'ClientScreenAvailHeight':1112,
'ClientWindowInnerWidth':2048,
'ClientWindowInnerHeight':1010,
'ClientBrowserVersion':65,
'ctl00$ContentPlaceHolder1$hiddenLanguage':'en-us'
}
myheaders = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.9,fr;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
response = session.post(url,parameters,headers=myheaders)
if response.status_code == 200:
self.log ("SMA Logon :" + str(response.status_code))
self._session = session
else:
self.log("Error SMA Login:" + str(response.status_code))
self._session = None
return self._session
def getSMAData(self):
session = self._Login()
url="https://www.sunnyportal.com/Dashboard"
myheaders = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.9,fr;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
response = session.get(url,headers=myheaders)
if response.status_code == 200:
myhtml = response.content
myj = json.loads(myhtml)
self.log("getSMAData:" + str(myj))
else:
self.log ("Error SMA getSMAData:" + myhtml)
myj = {"PV": "Error"}
return myj
i know it’s been a while since you posted your config. but i implemented it today, and it is working fine for all values, exept for PV Daly Yield
name: PV Daily Yield
unit_of_measurement: kWh
slave: 3
register: 30517
scale: 0.001
precision: 3
count: 4
data_type: uint
the PV total production is totaly correct, but the daily yield should be around 0.361kWh but is showing something completely different. could it be a wrong register? is there a way to find our the correct register?
i’m completely new at modbus. but you code works fine, except for that value
i anyone could help me out… thanks.
What model of inverter do you have? Download from sma site >support >downloads under your inverter range the excel file of modbus… Check there what register is the daily yield
Also check the total production register. It seems low
Andreas, thank you for your reaction. the total production is oké, the solar panels have been installed a few days ago, so that explains the low value…
i have a Sunny Boy 3.0, SB3.0-1AV-41 575.
i found the list you mean, in html format. https://files.sma.de/downloads/MODBUS-HTML_SBxx-1AV-41-V11.zip
my current register in my config file is:
- name: PV Daily Yield
unit_of_measurement: kWh
slave: 3
register: 30517
scale: 0.001
precision: 3
count: 4
data_type: uint
so the register number seems correct.
do i have to change other register values, if i would like to try register 30537.
do i have to do anything with “Number of contiguous SMA registers” = 2 and “Data type SMA” = U32
do i have to change something to “data_type: uint”
Sma registers == count so you have to Change to 2.
thanks but doesn"t seem to work, i’ll have te look into it a bit more.
when i try count 2, i have this:
- name: PV Dagelijkse opbrengs
unit_of_measurement: kWh
slave: 3
register: 30535
count: 2
scale: 0.01
precision: 2
data_type: uint
but i just keep getting -0,001kw
Weird…
your settings seem correct:
u16 ( count 1) or 32 ( count 2) or 64 (count 4) are for unsigned words
FIX0 is decimal number with no decimal space
data type is uint (unsigned integer)
try again register 30517:
- name: PV Daily Yield
unit_of_measurement: kWh
slave: 3
register: 30517
scale: 0.001
precision: 3
count: 4
data_type: uint
if that doesn’t work try sunspec registers at slave:126