• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

int-brain-lab / tycmd-wrapper / 9895020353

11 Jul 2024 03:49PM UTC coverage: 84.314% (+9.3%) from 75.0%
9895020353

push

github

bimac
Update documentation.yaml

43 of 51 relevant lines covered (84.31%)

10.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.31
/tycmd.py
1
"""A python wrapper for tycmd."""
2

3
from pathlib import Path
12✔
4
from subprocess import check_output, CalledProcessError
12✔
5
import json
12✔
6
import re
12✔
7
from logging import getLogger
12✔
8

9
__version__ = "0.1.1"
12✔
10
_TYCMD_VERSION = "0.9.9"
12✔
11

12
log = getLogger(__name__)
12✔
13

14

15
def identify(filename: Path | str) -> list[str]:
12✔
16
    """
17
    Identify models compatible with firmware.
18

19
    Parameters
20
    ----------
21
    filename : Path | str
22
        Path to the firmware file.
23

24
    Returns
25
    -------
26
    list[str]
27
        List of models compatible with firmware.
28
    """
29
    filename = str(_parse_firmware_file(filename))
12✔
30
    return_string = _call_tycmd(args=["identify", filename, "--json", "-qqq"])
12✔
31
    return_string = return_string.replace("\\", "\\\\")
12✔
32
    output = json.loads(return_string)
12✔
33
    if "error" in output:
12✔
34
        raise RuntimeError(output["error"])
12✔
35
    return output.get("models", [])
12✔
36

37

38
def list_boards(verbose: bool = True) -> list[dict]:
12✔
39
    """
40
    List available boards.
41

42
    Parameters
43
    ----------
44
    verbose : bool, optional
45
        If True, include detailed information about devices. Default is True.
46

47
    Returns
48
    -------
49
    list[dict]
50
        List of available devices.
51
    """
52
    args = ["tycmd", "list", "-O", "json"] + (["-v"] if verbose else [])
×
53
    return json.loads(check_output(args, text=True))
×
54

55

56
def version(full: bool = False) -> str:
12✔
57
    """
58
    Return version information from tycmd.
59

60
    Parameters
61
    ----------
62
    full : bool, optional
63
        If True, return the full version string as returned by the tycmd binary. If
64
        False, return only the version number. Default is False.
65

66
    Returns
67
    -------
68
    str
69
        The version of tycmd.
70
    """
71
    output = _call_tycmd(["--version"])
12✔
72
    if full:
12✔
73
        return output.strip()
12✔
74
    else:
75
        if (match := re.search(r"\d+\.\d+\.\d+", output)) is None:
12✔
76
            return ""
×
77
        return match.group()
12✔
78

79

80
def reset(
12✔
81
    serial: str | None = None, port: str | None = None, bootloader: bool = False
82
) -> bool:
83
    """
84
    Reset board.
85

86
    Parameters
87
    ----------
88
    serial : str, optional
89
        Serial number of board to be reset.
90

91
    port : str, optional
92
        Port of board to be reset.
93

94
    bootloader : bool, optional
95
        Switch board to bootloader if True. Default is False.
96

97
    Returns
98
    -------
99
    bool
100
        True if board was reset successfully, False otherwise.
101
    """
102
    try:
×
103
        _call_tycmd(
×
104
            ["reset"] + (["-b"] if bootloader else []), serial=serial, port=port
105
        )
106
        return True
×
107
    except CalledProcessError:
×
108
        return False
×
109

110

111
def _parse_firmware_file(filename: str | Path) -> Path:
12✔
112
    filepath = Path(filename).resolve()
12✔
113
    if not filepath.exists():
12✔
114
        raise FileNotFoundError(filepath)
12✔
115
    if filepath.is_dir():
12✔
116
        raise IsADirectoryError(filepath)
12✔
117
    if len(ext := filepath.suffixes) == 0 or ext[-1] not in (".hex", ".elf", ".ehex"):
12✔
118
        raise ValueError(f"Firmware '{filepath.name}' uses unrecognized extension")
12✔
119
    return filepath
12✔
120

121

122
def _call_tycmd(
12✔
123
    args: list[str],
124
    serial: str | None = None,
125
    family: str | None = None,
126
    port: str | None = None,
127
) -> str:
128
    tag = _assemble_tag(serial=serial, family=family, port=port)
12✔
129
    args = ["tycmd"] + args + tag
12✔
130
    log.debug(" ".join(args))
12✔
131
    return check_output(args, text=True)
12✔
132

133

134
def _assemble_tag(
12✔
135
    serial: str | None = None, family: str | None = None, port: str | None = None
136
) -> list[str]:
137
    tag = "" if serial is None else str(serial)
12✔
138
    tag += "" if family is None else f"-{family}"
12✔
139
    tag += "" if port is None else f"@{port}"
12✔
140
    return ["-B", tag] if len(tag) > 0 else []
12✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc