Shepherd-Core - Config-Models

Note

TODO: WORK IN PROGRESS

The models offer

  • one unified interface for all tools

  • auto-completion with neutral / sensible values

  • complex and custom datatypes (i.e. PositiveInt, lists-checks on length)

  • checking of inputs (validation) and type-casting

  • generate their own schema (for web-forms)

  • recursive inheritance (for content-configs)

  • pre-validation

  • store to & load from yaml or json with typecheck through wrapper

  • included documentation

Experiment

This category includes configuration-models for setting up an experiment. Part of the sub-systems are in the next section Observer Capabilities.

pydantic model shepherd_core.data_models.experiment.Experiment

Config for experiments on the testbed emulating energy environments for target nodes.

Fields:
  • id (uuid.UUID | int)

  • name (str)

  • description (str | None)

  • comment (str | None)

  • created (datetime.datetime)

  • owner_id (int | None)

  • email_results (bool)

  • sys_logging (shepherd_core.data_models.experiment.observer_features.SystemLogging)

  • time_start (datetime.datetime | None)

  • duration (datetime.timedelta | None)

  • abort_on_error (bool)

  • target_configs (List[shepherd_core.data_models.experiment.target_config.TargetConfig])

  • lib_ver (str | None)

field id: Annotated[UUID, UuidVersion(uuid_version=4)] | int [Optional]
field name: StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=32, pattern=^[^<>:;,?\"\*|\/\\]+$)] [Required]
Constraints:
  • max_length = 32

  • pattern = ^[^<>:;,?"*|/\]+$

field description: StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[ -~]+$)] | None, FieldInfo(annotation=NoneType, required=True, description='Required for public instances')] = None

Required for public instances

field comment: StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[ -~]+$)] | None = None
field created: datetime [Optional]
field owner_id: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=340282366920938463463374607431768211456)])] | None = None
field email_results: bool = False
field sys_logging: SystemLogging = SystemLogging({})
field time_start: datetime | None = None
field duration: timedelta | None = None
field abort_on_error: bool = False
field target_configs: Annotated[List[TargetConfig], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1), MaxLen(max_length=128)])] [Required]
Constraints:
  • min_length = 1

  • max_length = 128

field lib_ver: str | None = '2025.02.2'
get_target_ids() list
get_target_config(target_id: int) TargetConfig
pydantic model shepherd_core.data_models.experiment.TargetConfig

Configuration related to Target Nodes (DuT).

Fields:
  • target_IDs (List[int])

  • custom_IDs (List[int] | None)

  • energy_env (shepherd_core.data_models.content.energy_environment.EnergyEnvironment)

  • virtual_source (shepherd_core.data_models.content.virtual_source.VirtualSourceConfig)

  • target_delays (List[int] | None)

  • firmware1 (shepherd_core.data_models.content.firmware.Firmware)

  • firmware2 (shepherd_core.data_models.content.firmware.Firmware | None)

  • power_tracing (shepherd_core.data_models.experiment.observer_features.PowerTracing | None)

  • gpio_tracing (shepherd_core.data_models.experiment.observer_features.GpioTracing | None)

  • gpio_actuation (shepherd_core.data_models.experiment.observer_features.GpioActuation | None)

field target_IDs: Annotated[List[Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=340282366920938463463374607431768211456)])]], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1), MaxLen(max_length=128)])] [Required]
Constraints:
  • min_length = 1

  • max_length = 128

field custom_IDs: Annotated[List[Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=65536)])]], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1), MaxLen(max_length=128)])] | None = None
field energy_env: EnergyEnvironment [Required]
field virtual_source: VirtualSourceConfig = VirtualSourceConfig({'id': 1000, 'name': 'neutral', 'description': 'Direct feed-through of energy environment with no converter (allows on-off-patters)', 'created': datetime.datetime(2022, 12, 12, 12, 12, 12), 'updated_last': datetime.datetime(2022, 12, 12, 12, 12, 12), 'owner': 'Ingmar', 'group': 'NES Lab', 'visible2group': True, 'visible2all': True})
field target_delays: Annotated[List[Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0)])]], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1), MaxLen(max_length=128)])] | None = None
field firmware1: Firmware [Required]
field firmware2: Firmware | None = None
field power_tracing: PowerTracing | None = None
field gpio_tracing: GpioTracing | None = None
field gpio_actuation: GpioActuation | None = None
get_custom_id(target_id: int) int | None

Observer Capabilities

These are some of the sub-systems for configuring experiments and also tasks.

Link to Source

pydantic model shepherd_core.data_models.experiment.PowerTracing

Configuration for recording the Power-Consumption of the Target Nodes.

TODO: postprocessing not implemented ATM

Fields:
  • intermediate_voltage (bool)

  • delay (datetime.timedelta)

  • duration (datetime.timedelta | None)

  • calculate_power (bool)

  • samplerate (int)

  • discard_current (bool)

  • discard_voltage (bool)

field intermediate_voltage: bool = False
field delay: timedelta = 0
field duration: timedelta | None = None
field calculate_power: bool = False
field samplerate: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=10), Le(le=100000)])] = 100000
Constraints:
  • ge = 10

  • le = 100000

field discard_current: bool = False
field discard_voltage: bool = False
pydantic model shepherd_core.data_models.experiment.GpioTracing

Configuration for recording the GPIO-Output of the Target Nodes.

TODO: postprocessing not implemented ATM

Fields:
  • mask (int)

  • gpios (List[shepherd_core.data_models.testbed.gpio.GPIO] | None)

  • delay (datetime.timedelta)

  • duration (datetime.timedelta | None)

  • uart_decode (bool)

  • uart_pin (shepherd_core.data_models.testbed.gpio.GPIO)

  • uart_baudrate (int)

field mask: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=1024)])] = 1023
Constraints:
  • ge = 0

  • lt = 1024

field gpios: Annotated[List[GPIO], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1), MaxLen(max_length=10)])] | None = None
field delay: timedelta = 0
field duration: timedelta | None = None
field uart_decode: bool = False
field uart_pin: GPIO = GPIO({'id': 1008, 'name': 'GPIO8', 'description': 'alias UART_TX', 'direction': 'IO', 'dir_switch': 'DIR2', 'reg_pru': 'r31_08', 'pin_pru': 'P8_27', 'reg_sys': 15, 'pin_sys': 'P9_24'})
field uart_baudrate: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=2400), Le(le=921600)])] = 115200
Constraints:
  • ge = 2400

  • le = 921600

deactiveated due to Error (TODO)
.. autopydantic_model:: shepherd_core.data_models.experiment.GpioActuation
.. autopydantic_model:: shepherd_core.data_models.experiment.GpioLevel
pydantic model shepherd_core.data_models.experiment.SystemLogging

Configuration for recording Debug-Output of the Observers System-Services.

Fields:
  • dmesg (bool)

  • ptp (bool)

  • shepherd (bool)

field dmesg: bool = True
field ptp: bool = True
field shepherd: bool = True

Content-Types

Reusable user-defined meta-data for fw, h5 and vsrc-definitions.

Link to Source

pydantic model shepherd_core.data_models.content.EnergyEnvironment

Recording of meta-data representation of a testbed-component.

Fields:
  • data_path (pathlib.Path)

  • data_type (shepherd_core.data_models.content.energy_environment.EnergyDType)

  • data_local (bool)

  • duration (float)

  • energy_Ws (float)

  • valid (bool)

  • light_source (str | None)

  • weather_conditions (str | None)

  • indoor (bool | None)

  • location (str | None)

field data_path: Path [Required]
field data_type: EnergyDType [Required]
field data_local: bool = True
field duration: Annotated[float, Gt(gt=0)] [Required]
Constraints:
  • gt = 0

field energy_Ws: Annotated[float, Gt(gt=0)] [Required]
Constraints:
  • gt = 0

field valid: bool = False
field light_source: str | None = None
field weather_conditions: str | None = None
field indoor: bool | None = None
field location: str | None = None
pydantic model shepherd_core.data_models.content.Firmware

meta-data representation of a data-component.

Fields:
  • mcu (shepherd_core.data_models.testbed.mcu.MCU)

  • data (str | pathlib.Path)

  • data_type (shepherd_core.data_models.content.firmware_datatype.FirmwareDType)

  • data_hash (str | None)

  • data_local (bool)

field mcu: MCU [Required]
field data: Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=3, max_length=8000000, pattern=None)] | Path [Required]
field data_type: FirmwareDType [Required]
field data_hash: str | None = None
field data_local: bool = True
classmethod from_firmware(file: Path, *, embed: bool = True, **kwargs: Unpack[TypedDict]) Self

Embeds firmware and tries to fill parameters.

ELF -> mcu und data_type are deducted HEX -> must supply mcu manually.

compare_hash(path: Path | None = None) bool
extract_firmware(file: Path) Path

Store embedded fw-data in file.

  • file-suffix is derived from data-type and adapted

  • if provided path is a directory, the firmware-name is used

pydantic model shepherd_core.data_models.content.VirtualHarvesterConfig

A vHrv makes a source-characterization (i.e. ivcurve) usable for the vSrc.

Mostly used when the file-based energy environment of the virtual source is not already supplied as pre-harvested ivsample-stream.

Fields:
  • algorithm (shepherd_core.data_models.content.virtual_harvester.AlgorithmDType)

  • samples_n (int)

  • voltage_mV (float)

  • voltage_min_mV (float)

  • voltage_max_mV (float)

  • current_limit_uA (float)

  • voltage_step_mV (float | None)

  • setpoint_n (float)

  • interval_ms (float)

  • duration_ms (float)

  • rising (bool)

  • enable_linear_extrapolation (bool)

  • wait_cycles (int)

field algorithm: AlgorithmDType [Required]
field samples_n: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=8), Le(le=2000)])] = 8
Constraints:
  • ge = 8

  • le = 2000

field voltage_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=5000)])] = 2500
Constraints:
  • ge = 0

  • le = 5000

field voltage_min_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=5000)])] = 0
Constraints:
  • ge = 0

  • le = 5000

field voltage_max_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=5000)])] = 5000
Constraints:
  • ge = 0

  • le = 5000

field current_limit_uA: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=50000)])] = 50000
Constraints:
  • ge = 1

  • le = 50000

field voltage_step_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=1000000)])] | None = None
field setpoint_n: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=1.0)])] = 0.7
Constraints:
  • ge = 0

  • le = 1.0

field interval_ms: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.01), Le(le=1000000)])] = 100
Constraints:
  • ge = 0.01

  • le = 1000000

field duration_ms: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.01), Le(le=1000000)])] = 0.1
Constraints:
  • ge = 0.01

  • le = 1000000

field rising: bool = True
field enable_linear_extrapolation: bool = True
field wait_cycles: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=100)])] = 1
Constraints:
  • ge = 0

  • le = 100

calc_hrv_mode(*, for_emu: bool) int
calc_algorithm_num(*, for_emu: bool) int
calc_timings_ms(*, for_emu: bool) Tuple[float, float]

factor-in model-internal timing-constraints.

get_datatype() EnergyDType
calc_window_size(dtype_in: EnergyDType | None = None, *, for_emu: bool) int
pydantic model shepherd_core.data_models.content.VirtualSourceConfig

The vSrc uses the energy environment (file) for supplying the Target Node.

If not already done, the energy will be harvested and then converted during the experiment.

The converter-stage is software defined and offers: - buck-boost-combinations, - a simple diode + resistor and - an intermediate buffer capacitor.

Fields:
  • enable_boost (bool)

  • enable_buck (bool)

  • enable_feedback_to_hrv (bool)

  • interval_startup_delay_drain_ms (float)

  • harvester (shepherd_core.data_models.content.virtual_harvester.VirtualHarvesterConfig)

  • V_input_max_mV (float)

  • I_input_max_mA (float)

  • V_input_drop_mV (float)

  • R_input_mOhm (float)

  • C_intermediate_uF (float)

  • V_intermediate_init_mV (float)

  • I_intermediate_leak_nA (float)

  • V_intermediate_enable_threshold_mV (float)

  • V_intermediate_disable_threshold_mV (float)

  • interval_check_thresholds_ms (float)

  • V_pwr_good_enable_threshold_mV (float)

  • V_pwr_good_disable_threshold_mV (float)

  • immediate_pwr_good_signal (bool)

  • C_output_uF (float)

  • V_output_log_gpio_threshold_mV (float)

  • V_input_boost_threshold_mV (float)

  • V_intermediate_max_mV (float)

  • LUT_input_efficiency (List[List[float]])

  • LUT_input_V_min_log2_uV (int)

  • LUT_input_I_min_log2_nA (int)

  • V_output_mV (float)

  • V_buck_drop_mV (float)

  • LUT_output_efficiency (List[float])

  • LUT_output_I_min_log2_nA (int)

field enable_boost: bool = False
field enable_buck: bool = False
field enable_feedback_to_hrv: bool = False
field interval_startup_delay_drain_ms: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 0
Constraints:
  • ge = 0

  • le = 10000

field harvester: VirtualHarvesterConfig = VirtualHarvesterConfig({'id': 2206, 'name': 'mppt_opt', 'description': 'Power-Optimum with very fast PO-Variant (harvesting) or special max-pwr-picker (emulator / ivcurve)', 'created': datetime.datetime(2022, 12, 12, 12, 12, 12), 'updated_last': datetime.datetime(2022, 12, 12, 12, 12, 12), 'owner': 'Ingmar', 'group': 'NES Lab', 'visible2group': True, 'visible2all': True, 'algorithm': 'mppt_opt', 'voltage_step_mV': 1.0, 'interval_ms': 0.01})
field V_input_max_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 10000
Constraints:
  • ge = 0

  • le = 10000

field I_input_max_mA: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4290.0)])] = 4200
Constraints:
  • ge = 0

  • le = 4290.0

field V_input_drop_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4290000.0)])] = 0
Constraints:
  • ge = 0

  • le = 4290000.0

field R_input_mOhm: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4290000.0)])] = 0
Constraints:
  • ge = 0

  • le = 4290000.0

field C_intermediate_uF: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=100000)])] = 0
Constraints:
  • ge = 0

  • le = 100000

field V_intermediate_init_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 3000
Constraints:
  • ge = 0

  • le = 10000

field I_intermediate_leak_nA: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4290000000.0)])] = 0
Constraints:
  • ge = 0

  • le = 4290000000.0

field V_intermediate_enable_threshold_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 1
Constraints:
  • ge = 0

  • le = 10000

field V_intermediate_disable_threshold_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 0
Constraints:
  • ge = 0

  • le = 10000

field interval_check_thresholds_ms: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4290.0)])] = 0
Constraints:
  • ge = 0

  • le = 4290.0

field V_pwr_good_enable_threshold_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 2800
Constraints:
  • ge = 0

  • le = 10000

field V_pwr_good_disable_threshold_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 2200
Constraints:
  • ge = 0

  • le = 10000

field immediate_pwr_good_signal: bool = True
field C_output_uF: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4290000.0)])] = 1.0
Constraints:
  • ge = 0

  • le = 4290000.0

field V_output_log_gpio_threshold_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4290000.0)])] = 1400
Constraints:
  • ge = 0

  • le = 4290000.0

field V_input_boost_threshold_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 0
Constraints:
  • ge = 0

  • le = 10000

field V_intermediate_max_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=10000)])] = 10000
Constraints:
  • ge = 0

  • le = 10000

