Ejemplo n.º 1
0
    def set_attribute_value(self, nodeid, attr, value):
        with self._lock:
            self.logger.debug("set attr val: %s %s %s", nodeid, attr, value)
            node = self._nodes.get(nodeid, None)
            if node is None:
                return ua.StatusCode(ua.StatusCodes.BadNodeIdUnknown)
            attval = node.attributes.get(attr, None)
            if attval is None:
                self.logger.warning(
                    "Tried to write attribute '%s' in %s, but the attribute is missing",
                    attr, nodeid)
                return ua.StatusCode(ua.StatusCodes.BadAttributeIdInvalid)

            old = attval.value
            attval.value = value
            cbs = []
            if old.Value != value.Value:  # only send call callback when a value change has happend
                cbs = list(attval.datachange_callbacks.items())

        for k, v in cbs:
            try:
                v(k, value)
            except Exception as ex:
                self.logger.exception(
                    "Error calling datachange callback %s, %s, %s", k, v, ex)

        return ua.StatusCode()
Ejemplo n.º 2
0
 def _call(self, method):
     res = ua.CallMethodResult()
     if method.ObjectId not in self._aspace or method.MethodId not in self._aspace:
         res.StatusCode = ua.StatusCode(ua.StatusCodes.BadNodeIdInvalid)
     else:
         node = self._aspace[method.MethodId]
         if node.call is None:
             res.StatusCode = ua.StatusCode(ua.StatusCodes.BadNothingToDo)
         else:
             try:
                 result = node.call(method.ObjectId, *method.InputArguments)
                 if isinstance(result, ua.CallMethodResult):
                     res = result
                 elif isinstance(result, ua.StatusCode):
                     res.StatusCode = result
                 else:
                     res.OutputArguments = result
                 while len(res.InputArgumentResults) < len(
                         method.InputArguments):
                     res.InputArgumentResults.append(ua.StatusCode())
             except Exception:
                 self.logger.exception(
                     "Error executing method call %s, an exception was raised: ",
                     method)
                 res.StatusCode = ua.StatusCode(
                     ua.StatusCodes.BadUnexpectedError)
     return res
Ejemplo n.º 3
0
 def write(self, params, user=User.Admin):
     self.logger.debug("write %s as user %s", params, user)
     res = []
     for writevalue in params.NodesToWrite:
         if user != User.Admin:
             if writevalue.AttributeId != ua.AttributeIds.Value:
                 res.append(
                     ua.StatusCode(ua.StatusCodes.BadUserAccessDenied))
                 continue
             al = self._aspace.get_attribute_value(
                 writevalue.NodeId, ua.AttributeIds.AccessLevel)
             ual = self._aspace.get_attribute_value(
                 writevalue.NodeId, ua.AttributeIds.UserAccessLevel)
             if not ua.ua_binary.test_bit(
                     al.Value.Value, ua.AccessLevel.
                     CurrentWrite) or not ua.ua_binary.test_bit(
                         ual.Value.Value, ua.AccessLevel.CurrentWrite):
                 res.append(
                     ua.StatusCode(ua.StatusCodes.BadUserAccessDenied))
                 continue
         res.append(
             self._aspace.set_attribute_value(writevalue.NodeId,
                                              writevalue.AttributeId,
                                              writevalue.Value))
     return res
Ejemplo n.º 4
0
 def test_string_to_variant_status_code(self):
     s_statuscode = "Good"
     statuscode = ua.StatusCode(ua.StatusCodes.Good)
     s_statuscode2 = "Uncertain"
     statuscode2 = ua.StatusCode(ua.StatusCodes.Uncertain)
     self.assertEqual(string_to_val(s_statuscode, ua.VariantType.StatusCode), statuscode)
     self.assertEqual(string_to_val(s_statuscode2, ua.VariantType.StatusCode), statuscode2)
