#!/usr/bin/env python3 from sensor import Sensor from sys import argv,exit # query read input # read holding # write input/holding [REG] # # # # query_device.py ADDR [BAUDRATE] [{read [REGISTER] | write REGISTER}] # where: # - ADDR is MODBUS address. Special case is ADDR=0 (broadcast), # for which you may write, but not read # - BAUDRATE is baudrate (duh!), default value 19200 # - REGISTER is either register number (e.g. 30010 for input register CO2), # or register name (e.g. CO2) # - list of register names... # - if only ADDR (and optionally BAUDRATE) is supplied, query all possible information from sensor # def print_help(): print("HEEEELP") # default values DEFAULT_BAUDRATE = 19200 DEFAULT_ACTION = 'all' # first positional argument (ADDR) is necessary arg_index = 1 try: addr = int(argv[arg_index]) except IndexError: print('Argument needed: ADDR') print_help() exit(-1) except ValueError: print(f'{argv[arg_index]} is invalid form for argument ADDR') print_help() exit(-2) # second argument might be either BAUDRATE, read or write (or nothing) arg_index += 1 action = None register_number = [] register_name = [] baudrate = None value = None while arg_index < len(argv): if not baudrate: try: baudrate = int(argv[arg_index]) except ValueError: baudrate = DEFAULT_BAUDRATE continue elif not action: action = argv[arg_index] elif action == 'write' and value == None: try: value = int(argv[arg_index]) except ValueError: print(f'Wrong format for argument "value"') exit(-3) else: # rest of the arguments should be register numbers/names try: register_number.append(int(argv[arg_index])) except ValueError: register_name.append(argv[arg_index]) arg_index += 1 # sanity check if not action: action = 'all' if action != 'read' and action != 'write' and action != 'all': print(f'Unknown action {action}') exit(-4) if action == 'write' and value == None: print(f'Action "write" needs value"') exit(-5) if action == 'write' and len(register_number) + len(register_name) != 1: print(f'Action "write" needs exactly one register to write to') exit(-6) if not baudrate: baudrate = DEFAULT_BAUDRATE if action != 'write' and len(register_name) + len(register_number) == 0: input_registers = [ x for x in Sensor.input_register_offset.keys() ] holding_registers = [ x for x in Sensor.holding_register_offset.keys() ] register_name = input_registers + holding_registers # Query device print('---- Query device ----') print(f'Address: {addr}\nBaudrate: {baudrate}\nAction: {action}') if action == 'write': print(f'Value to be written: {value}') # open device s = Sensor(address=addr, baudrate=baudrate) if action == 'read' or action == 'all': print('---- Register readout ----') for register in register_name + register_number: if isinstance(register, str): reg_name = register if register in Sensor.input_register_offset: reg_number = Sensor.input_register_start + Sensor.input_register_offset[register] elif register in Sensor.holding_register_offset: reg_number = Sensor.holding_register_start + Sensor.holding_register_offset[register] else: print(f'Register name {register} not known') exit(-7) else: reg_number = register reg_name = '' try: result = s.read_register(reg_number) except ValueError: print(f'Register number {reg_number} cannot be read (wrong number?)') exit(-8) print(f'{reg_number : <10} {int(result) : <10} {reg_name}') elif action == 'write': if len(register_name) > 0: if register_name[0] not in Sensor.holding_register_offset: print(f'Register {register_name[0]} does not exist or is not holding register') exit(-9) reg_number = Sensor.holding_register_start + Sensor.holding_register_offset[register_name[0]] elif len(register_number) > 0: reg_number = register_number[0] print('---- Register write ----') try: s.write_register(reg_number, value) except ValueError: print(f'Register number {reg_number} cannot be written') exit(-9) exit(0)