Issue with ResourceOpenAttribute
and EmbedPropertiesAttribute
in Python
Hello everyone,
I am currently unable to use ResourceOpenAttribute
and EmbedPropertiesAttribute
in Python, even though I have the latest versions of the plugins installed.
Here is a sample of the code I am working with:
Broker = opentap.property(Broker, None).add_attribute(OpenTap.Display("MQTT Broker"))\
.add_attribute(OpenTap.ResourceOpenAttribute(OpenTap.ResourceOpenBehavior.Ignore))
Meas = opentap.property(Measurement, None).add_attribute(OpenTap.Display("Measurement"))\
.add_attribute(OpenTap.EmbedPropertiesAttribute())
The Measurement
class looks like this:
class Measurement:
UpperLimit = None
LowerLimit = None
Value = None
Verdict = None
Issue Log Excerpt:
2024-09-06 13:30:40.919831 ; Python ; Debug ; Loading: Demo.DemoStep
2024-09-06 13:30:40.970696 ; Python ; Error ; Caught exception loading Demo.DemoStep: Unable to cast object of type 'OpenTap.EmbedPropertiesAttribute' to type 'System.Type'.
2024-09-06 13:30:40.973255 ; Python ; Debug ; PythonException: Unable to cast object of type 'OpenTap.EmbedPropertiesAttribute' to type 'System.Type'.
2024-09-06 13:30:40.983317 ; Python ; Debug ; File "\Demo\DemoStep.py", line 16, in <module>
2024-09-06 13:30:40.983317 ; Python ; Debug ; class DemoStep(TestStep):
2024-09-06 13:30:40.983317 ; Python ; Debug ; at Python.Runtime.PythonException.ThrowLastAsClrException()
2024-09-06 13:30:40.983317 ; Python ; Debug ; at Python.Runtime.NewReferenceExtensions.BorrowOrThrow(NewReference& reference)
2024-09-06 13:30:40.983317 ; Python ; Debug ; at Python.Runtime.PyModule.Import(String name)
2024-09-06 13:30:40.983317 ; Python ; Debug ; at OpenTap.Python.PythonPluginProvider.Search()
2024-09-06 13:30:40.984329 ; Python ; Debug ; Exception caught at:
2024-09-06 13:30:40.987420 ; Python ; Debug ; at Void <StartAwaitable>b__0()
2024-09-06 13:30:40.987420 ; Python ; Debug ; at Void Process()
2024-09-06 13:30:40.987420 ; Python ; Debug ; at Void processQueue()
2024-09-06 13:30:40.987420 ; Python ; Debug ; at Void RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
Request for Help:
I am getting the following error:
- Unable to cast object of type âOpenTap.EmbedPropertiesAttributeâ to type âSystem.Typeâ
- Unable to cast object of type âOpenTap.ResourceOpenAttributeâ to type âSystem.Typeâ
Any help to resolve this issue would be highly appreciated!
Thanks!
Hi @yannick.njanjo,
Did you try writing OpenTap.ResourceOpen
instead of OpenTap.ResourceOpenAttribute
. This might seem a bit surprising. The problem is that OpenTap.ResourceOpenAttribute will create an instance of the attribute object, which is difficult to convert back into what we need to generate the .NET class.
I think this should work:
Broker = opentap.property(Broker, None).add_attribute(OpenTap.Display("MQTT Broker"))\
.add_attribute(OpenTap.ResourceOpen(OpenTap.ResourceOpenBehavior.Ignore))
Meas = opentap.property(Measurement, None).add_attribute(OpenTap.Display("Measurement"))\
.add_attribute(OpenTap.EmbedProperties())
Hi Rolf,
Thanks for your reply. I figured this out but forgot to update the post as I was busy with another project.
Unfortunately, the EmbedProperties
attribute still doesnât work. When I apply it to a class attribute, it disappears from the Settings area in the editor. Without it, the setting is displayed as a serialized string, e.g., {UpperLimit=0, LowerLimit=0,...}
.
Do you have any idea why this happens?
Can you show how you use it?
MV = opentap.property(Measurement, None).add_attribute(OpenTap.Display("Measurement"))\
.add_attribute(OpenTap.EmbedProperties())
Ok, thats a start
I also need to see the object you are embedding and when you create the instance of it.
Sorry it took me a few minutes. I had to rewrite it again from âscratchâ.
"""
An example of how to define a Python Test Step
"""
import time
import opentap
from opentap import *
import System
from System import Double, Int32, String
import OpenTap
from OpenTap import Display, Unit
VALID_DATA_TYPES = (int, float, str, bool)
class Measurement:
_UpperLimit = opentap.property(Double, None).add_attribute(OpenTap.Display("Upper Limit"))
_LowerLimit = opentap.property(Double, None).add_attribute(OpenTap.Display("Lower Limit"))
_SetPoint = opentap.property(Double, None).add_attribute(OpenTap.Display("Set Point"))
def __init__(self, data_type: type, unit: str):
if data_type not in VALID_DATA_TYPES:
raise ValueError(f"data_type must be one of the following types: {VALID_DATA_TYPES}")
self._data_type = data_type
self._unit = unit
self._value = None
self._timestamp = None
self._verdict = OpenTap.Verdict.NotSet
@property
def SetPoint(self):
return self._SetPoint
@SetPoint.setter
def SetPoint(self, value):
if not isinstance(value, self._data_type):
raise TypeError(f"SetPoint must be of type {self._data_type.__name__}")
if self._UpperLimit is not None and value > self._UpperLimit:
raise ValueError(f"SetPoint {value} cannot exceed UpperLimit {self._UpperLimit}")
if self._LowerLimit is not None and value < self._LowerLimit:
raise ValueError(f"SetPoint {value} cannot be less than LowerLimit {self._LowerLimit}")
self._SetPoint = value
@property
def Value(self):
return self._value
@Value.setter
def Value(self, new_value):
if not isinstance(new_value, self._data_type):
raise TypeError(f"Value must be of type {self._data_type.__name__}")
self._value = new_value
self._timestamp = time.time()
@property
def Verdict(self):
return self._verdict
@Verdict.setter
def Verdict(self, new_verdict: OpenTap.Verdict):
if not isinstance(new_verdict, OpenTap.Verdict):
raise ValueError(f"Invalid verdict. Verdict must be an instance of OpenTap.Verdict")
self._verdict = new_verdict
@property
def Timestamp(self):
return self._timestamp
@property
def DataType(self) -> str:
# return str(self._data_type).split("'")[1]
return self._data_type.__name__
@property
def Unit(self):
return self._unit
@attribute(Display(Name="ForumStep", Description="ForumStep Description", Group="Demo"))
class ForumStep(TestStep):
# Add your Test Step settings here
# Example:
# CellSize = property(Int32, 1)\
# .add_attribute(Display(Name="Cell Size", Description="Size of the cell", Group="Cell Settings", Order=1))
MV = opentap.property(Measurement, None).add_attribute(OpenTap.Display("Measurement"))\
.add_attribute(OpenTap.EmbedProperties())
def __init__(self):
super().__init__()
self.Name="ForumStep"
MV = Measurement(Int32, "°C")
def Run(self):
# Add code here to execute when test step runs
self.log.Info("Running ForumStep")
First thing to try: Can you try to make Measurement inherit from System.Object? It needs to be a .NET object for it to work with EmbedPropertiesAttribute.
1 Like
It worked thanks.
class Measurement(Object):