Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ The project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Added progress indicator to more commands
- `points` option in set measurement and station calculation is now a multi
option, instead of a comma separated string list
- `chunk` option of file download now expects size in bytes, instead of
encoded hex characters

### Fixed

Expand Down
10 changes: 6 additions & 4 deletions docs/about.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ These have to be set before specifying the command groups.

iman --info --file iman.log measure ...

Usage
-----
.. tip::

.. click:: instrumentman:cli
:prog: iman
See the command help for all logging options.

.. code-block:: shell

iman -h
4 changes: 2 additions & 2 deletions docs/commands/files/download.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Downloading
===========

A useful file management feature is the ability to download a file from the
instrument. The download command can be used to download a file identified
A useful file management feature that gives the ability to download a file from
the instrument. The download command can be used to download a file identified
by either a file name and type, or a full file path.

.. caution::
Expand Down
2 changes: 1 addition & 1 deletion docs/commands/protocoltest/geocom.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ see what part of the protocol might be usable on the instrument.

.. note::

The commands only does surface level testing by executing one command
The command only does surface level testing by executing one command
from each subsystem. The results are only informative, they might not be
completely accurate. It might happen, that an instrument responds to the
command used for testing, but does not actually respond to the other
Expand Down
2 changes: 1 addition & 1 deletion docs/commands/targets/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Targets

To run a point measurement program, the targets first must be defined. This is
done in JSON format, providing the point IDs, prism types and their 3D
coordinates in an arbitrary coordinate system. This application provdes ways
coordinates in an arbitrary coordinate system. This application provides ways
to create such a definition.

.. note::
Expand Down
5 changes: 2 additions & 3 deletions docs/commands/targets/measure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ aimed at.
.. caution::
:class: warning

The appropriate prism type needs to be set on the instrument before
recording each target point. The program will automatically request
the type from the instrument after the point is measured.
The appropriate prism type and target height needs to be set on the
instrument before recording each target point.

This is needed, because the automated measurement programs support target
series with mixed reflector types. The prism types are set according to
Expand Down
39 changes: 37 additions & 2 deletions src/instrumentman/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,43 @@ def cli(
dateformat: str = "%Y-%m-%d %H:%M:%S",
rotate: tuple[int, int] | None = None
) -> None:
"""Automated measurement programs and related utilities for surveying
instruments."""
"""
\b
+--------------------------------------------------------------------+
| |
| .---------. |
| / +-------+ \\ |
| .__| +---+ |__. |
| | | | | | | ___ |
| | |=| @ |=| | |_ _| _ __ ___ __ _ _ __ |
| | | | | | | | | _____ | '_ ` _ \\ / _` | | '_ \\ |
| | | +---+ | | | | |_____| | | | | | | | (_| | | | | | |
| .+--+-------+--+. |___| |_| |_| |_| \\__,_| |_| |_| |
| | .----. 123 | |
| | |____| 456 | |
| '_______________' |
| |
+--------------------------------------------------------------------+

Instrumentman (or I-man for short) is a collection of command line programs
related to the automation of surveying instruments (primarily robotic total
stations) through serial line command protocols (mainly Leica GeoCom).

The individual commands are available through their respective action
based command groups. The help page for each command can be accessed
through the -h/--help option. Logging can be set up with options of this
root command.

Examples:

iman download file -h

iman --debug --file log.log measure inclination -o incline.csv -p 3 COM1

iman calc sets merged.json results.csv

iman terminal
"""
configure_logging(
protocol,
debug,
Expand Down
45 changes: 37 additions & 8 deletions src/instrumentman/datatransfer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,45 @@
@option(
"-o",
"--output",
help="file to save received data",
help="File to save received data",
type=File("wb", encoding="utf8", lazy=True)
)
@option(
"--eof",
help="end-of-file marker (i.e. the last line to receive)",
help="End-of-file marker (i.e. the last line to receive)",
type=str,
default=""
)
@option(
"--autoclose/--no-autoclose",
help="close transfer automatically upon timeout or when EOF is received",
help="Close transfer automatically upon timeout or when EOF is received",
default=True
)
@option(
"--include-eof/--no-include-eof",
help=(
"wether the EOF marker is part of the output format "
"Wether the EOF marker is part of the output format "
"(or just sent by the instrument regardless of the format in question)"
),
default=False
)
def cli_download(**kwargs: Any) -> None:
"""Receive data sent from the instrument."""
"""
Receive data sent from the instrument.

This command is intended to receive and save ASCII or extended ASCII
documents line by line, such as typical data exports from instruments.

To sucessfully receive the data, the program has to be started before the
instrument starts sending the lines.

Since not all ASCII export formats have an EOF marker, the download can be
closed by two mechanisms if no marker is set. The process can be closed
manually by keyboard interrupt once all data expected was received.
Alternatively the process can close automatically at the first connection
timeout (only if a first line was ever received, otherwise the program
waits indefinitely and has to be interrupted manually).
"""
from .app import main_download

main_download(**kwargs)
Expand All @@ -63,20 +78,34 @@ def cli_download(**kwargs: Any) -> None:
@com_port_argument()
@argument(
"file",
help="data file to upload",
help="Data file to upload",
type=File("rt", encoding="ascii")
)
@com_baud_option(1200)
@com_timeout_option()
@option(
"-s",
"--skip",
help="number of header rows to skip",
help="Number of header rows to skip",
type=IntRange(min=0),
default=0
)
def cli_upload(**kwargs: Any) -> None:
"""Upload ASCII data to the instrument."""
"""
Upload ASCII data to the instrument.

This command can be used to send ASCII data line by line to an instrument,
that supports serial data transfer. Such data can be a CSV formatted
coordinate list, or an instrument specific format type (e.g. Leica GSI,
Sokkia SDR).

To ensure the successful reception of the data, it is recommended to use
1200 baud. At higher speeds the instrument might not be able to process the
data quickly enough, leading to the receiving buffer filling up, which will
result in loss of data.

The instrument should be set to receiving mode before starting the upload.
"""
from .app import main_upload

main_upload(**kwargs)
52 changes: 37 additions & 15 deletions src/instrumentman/filetransfer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
@com_port_argument()
@argument(
"directory",
help="directory to list files in (path should end with '/')",
help="Directory to list files in",
type=str,
default="/"
default=""
)
@com_option_group()
@option(
"-d",
"--device",
help="memory device",
help="Memory device",
type=Choice(
(
"internal",
Expand All @@ -47,7 +47,7 @@
@option(
"-f",
"--filetype",
help="file type (ignored in recursive mode)",
help="File type (all files are shown when not set)",
type=Choice(
(
"image",
Expand All @@ -65,14 +65,26 @@
@option(
"--depth",
help=(
"recursive depth "
"Recursive depth "
"(0: unlimited; 1<=x: depth of directory search)"
),
type=IntRange(0),
default=1
)
def cli_list(**kwargs: Any) -> None:
"""List files on an instrument."""
"""
List files on an instrument.

For each file in the specified directory (and discovered subdirectories
when recursive search is enabled) the file name, file size and the time of
last modification is displayed. Not empty directories and items, that are
likely directories are show in blue and light blue colors. Known text
formats are shown green. Image and drawing formats are shown in magenta.
Database files are red. Other files are shown without special color.

This command requires a GeoCom capable instrument, that supports file
operations (TPS1200 and later).
"""
from .app import main_list

main_list(**kwargs)
Expand All @@ -87,21 +99,21 @@ def cli_list(**kwargs: Any) -> None:
@argument(
"filename",
help=(
"file to download (including path with '/' separators if filetype "
"File to download (including path with '/' separators if filetype "
"option is not specified)"
),
type=str
)
@argument(
"output",
help="file to save downloaded data to",
help="File to save downloaded data to",
type=File("wb", lazy=False)
)
@com_option_group()
@option(
"-d",
"--device",
help="memory device",
help="Memory device",
type=Choice(
(
"internal",
Expand All @@ -117,7 +129,7 @@ def cli_list(**kwargs: Any) -> None:
@option(
"-f",
"--filetype",
help="file type",
help="File type (full file path is required if this option is not set)",
type=Choice(
(
"image",
Expand All @@ -137,17 +149,27 @@ def cli_list(**kwargs: Any) -> None:
@option(
"-c",
"--chunk",
help="chunk size (max 450 for normal and 1800 for VivaTPS large download)",
type=IntRange(1, 1800),
default=450
help="Chunk size (max. 225 for normal and 900 for large download mode)",
type=IntRange(1, 900),
default=225
)
@option(
"--large",
help="use large download commands (only available from VivaTPS)",
help="Use large download commands (only available from VivaTPS)",
is_flag=True
)
def cli_download(**kwargs: Any) -> None:
"""Download a file from the instrument."""
"""
Download a file from the instrument.

Any format can be transferred. The file is downloaded in chunks of hex
encoded binary data. The speed is strongly dependent on the connection
baud and chunk size. Use the highest baud supported by the instrument, and
the largest chunk size for the fastest download.

This command requires a GeoCom capable instrument, that supports file
operations (TPS1200 and later).
"""
from .app import main_download

main_download(**kwargs)
6 changes: 3 additions & 3 deletions src/instrumentman/filetransfer/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def run_download(
file: BufferedWriter,
device: str = "internal",
filetype: str = "unknown",
chunk: int = 450,
chunk: int = 225,
large: bool = False
) -> None:
setup = tps.ftr.setup_download
Expand All @@ -266,7 +266,7 @@ def run_download(
logger.debug(f"Download setup: large={str(large)}, chunk={chunk:d}")
resp_setup = setup(
filename,
chunk,
chunk * 2, # chunk size is in bytes, but command expects in hex chars
_DEVICE[device],
_FILE[filetype]
)
Expand Down Expand Up @@ -307,7 +307,7 @@ def main_download(
sync_after_timeout: bool = False,
device: str = "internal",
filetype: str = "unknown",
chunk: int = 450,
chunk: int = 225,
large: bool = False
) -> None:
logger = getLogger("iman.files.download")
Expand Down
Loading