field LUT_input_efficiency: Annotated[List[Annotated[List[Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.0), Le(le=1.0)])]], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=12), MaxLen(max_length=12)])]], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=12), MaxLen(max_length=12)])] = [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]]
Constraints:
  • min_length = 12

  • max_length = 12

field LUT_input_V_min_log2_uV: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=20)])] = 0
Constraints:
  • ge = 0

  • le = 20

field LUT_input_I_min_log2_nA: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=20)])] = 1
Constraints:
  • ge = 1

  • le = 20

field V_output_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=5000)])] = 2400
Constraints:
  • ge = 0

  • le = 5000

field V_buck_drop_mV: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=5000)])] = 0
Constraints:
  • ge = 0

  • le = 5000

field LUT_output_efficiency: Annotated[List[Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.0), Le(le=1.0)])]], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=12), MaxLen(max_length=12)])] = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
Constraints:
  • min_length = 12

  • max_length = 12

field LUT_output_I_min_log2_nA: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=20)])] = 1
Constraints:
  • ge = 1

  • le = 20

calc_internal_states() dict

Update the model-states for the capacitor and other elements.

This also compensates for current-surge of real capacitors when the converter gets turned on:

  • surges are hard to detect & record

  • this can be const value, because

  • the converter always turns on with “V_storage_enable_threshold_uV”.

TODO: currently neglecting delay after disabling converter, boost only has simpler formula, second enabling when V_Cap >= V_out

Math behind this calculation:

  • Energy-Change Storage Cap -> E_new = E_old - E_output

  • with Energy of a Cap -> E_x = C_x * V_x^2 / 2

  • combine formulas -> C_store * V_store_new^2 / 2 = C_store * V_store_old^2 / 2 - C_out * V_out^2 / 2

  • convert formula to V_new -> V_store_new^2 = V_store_old^2 - (C_out / C_store) * V_out^2

  • convert into dV -> dV = V_store_new - V_store_old

  • in case of V_cap = V_out -> dV = V_store_old * (sqrt(1 - C_out / C_store) - 1)

Note: dV values will be reversed (negated), because dV is always negative (Voltage drop)

calc_converter_mode(dtype_in: EnergyDType, *, log_intermediate_node: bool) int

Assembles bitmask from discrete values.

log_intermediate_node: record / log virtual intermediate (cap-)voltage and -current (out) instead of output-voltage and -current

calc_cap_constant_us_per_nF_n28() int

Calc constant to convert capacitor-current to Voltage-delta.

dV[uV] = constant[us/nF] * current[nA] = constant[us*V/nAs] * current[nA]

Tasks

These are digestible configs for shepherd-herd or -sheep.

Link to Source

pydantic model shepherd_core.data_models.task.HarvestTask

Config for the Observer in Harvest-Mode to record IV data from a harvesting-source.

Fields:
  • output_path (pathlib.Path)

  • force_overwrite (bool)

  • output_compression (shepherd_core.data_models.task.emulation.Compression | None)

  • time_start (datetime.datetime | None)

  • duration (datetime.timedelta | None)

  • abort_on_error (bool)

  • use_cal_default (bool)

  • virtual_harvester (shepherd_core.data_models.content.virtual_harvester.VirtualHarvesterConfig)

  • power_tracing (shepherd_core.data_models.experiment.observer_features.PowerTracing)

  • sys_logging (shepherd_core.data_models.experiment.observer_features.SystemLogging | None)

  • verbose (int)

field output_path: Path [Required]
field force_overwrite: bool = False
field output_compression: Compression | None = Compression.lzf
field time_start: datetime | None = None
field duration: timedelta | None = None
field abort_on_error: bool = False
field use_cal_default: bool = False
field virtual_harvester: VirtualHarvesterConfig = VirtualHarvesterConfig({'id': 2206, 'name': 'mppt_opt', 'description': 'Power-Optimum with very fast PO-Variant (harvesting) or special max-pwr-picker (emulator / ivcurve)', 'created': datetime.datetime(2022, 12, 12, 12, 12, 12), 'updated_last': datetime.datetime(2022, 12, 12, 12, 12, 12), 'owner': 'Ingmar', 'group': 'NES Lab', 'visible2group': True, 'visible2all': True, 'algorithm': 'mppt_opt', 'voltage_step_mV': 1.0, 'interval_ms': 0.01})
field power_tracing: PowerTracing = PowerTracing({})
field sys_logging: SystemLogging | None = SystemLogging({})
field verbose: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4)])] = 2
Constraints:
  • ge = 0

  • le = 4

