How to prevent an out of range value to be written? #1563
-
Hi, I'm currently implementing an OPC UA server using asyncua. I tried to use a subscription handler with a Then I tried to use a callback function and register it using After some digging in the internals of asyncua I came up with the idea to replace the from asyncua.server.address_space import AttributeService
class CustomAttributeService(AttributeService):
async def write(self, params: ua.WriteParameters, user: User = User(role=UserRole.Admin)) -> List[ua.StatusCode]:
res: List[ua.StatusCode] = []
for writevalue in params.NodesToWrite:
... # code copied from AttributeService.write
# --- Custom code
if writevalue.NodeId == ua.NodeId(...): # the node I'm interested in
if writevalue.Value.Value.Value > 100:
_logger.error(f"Value out of range")
res.append(ua.StatusCode(ua.StatusCodes.BadOutOfRange))
continue
# --- End of custom code
res.append(
await self._aspace.write_attribute_value(writevalue.NodeId, writevalue.AttributeId, dv)
)
return res
...
server = Server()
server.iserver.attribute_service = CustomAttributeService(server.iserver.aspace)
... This does seem to work (testing with UaExpert) as I'm now getting the desired "Write to node ... failed [ret = Bad_OutOfRange]" message logged in UaExpert. Is there something that I'm missing which would allow me to return different status codes for the write service? Thanks in advance! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
Did you try to raise a exception? |
Beta Was this translation helpful? Give feedback.
-
the proper way to model it in opc ua would be to use a "i=15318 [BaseAnalogType]" an set the Range-ExtensionObject to the limits so the clients could check before write, but thats a modelling topic... the thing is where do you think to get the actual limits? their are not part of the variable itself!? in order to achieve this feature you need to rewrite and create a setter, which needs to be injected and must be part of the Variables "NodeData" itself and must be called within the Addressspace Write! opcua-asyncio/asyncua/server/address_space.py Line 777 in 3268568 |
Beta Was this translation helpful? Give feedback.
Did you try to raise a exception?
raise ua.uaerrors.BadOutOfRange()
raise ServiceError(ua.StatusCodes.BadOutOfRange)