|
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