Ejemplo n.º 5
0
    def set_attribute_value(self, nodeid, attr, value):
        with self._lock:
            self.logger.debug("set attr val: %s %s %s", nodeid, attr, value)
            if nodeid not in self._nodes:
                return ua.StatusCode(ua.StatusCodes.BadNodeIdUnknown)
            node = self._nodes[nodeid]
            if attr not in node.attributes:
                return ua.StatusCode(ua.StatusCodes.BadAttributeIdInvalid)
            if not value.SourceTimestamp:
                value.SourceTimestamp = datetime.utcnow()
            if not value.ServerTimestamp:
                value.ServerTimestamp = datetime.utcnow()

            attval = node.attributes[attr]
            old = attval.value
            attval.value = value
            cbs = []
            if old.Value != value.Value:  # only send call callback when a value change has happend
                cbs = list(attval.datachange_callbacks.items())

        for k, v in cbs:
            try:
                v(k, value)
            except Exception as ex:
                self.logger.exception("Error calling datachange callback %s, %s, %s", k, v, ex)

        return ua.StatusCode()
Ejemplo n.º 6
0
    def set_attribute_value(self, nodeid, attr, value):
        with self._lock:
            self.logger.debug("set attr val: %s %s %s", nodeid, attr, value)
            if not nodeid in self._nodes:
                return ua.StatusCode(ua.StatusCodes.BadNodeIdUnknown)
            node = self._nodes[nodeid]
            if not attr in node.attributes:
                return ua.StatusCode(ua.StatusCodes.BadAttributeIdInvalid)
            if not value.SourceTimestamp:
                value.SourceTimestamp = datetime.now()
            if not value.ServerTimestamp:
                value.ServerTimestamp = datetime.now()

            attval = node.attributes[attr]
            attval.value = value
            if attval.value_callback:
                return attval.value_callback(nodeid, attr, value)
            for k, v in attval.datachange_callbacks.items():
                try:
                    v(k, value)
                except Exception as ex:
                    self.logger.exception(
                        "Error calling datachange callback %s, %s, %s", k, v,
                        ex)
            return ua.StatusCode()
Ejemplo n.º 7
0
    def _delete_node(self, item, user):
        if not user == User.Admin:
            return ua.StatusCode(ua.StatusCodes.BadUserAccessDenied)

        if item.NodeId not in self._aspace:
            self.logger.warning("DeleteNodesItem: node does not exists")
            return ua.StatusCode(ua.StatusCodes.BadNodeIdUnknown)

        if item.DeleteTargetReferences:
            for elem in self._aspace.keys():
                for rdesc in self._aspace[elem].references:
                    if rdesc.NodeId == item.NodeId:
                        self._aspace[elem].references.remove(rdesc)

        for handle, callback in list(self._aspace[item.NodeId].attributes[
                ua.AttributeIds.Value].datachange_callbacks.items()):
            try:
                callback(handle, None,
                         ua.StatusCode(ua.StatusCodes.BadNodeIdUnknown))
                self._aspace.delete_datachange_callback(handle)
            except Exception as ex:
                self.logger.exception(
                    "Error calling datachange callback %s, %s, %s", k, v, ex)

        del self._aspace[item.NodeId]

        return ua.StatusCode()
Ejemplo n.º 8
0
def turn_pump_off(parent):
    if manualoperation.get_value() == True:
        pump_closed.set_value(True)
        pump_q.set_value(0)
        return ua.StatusCode(0)
    else:
        return ua.StatusCode(0x80000000)  # Status code for Bad error
Ejemplo n.º 9
0
def turn_pump_on(parent):
    if manualoperation.get_value() == True:
        pump_closed.set_value(False)
        pump_q.set_value(1)  # Flowrate defined in project implementation
        return ua.StatusCode(0)
    else:
        return ua.StatusCode(0x80000000)  # Status code for Bad error
Ejemplo n.º 10
0
def turn_control_on(parent):
    if manualoperation.get_value() == True:
        c_sp1_open.set_value(True)
        c_sp2_open.set_value(True)
        c_sp3_open.set_value(True)
        return ua.StatusCode(0)
    else:
        return ua.StatusCode(0x80000000)  # Status code for Bad error
