|
1 | 1 | import logging
|
2 | 2 | from datetime import datetime
|
| 3 | +import random |
3 | 4 |
|
4 | 5 | from opcua import ua
|
5 | 6 | from opcua.server.user_manager import UserManager
|
@@ -473,40 +474,34 @@ def _call(self, method):
|
473 | 474 |
|
474 | 475 |
|
475 | 476 | class AddressSpace(ThreadSafeDict):
|
476 |
| - |
477 | 477 | """
|
478 | 478 | The address space object stores all the nodes of the OPC-UA server
|
479 | 479 | and helper methods.
|
480 | 480 | The methods are thread safe
|
481 | 481 | """
|
| 482 | + # https://opcfoundation.org/UA/schemas/1.03/Opc.Ua.Types.bsd |
| 483 | + # numeric nodeid is UInt32, but Siemens MindSphere uses Int32. |
| 484 | + MAX_NUMERIC_IDENTIFIER = 0x7fffffff |
482 | 485 | DEFAULT_USER_NAMESPACE_INDEX = 2
|
483 | 486 |
|
484 | 487 | def __init__(self, cache=None):
|
485 | 488 | super(AddressSpace, self).__init__(cache)
|
486 | 489 | self.logger = logging.getLogger(__name__)
|
487 | 490 | self._datachange_callback_counter = 200
|
488 | 491 | self._handle_to_attribute_map = {}
|
489 |
| - self._nodeid_counter = {0: 20000, 1: 2000} |
490 | 492 |
|
491 | 493 | def generate_nodeid(self, idx=DEFAULT_USER_NAMESPACE_INDEX):
|
492 |
| - if idx in self._nodeid_counter: |
493 |
| - self._nodeid_counter[idx] += 1 |
494 |
| - else: |
495 |
| - # get the biggest identifier number from the existed nodes in address space |
496 |
| - identifier_list = sorted([nodeid.Identifier for nodeid in self |
497 |
| - if nodeid.NamespaceIndex == idx and nodeid.NodeIdType |
498 |
| - in (ua.NodeIdType.Numeric, ua.NodeIdType.TwoByte, ua.NodeIdType.FourByte)]) |
499 |
| - if identifier_list: |
500 |
| - self._nodeid_counter[idx] = identifier_list[-1] |
501 |
| - else: |
502 |
| - self._nodeid_counter[idx] = 1 |
503 |
| - nodeid = ua.NodeId(self._nodeid_counter[idx], idx) |
| 494 | + nodeid = ua.NodeId( |
| 495 | + identifier=random.randrange(AddressSpace.MAX_NUMERIC_IDENTIFIER), |
| 496 | + namespaceidx=idx |
| 497 | + ) |
504 | 498 | with self._lock: # OK since reentrant lock
|
505 |
| - while True: |
| 499 | + for retry in range(0, 10): |
506 | 500 | if nodeid in self:
|
507 | 501 | nodeid = self.generate_nodeid(idx)
|
508 | 502 | else:
|
509 | 503 | return nodeid
|
| 504 | + assert(False) # What are the odds? |
510 | 505 |
|
511 | 506 | def get_attribute_value(self, nodeid, attr):
|
512 | 507 | with self._lock:
|
|
0 commit comments