134 lines
4.4 KiB
Python
Executable File
134 lines
4.4 KiB
Python
Executable File
#!/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)
|