Ejemplo n.º 11
0
def turn_fuzzy_off(parent):
    if manualoperation.get_value() == True:
        f_sp1_open.set_value(False)
        f_sp2_open.set_value(False)
        f_sp3_open.set_value(False)
        return ua.StatusCode(0)
    else:
        return ua.StatusCode(0x80000000)  # Status code for Bad error
Ejemplo n.º 12
0
 def _add_reference(self, addref, user):
     sourcedata = self._aspace.get(addref.SourceNodeId)
     if sourcedata is None:
         return ua.StatusCode(ua.StatusCodes.BadSourceNodeIdInvalid)
     if addref.TargetNodeId not in self._aspace:
         return ua.StatusCode(ua.StatusCodes.BadTargetNodeIdInvalid)
     if user != User.Admin:
         return ua.StatusCode(ua.StatusCodes.BadUserAccessDenied)
     return self._add_reference_no_check(sourcedata, addref)
Ejemplo n.º 13
0
 def func2(parent, methodname, value):
     if methodname == "panic":
         return ua.StatusCode(ua.StatusCodes.BadOutOfMemory)
     if methodname != "sin":
         res = ua.CallMethodResult()
         res.StatusCode = ua.StatusCode(ua.StatusCodes.BadInvalidArgument)
         res.InputArgumentResults = [ua.StatusCode(ua.StatusCodes.BadNotSupported), ua.StatusCode()]
         return res
     return math.sin(value)
Ejemplo n.º 14
0
    def _add_node(self, item, user):
        result = ua.AddNodesResult()

        # If Identifier of requested NodeId is null we generate a new NodeId using
        # the namespace of the nodeid, this is an extention of the spec to allow
        # to requests the server to generate a new nodeid in a specified namespace
        if item.RequestedNewNodeId.has_null_identifier():
            self.logger.debug(
                "RequestedNewNodeId has null identifier, generating Identifier"
            )
            nodedata = NodeData(
                self._aspace.generate_nodeid(
                    item.RequestedNewNodeId.NamespaceIndex))
        else:
            nodedata = NodeData(item.RequestedNewNodeId)

        if nodedata.nodeid in self._aspace:
            self.logger.warning(
                "AddNodesItem: Requested NodeId %s already exists",
                nodedata.nodeid)
            result.StatusCode = ua.StatusCode(ua.StatusCodes.BadNodeIdExists)
            return result

        if item.ParentNodeId.is_null():
            # self.logger.warning("add_node: creating node %s without parent", nodedata.nodeid)
            # should return Error here, but the standard namespace define many nodes without parents...
            pass
        elif item.ParentNodeId not in self._aspace:
            self.logger.warning(
                "add_node: while adding node %s, requested parent node %s does not exists",
                nodedata.nodeid, item.ParentNodeId)
            result.StatusCode = ua.StatusCode(
                ua.StatusCodes.BadParentNodeIdInvalid)
            return result

        if not user == User.Admin:
            result.StatusCode = ua.StatusCode(
                ua.StatusCodes.BadUserAccessDenied)
            return result

        self._add_node_attributes(nodedata, item)

        # now add our node to db
        self._aspace[nodedata.nodeid] = nodedata

        if not item.ParentNodeId.is_null():
            self._add_ref_from_parent(nodedata, item)
            self._add_ref_to_parent(nodedata, item, user)

        # add type definition
        if item.TypeDefinition != ua.NodeId():
            self._add_type_definition(nodedata, item, user)

        result.StatusCode = ua.StatusCode()
        result.AddedNodeId = nodedata.nodeid

        return result
Ejemplo n.º 15
0
def toggle_manual(parent):
    if manualoperation.get_value() == True:
        manualoperation.set_value(False)
        return ua.StatusCode(0)
    elif manualoperation.get_value() == False:
        manualoperation.set_value(True)
        return ua.StatusCode(0)
    else:
        return ua.StatusCode(0x80000000)  # Status code for Bad error
