iaq_sensor_wired/tests/query_device.py
2021-11-26 20:34:32 +01:00

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)