#!/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 = '0.1.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('-i', '--interval', type=int, default=1800, help='The interval time in seconds to on/off the charger, default is 1800 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('-P', '--parallel', type=int, nargs='*', choices=(17, 18, 19), # help='set to parallel mode, parameter is the unit id, can be used multiple times') parser.add_argument('-q', '--quiet', action='store_true', help='quiet mode, suppress all output') 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 in {args.interval} seconds') counter = 0 while counter <= args.repeat: # start charging instrument.write_bit(registeraddress=enable_charger_address, value=1) monitor_charger(instrument, duration=args.interval) print() # stop charging instrument.write_bit(registeraddress=enable_charger_address, value=0) monitor_charger(instrument, duration=args.interval) print() counter += 1 print(f'Charging cycle {counter} completed.') if __name__ == "__main__": run()