Ejemplo n.º 16
0
 def _add_unique_reference(self, nodedata, desc):
     for r in nodedata.references:
         if r.ReferenceTypeId == desc.ReferenceTypeId and r.NodeId == desc.NodeId:
             if r.IsForward != desc.IsForward:
                 self.logger.error("Cannot add conflicting reference %s ", str(desc))
                 return ua.StatusCode(ua.StatusCodes.BadReferenceNotAllowed)
             break  # ref already exists
     else:
         nodedata.references.append(desc)
     return ua.StatusCode()
Ejemplo n.º 17
0
    def _add_node(self, item, user):
        result = ua.AddNodesResult()

        if item.RequestedNewNodeId in self._aspace:
            self.logger.warning("AddNodeItem: node already exists")
            result.StatusCode = ua.StatusCode(ua.StatusCodes.BadNodeIdExists)
            return result
        nodedata = NodeData(item.RequestedNewNodeId)
        # add common attrs
        nodedata.attributes[ua.AttributeIds.NodeId] = AttributeValue(ua.DataValue(ua.Variant(item.RequestedNewNodeId, ua.VariantType.NodeId)))
        nodedata.attributes[ua.AttributeIds.BrowseName] = AttributeValue(ua.DataValue(ua.Variant(item.BrowseName, ua.VariantType.QualifiedName)))
        nodedata.attributes[ua.AttributeIds.NodeClass] = AttributeValue(ua.DataValue(ua.Variant(item.NodeClass, ua.VariantType.Int32)))
        # add requested attrs
        self._add_nodeattributes(item.NodeAttributes, nodedata)

        # add parent
        if item.ParentNodeId == ua.NodeId():
            #self.logger.warning("add_node: creating node %s without parent", item.RequestedNewNodeId)
            pass
        elif item.ParentNodeId not in self._aspace:
            #self.logger.warning("add_node: while adding node %s, requested parent node %s does not exists", item.RequestedNewNodeId, item.ParentNodeId)
            result.StatusCode = ua.StatusCode(ua.StatusCodes.BadParentNodeIdInvalid)
            return result
        else:
            if not user == User.Admin:
                result.StatusCode = ua.StatusCode(ua.StatusCodes.BadUserAccessDenied)
                return result

            desc = ua.ReferenceDescription()
            desc.ReferenceTypeId = item.ReferenceTypeId
            desc.NodeId = item.RequestedNewNodeId
            desc.NodeClass = item.NodeClass
            desc.BrowseName = item.BrowseName
            desc.DisplayName = ua.LocalizedText(item.BrowseName.Name)
            desc.TypeDefinition = item.TypeDefinition
            desc.IsForward = True
            self._aspace[item.ParentNodeId].references.append(desc)

        # now add our node to db
        self._aspace[item.RequestedNewNodeId] = nodedata

        # add type definition
        if item.TypeDefinition != ua.NodeId():
            addref = ua.AddReferencesItem()
            addref.SourceNodeId = item.RequestedNewNodeId
            addref.IsForward = True
            addref.ReferenceTypeId = ua.NodeId(ua.ObjectIds.HasTypeDefinition)
            addref.TargetNodeId = item.TypeDefinition
            addref.TargetNodeClass = ua.NodeClass.DataType
            self._add_reference(addref, user)

        result.StatusCode = ua.StatusCode()
        result.AddedNodeId = item.RequestedNewNodeId

        return result
Ejemplo n.º 18
0
 def _delete_unique_reference(self, item, invert=False):
     if invert:
         source, target, forward = item.TargetNodeId, item.SourceNodeId, not item.IsForward
     else:
         source, target, forward = item.SourceNodeId, item.TargetNodeId, item.IsForward
     for rdesc in self._aspace[source].references:
         if rdesc.NodeId == target and rdesc.ReferenceTypeId == item.ReferenceTypeId:
             if rdesc.IsForward == forward:
                 self._aspace[source].references.remove(rdesc)
                 return ua.StatusCode()
     return ua.StatusCode(ua.StatusCodes.BadNotFound)
Ejemplo n.º 19
0
    def test_status_code_to_string(self):
        # serialize a status code and deserialize it, name and doc resolution should work just fine
        statuscode = ua.StatusCode(ua.StatusCodes.BadNotConnected)
        statuscode2 = struct_from_binary(ua.StatusCode, io.BytesIO(struct_to_binary(ua.StatusCode(ua.StatusCodes.BadNotConnected))))

        self.assertEqual(statuscode, statuscode2)
        self.assertEqual(statuscode.value, statuscode2.value)

        # properties that are not serialized should still translate properly
        self.assertEqual(statuscode.name, statuscode2.name)
        self.assertEqual(statuscode.doc, statuscode2.doc)
Ejemplo n.º 20
0
    def _add_node(self, item, user, check=True):
        self.logger.debug("Adding node %s %s", item.RequestedNewNodeId, item.BrowseName)
        result = ua.AddNodesResult()

        if not user == User.Admin:
            result.StatusCode = ua.StatusCode(ua.StatusCodes.BadUserAccessDenied)
            return result

        if item.RequestedNewNodeId.has_null_identifier():
            # If Identifier of requested NodeId is null we generate a new NodeId using
            # the namespace of the nodeid, this is an extention of the spec to allow
            # to requests the server to generate a new nodeid in a specified namespace
            self.logger.debug("RequestedNewNodeId has null identifier, generating Identifier")
            item.RequestedNewNodeId = self._aspace.generate_nodeid(item.RequestedNewNodeId.NamespaceIndex)
        else:
            if item.RequestedNewNodeId in self._aspace:
                self.logger.warning("AddNodesItem: Requested NodeId %s already exists", item.RequestedNewNodeId)
                result.StatusCode = ua.StatusCode(ua.StatusCodes.BadNodeIdExists)
                return result

        if item.ParentNodeId.is_null():
            self.logger.info("add_node: while adding node %s, requested parent node is null %s %s",
                             item.RequestedNewNodeId, item.ParentNodeId, item.ParentNodeId.is_null())
            if check:
                result.StatusCode = ua.StatusCode(ua.StatusCodes.BadParentNodeIdInvalid)
                return result

        parentdata = self._aspace.get(item.ParentNodeId)
        if parentdata is None and not item.ParentNodeId.is_null():
            self.logger.info("add_node: while adding node %s, requested parent node %s does not exists",
                             item.RequestedNewNodeId, item.ParentNodeId)
            result.StatusCode = ua.StatusCode(ua.StatusCodes.BadParentNodeIdInvalid)
            return result

        nodedata = NodeData(item.RequestedNewNodeId)

        self._add_node_attributes(nodedata, item, add_timestamps=check)

        # now add our node to db
        self._aspace[nodedata.nodeid] = nodedata

        if parentdata is not None:
            self._add_ref_from_parent(nodedata, item, parentdata)
            self._add_ref_to_parent(nodedata, item, parentdata)

        # add type definition
        if item.TypeDefinition != ua.NodeId():
            self._add_type_definition(nodedata, item)

        result.StatusCode = ua.StatusCode()
        result.AddedNodeId = nodedata.nodeid

        return result
Ejemplo n.º 21
0
 def delete_subscriptions(self, ids):
     self.logger.info("delete subscriptions: %s", ids)
     res = []
     for i in ids:
         with self._lock:
             if i not in self.subscriptions:
                 res.append(ua.StatusCode(ua.StatusCodes.BadSubscriptionIdInvalid))
             else:
                 sub = self.subscriptions.pop(i)
                 sub.stop()
                 res.append(ua.StatusCode())
     return res
Ejemplo n.º 22
0
def turn_all_on(parent):
    if manualoperation.get_value() == True:
        c_sp1_open.set_value(True)
        c_sp2_open.set_value(True)
        c_sp3_open.set_value(True)
        f_sp1_open.set_value(True)
        f_sp2_open.set_value(True)
        f_sp3_open.set_value(True)
        pump_closed.set_value(False)
        pump_q.set_value(1)
        return ua.StatusCode(0)
    else:
        return ua.StatusCode(0x80000000)  # Status code for Bad error
Ejemplo n.º 23
0
    def _delete_reference(self, item, user):
        if item.SourceNodeId not in self._aspace:
            return ua.StatusCode(ua.StatusCodes.BadSourceNodeIdInvalid)
        if item.TargetNodeId not in self._aspace:
            return ua.StatusCode(ua.StatusCodes.BadTargetNodeIdInvalid)
        if item.ReferenceTypeId not in self._aspace:
            return ua.StatusCode(ua.StatusCodes.BadReferenceTypeIdInvalid)
        if user != User.Admin:
            return ua.StatusCode(ua.StatusCodes.BadUserAccessDenied)

        if item.DeleteBidirectional:
            self._delete_unique_reference(item, True)
        return self._delete_unique_reference(item)
Ejemplo n.º 24
0
 def _delete_monitored_items(self, mid):
     if not mid in self._monitored_items:
         return ua.StatusCode(ua.StatusCodes.BadMonitoredItemIdInvalid)
     for k, v in self._monitored_events.items():
         if v == mid:
             self._monitored_events.pop(k)
             break
     for k, v in self._monitored_datachange.items():
         if v == mid:
             self.aspace.delete_datachange_callback(k)
             self._monitored_datachange.pop(k)
             break
     self._monitored_items.pop(mid)
     return ua.StatusCode()
Ejemplo n.º 25
0
 def add_datachange_callback(self, nodeid, attr, callback):
     with self._lock:
         self.logger.debug("set attr callback: %s %s %s", nodeid, attr, callback)
         if nodeid not in self._nodes:
             return ua.StatusCode(ua.StatusCodes.BadNodeIdUnknown), 0
         node = self._nodes[nodeid]
         if attr not in node.attributes:
             return ua.StatusCode(ua.StatusCodes.BadAttributeIdInvalid), 0
         attval = node.attributes[attr]
         self._datachange_callback_counter += 1
         handle = self._datachange_callback_counter
         attval.datachange_callbacks[handle] = callback
         self._handle_to_attribute_map[handle] = (nodeid, attr)
         return ua.StatusCode(), handle
Ejemplo n.º 26
0
 def __init__(self):
     self.BooleanValue = True
     self.SByteValue = 0
     self.ByteValue = 0
     self.Int16Value = 0
     self.UInt16Value = 0
     self.Int32Value = 0
     self.UInt32Value = 0
     self.Int64Value = 0
     self.UInt64Value = 0
     self.FloatValue = 0
     self.DoubleValue = 0
     self.StringValue = ''
     self.DateTimeValue = datetime.utcnow()
     self.GuidValue = uuid.uuid4()
     self.ByteStringValue = b''
     self.XmlElementValue = ua.XmlElement()
     self.NodeIdValue = ua.NodeId()
     self.ExpandedNodeIdValue = ua.ExpandedNodeId()
     self.QualifiedNameValue = ua.QualifiedName()
     self.LocalizedTextValue = ua.LocalizedText()
     self.StatusCodeValue = ua.StatusCode()
     self.VariantValue = ua.Variant()
     self.EnumerationValue = 0
     self.StructureValue = ua.ExtensionObject()
     self.Number = ua.Variant()
     self.Integer = ua.Variant()
     self.UInteger = ua.Variant()