pydantic model shepherd_core.data_models.task.EmulationTask

Configuration for the Observer in Emulation-Mode.

Fields:
  • input_path (pathlib.Path)

  • output_path (pathlib.Path | None)

  • force_overwrite (bool)

  • output_compression (shepherd_core.data_models.task.emulation.Compression | None)

  • time_start (datetime.datetime | None)

  • duration (datetime.timedelta | None)

  • abort_on_error (bool)

  • use_cal_default (bool)

  • enable_io (bool)

  • io_port (shepherd_core.data_models.testbed.cape.TargetPort)

  • pwr_port (shepherd_core.data_models.testbed.cape.TargetPort)

  • voltage_aux (float | str)

  • virtual_source (shepherd_core.data_models.content.virtual_source.VirtualSourceConfig)

  • power_tracing (shepherd_core.data_models.experiment.observer_features.PowerTracing | None)

  • gpio_tracing (shepherd_core.data_models.experiment.observer_features.GpioTracing | None)

  • gpio_actuation (shepherd_core.data_models.experiment.observer_features.GpioActuation | None)

  • sys_logging (shepherd_core.data_models.experiment.observer_features.SystemLogging | None)

  • verbose (int)

field input_path: Path [Required]
field output_path: Path | None = None
field force_overwrite: bool = False
field output_compression: Compression | None = Compression.lzf
field time_start: datetime | None = None
field duration: timedelta | None = None
field abort_on_error: bool = False
field use_cal_default: bool = False
field enable_io: bool = False
field io_port: TargetPort = TargetPort.A
field pwr_port: TargetPort = TargetPort.A
field voltage_aux: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4.5)])] | str = 0
field virtual_source: VirtualSourceConfig = VirtualSourceConfig({'id': 1000, 'name': 'neutral', 'description': 'Direct feed-through of energy environment with no converter (allows on-off-patters)', 'created': datetime.datetime(2022, 12, 12, 12, 12, 12), 'updated_last': datetime.datetime(2022, 12, 12, 12, 12, 12), 'owner': 'Ingmar', 'group': 'NES Lab', 'visible2group': True, 'visible2all': True})
field power_tracing: PowerTracing | None = PowerTracing({})
field gpio_tracing: GpioTracing | None = GpioTracing({})
field gpio_actuation: GpioActuation | None = None
field sys_logging: SystemLogging | None = SystemLogging({})
field verbose: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4)])] = 2
Constraints:
  • ge = 0

  • le = 4

classmethod from_xp(xp: Experiment, tb: Testbed, tgt_id: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=340282366920938463463374607431768211456)])], root_path: Path) Self
pydantic model shepherd_core.data_models.task.FirmwareModTask

Config for Task that adds the custom ID to the firmware & stores it into a file.

Fields:
  • data (str | pathlib.Path)

  • data_type (shepherd_core.data_models.content.firmware_datatype.FirmwareDType)

  • custom_id (int | None)

  • firmware_file (pathlib.Path)

  • verbose (int)

field data: Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=3, max_length=8000000, pattern=None)] | Path [Required]
field data_type: FirmwareDType [Required]
field custom_id: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=65536)])] | None = None
field firmware_file: Path [Required]
field verbose: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4)])] = 2
Constraints:
  • ge = 0

  • le = 4

classmethod from_xp(xp: Experiment, tb: Testbed, tgt_id: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=340282366920938463463374607431768211456)])], mcu_port: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=2)])], fw_path: Path) Self
classmethod from_firmware(fw: Firmware, **kwargs: Unpack[TypedDict]) Self
pydantic model shepherd_core.data_models.task.ProgrammingTask

