xcom485i.client module¶
Warning
Changing parameters when the inverters are in operation should be done carefully. The modification of parameters can restart the corresponding algorithm inside the inverter. For example, the change of a delay can restart the timer attached to it.
When you are using the RCC remote control, the Xtender inverter/charger, VarioTrack and VarioString MPPT solar chargers store their parameter values in a non-volatile flash memory. Because of the endurance of this memory, the number of writes on a single parameter is only guaranteed for 1000 write operations. To allow the cyclic write of parameters without count limit, we suggest you to write the parameters in RAM only
-
Xcom485i.__init__(serial_port, offset=0, debug=False)[source]¶ serial device must be configured with :
- EVEN parity
- 1 start bit
- 8 data bits, LSB first
- 1 parity bit (Even)
- 1 stop bit
- timeout 1 second
Parameters: - serial_port – Instance of serial module
- offset – The address offset as defined with the dip-switches
- debug (boolean) – Activate debug traces for tx/rx frames
-
class
xcom485i.client.Xcom485i(serial_port, offset=0, debug=False)[source]¶ Bases:
objectThis class act as a Modbus master in order to communicate with the Xcom-485i gateway (slave)
-
serial_port¶ Serial port used for communication with the gateway
Type: serial.Serial
-
addresses¶ Instance of Addresses class grouping all the ones accessible from the Xcom-485i
Type: xcom485i.addresses.Addresses
-
message_registers()[source]¶ Read pending messages stored into the gateway.
Note
Once a message is read, it is deleted inside the Xcom-485i, so use Xcom485i.pending_message_count in order to know how many messages are pending and iteratively call this function to retrieve all messages.
The response is like :
- Input Register 0 (@ 0x0001)| 2 bytes | Device source
- Input Register 1 (@ 0x0002)| 2 bytes | Message ID
- Input Register 2 (@ 0x0003)| 2 bytes | Optional value Most significant word
- Input Register 3 (@ 0x0004)| 2 bytes | Optional value Least significant word
Returns: Content of Input Register 0, 1, 2, 3 Return type: bytes Example
# Read all pending messages stored into the gateway # Run this example within the 'examples/' folder using 'python ex_read_messages.py' from a CLI # after installing xcom485i package with 'pip install xcom485i' import serial from xcom485i.client import Xcom485i SERIAL_PORT_NAME = 'COM4' # your serial port interface name SERIAL_PORT_BAUDRATE = 9600 # baudrate used by your serial interface DIP_SWITCHES_ADDRESS_OFFSET = 0 # your modbus address offset as set inside the Xcom485i device if __name__ == "__main__": try: serial_port = serial.Serial(SERIAL_PORT_NAME, SERIAL_PORT_BAUDRATE, parity=serial.PARITY_EVEN, timeout=1) except serial.serialutil.SerialException as e: print("Check your serial configuration : ", e) else: xcom485i = Xcom485i(serial_port, DIP_SWITCHES_ADDRESS_OFFSET, debug=True) # always check the number of pending messages pending_message_count = xcom485i.pending_message_count() print('pending_message_count:', pending_message_count) for _ in range(pending_message_count): message_registers = xcom485i.message_registers() print('Message N°:', _) print(" device source: ", message_registers[0]) print(" message id: ", message_registers[1]) print(" optionnal most significant word: ", message_registers[2]) print(" optionnal least significant word: ", message_registers[3])
-
pending_message_count()[source]¶ Get the number of currently pending messages stored into the gateway, by reading the content of the 0x0000 input register.
Note
Within the Xtender system, any device (Xtender, VarioTrack, VarioString, BSP, Xcom-CAN BMS) can send messages. These messages are displayed on the RCC and also available on the Studer Portal whenever the installation is connected to the Internet.
Returns: The number of pending messages (up to 128) Return type: int See also
-
read_info(slave_id, address)[source]¶ Read a user info from a targeted device as a float.
Note
The available user information is the same as the values that can be chosen to be displayed on the RCC. This user information gives the current state of the system. The user information can not be modified and their values change during the operation of the system.
Parameters: - slave_id – Slave identifier number (targeted device)
- address – Register starting address, see Studer Modbus RTU Appendix for the complete list of accessible register per device
Returns: User info read
Return type: float
Example
# Read user info 3001, Battery temperature, (Modbus register 2) from the first Xtender # Run this example within the 'examples/' folder using 'python ex_read_info.py' from a CLI # after installing xcom485i package with 'pip install xcom485i' import serial from xcom485i.client import Xcom485i SERIAL_PORT_NAME = 'COM4' # your serial port interface name SERIAL_PORT_BAUDRATE = 9600 # baudrate used by your serial interface DIP_SWITCHES_ADDRESS_OFFSET = 0 # your modbus address offset as set inside the Xcom485i device if __name__ == "__main__": try: serial_port = serial.Serial(SERIAL_PORT_NAME, SERIAL_PORT_BAUDRATE, parity=serial.PARITY_EVEN, timeout=1) except serial.serialutil.SerialException as e: print("Check your serial configuration : ", e) else: xcom485i = Xcom485i(serial_port, DIP_SWITCHES_ADDRESS_OFFSET, debug=True) read_value = xcom485i.read_info(xcom485i.addresses.xt_1_device_id, 2) print('read_value:', read_value)
-
read_input_registers(slave_id, address, quantity)[source]¶ Get raw data from input registers.
Parameters: - slave_id – Slave identifier number (targeted device)
- address – Register starting address
- quantity – Quantity of registers to read
Returns: Raw data from targeted registers
Return type: bytes
-
read_parameter(slave_id, address)[source]¶ Read a parameter from a targeted device as a float.
Note
All parameters accessible from RCC can also be accessed with the Modbus protocol.
It is possible to read the actual value of the parameter from Flash, but also the minimum and the maximum value.
To distinguish between these, we use a different register address offset as explained below:
- read value from flash : offset is 0 (READ_PARAM_FLASH_OFFSET)
- read min allowed value : offset is 2000 (READ_PARAM_MIN_OFFSET)
- read max allowed value : offset is 4000 (READ_PARAM_MAX_OFFSET)
Parameters: - slave_id (int) – Slave identifier number (targeted device)
- address (int) – Register starting address, see Studer Modbus RTU Appendix for the complete list of accessible register per device
Returns: parameter read
Return type: float
Example
# Read parameter 1107, Maximum current of AC source, (Modbus register 14) from the first Xtender # Run this example within the 'examples/' folder using 'python ex_read_param.py' from a CLI # after installing xcom485i package with 'pip install xcom485i' import serial from xcom485i.client import Xcom485i SERIAL_PORT_NAME = 'COM4' # your serial port interface name SERIAL_PORT_BAUDRATE = 9600 # baudrate used by your serial interface DIP_SWITCHES_ADDRESS_OFFSET = 0 # your modbus address offset as set inside the Xcom485i device if __name__ == "__main__": try: serial_port = serial.Serial(SERIAL_PORT_NAME, SERIAL_PORT_BAUDRATE, parity=serial.PARITY_EVEN, timeout=1) except serial.serialutil.SerialException as e: print("Check your serial configuration : ", e) else: xcom485i = Xcom485i(serial_port, DIP_SWITCHES_ADDRESS_OFFSET, debug=True) # read actual value stored into flash memory read_value = xcom485i.read_parameter(xcom485i.addresses.xt_1_device_id, 14 + xcom485i.addresses.read_param_flash_offset) print('read_value:', read_value) # read minimum value of this parameter read_value = xcom485i.read_parameter(xcom485i.addresses.xt_1_device_id, 14 + xcom485i.addresses.read_param_min_offset) assert read_value == 2.0 # only for 1107 parameter print('read_min_value:', read_value) # read maximum value of this parameter read_value = xcom485i.read_parameter(xcom485i.addresses.xt_1_device_id, 14 + xcom485i.addresses.read_param_max_offset) assert read_value == 50.0 # only for 1107 parameter print('read_max_value:', read_value)
-
read_time(slave_id)[source]¶ Read the system time from a targeted installation.
Note
The system time is available at the address 0 of the device system.
The time registers are accessible separetely if needed by using the correct address and length.
Here is the list of time registers:
- 0 -> Microsecond
- 1 -> Second
- 2 -> Minute
- 3 -> Hour
- 4 -> Weekday
- 5 -> Day
- 6 -> Month
- 7 -> Year (format 2022 = 22)
Parameters: slave_id (int) – Slave identifier number (targeted device) Returns: actual system time Return type: datetime Example
# Read the system time # Run this example within the 'examples/' folder using 'python ex_read_time.py' from a CLI after installing # xcom485i package with 'pip install xcom485i' import serial from xcom485i.client import Xcom485i SERIAL_PORT_NAME = 'COM4' # your serial port interface name SERIAL_PORT_BAUDRATE = 9600 # baudrate used by your serial interface DIP_SWITCHES_ADDRESS_OFFSET = 0 # your modbus address offset as set inside the Xcom485i device if __name__ == "__main__": try: serial_port = serial.Serial(SERIAL_PORT_NAME, SERIAL_PORT_BAUDRATE, parity=serial.PARITY_EVEN, timeout=1) except serial.serialutil.SerialException as e: print("Check your serial configuration : ", e) else: xcom485i = Xcom485i(serial_port, DIP_SWITCHES_ADDRESS_OFFSET, debug=True) # read actual value stored into flash memory read_value = xcom485i.read_time(xcom485i.addresses.system_device_id) print('Read time:', read_value)
-
write_parameter(slave_id, address, value)[source]¶ - Write a parameter value into a targeted device.
Note
All parameters accessible from RCC can also be accessed with the Modbus protocol.
In the Xtender system, it is possible to write a value in Flash (and RAM) or in RAM only.
To distinguish between both, we use a different register address offset as explained below:
- write value into FLASH and RAM : offset is 0 (WRITE_PARAM_FLASH_RAM)
- write value into RAM only : offset is 6000 (WRITE_PARAM_RAM_ONLY)
Parameters: - slave_id – Slave identifier number (targeted device)
- address – Register starting address, see Studer Modbus RTU Appendix for the complete list of accessible register per device
- value – The value to write
Returns: Quantity of written registers (must be 2)
Return type: int
Example
# Write parameter 1107 in RAM only, Maximum current of AC source, (Modbus register 14) # from the first Xtender # Run this example within the 'examples/' folder using 'python ex_write_param.py' from a CLI # after installing xcom485i package with 'pip install xcom485i' import serial from xcom485i.client import Xcom485i SERIAL_PORT_NAME = 'COM4' # your serial port interface name SERIAL_PORT_BAUDRATE = 9600 # baudrate used by your serial interface DIP_SWITCHES_ADDRESS_OFFSET = 0 # your modbus address offset as set inside the Xcom485i device if __name__ == "__main__": try: serial_port = serial.Serial(SERIAL_PORT_NAME, SERIAL_PORT_BAUDRATE, parity=serial.PARITY_EVEN, timeout=1) except serial.serialutil.SerialException as e: print("Check your serial configuration : ", e) else: xcom485i = Xcom485i(serial_port, DIP_SWITCHES_ADDRESS_OFFSET, debug=True) value = 8 # 8 [A] echo = xcom485i.write_parameter(xcom485i.addresses.xt_1_device_id, 14 + xcom485i.addresses.write_param_ram_only, value) # a value of 2 is expected on write action, represent the number of registers written assert echo == 2 print('echo:', echo)
-
write_time(slave_id, value)[source]¶ Write the time of a targeted installation.
Note
It is only possible to set the time and date by writting all registers at the same time.
Here is the list of time registers:
- 0 -> Microsecond
- 1 -> Second
- 2 -> Minute
- 3 -> Hour
- 4 -> Weekday
- 5 -> Day
- 6 -> Month
- 7 -> Year (format 2022 = 22)
Parameters: - slave_id – Slave identifier number (targeted device)
- value – The new datetime to write
Returns: Quantity of written registers (must be 8)
Return type: int
Example
# Write the system time # Run this example within the 'examples/' folder using 'python ex_write_time.py' from a CLI after installing # xcom485i package with 'pip install xcom485i' import serial from xcom485i.client import Xcom485i from datetime import datetime SERIAL_PORT_NAME = 'COM4' # your serial port interface name SERIAL_PORT_BAUDRATE = 9600 # baudrate used by your serial interface DIP_SWITCHES_ADDRESS_OFFSET = 0 # your modbus address offset as set inside the Xcom485i device if __name__ == "__main__": try: serial_port = serial.Serial(SERIAL_PORT_NAME, SERIAL_PORT_BAUDRATE, parity=serial.PARITY_EVEN, timeout=1) except serial.serialutil.SerialException as e: print("Check your serial configuration : ", e) else: xcom485i = Xcom485i(serial_port, DIP_SWITCHES_ADDRESS_OFFSET, debug=True) # current date and time current_dt = datetime.now() print(current_dt) echo = xcom485i.write_time(xcom485i.addresses.system_device_id, current_dt) assert echo == 8 # a value of 2 is expected on write action, represent the number of registers written print('echo:', echo)
-