FreeOpcUa / opcua-asyncio

OPC UA library for python >= 3.7
GNU Lesser General Public License v3.0
1.11k stars 358 forks source link

Intendet way for comparing values of two nodes #1592

Closed Fliens closed 7 months ago

Fliens commented 7 months ago

Hi as the title says, I want to compare the values of two nodes.

I want to make sure that python does nothing unintendet in the background with the node datatypes. For example when comparing nodes with different types of int: int16, int32, int64, Uint16, Uint32, Uint64.

I'm worried that the python "==" could create false positive or general negative results when comparing plain values of nodes

Example

value1 = node1.read_data_value().Value.Value
value2 = node2.read_data_value().Value.Value
print(value1 == value2)

value1 = node1.get_value()
value2 = node2.get_value()
print(value1 == value2)

Is there a better way to compare two ua.DataValue() or ua.Variant() that keeps the datatype of the value in mind? Instances of these classes can't be compared directly since they also have a timestamp that might not be important for comparing their values.

Sth like this:

value1 = node1.read_data_value().Value.Value
value2 = node2.read_data_value().Value.Value
print(ua.uatypes.compare_variants(value1, value2)).
# Returns True if both values are the same when cast to the same datatype
AndreasHeine commented 7 months ago

ua.DataValue() or ua.Variant() are both python dataclasses.

DataValue has no __eq__ method! https://github.com/FreeOpcUa/opcua-asyncio/blob/d4d4c84366dea6bc0ede632fff0821b00f85d8eb/asyncua/ua/uatypes.py#L1069

Variant has a __eq__ method https://github.com/FreeOpcUa/opcua-asyncio/blob/d4d4c84366dea6bc0ede632fff0821b00f85d8eb/asyncua/ua/uatypes.py#L911

    def __eq__(self, other):
        if (
            isinstance(other, Variant)
            and self.VariantType == other.VariantType
            and self.Value == other.Value
        ):
            return True
        return False

so comparing variant1 == variant2 should work as in python docs described. https://docs.python.org/3/reference/datamodel.html#object.__eq__

Fliens commented 7 months ago

Ahh great thank you for the response this answers my question :)