Skip to content

Commit

Permalink
Add DynamicInteger for parameter array length
Browse files Browse the repository at this point in the history
  • Loading branch information
fqqb committed Mar 22, 2024
1 parent ca0aecd commit 874cec0
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/yamcs/pymdb/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from collections.abc import Mapping, Sequence
from typing import TYPE_CHECKING

from yamcs.pymdb.datatypes import AggregateDataType, ArrayDataType
from yamcs.pymdb.datatypes import AggregateDataType, ArrayDataType, DynamicInteger

if TYPE_CHECKING:
from yamcs.pymdb.expressions import Expression
Expand Down Expand Up @@ -163,6 +163,8 @@ def fit_entries(self):
length = parameter.length
encoding = parameter.data_type.encoding
if encoding and encoding.bits:
if isinstance(length, DynamicInteger):
raise Exception("Cannot determine dynamic integer value")
bits = length * encoding.bits
elif isinstance(parameter, AggregateDataType):
raise NotImplementedError()
Expand Down
18 changes: 15 additions & 3 deletions src/yamcs/pymdb/datatypes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from collections.abc import Mapping, Sequence
from dataclasses import dataclass
from datetime import datetime
from enum import Enum, auto
from typing import TYPE_CHECKING, Any, Literal, TypeAlias
Expand All @@ -9,7 +10,7 @@

if TYPE_CHECKING:
from yamcs.pymdb.calibrators import Calibrator
from yamcs.pymdb.parameters import AbsoluteTimeParameter
from yamcs.pymdb.parameters import AbsoluteTimeParameter, IntegerParameter


class Epoch(Enum):
Expand All @@ -22,6 +23,17 @@ class Epoch(Enum):
Choices: TypeAlias = list[tuple[int, str] | tuple[int, str, str]] | type[Enum]


@dataclass
class DynamicInteger:
parameter: IntegerParameter | str
"""
Retrieve the value of this parameter.
The parameter may be specified as ``str``, which is intended for referencing
a parameter that is not managed with PyMDB.
"""


class DataType:
def __init__(
self,
Expand Down Expand Up @@ -102,7 +114,7 @@ class ArrayDataType(DataType):
def __init__(
self,
data_type: DataType,
length: int,
length: int | DynamicInteger,
short_description: str | None = None,
long_description: str | None = None,
extra: Mapping[str, str] | None = None,
Expand All @@ -116,7 +128,7 @@ def __init__(
encoding=encoding,
)
self.data_type: DataType = data_type
self.length: int = length
self.length: int | DynamicInteger = length


class BinaryDataType(DataType):
Expand Down
3 changes: 2 additions & 1 deletion src/yamcs/pymdb/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
BooleanDataType,
Choices,
DataType,
DynamicInteger,
EnumeratedDataType,
Epoch,
FloatDataType,
Expand Down Expand Up @@ -248,7 +249,7 @@ def __init__(
system: System,
name: str,
data_type: DataType,
length: int,
length: int | DynamicInteger,
aliases: Mapping[str, str] | None = None,
data_source: DataSource = DataSource.TELEMETERED,
initial_value: Any = None,
Expand Down
21 changes: 20 additions & 1 deletion src/yamcs/pymdb/xtce.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
BooleanMember,
Choices,
DataType,
DynamicInteger,
EnumeratedDataType,
EnumeratedMember,
Epoch,
Expand Down Expand Up @@ -920,8 +921,26 @@ def add_array_parameter_type(
dim_el = ET.SubElement(dims_el, "Dimension")
start_idx_el = ET.SubElement(dim_el, "StartingIndex")
ET.SubElement(start_idx_el, "FixedValue").text = "0"

end_idx_el = ET.SubElement(dim_el, "EndingIndex")
ET.SubElement(end_idx_el, "FixedValue").text = str(data_type.length - 1)
if isinstance(data_type.length, DynamicInteger):
dyn_el = ET.SubElement(end_idx_el, "DynamicValue")
ref_el = ET.SubElement(dyn_el, "ParameterInstanceRef")
parameter = data_type.length.parameter
if isinstance(parameter, Parameter):
ref_el.attrib["parameterRef"] = self.make_ref(
parameter.qualified_name,
start=system,
)
else:
ref_el.attrib["parameterRef"] = self.make_ref(
parameter,
start=system,
)
adj_el = ET.SubElement(dyn_el, "LinearAdjustment")
adj_el.attrib["intercept"] = "-1"
else:
ET.SubElement(end_idx_el, "FixedValue").text = str(data_type.length - 1)

el_type = data_type.data_type
if isinstance(el_type, AbsoluteTimeDataType):
Expand Down

0 comments on commit 874cec0

Please sign in to comment.