Files
controller-wisetopdataserver/python/biopro/device/main.py
T
2021-12-20 14:52:55 +08:00

348 lines
11 KiB
Python

from pprint import pprint
from biopro.util.cli import *
from .manager import *
# noinspection PyUnusedLocal
class Main(CliReplMain, DeviceManagerOptions):
""""""
def __init__(self):
super().__init__()
DeviceManagerOptions.__init__(self)
self._manager: DeviceManager = None
self._found: Optional[List[DeviceResponseInfo]] = None
@cli_flags('-h', '--help', force_return=True)
def _help(self, opt: str):
"""print help document"""
self.print_help()
def __enter__(self):
self._manager = DeviceManager(self)
self._manager.setup()
self._manager.reload_library()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self._manager is not None:
self._manager.shutdown()
@cli_command('h', 'help')
def _help_1(self, cmd: str, argv: List[str]):
"""print help documents"""
self.print_help()
@cli_command('master')
def _master(self, cmd: str, argv: List[str]):
"""print master device"""
print(self._manager.master_device)
@cli_command('library-path')
def _list_library_path(self, cmd: str, argv: List[str]):
"""print library root path"""
for path in self._manager.library_path:
print(str(path))
@cli_command('library', value='[LIBRARY[:VERSION]]')
def _list_library(self, cmd: str, argv: List[str]):
"""list/print load library"""
a = Arguments(argv)
if len(a) == 0:
for i, library in enumerate(self._manager.list_library()):
self._print_library(library, prefix='[%d] ' % i)
else:
library = a.required('LIBRARY')
self._print_library(self._get_library(library), detail=True)
@cli_command('reload')
def _reload(self, cmd: str, argv: List[str]):
"""reload library from library root path"""
self._manager.reload_library()
@cli_command('reset')
def _reset(self, cmd: str, argv: List[str]):
"""master device reset"""
self._manager.reset()
@cli_command('scan')
def _scan(self, cmd: str, argv: List[str]):
"""master device scan"""
for found in self._manager.scan():
self._print_found_device(found)
@cli_command('found', value='[IDX]')
def _found(self, cmd: str, argv: List[str]):
"""list/print found device"""
a = Arguments(argv)
if len(a) == 0:
self._found = self._manager.found()
self._list_found()
else:
if self._found is None:
self._found = self._manager.found()
idx = a.required(('IDX', int))
found = self._found[idx]
info = self._manager.found_device(found)
self._print_found_device(info, detail=True)
@cli_command('connect', value='[IDX]')
def _connect(self, cmd: str, argv: List[str]):
"""connect to device"""
a = Arguments(argv)
if len(a) == 0:
self._list_found()
else:
idx = a.required(('IDX', int))
found = self._found[idx]
info = self._manager.found_device(found)
device = self._manager.connect(info)
self._print_connected_device(device)
@cli_command('device', value='[DEVICE]')
def _device(self, cmd: str, argv: List[str]):
"""list/print connected device"""
a = Arguments(argv)
if len(a) == 0:
self._list_device()
else:
device = a.required(('DEVICE', int))
self._print_connected_device(self._get_device(device), detail=True)
@cli_command('disconnect', value=('--all|DEVICE', '[-f|--force]'))
def _disconnect(self, cmd: str, argv: List[str]):
"""disconnect device"""
a = Arguments(argv)
force = a.has_opt('-f') or a.has_opt('--force')
if len(a) == 1:
device = a.required(('DEVICE', int))
device = self._get_device(device)
self._manager.disconnect(device.device_id, force=force)
else:
if a.has_opt('--all'):
self._manager.disconnect_all(force=force)
# @cli_command('new-dummy', value=('LIBRARY[:VERSION]', '[NAME]'))
# def _new_dummy_device(self, cmd: str, argv: List[str]):
# """new a dummy device.
#
# **arguments**
#
# * LIBRARY : used library name
# * VERSION : used library version
# * NAME : device display name
# """
#
# a = Arguments(argv)
#
# if len(a) == 1:
# library = a.required('LIBRARY')
# device_name = 'dummy'
#
# else:
# library, device_name = a.required('LIBRARY', 'NAME')
#
# library = self._get_library(library)
#
# address = EMPTY_ADDRESS
# serial = DeviceSerialNumber.UNKNOWN
# response = DeviceResponseInfo(device_name, serial, address)
#
# device = DebugDevice(self._manager, library, len(self._manager.list_device()), response=response)
#
# self._manager.add_connected_device(device)
# self._print_connected_device(device)
@cli_command('instruction', value=('[DEVICE]', '[COMMAND]'))
def _instruction(self, cmd: str, argv: List[str]):
"""list/call instruction"""
a = Arguments(argv)
if len(a) == 0:
self._list_device()
elif len(a) == 1:
device = a.required(('DEVICE', int))
for instruction in self._get_device(device).instructions():
print(instruction)
else:
device, command = a.required(('DEVICE', int), ('COMMAND', str))
self._get_device(device).call_instruction(command)
@cli_command('get', value=('[DEVICE]', '[PARAMETER]'))
def _get_parameter(self, cmd: str, argv: List[str]):
"""list/get parameter value"""
a = Arguments(argv)
if len(a) == 0:
self._list_device()
elif len(a) == 1:
self._list_parameter(a.required(('DEVICE', int)))
else:
device, parameter = a.required(('DEVICE', int), ('PARAMETER', str))
print(self._get_device(device).get_parameter(parameter))
@cli_command('value', value=('[DEVICE]', '[PARAMETER]'))
def _value_parameter(self, cmd: str, argv: List[str]):
"""list/get parameter present value"""
a = Arguments(argv)
if len(a) == 0:
self._list_device()
elif len(a) == 1:
self._list_parameter(a.required(('DEVICE', int)))
else:
device, parameter = a.required(('DEVICE', int), ('PARAMETER', str))
print(self._get_device(device).get_parameter_value(parameter))
@cli_command('set', value=('[DEVICE]', '[PARAMETER]', '[VALUE]'))
def _set_parameter(self, cmd: str, argv: List[str]):
"""list/set parameter"""
a = Arguments(argv, no_options_parsing=True)
if len(a) == 0:
self._list_device()
elif len(a) == 1:
self._list_parameter(a.required(('DEVICE', int)))
elif len(a) == 2:
device, parameter = a.required(('DEVICE', int), ('PARAMETER', str))
device = self._get_device(device)
table = device.library.parameter_table
info = table[parameter]
domain = info.domain
p = device.get_parameter(info.name)
v = table.get_value(info, p, device.context)
print('domain :', domain)
print('current :', p, '=', v)
print('PARA = VALUE')
if isinstance(domain, ParameterCollectionDomain):
domain = domain.element_domain
if domain == ParameterConstantDomain:
print(' ', p, '=', v)
elif domain == ParameterBoolDomain:
print(' ', 0, '=', table.get_value(info, 0, device.context))
print(' ', 1, '=', table.get_value(info, 1, device.context))
elif isinstance(domain, ParameterValueDomain):
for p in range(*domain.range):
print(' ', p, '=', table.get_value(info, p, device.context))
else:
device, parameter, value = a.required(('DEVICE', int), ('PARAMETER', str), ('VALUE', str))
device = self._get_device(device)
table = device.library.parameter_table
info = table[parameter]
device.set_parameter(parameter, value)
p = device.get_parameter(info.name)
v = table.get_value(info, p, device.context)
print('current :', p, '=', v)
@cli_command('command', value='COMMAND')
def _command(self, cmd: str, argv: List[str]):
"""send command through master device function handle_command()."""
a = Arguments(argv)
command = a.required('COMMAND')
self._manager.handle_command(None, command, a.opts())
def _get_library(self, library: str) -> DeviceLibrary:
library_name, library_version = part_suffix(library, ':')
ret = self._manager.get_library(library_name, library_version)
if ret is None:
raise RuntimeError('library', library, 'not found')
return ret
def _get_device(self, device: int) -> CompletedDevice:
ret = self._manager.get_device(device)
if ret is None:
raise RuntimeError('device not found')
return ret
def _list_found(self):
for i, found in enumerate(self._found):
self._print_found_device(found, prefix='[%d] ' % i)
def _list_device(self):
for i, device in enumerate(self._manager.list_device()):
self._print_connected_device(device, prefix='[%d] ' % i)
def _list_parameter(self, device: int):
for parameter in self._get_device(device).library.parameter_table.keys():
print(parameter)
@staticmethod
def _print_library(library: DeviceLibrary, detail=False, prefix: str = ''):
if not detail:
print(prefix + library.name, library.version)
else:
pprint(library.as_json(), width=120, indent=2)
def _print_found_device(self, device: DeviceResponseInfo, detail=False, prefix: str = ''):
if not detail:
print(prefix + address_str(device.mac_address), device.device_name, device.serial_number)
else:
library = self._manager.match_library(device)
if library is not None:
lib_name = library.name
lib_version = library.version
else:
lib_name = ''
lib_version = ''
print(prefix + address_str(device.mac_address), device.device_name, device.serial_number,
'library :', lib_name, lib_version)
@staticmethod
def _print_connected_device(device: Device, detail=False, prefix: str = ''):
if detail:
print(prefix + address_str(device.mac_address), device.device_name, device.serial_number)
else:
# XXX detail information for Device
print(prefix + address_str(device.mac_address), device.device_name, device.serial_number)
if __name__ == '__main__':
Main().main()