@@ 297-370 (lines=74) @@ | ||
294 | ReferenceType = 1371236 |
|
295 | View = 1335532 |
|
296 | ||
297 | ||
298 | class AttributeWriteMask(IntEnum): |
|
299 | ''' |
|
300 | Define bits used to indicate which attributes are writable. |
|
301 | ||
302 | :ivar None_: |
|
303 | :vartype None_: 0 |
|
304 | :ivar AccessLevel: |
|
305 | :vartype AccessLevel: 1 |
|
306 | :ivar ArrayDimensions: |
|
307 | :vartype ArrayDimensions: 2 |
|
308 | :ivar BrowseName: |
|
309 | :vartype BrowseName: 4 |
|
310 | :ivar ContainsNoLoops: |
|
311 | :vartype ContainsNoLoops: 8 |
|
312 | :ivar DataType: |
|
313 | :vartype DataType: 16 |
|
314 | :ivar Description: |
|
315 | :vartype Description: 32 |
|
316 | :ivar DisplayName: |
|
317 | :vartype DisplayName: 64 |
|
318 | :ivar EventNotifier: |
|
319 | :vartype EventNotifier: 128 |
|
320 | :ivar Executable: |
|
321 | :vartype Executable: 256 |
|
322 | :ivar Historizing: |
|
323 | :vartype Historizing: 512 |
|
324 | :ivar InverseName: |
|
325 | :vartype InverseName: 1024 |
|
326 | :ivar IsAbstract: |
|
327 | :vartype IsAbstract: 2048 |
|
328 | :ivar MinimumSamplingInterval: |
|
329 | :vartype MinimumSamplingInterval: 4096 |
|
330 | :ivar NodeClass: |
|
331 | :vartype NodeClass: 8192 |
|
332 | :ivar NodeId: |
|
333 | :vartype NodeId: 16384 |
|
334 | :ivar Symmetric: |
|
335 | :vartype Symmetric: 32768 |
|
336 | :ivar UserAccessLevel: |
|
337 | :vartype UserAccessLevel: 65536 |
|
338 | :ivar UserExecutable: |
|
339 | :vartype UserExecutable: 131072 |
|
340 | :ivar UserWriteMask: |
|
341 | :vartype UserWriteMask: 262144 |
|
342 | :ivar ValueRank: |
|
343 | :vartype ValueRank: 524288 |
|
344 | :ivar WriteMask: |
|
345 | :vartype WriteMask: 1048576 |
|
346 | :ivar ValueForVariableType: |
|
347 | :vartype ValueForVariableType: 2097152 |
|
348 | ''' |
|
349 | None_ = 0 |
|
350 | AccessLevel = 1 |
|
351 | ArrayDimensions = 2 |
|
352 | BrowseName = 4 |
|
353 | ContainsNoLoops = 8 |
|
354 | DataType = 16 |
|
355 | Description = 32 |
|
356 | DisplayName = 64 |
|
357 | EventNotifier = 128 |
|
358 | Executable = 256 |
|
359 | Historizing = 512 |
|
360 | InverseName = 1024 |
|
361 | IsAbstract = 2048 |
|
362 | MinimumSamplingInterval = 4096 |
|
363 | NodeClass = 8192 |
|
364 | NodeId = 16384 |
|
365 | Symmetric = 32768 |
|
366 | UserAccessLevel = 65536 |
|
367 | UserExecutable = 131072 |
|
368 | UserWriteMask = 262144 |
|
369 | ValueRank = 524288 |
|
370 | WriteMask = 1048576 |
|
371 | ValueForVariableType = 2097152 |
|
372 | ||
373 |
@@ 805-865 (lines=61) @@ | ||
802 | elif isinstance(val, bytes): |
|
803 | return VariantType.ByteString |
|
804 | elif isinstance(val, datetime): |
|
805 | return VariantType.DateTime |
|
806 | elif isinstance(val, uuid.UUID): |
|
807 | return VariantType.Guid |
|
808 | else: |
|
809 | if isinstance(val, object): |
|
810 | try: |
|
811 | return getattr(VariantType, val.__class__.__name__) |
|
812 | except AttributeError: |
|
813 | return VariantType.ExtensionObject |
|
814 | else: |
|
815 | raise UaError("Could not guess UA type of {0} with type {1}, specify UA type".format(val, type(val))) |
|
816 | ||
817 | def __str__(self): |
|
818 | return "Variant(val:{0!s},type:{1})".format(self.Value, self.VariantType) |
|
819 | __repr__ = __str__ |
|
820 | ||
821 | def to_binary(self): |
|
822 | b = [] |
|
823 | encoding = self.VariantType.value & 0b111111 |
|
824 | if self.is_array or type(self.Value) in (list, tuple): |
|
825 | self.is_array = True |
|
826 | encoding = uabin.set_bit(encoding, 7) |
|
827 | if self.Dimensions is not None: |
|
828 | encoding = uabin.set_bit(encoding, 6) |
|
829 | b.append(uabin.Primitives.UInt8.pack(encoding)) |
|
830 | b.append(uabin.pack_uatype_array(self.VariantType, flatten(self.Value))) |
|
831 | if self.Dimensions is not None: |
|
832 | b.append(uabin.pack_uatype_array(VariantType.Int32, self.Dimensions)) |
|
833 | else: |
|
834 | b.append(uabin.Primitives.UInt8.pack(encoding)) |
|
835 | b.append(uabin.pack_uatype(self.VariantType, self.Value)) |
|
836 | ||
837 | return b"".join(b) |
|
838 | ||
839 | @staticmethod |
|
840 | def from_binary(data): |
|
841 | dimensions = None |
|
842 | array = False |
|
843 | encoding = ord(data.read(1)) |
|
844 | int_type = encoding & 0b00111111 |
|
845 | vtype = datatype_to_varianttype(int_type) |
|
846 | if uabin.test_bit(encoding, 7): |
|
847 | value = uabin.unpack_uatype_array(vtype, data) |
|
848 | array = True |
|
849 | else: |
|
850 | value = uabin.unpack_uatype(vtype, data) |
|
851 | if uabin.test_bit(encoding, 6): |
|
852 | dimensions = uabin.unpack_uatype_array(VariantType.Int32, data) |
|
853 | value = reshape(value, dimensions) |
|
854 | return Variant(value, vtype, dimensions, is_array=array) |
|
855 | ||
856 | ||
857 | def reshape(flat, dims): |
|
858 | subdims = dims[1:] |
|
859 | subsize = 1 |
|
860 | for i in subdims: |
|
861 | if i == 0: |
|
862 | i = 1 |
|
863 | subsize *= i |
|
864 | while dims[0] * subsize > len(flat): |
|
865 | flat.append([]) |
|
866 | if not subdims or subdims == [0]: |
|
867 | return flat |
|
868 | return [reshape(flat[i: i + subsize], subdims) for i in range(0, len(flat), subsize)] |