Skip to content
Snippets Groups Projects
Commit bf20ebc8 authored by Matthias Stefan Bodenbenner's avatar Matthias Stefan Bodenbenner
Browse files

updated requirements

parent 48d4ae57
No related branches found
No related tags found
No related merge requests found
Pipeline #377256 passed
[![Build](https://git-ce.rwth-aachen.de/wzl-mq-ms/forschung-lehre/lava/unified-device-interface/python/badges/master/pipeline.svg)](https://git-ce.rwth-aachen.de/wzl-mq-ms/forschung-lehre/lava/unified-device-interface/python/commits/master) [![Build](https://git-ce.rwth-aachen.de/wzl-mq-ms/forschung-lehre/lava/unified-device-interface/python/badges/master/pipeline.svg)](https://git-ce.rwth-aachen.de/wzl-mq-ms/forschung-lehre/lava/unified-device-interface/python/commits/master)
# Python Unified Device Interface # Python Unified Device Interface
Current stable version: 10.0.5 Current stable version: 10.0.6
## Installation ## Installation
1. Install the WZL-UDI package via pip 1. Install the WZL-UDI package via pip
...@@ -22,28 +22,28 @@ Examples of fictional devices using the library can be found [here](https://git- ...@@ -22,28 +22,28 @@ Examples of fictional devices using the library can be found [here](https://git-
Scientific background and publications related to the _(Python) Unified Device Interface_ are: Scientific background and publications related to the _(Python) Unified Device Interface_ are:
[Bodenbenner, M.](mailto:m.bodenbenner@wzl-mq.rwth-aachen.de); Sanders, M. P.; Montavon, B.; Schmitt, R. H. (2021): [Bodenbenner, M.](mailto:matthias.bodenbenner@wzl-iqs.rwth-aachen.de); Sanders, M. P.; Montavon, B.; Schmitt, R. H. (2021):
Domain-Specific Language for Sensors in the Internet of Production. Domain-Specific Language for Sensors in the Internet of Production.
In: Bernd-Arno Behrens, Alexander Brosius, Wolfgang Hintze, Steffen Ihlenfeldt und Jens Peter Wulfsberg (Hg.): In: Bernd-Arno Behrens, Alexander Brosius, Wolfgang Hintze, Steffen Ihlenfeldt und Jens Peter Wulfsberg (Hg.):
Production at the leading edge of technology. Proceedings of the 10th Congress of the German Academic Association for Production Technology (WGP), Dresden, 23-24 September 2020. Berlin, Heidelberg, 2021. 1st ed. 2021. Berlin, Heidelberg: Springer (Lecture Notes in Production Engineering), S. 448–456, Production at the leading edge of technology. Proceedings of the 10th Congress of the German Academic Association for Production Technology (WGP), Dresden, 23-24 September 2020. Berlin, Heidelberg, 2021. 1st ed. 2021. Berlin, Heidelberg: Springer (Lecture Notes in Production Engineering), S. 448–456,
http://dx.doi.org/10.1007/978-3-662-62138-7_45 http://dx.doi.org/10.1007/978-3-662-62138-7_45
[Bodenbenner, M.](mailto:m.bodenbenner@wzl-mq.rwth-aachen.de); Montavon, B.; Schmitt, R.H. (2021): [Bodenbenner, M.](mailto:matthias.bodenbenner@wzl-iqs.rwth-aachen.de); Montavon, B.; Schmitt, R.H. (2021):
FAIR sensor services - Towards sustainable sensor data management. FAIR sensor services - Towards sustainable sensor data management.
In: Measurement: Sensors 18, S. 100206, In: Measurement: Sensors 18, S. 100206,
https://doi.org/10.1016/j.measen.2021.100206 https://doi.org/10.1016/j.measen.2021.100206
[Bodenbenner, M.](mailto:m.bodenbenner@wzl-mq.rwth-aachen.de); Montavon, B.; Schmitt, R.H. (2022): [Bodenbenner, M.](mailto:matthias.bodenbenner@wzl-iqs.rwth-aachen.de); Montavon, B.; Schmitt, R.H. (2022):
Model-driven development of interoperable communication interfaces for FAIR sensor services, Model-driven development of interoperable communication interfaces for FAIR sensor services,
In: Measurement: Sensors, Volume 24, S. 100442, In: Measurement: Sensors, Volume 24, S. 100442,
https://doi.org/10.1016/j.measen.2022.100442 https://doi.org/10.1016/j.measen.2022.100442
[Montavon, B.](mailto:b.montavon@wzl-mq.rwth-aachen.de) (2021): [Montavon, B.](mailto:benjamin.montavon@wzl-iqd.rwth-aachen.de) (2021):
Virtual Reference Frame Based on Distributed Large-Scale Metrology Providing Coordinates as a Service. Virtual Reference Frame Based on Distributed Large-Scale Metrology Providing Coordinates as a Service.
Aachen: Apprimus Verlag, Aachen: Apprimus Verlag,
https://doi.org/10.18154/RWTH-2021-10238 https://doi.org/10.18154/RWTH-2021-10238
[Montavon, B.](mailto:b.montavon@wzl-mq.rwth-aachen.de); Peterek, M.; Schmitt, R. H. (2019): [Montavon, B.](mailto:benjamin.montavon@wzl-iqd.rwth-aachen.de); Peterek, M.; Schmitt, R. H. (2019):
Model-based interfacing of large-scale metrology instruments. Model-based interfacing of large-scale metrology instruments.
In: Ettore Stella (Hg.): Multimodal Sensing: Technologies and Applications. 26-27 June 2019, Munich, Germany. Multimodal Sensing and Artificial Intelligence: Technologies and Applications. Munich, Germany, 6/24/2019 - 6/27/2019. Bellingham, Washington: SPIE (Proceedings of SPIE. 5200-, volume 11059), S. 11, In: Ettore Stella (Hg.): Multimodal Sensing: Technologies and Applications. 26-27 June 2019, Munich, Germany. Multimodal Sensing and Artificial Intelligence: Technologies and Applications. Munich, Germany, 6/24/2019 - 6/27/2019. Bellingham, Washington: SPIE (Proceedings of SPIE. 5200-, volume 11059), S. 11,
https://doi.org/10.1117/12.2527461 https://doi.org/10.1117/12.2527461
...@@ -56,7 +56,7 @@ Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) ...@@ -56,7 +56,7 @@ Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation)
Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) under Project-ID 432233186 -- AIMS. Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) under Project-ID 432233186 -- AIMS.
## License of used third-party libraries ## Licenses of third-party libraries used
| Library | License | | Library | License |
|--------------|---------------------------------------| |--------------|---------------------------------------|
...@@ -69,10 +69,13 @@ Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) ...@@ -69,10 +69,13 @@ Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation)
## Recent changes ## Recent changes
**10.0.6** - 2024-03-22
- fixed validation of rfc3339 datetime strings
**10.0.5** - 2024-03-22 **10.0.5** - 2024-03-22
- bug fix in streaming - bug fix in streaming
- **10.0.4** - 2024-03-22 **10.0.4** - 2024-03-22
- increased logging verbosity of streaming class - increased logging verbosity of streaming class
- fixed streaming of semantic measurements - fixed streaming of semantic measurements
......
...@@ -4,7 +4,7 @@ with open("README.md", "r", encoding="utf-8") as fh: ...@@ -4,7 +4,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read() long_description = fh.read()
setup(name='wzl-udi', setup(name='wzl-udi',
version='10.0.5', version='10.0.6',
url='https://git-ce.rwth-aachen.de/wzl-mq-public/soil/python', url='https://git-ce.rwth-aachen.de/wzl-mq-public/soil/python',
project_urls={ project_urls={
"Bug Tracker": "https://git-ce.rwth-aachen.de/wzl-mq-public/soil/python/-/issues", "Bug Tracker": "https://git-ce.rwth-aachen.de/wzl-mq-public/soil/python/-/issues",
......
...@@ -24,6 +24,31 @@ from ..utils.error import DeviceException ...@@ -24,6 +24,31 @@ from ..utils.error import DeviceException
logger = root_logger.get(__name__) logger = root_logger.get(__name__)
def validate_time(time_rfc3339: Union[str, List]):
if isinstance(time_rfc3339, list):
for e in time_rfc3339:
if not validate_time(e):
return False
return True
else:
if time_rfc3339 is None or time_rfc3339 == "":
return False
formats = ["%Y-%m-%dT%H:%M:%S.%f%z", "%Y-%m-%dT%H:%M:%S%z", "%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m-%dT%H:%M:%SZ"]
for fmt in formats:
try:
if fmt.endswith('Z'):
datetime.datetime.strptime(time_rfc3339.rstrip('Z'), fmt.rstrip('Z'))
else:
datetime.datetime.strptime(time_rfc3339, fmt)
return True
except ValueError:
continue
return False
def parse_time(time_rfc3339: Union[str, List]): def parse_time(time_rfc3339: Union[str, List]):
if isinstance(time_rfc3339, list): if isinstance(time_rfc3339, list):
return [parse_time(e) for e in time_rfc3339] return [parse_time(e) for e in time_rfc3339]
...@@ -38,10 +63,10 @@ def parse_time(time_rfc3339: Union[str, List]): ...@@ -38,10 +63,10 @@ def parse_time(time_rfc3339: Union[str, List]):
# Attempt to parse the timestamp with the current format # Attempt to parse the timestamp with the current format
if fmt.endswith('Z'): if fmt.endswith('Z'):
# Strip the 'Z' and replace it after parsing if format specifies 'Z' at the end # Strip the 'Z' and replace it after parsing if format specifies 'Z' at the end
dt = datetime.strptime(time_rfc3339.rstrip('Z'), fmt.rstrip('Z')) dt = datetime.datetime.strptime(time_rfc3339.rstrip('Z'), fmt.rstrip('Z'))
dt = dt.replace(tzinfo=pytz.UTC) dt = dt.replace(tzinfo=pytz.UTC)
else: else:
dt = datetime.strptime(time_rfc3339, fmt) dt = datetime.datetime.strptime(time_rfc3339, fmt)
return dt return dt
except ValueError: except ValueError:
...@@ -217,7 +242,7 @@ class Variable(Element, ABC): ...@@ -217,7 +242,7 @@ class Variable(Element, ABC):
"Time field {} must be string.".format( "Time field {} must be string.".format(
value)) value))
elif datatype == Datatype.TIME and isinstance(value, str): elif datatype == Datatype.TIME and isinstance(value, str):
if value != "" and value is not None and not rfc3339.validate_rfc3339(value): if value != "" and value is not None and not validate_time(value):
raise TypeException("Value is not a valid RFC3339-formatted timestring: {}".format(value)) raise TypeException("Value is not a valid RFC3339-formatted timestring: {}".format(value))
else: else:
# recursion case: value is an array or matrix => check datatype of each "subvalue" recursively # recursion case: value is an array or matrix => check datatype of each "subvalue" recursively
...@@ -279,7 +304,7 @@ class Variable(Element, ABC): ...@@ -279,7 +304,7 @@ class Variable(Element, ABC):
raise RangeException("Enum value {} is not within the set of allowed values!".format(value)) raise RangeException("Enum value {} is not within the set of allowed values!".format(value))
elif datatype == Datatype.TIME and value is not None and value != "": elif datatype == Datatype.TIME and value is not None and value != "":
if range[0] is not None: if range[0] is not None:
if not rfc3339.validate_rfc3339(range[0]): if not validate_time(range[0]):
raise TypeException( raise TypeException(
"Can not check range of time value. Lower bound {} is not a valid RFC3339 timestring.".format( "Can not check range of time value. Lower bound {} is not a valid RFC3339 timestring.".format(
range[0])) range[0]))
...@@ -288,7 +313,7 @@ class Variable(Element, ABC): ...@@ -288,7 +313,7 @@ class Variable(Element, ABC):
"Time value {} is smaller than lower bound {}!".format(parse_time(value), "Time value {} is smaller than lower bound {}!".format(parse_time(value),
parse_time(range[0]))) parse_time(range[0])))
elif range[1] is not None: elif range[1] is not None:
if not rfc3339.validate_rfc3339(range[1]): if not validate_time(range[1]):
raise TypeException( raise TypeException(
"Can not check range of time value. Upper bound {} is not a valid RFC3339 timestring.".format( "Can not check range of time value. Upper bound {} is not a valid RFC3339 timestring.".format(
range[0])) range[0]))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment