Skip to content

Commit b4f978c

Browse files
committed
Add units, min/max, and alarm limits to Int and Float
1 parent d801675 commit b4f978c

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

src/fastcs/attributes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from enum import Enum
44
from typing import Any, Generic, Protocol, runtime_checkable
55

6-
from .datatypes import ATTRIBUTE_TYPES, AttrCallback, DataType, T
6+
from .datatypes import ATTRIBUTE_TYPES, AttrCallback, DataType, T, validate_value
77

88

99
class AttrMode(Enum):
@@ -115,7 +115,7 @@ def get(self) -> T:
115115
return self._value
116116

117117
async def set(self, value: T) -> None:
118-
self._value = self._datatype.dtype(value)
118+
self._value = self._datatype.dtype(validate_value(self._datatype, value))
119119

120120
if self._update_callback is not None:
121121
await self._update_callback(self._value)
@@ -202,6 +202,6 @@ def __init__(
202202
)
203203

204204
async def process(self, value: T) -> None:
205-
await self.set(value)
205+
await self.set(validate_value(self._datatype, value))
206206

207207
await super().process(value) # type: ignore

src/fastcs/datatypes.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,20 @@ def dtype(self) -> type[T]: # Using property due to lack of Generic ClassVars
2121
pass
2222

2323

24+
T_Numerical = TypeVar("T_Numerical", int, float)
25+
26+
27+
@dataclass(frozen=True)
28+
class _Numerical(DataType[T_Numerical]):
29+
units: str | None = None
30+
min: int | None = None
31+
max: int | None = None
32+
min_alarm: int | None = None
33+
max_alarm: int | None = None
34+
35+
2436
@dataclass(frozen=True)
25-
class Int(DataType[int]):
37+
class Int(_Numerical[int]):
2638
"""`DataType` mapping to builtin ``int``."""
2739

2840
@property
@@ -31,7 +43,7 @@ def dtype(self) -> type[int]:
3143

3244

3345
@dataclass(frozen=True)
34-
class Float(DataType[float]):
46+
class Float(_Numerical[float]):
3547
"""`DataType` mapping to builtin ``float``."""
3648

3749
prec: int = 2
@@ -60,3 +72,15 @@ class String(DataType[str]):
6072
@property
6173
def dtype(self) -> type[str]:
6274
return str
75+
76+
77+
def validate_value(datatype: DataType[T], value: T) -> T:
78+
"""Validate a value against a datatype."""
79+
80+
if isinstance(datatype, (Int | Float)):
81+
assert isinstance(value, (int | float)), f"Value {value} is not a number"
82+
if datatype.min is not None and value < datatype.min:
83+
raise ValueError(f"Value {value} is less than minimum {datatype.min}")
84+
if datatype.max is not None and value > datatype.max:
85+
raise ValueError(f"Value {value} is greater than maximum {datatype.max}")
86+
return value

0 commit comments

Comments
 (0)