Problem statement:
Want the ability to access Studer performance data from Home Assistant (HA), and change Studer settings from within HA. Having this ability would allow a more customized optimization of the PV use through the automations that are possible in HA. Studer gives the ability to monitor and control their PV systems both locally through a RCC or by web interface through their portal. Through the RESTful integration, HA can access the Studer portal to read performance data, and probably also make changes to the Studer settings, but there are some problems with this approach. The portal communication often breaks down resulting in data being inaccessible for significant periods of time. The portal only gives access to change the settings in the hardware’s flash memory and doesn’t have the option to limit changes to RAM. Studer says that their flash memory is only rated for about 1000 write cycles, so repeated writes to flash will eventually wear it out.
There are other alternatives. In Github, there are a couple of python libraries that can used to access Studer performance data from Home Assistant, and change Studer settings through local communication which avoids the Studer portal. The one that I have chosen to use is GitHub - zocker-160/xcom-protocol: Python library implementing Studer-Innotec Xcom protocol used by Xcom-232i and Xcom-LAN. I chose this one because it seems to be straight forward, and gives the option to change Studer settings in RAM only so that the flash memory isn’t worn out. This library offers 3 communication modes:
1. Local serial which is probably the most reliable and highest performance option, but requires purchasing and installing additional hardware (Xcom-485i) and wiring.
2. UDP over the existing local area network using the Xcom-LAN which most installations probably already have. I haven’t done much testing with this method, but it is probably very reliable, and reasonably fast. But using this method requires that the Moxa serial server that is used in the Xcom-LAN be reconfigured to UDP which means that the system will no longer be accessible from the portal.
3. The last method, which is a recent addition, and which I am using is with the Moxa in TCP client mode so that it can maintain communication with the Studer portal. With this method, I am able to read the Studer data about every 6 seconds while remaining connected to the portal. There are occasional short drops in communication that could be due to collisions with the portal data requests, but it has been much more reliable than using the RESTful integration and I am happy with it so far.
Summary of steps:
I. Choose a location to run the python library and script.
II. In the Moxa list of TCP servers, add the ip address of the machine that will run the python library and script.
III. From a command prompt on the machine where you installed the library, enter library calls to confirm that you can read Studer data. Do the same with writing some Studer setting changes.
IV. Add an account in HA that the python script will use for accessing HA. You will also need to create a long lived token in this account to provide the credentials to the script.
V. Test using a script to write to HA the values that were read from the Studer.
VI. Test using a script to read values from HA and write those values to the Studer.
I. Choose a location to run the python library and script. You can start off running it on your PC to test it out, then later install it on the same machine that runs your HA installation, or install where ever it is most convenient.
1. Install the python library.
2. Get the ip address of this machine. You can find it in your router’s list of network active DHCP leases with a host name of that machine’s name, or you can run a network scanner app on your phone to find the address. Save this address to enter in step 2.d.
3. Follow the installation instructions at https://github.com/zocker-160/xcom-protocol to install the xcom-protocol library on your machine.
a. Click on the green Code button, then download ZIP button to download the xcom-protocol-master.zip zipfile. Copy this zip file to folder where you will run the python script from.
b. Open a terminal window on the machine where the library will be installed and navigate to the folder where you will run the python script from.
c. To install the library, at the terminal command prompt, type: pip install xcom-protocol-master.zip
II. Add machine’s ip address to Moxa’s list of TCP servers
1. Get the ip address of your Moxa serial server from your router’s list of network active DHCP or you can run a network scanner app.
2. Log into the Moxa by placing its ip address into a web browser. The default user name is “admin”, and the default password is “xcomlan”. Click continue button to access the Moxa menu.
3. In the Moxa menu, click Operating Settings, then Port 1.
4. Enter the ip address of the machine that will run python into an empty Destination IP address field, and 4001 in the Port field. Click the submit button.
5. On the next page, click the save/restart button.
III. Test the library installation, from a command prompt on the machine where you installed the library, enter library calls to test the installation:
1. Start the python interpreter by typing “python3” at the command prompt.
2. Import the library functions by entering the following at the python command prompt:
from xcom_proto import XcomP as param
from xcom_proto import XcomC
from xcom_proto import XcomLANTCP
3. Read tests:
a. To test reads, copy/paste the following block of commands to the command prompt to make a test read from your inverter (make sure to keep the 4 space indentation after the “with” statement for the getValue commands, and no indentation for the print commands):
with XcomLANTCP(port=4001) as xcom:
soc = xcom.getValue(param.BATT_SOC) # Make sure this line is indented 4 spaces
gridpower = xcom.getValue(param.AC_POWER_IN) # Make sure this line is indented 4 spaces
houseload = xcom.getValue(param.AC_POWER_OUT) # Make sure this line is indented 4 spaces
Wait for the “>>>” python command prompt to return. You my need to add a couple of carriage returns for it to come back.
print('soc = ',soc, '%')
print('gridpower = ',gridpower, 'kW')
print('houseload = ',houseload, 'kW')
If everything is correct, you should see a print to screen of three inverter data points.
4. Write tests to inverter RAM:
a. First confirm that the inverter Smart Boost Limit (parameter 1607) is set to 100.0%. (Note: writes to RAM cannot be read back, so to confirm that the write was successful, you will need to observe system behavior.)
b. Then, at a time when the solar power is too low to meet the power needs of the house, and the State of Charge Level for Backup (parameter 6062), you should see power flowing from the battery to the house.
c. Copy/paste the following block of commands to the command prompt to make a test write to your inverter (make sure to keep the 4 space indentation after the “with” statement):
d.
with XcomLANTCP(port=4001) as xcom:
xcom.setValue(param.SMART_BOOST_LIMIT, 0.0) # Make sure this line is indented 4 spaces
e. If everything is correct, you should see power flow from the battery stop, and the house power will instead be supplied by the grid. Setting the Smart Boost Limit to 0, essentially makes your system behave like a grid tied system without battery backup which can be useful to reduce battery wear or to conserve battery charge for use during a high tariff period.
f. To return the system back to the prior condition, Copy/paste the following block of commands to the command prompt:
with XcomLANTCP(port=4001) as xcom:
xcom.setValue(param.SMART_BOOST_LIMIT, 100.0) # Make sure this line is indented 4 spaces
5. Use the measurements python test script to perform reads.
a. Copy the file measurements.py to the folder that the commend prompt is open to.
b. Start python if its not already running by typing python3 at the command prompt.
c. At the command prompt, type: measurements.py 10 3
d. The number 10 in the argument list is the number of times to execute the loop in the script, and the number 3 is the delay to wait after each execution of the loop.
e. If everything is correct, you should see a csv file in the folder that the script was run from. The csv file can be opened as a spreadsheet and have 10 rows of data. If there were errors in running the script, you may need to comment out lines that refer to hardware that is not in your system such as a second Vario String, by placing a “#” at the beginning of those lines.
IV. Add an account in HA that the python script will use for accessing HA.
1. Add and configure account.
a. From an HA administrative user account go to Settings, People, Users.
b. Click the add user button in the bottom, right of the screen.
c. Assign a Display Name, User Name, password, select Can only log in from the local network, and also select Administrator.
2. Create a token
a. Log into the newly created account.
b. Click on the account properties button in the lower right screen.
c. Scroll to the bottom of the page and click the Create Token link.
d. Give a name to the token, and copy the token.
3. Copy the token and HA ip address to the script.
a. Open the script ha_xcom.py and copy the newly created token to the line
HOME_ASS_TOKEN = "<your token>" # replacing <your token> with the token. Make sure to leave the quotes in place.
b. While you have the script open, also copy the ip address of your HA installation to the line
HOME_ASS_URL = "http://<ip>:8123/api/states/" # replacing <ip> with your HA installation ip address. Make sure to leave the quotes in place.
V. Test using the ha_xcom001.py script to read values from the Studer and write those values to HA.
1. Read values from the Studer and write those values to HA.
a. Copy the file ha_xcom001.py to the folder that the commend prompt is open to.
b. Start python if its not already running by typing python3 at the command prompt.
c. At the command prompt, type: ha_xcom001.py -1 3
d. The number -1 in the argument list tell the loop in the script to execute without stopping, and the number 3 is the delay to wait after each execution of the loop.
e. If everything is correct, you should see in the HA Overview dashboard the creation of several new sensors that begin with “scom” and they should have live data from your Studer system that updates about every 6 seconds.
VI. Test using the ha_xcom001.py script to read values from HA and write those values to the Studer.
1. Add numeric input helpers in HA to create the following entities
a. input_number.studer_python_script_loop_delay, minimum 0, maximum 30
b. input_number.studer_smart_boost_limit, minimum 0, maximum 100
c. input_number.studer_soc_level_for_backup, minimum 66, maximum 4 (the maximum and minimum limits you choose will depend on your system configuration)
2. In HA , add templates to the configuration.yaml file or a yaml file that is included in it to create new sensors for the script to read.
- name: "HA SCOM Studer Python Script Loop Delay"
unique_id: "ha_studer_python_script_loop_delay"
unit_of_measurement: "s"
device_class: "duration"
state_class: "measurement"
state: >-
{% set delay_time = states('input_number.studer_python_script_loop_delay' )|float() %}
{{ delay_time }}
- name: "HA SCOM Studer Smart Boost Limit"
unique_id: "ha_studer_smart_boost_limit"
unit_of_measurement: "%"
device_class: "battery"
state_class: "measurement"
state: >-
{% set smart_boost = states('input_number.studer_smart_boost_limit' )|float() %}
{{ smart_boost }}
- name: "HA SCOM Studer SOC Level for Backup"
unique_id: "ha_studer_soc_level_for_backup"
unit_of_measurement: "%"
device_class: "battery"
state_class: "measurement"
state: >-
{% set soc_level_for_backup = states('input_number.studer_soc_level_for_backup' )|float() %}
{% set soc_level_for_grid_feeding = states('sensor.scom_soc_level_for_grid_feeding' )|float() %}
{% if soc_level_for_backup > soc_level_for_grid_feeding %}
{{ soc_level_for_grid_feeding }}
{% else %}
{{ soc_level_for_backup }}
{% endif %}
3. Uncomment lines 205 to 223 in the ha_xcom001.py to allow it to read the newly created sensors.
4. Run the ha_xcom001.py script, and you should see the Studer system respond to changes in the HA helper input values.