Shepherd-Sheep

The shepherd-sheep API offers high level access to shepherd’s functionality and forms the base for the two command line utilities. With the introduction of the core-lib the api was simplified and modernized with a model-based approach. The pydantic data-models offer self-validating config-parameters with neutral defaults.

For lower-level access, have a look at the Shepherd-Sheep - Advanced. There is a third option called debug-api, used i.e. by the programmer. It will not be documented here. To learn about the functionality the source should be consulted.

Harvesting

The run_harvester()-function can be used to configure all relevant hardware and software and to sample and extract data from the analog frontend.

from contextlib import ExitStack

from shepherd_core.data_models.task import HarvestTask
from shepherd_sheep.shepherd_harvester import ShepherdHarvester
from shepherd_sheep.logger import set_verbosity

The snippet is taken from the actual implementation in sheep/init and references the HarvestTask

Emulating

The run_emulator()-function can be used to emulate previously recorded IV data for an attached sensor node.

from contextlib import ExitStack

from shepherd_core.data_models.task import EmulationTask
from shepherd_sheep.shepherd_emulator import ShepherdEmulator
from shepherd_sheep.logger import set_verbosity

The snippet is taken from the actual implementation in sheep/init and references the EmulationTask.

Note

TODO: add user/task-config and relink both tasks above

Modify Firmware

The run_firmware_mod()-function can be used to customize a firmware before flashing it.

import shutil

from shepherd_core.data_models import FirmwareDType
from shepherd_core.data_models.task import FirmwareModTask
from shepherd_core.fw_tools import extract_firmware
from shepherd_core.fw_tools import firmware_to_hex
from shepherd_core.fw_tools import modify_uid
from shepherd_sheep.logger import set_verbosity

The snippet is taken from the actual implementation in sheep/init and references the FirmwareModTask.

Program Target

The run_programmer()-function can flash a .hex-file to a target of choice.

from contextlib import ExitStack

from shepherd_core.data_models.task import ProgrammingTask
from shepherd_sheep import sysfs_interface
from shepherd_sheep.logger import set_verbosity
from shepherd_sheep.shepherd_debug import ShepherdDebug
# Note: probably some includes missing

The snippet is taken from the actual implementation in sheep/init and references the ProgrammingTask.

Example-Code

This snippet shows the harvester and emulator instantiated with custom config-models. It was used as a 10h stress-test to find a memory leak.

from pathlib import Path

from shepherd_core.data_models.content import VirtualSourceConfig
from shepherd_core.data_models.task import EmulationTask
from shepherd_core.data_models.task import HarvestTask
from shepherd_sheep.logger import log
from shepherd_sheep.shepherd_run_functions import run_emulator
from shepherd_sheep.shepherd_run_functions import run_harvester

# run on observer with
# sudo python3 /opt/shepherd/software/python-package/tests_manual/testbench_longrun.py

if __name__ == "__main__":
    duration = 10 * 60 * 60  # s
    benchmark_path = Path("/var/shepherd/recordings")
    file_rec = benchmark_path / "benchmark_rec.h5"
    file_emu1 = benchmark_path / "benchmark_emu1.h5"
    file_emu2 = benchmark_path / "benchmark_emu2.h5"

    if not file_rec.exists():
        log.info("Start harvesting")
        hrv = HarvestTask(
            output_path=file_rec,
            duration=duration,
            force_overwrite=True,
            use_cal_default=True,
        )
        run_harvester(hrv)

    log.info("Starting Emulation1, only logging of SysUtil-Stats")
    emu1 = EmulationTask(
        input_path=file_rec,
        output_path=file_emu1,
        duration=duration,
        force_overwrite=True,
        virtual_source=VirtualSourceConfig(name="BQ25570s"),
        power_tracing=None,
        gpio_tracing=None,
        verbose=3,
    )
    run_emulator(emu1)

    log.info("Starting Emulation2, ")
    emu2 = EmulationTask(
        input_path=file_rec,
        output_path=file_emu2,
        duration=duration,
        force_overwrite=True,
        virtual_source=VirtualSourceConfig(name="BQ25570s"),
        verbose=3,
    )
    run_emulator(emu2)

Source: ./tests_manual/testbench_longrun.py