Ejemplo n.º 27
0
    def write(self, params):
        with self.aspace._lock:
            if params.NodesToWrite[0].NodeId.NamespaceIndex == 2 :
                if self.data_cache_state:
                    logging.debug("--- DataCache Write ---")

                    if self.initialization_cache:
                        self.write_data_request(params.NodesToWrite[0].NodeId, 
                                            params.NodesToWrite[0].Value.Value._value)
                        return self.iserver.attribute_service.write(params, self.user)
                    
                    uncertain_status = ua.StatusCode(ua.StatusCodes.Uncertain)
                    uncertain_response = self.iserver.attribute_service.write(params, self.user)
                    uncertain_response[0] = uncertain_status
                    #need to implement ack from onem2m side
                    self.write_data_request(params.NodesToWrite[0].NodeId, 
                                            params.NodesToWrite[0].Value.Value._value)
                    return uncertain_response

                else:
                    logging.debug("--- Direct Access Write ---")
                    self.write_data_request(params.NodesToWrite[0].NodeId, 
                                            params.NodesToWrite[0].Value.Value._value)
                    return self.iserver.attribute_service.write(params, self.user)
                
                
                
            return self.iserver.attribute_service.write(params, self.user)
Ejemplo n.º 28
0
 def get_attribute_value(self, nodeid, attr):
     with self._lock:
         self.logger.debug("get attr val: %s %s", nodeid, attr)
         if nodeid not in self._nodes:
             dv = ua.DataValue()
             dv.StatusCode = ua.StatusCode(ua.StatusCodes.BadNodeIdUnknown)
             return dv
         node = self._nodes[nodeid]
         if attr not in node.attributes:
             dv = ua.DataValue()
             dv.StatusCode = ua.StatusCode(ua.StatusCodes.BadAttributeIdInvalid)
             return dv
         attval = node.attributes[attr]
         if attval.value_callback:
             return attval.value_callback()
         return attval.value
Ejemplo n.º 29
0
    def read_node_history(self, node_id, start, end, nb_values):
        with self._lock:
            _c_read = self._conn.cursor()

            table = self._get_table_name(node_id)
            start_time, end_time, order, limit = self._get_bounds(start, end, nb_values)

            cont = None
            results = []

            # select values from the database; recreate UA Variant from binary
            try:
                for row in _c_read.execute('SELECT * FROM "{tn}" WHERE "SourceTimestamp" BETWEEN ? AND ? '
                                           'ORDER BY "_Id" {dir} LIMIT ?'.format(tn=table, dir=order),
                                           (start_time, end_time, limit,)):

                    # rebuild the data value object
                    dv = ua.DataValue(variant_from_binary(Buffer(row[6])))
                    dv.ServerTimestamp = row[1]
                    dv.SourceTimestamp = row[2]
                    dv.StatusCode = ua.StatusCode(row[3])

                    results.append(dv)

            except sqlite3.Error as e:
                self.logger.error('Historizing SQL Read Error for %s: %s', node_id, e)

            if nb_values:
                if len(results) > nb_values:
                    cont = results[nb_values].SourceTimestamp

                results = results[:nb_values]

            return results, cont
Ejemplo n.º 30
0
    def _read_history(self, details, rv):
        """
        determine if the history read is for a data changes or events; then read the history for that node
        """
        result = ua.HistoryReadResult()
        if isinstance(details, ua.ReadRawModifiedDetails):
            if details.IsReadModified:
                result.HistoryData = ua.HistoryModifiedData()
                # we do not support modified history by design so we return what we have
            else:
                result.HistoryData = ua.HistoryData()
            dv, cont = self._read_datavalue_history(rv, details)
            result.HistoryData.DataValues = dv
            result.ContinuationPoint = cont

        elif isinstance(details, ua.ReadEventDetails):
            result.HistoryData = ua.HistoryEvent()
            # FIXME: filter is a cumbersome type, maybe transform it something easier
            # to handle for storage
            ev, cont = self._read_event_history(rv, details)
            result.HistoryData.Events = ev
            result.ContinuationPoint = cont

        else:
            # we do not currently support the other types, clients can process data themselves
            result.StatusCode = ua.StatusCode(ua.StatusCodes.BadNotImplemented)
        return result