Commit 11db062a authored by joaovitor8's avatar joaovitor8

Adding the methods necessary for Modifying Subscriptions, make deadband...

Adding the methods necessary for Modifying Subscriptions, make deadband filters and also added support to deadband filter on server side.
parent b756f0ab
...@@ -272,18 +272,27 @@ class Subscription(object): ...@@ -272,18 +272,27 @@ class Subscription(object):
del(self._monitoreditems_map[k]) del(self._monitoreditems_map[k])
return return
def modify_monitored_item(self, handle, new_samp_time, new_queuesize=0, mod_filter=None): def modify_monitored_item(self, handle, new_samp_time, new_queuesize=0, mod_filter_val=None):
""" """
Modify a monitored item. Modify a monitored item.
:param handle: Handle returned when originally subscribing :param handle: Handle returned when originally subscribing
:param new_samp_time: New wanted sample time :param new_samp_time: New wanted sample time
:param new_queuesize: New wanted queuesize, default is 0 :param new_queuesize: New wanted queuesize, default is 0
:param mod_filter: New wanted filter, default is None :param mod_filter_val: New deadband filter value
:return: Return a Modify Monitored Item Result :return: Return a Modify Monitored Item Result
""" """
if mod_filter_val < 0:
mod_filter = ua.DataChangeFilter()
mod_filter.DeadbandValue = -1
else:
mod_filter = ua.DataChangeFilter()
mod_filter.Trigger = ua.DataChangeTrigger(1) # send notification when status or value change
mod_filter.DeadbandType = 1
mod_filter.DeadbandValue = mod_filter_val # absolute float value or from 0 to 100 for percentage deadband
modif_item = ua.MonitoredItemModifyRequest() modif_item = ua.MonitoredItemModifyRequest()
modif_item.MonitoredItemId = handle modif_item.MonitoredItemId = handle
modif_item.RequestedParameters = self._modify_monitored_item_request(new_queuesize, new_samp_time, mod_filter) modif_item.RequestedParameters = self._modify_monitored_item_request(new_queuesize, new_samp_time,
mod_filter)
params = ua.ModifyMonitoredItemsParameters() params = ua.ModifyMonitoredItemsParameters()
params.SubscriptionId = self.subscription_id params.SubscriptionId = self.subscription_id
params.ItemsToModify.append(modif_item) params.ItemsToModify.append(modif_item)
...@@ -301,7 +310,7 @@ class Subscription(object): ...@@ -301,7 +310,7 @@ class Subscription(object):
def deadband_monitor(self, var, deadband_val, deadbandtype=1, queuesize=0, attr=ua.AttributeIds.Value): def deadband_monitor(self, var, deadband_val, deadbandtype=1, queuesize=0, attr=ua.AttributeIds.Value):
""" """
Function to create a subscription with a Deadband Value. Method to create a subscription with a Deadband Value.
Default deadband value type is absolute. Default deadband value type is absolute.
Return a handle which can be used to unsubscribe Return a handle which can be used to unsubscribe
:param var: Variable to which you want to subscribe :param var: Variable to which you want to subscribe
...@@ -310,8 +319,18 @@ class Subscription(object): ...@@ -310,8 +319,18 @@ class Subscription(object):
:param queuesize: Wanted queue size, default is 1 :param queuesize: Wanted queue size, default is 1
""" """
deadband_filter = ua.DataChangeFilter() deadband_filter = ua.DataChangeFilter()
deadband_filter.Trigger = DataChangeTrigger(1) # send notification when status or value change deadband_filter.Trigger = ua.DataChangeTrigger(1) # send notification when status or value change
deadband_filter.DeadbandType = deadbandtype deadband_filter.DeadbandType = deadbandtype
deadband_filter.DeadbandValue = deadband_val # absolute float value or from 0 to 100 for percentage deadband deadband_filter.DeadbandValue = deadband_val # absolute float value or from 0 to 100 for percentage deadband
return self._subscribe(var, attr, deadband_filter, queuesize) return self._subscribe(var, attr, deadband_filter, queuesize)
def _modify_monitored_item_request(self, new_queuesize, new_samp_time, mod_filter):
req_params = ua.MonitoringParameters()
with self._lock:
req_params.ClientHandle = self._client_handle
req_params.QueueSize = new_queuesize
req_params.Filter = mod_filter
req_params.SamplingInterval = new_samp_time
return req_params
...@@ -553,7 +553,7 @@ class AddressSpace(object): ...@@ -553,7 +553,7 @@ class AddressSpace(object):
for k, v in cbs: for k, v in cbs:
try: try:
v(k, value) v(k, value, old)
except Exception as ex: except Exception as ex:
self.logger.exception("Error calling datachange callback %s, %s, %s", k, v, ex) self.logger.exception("Error calling datachange callback %s, %s, %s", k, v, ex)
......
...@@ -60,7 +60,7 @@ class MonitoredItemService(object): ...@@ -60,7 +60,7 @@ class MonitoredItemService(object):
def trigger_datachange(self, handle, nodeid, attr): def trigger_datachange(self, handle, nodeid, attr):
self.logger.debug("triggering datachange for handle %s, nodeid %s, and attribute %s", handle, nodeid, attr) self.logger.debug("triggering datachange for handle %s, nodeid %s, and attribute %s", handle, nodeid, attr)
variant = self.aspace.get_attribute_value(nodeid, attr) variant = self.aspace.get_attribute_value(nodeid, attr)
self.datachange_callback(handle, variant) self.datachange_callback(handle, variant, variant)
def _modify_monitored_item(self, params): def _modify_monitored_item(self, params):
with self._lock: with self._lock:
...@@ -71,6 +71,7 @@ class MonitoredItemService(object): ...@@ -71,6 +71,7 @@ class MonitoredItemService(object):
result.RevisedSamplingInterval = self.isub.data.RevisedPublishingInterval result.RevisedSamplingInterval = self.isub.data.RevisedPublishingInterval
result.RevisedQueueSize = params.RequestedParameters.QueueSize result.RevisedQueueSize = params.RequestedParameters.QueueSize
result.FilterResult = params.RequestedParameters.Filter result.FilterResult = params.RequestedParameters.Filter
mdata.mfilter = result.FilterResult
mdata.parameters = result mdata.parameters = result
return result return result
result = ua.MonitoredItemModifyResult() result = ua.MonitoredItemModifyResult()
...@@ -162,22 +163,33 @@ class MonitoredItemService(object): ...@@ -162,22 +163,33 @@ class MonitoredItemService(object):
self._monitored_items.pop(mid) self._monitored_items.pop(mid)
return ua.StatusCode() return ua.StatusCode()
def datachange_callback(self, handle, value, error=None): def datachange_callback(self, handle, value, value_old, error=None):
if error: if error:
self.logger.info("subscription %s: datachange callback called with handle '%s' and erorr '%s'", self.logger.info("subscription %s: datachange callback called with handle '%s' and erorr '%s'", self,
self, handle, error) handle, error)
self.trigger_statuschange(error) self.trigger_statuschange(error)
else: else:
self.logger.info("subscription %s: datachange callback called with handle '%s' and value '%s'", self.logger.info("subscription %s: datachange callback called with handle '%s' and value '%s'", self,
self, handle, value.Value) handle, value.Value)
event = ua.MonitoredItemNotification() event = ua.MonitoredItemNotification()
with self._lock: with self._lock:
mid = self._monitored_datachange[handle] mid = self._monitored_datachange[handle]
mdata = self._monitored_items[mid] mdata = self._monitored_items[mid]
if mdata.mfilter != None:
deadband_flag_pass = self.deadband_callback(value, value_old, mdata.mfilter)
else:
deadband_flag_pass = True
if deadband_flag_pass:
event.ClientHandle = mdata.client_handle event.ClientHandle = mdata.client_handle
event.Value = value event.Value = value
self.isub.enqueue_datachange_event(mid, event, mdata.parameters.RevisedQueueSize) self.isub.enqueue_datachange_event(mid, event, mdata.parameters.RevisedQueueSize)
def deadband_callback(self, value, value_old, filter):
if ((abs(value.Value.Value - value_old.Value.Value)) > filter.DeadbandValue):
return True
else:
return False
def trigger_event(self, event): def trigger_event(self, event):
with self._lock: with self._lock:
if event.SourceNode not in self._monitored_events: if event.SourceNode not in self._monitored_events:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment