def modify_monitored_item(self, handle, new_samp_time, new_queuesize=0, mod_filter_val=-1): """ Modify a monitored item. :param handle: Handle returned when originally subscribing :param new_samp_time: New wanted sample time :param new_queuesize: New wanted queuesize, default is 0 :param mod_filter_val: New deadband filter value :return: Return a Modify Monitored Item Result """ for monitored_item_index in self._monitoreditems_map: if self._monitoreditems_map[monitored_item_index].server_handle == handle: item_to_change = self._monitoreditems_map[monitored_item_index] break if mod_filter_val is None: mod_filter = None elif mod_filter_val < 0: mod_filter = item_to_change.mfilter 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.MonitoredItemId = handle modif_item.RequestedParameters = self._modify_monitored_item_request(new_queuesize, new_samp_time, mod_filter, item_to_change.client_handle) params = ua.ModifyMonitoredItemsParameters() params.SubscriptionId = self.subscription_id params.ItemsToModify.append(modif_item) results = self.server.modify_monitored_items(params) item_to_change.mfilter = results[0].FilterResult return results
def deadband_monitor(self, var, deadband_val, deadbandtype=1, queuesize=0, attr=ua.AttributeIds.Value): """ Method to create a subscription with a Deadband Value. Default deadband value type is absolute. Return a handle which can be used to unsubscribe :param var: Variable to which you want to subscribe :param deadband_val: Absolute float value :param deadbandtype: Default value is 1 (absolute), change to 2 for percentage deadband :param queuesize: Wanted queue size, default is 1 """ deadband_filter = ua.DataChangeFilter() deadband_filter.Trigger = ua.DataChangeTrigger(1) # send notification when status or value change deadband_filter.DeadbandType = deadbandtype deadband_filter.DeadbandValue = deadband_val # absolute float value or from 0 to 100 for percentage deadband return self._subscribe(var, attr, deadband_filter, queuesize)
def set_datachange_filter(self, deadband_val, deadbandtype=1): deadband_filter = ua.DataChangeFilter() deadband_filter.Trigger = ua.DataChangeTrigger(1) # send notification when status or value change deadband_filter.DeadbandType = deadbandtype #type = 0 -> notification every change; type = 1 -> absolute deadband_val is considered; type = 2 -> percent deadband_val is considered deadband_filter.DeadbandValue = deadband_val return deadband_filter
def _subscribe(self, node=None): if not isinstance(node, Node): node = self.window.get_current_node() if node is None: return if node.get_node_class() != ua.NodeClass.Variable: self.window.log_window.ui.logTextEdit.append( "Select a variable node") return if node in self._subscribed_nodes: self.window.log_window.ui.logTextEdit.append( "already subscribed to node: %s " % node) return self.monitored_item_model.setHorizontalHeaderLabels( ["DisplayName", "Value", "Timestamp", "Subscription Id"]) text = str(node.get_display_name().Text) row = [ QStandardItem(text), QStandardItem("No Data yet"), QStandardItem(""), QStandardItem(str(self.subscription_id)) ] row[0].setData(node) self.monitored_item_model.appendRow(row) self._subscribed_nodes.append(node) try: mir = self._datachange_sub[ self.subscription_id]._make_monitored_item_request( node, ua.AttributeIds.Value, None, self.queue_size) #mfilter, queue size mir.RequestedParameters.DiscardOldest = self.discard_oldest mir.RequestedParameters.SamplingInterval = self.sampling_interval mir.MonitoringMode = self.monitoring_mode print(mir.MonitoringMode) mod_filter = ua.DataChangeFilter() mod_filter.Trigger = ua.DataChangeTrigger( 1) # send notification when status or value change if self.deadband_type != None: if self.deadband_type == 1: if node.get_data_type_as_variant_type( ) in self.numeric_types: mod_filter.DeadbandType = self.deadband_type #1 assoluta , 2 percentage mod_filter.DeadbandValue = self.deadband_value else: self.window.log_window.ui.logTextEdit.append( "filter must be used for numeric data type") elif self.deadband_type == 2: properties = node.get_properties() EURange = False for p in properties: browse_name = p.get_browse_name().Name if browse_name == "EURange": EURange = True if node.get_type_definition( ).Identifier == ua.object_ids.ObjectIds.AnalogItemType and EURange == True: if node.get_data_type_as_variant_type( ) in self.numeric_types: mod_filter.DeadbandType = self.deadband_type #1 assoluta , 2 percentage mod_filter.DeadbandValue = self.deadband_value else: self.window.log_window.ui.logTextEdit.append( "filter must be used for numeric data type") else: self.window.log_window.ui.logTextEdit.append( "percentage deadband must be applied to AnalagoItemType with EUrange" ) mir.RequestedParameters.Filter = mod_filter handle = self._datachange_sub[ self.subscription_id].create_monitored_items([mir]) self._subs_dc[node.nodeid] = (handle[0], self.subscription_id) except Exception as ex: self.window.log_window.ui.logTextEdit.append(str(ex)) idx = self.monitored_item_model.indexFromItem(row[0]) self.monitored_item_model.takeRow(idx.row())
def create_monitored_items(self, nodes, index): monitored_items = [] if not isinstance(nodes, list): nodes = [nodes] for node in nodes: # Set item to monitor rv = ua.ReadValueId() rv.NodeId = node.nodeid rv.AttributeId = ua.AttributeIds.Value # Set monitoring parameters mparams = ua.MonitoringParameters() self._client_handle += 1 mparams.ClientHandle = self._client_handle mparams.SamplingInterval = self.samplingInterval mparams.QueueSize = self.queueSize mparams.DiscardOldest = self.discardOldest # Create monitored item filter if self.dataChangeFilter: mfilter = ua.DataChangeFilter() mfilter.Trigger = ua.DataChangeTrigger(self.dataChangeTrigger) if self.deadbandType == ua.DeadbandType.Absolute: if node.get_data_value( ).Value.VariantType in self.numericTypes: mfilter.DeadbandType = self.deadbandType mfilter.DeadbandValue = self.deadbandValue # absolute float value or from 0 to 100 for percentage deadband else: self.deadbandType = ua.DeadbandType.None_ mfilter.DeadbandType = self.deadbandType elif self.deadbandType == ua.DeadbandType.Percent: has_EURange = False if node.get_type_definition( ).Identifier == ua.object_ids.ObjectIds.AnalogItemType: # Get node properties descriptions = node.get_references( ua.ObjectIds.HasProperty, ua.BrowseDirection.Forward, ua.NodeClass.Variable, False) for desc in descriptions: if desc.BrowseName.Name == "EURange" and self.get_node( desc.NodeId).get_value() is not None: has_EURange = True if has_EURange: mfilter.DeadbandType = self.deadbandType mfilter.DeadbandValue = self.deadbandValue # absolute float value or from 0 to 100 for percentage deadband else: self.deadbandType = ua.DeadbandType.None_ mfilter.DeadbandType = self.deadbandType else: mfilter = None mparams.Filter = mfilter # Create monitored item request mir = ua.MonitoredItemCreateRequest() mir.ItemToMonitor = rv mir.MonitoringMode = ua.MonitoringMode.Reporting mir.RequestedParameters = mparams # Append to list monitored_items.append(mir) sub, monitored_items_handles = self._datachange_subs[index] handles = sub.create_monitored_items(monitored_items) for i in range(len(handles)): handle = handles[i] if type(handle) == ua.StatusCode: handle.check() monitored_items_handles[nodes[i].nodeid] = handle