Config for a Task programming the selected target.

Fields:
  • firmware_file (pathlib.Path)

  • target_port (shepherd_core.data_models.testbed.cape.TargetPort)

  • mcu_port (int)

  • mcu_type (str)

  • voltage (float)

  • datarate (int)

  • protocol (shepherd_core.data_models.testbed.mcu.ProgrammerProtocol)

  • simulate (bool)

  • verbose (int)

field firmware_file: Path [Required]
field target_port: TargetPort = TargetPort.A
field mcu_port: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=2)])] = 1
Constraints:
  • ge = 1

  • le = 2

field mcu_type: StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[ -~]+$)] [Required]
Constraints:
  • pattern = ^[ -~]+$

field voltage: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Lt(lt=5)])] = 3
Constraints:
  • ge = 1

  • lt = 5

field datarate: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Gt(gt=0), Le(le=1000000)])] = 200000
Constraints:
  • gt = 0

  • le = 1000000

field protocol: ProgrammerProtocol [Required]
field simulate: bool = False
field verbose: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Le(le=4)])] = 2
Constraints:
  • ge = 0

  • le = 4

classmethod from_xp(xp: Experiment, tb: Testbed, tgt_id: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=340282366920938463463374607431768211456)])], mcu_port: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=2)])], fw_path: Path) Self | None
pydantic model shepherd_core.data_models.task.ObserverTasks

Collection of tasks for selected observer included in experiment.

Fields:
  • observer (str)

  • owner_id (int | None)

  • time_prep (datetime.datetime)

  • root_path (pathlib.Path)

  • abort_on_error (bool)

  • fw1_mod (shepherd_core.data_models.task.firmware_mod.FirmwareModTask | None)

  • fw2_mod (shepherd_core.data_models.task.firmware_mod.FirmwareModTask | None)

  • fw1_prog (shepherd_core.data_models.task.programming.ProgrammingTask | None)

  • fw2_prog (shepherd_core.data_models.task.programming.ProgrammingTask | None)

  • emulation (shepherd_core.data_models.task.emulation.EmulationTask | None)

field observer: StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=32, pattern=^[^<>:;,?\"\*|\/\\]+$)] [Required]
Constraints:
  • max_length = 32

  • pattern = ^[^<>:;,?"*|/\]+$

field owner_id: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=340282366920938463463374607431768211456)])] | None [Required]
field time_prep: datetime [Required]
field root_path: Path [Required]
field abort_on_error: bool [Required]
field fw1_mod: FirmwareModTask | None = None
field fw2_mod: FirmwareModTask | None = None
field fw1_prog: ProgrammingTask | None = None
field fw2_prog: ProgrammingTask | None = None
field emulation: EmulationTask | None = None
classmethod from_xp(xp: Experiment, tb: Testbed, tgt_id: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=340282366920938463463374607431768211456)])]) Self
get_tasks() List[ShpModel]
get_output_paths() dict
pydantic model shepherd_core.data_models.task.TestbedTasks

Collection of tasks for all observers included in experiment.

Fields:
  • name (str)

  • observer_tasks (List[shepherd_core.data_models.task.observer_tasks.ObserverTasks])

  • email_results (bool)

  • owner_id (int | None)

field name: StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=32, pattern=^[^<>:;,?\"\*|\/\\]+$)] [Required]
Constraints:
  • max_length = 32

  • pattern = ^[^<>:;,?"*|/\]+$

field observer_tasks: Annotated[List[ObserverTasks], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1), MaxLen(max_length=128)])] [Required]
Constraints:
  • min_length = 1

  • max_length = 128

field email_results: bool = False
field owner_id: Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0), Lt(lt=340282366920938463463374607431768211456)])] | None [Required]
classmethod from_xp(xp: Experiment, tb: Testbed | None = None) Self
get_observer_tasks(observer: str) ObserverTasks | None
get_output_paths() dict