#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' The app will try to start charging and show the charger voltage, battery voltage and charging current stop charging in 30 seconds ''' from minimalmodbus import Instrument, MODE_RTU import sys import time VERSION = '3.0.0' UNIT = 16 MODBUS_FC_READ_SINGLE_COIL = int("0x01", 16) MODBUS_FC_READ_SINGLE_DISCRETE = int("0x02", 16) MODBUS_FC_READ_HOLDING_REGISTERS = int("0x03", 16) MODBUS_FC_READ_INPUT_REGISTERS = int("0x04", 16) MODBUS_FC_WRITE_SINGLE_REGISTER = int("0x06", 16) enable_charger_address = 0 charger_voltage_adddress = 30 batery_voltage_address = 32 current_address = 31 def monitor_charger(instrument, interval=1, duration=30): """ Monitor the charger voltage, battery voltage and current for a given duration. """ t = 0 while t < duration: try: charger_voltage = instrument.read_registers(registeraddress=charger_voltage_adddress, number_of_registers=1, functioncode=MODBUS_FC_READ_INPUT_REGISTERS) battery_voltage = instrument.read_registers(registeraddress=batery_voltage_address, number_of_registers=1, functioncode=MODBUS_FC_READ_INPUT_REGISTERS) current = instrument.read_registers(registeraddress=current_address, number_of_registers=1, functioncode=MODBUS_FC_READ_INPUT_REGISTERS) print(f'Time: {t}s - Charger Voltage: {charger_voltage[0]}({charger_voltage[0] / 128:.2f} V ) ' f'Battery Voltage: {battery_voltage[0]}({battery_voltage[0] / 128:.2f} V ) ' f'Current: {current[0]}({current[0] / 128:.2f} A )') sys.stdout.flush() except Exception as e: print(f'Error reading registers: {e}') pass time.sleep(interval) t += interval print() def run(): import argparse parser = argparse.ArgumentParser(description='xnergy charger control demo') parser.add_argument('port', type=str, help='The serial port(RS485) that connect to xnergy RCU') parser.add_argument('--duration-on', type=int, default=100, help='The duration time in seconds to keep the charger on, default is 100 seconds') parser.add_argument('--duration-off', type=int, default=10, help='The duration time in seconds to keep the charger off, default is 10 seconds') parser.add_argument('-r', '--repeat', type=int, default=1, help='The number of times to repeat the charging cycle, default is 1') parser.add_argument('-q', '--quiet', action='store_true', help='quiet mode, suppress all output') parser.add_argument('-v', '--version', action='version', version=f'%(prog)s {VERSION}') args = parser.parse_args() instrument = Instrument(port=args.port, mode=MODE_RTU, slaveaddress=UNIT, debug=not args.quiet) instrument.serial.baudrate = 9600 print(f'Start Charging, will start/stop charging {args.repeat} times with on duration {args.duration_on}s and off duration {args.duration_off}s') counter = 0 while counter <= args.repeat: # start charging instrument.write_bit(registeraddress=enable_charger_address, value=1) monitor_charger(instrument, duration=args.duration_on) print() # stop charging instrument.write_bit(registeraddress=enable_charger_address, value=0) monitor_charger(instrument, duration=args.duration_off) print() counter += 1 print(f'Charging cycle {counter} completed.') if __name__ == "__main__": run()