Release Notes¶
(unreleased)¶
Bug Fixes¶
-
The ten-minute Script Mode timeout now reports “Scripting Period ended” instead of “Trial period ended”.
-
dir(node)now exposes valid Python aliases for child names containing spaces, punctuation, leading digits, or keywords; the same aliases work with dot access. -
Client and server
browse()andbrowsePage()now return all reference fields by default; explicit result masks remain supported. -
Local
ExpandedNodeIdvalues, including browse results, now display registered namespace shortnames and accept those strings when reconstructed.
2.2.0¶
New Features¶
-
Added bundled namespaces for CNC, DI package metadata, FDT, plastics dosing and foam cutting, surface cleaning and multi-stage systems, and unattended retail.
-
Client
browsePage/browseNextand shared path-translation helpers match server browsing contracts. -
Client
addObject/addVariablereturn typed handles with server-style inputs; both conveniences acceptparentReferenceand default toOrganizes. -
server.loopexposes the server's owning asyncio event loop as a read-only property. -
Client.connect(createDefaultSubscription=False)opens a session without requiring subscription support or capacity. -
Client.invalidateNodeCache(node)clears cached child navigation; omitnodeto invalidate all handles. -
Servers expose typed
server[nodeId]lookup androot,objects,types, andviewsfolder handles, preserving node identity and application state; await indexing in async tasks. -
Python history backends can serve pages through
getHistoryPage, including token release and session validation.
Improvements¶
-
The Server SDK is now considered stable; removed the beta warning from startup banners and documentation.
-
Event-monitoring callback types and guides describe path-string payload keys, including nested fields.
-
MonitoredItem.requestedParamsexposes the original creation settings; configuration snapshots also isolate nested filters. -
Clarified value conversion, namespace mapping, and API behavior in the guides and examples, and repaired reference links.
Bug Fixes¶
-
Value-only client/server reads and callable nodes accept all Good-severity statuses; use
valueOnly=Falseto inspect status and timestamps. -
Scalar
write(node, None)now matches batch null writes; callable local nodes returnNonewhen reading an accepted null value. -
Variables added with
historizing=Trueto a running server register for history immediately; failed registration removes the new node. -
Variable creation accepts typed empty NumPy arrays and explicitly typed empty sequences, retaining the datatype and declared ValueRank.
-
Automatic datatype discovery preserves string, GUID, and opaque NodeIds, follows every browse page, and reports read failures.
-
Client child-navigation caches refresh after client mutations, reconnects, namespace updates, explicit browsing, and cached misses.
-
Callable local nodes preserve DataValue status and timestamp metadata, matching client nodes.
-
Client node creation and history failures preserve
StatusCodeError.code; batch history errors identify the failed target in exception notes. -
Node lookup validates service and attribute results; malformed responses raise
RuntimeError. -
Server.historize()andunhistorize()work in async code and restore node attributes when history configuration fails. -
Calling
Server.stop()from its worker loop no longer blocks shutdown; async worker callbacks can await the returned task. -
Repeated
Server.deleteMonitoredItem(handle)calls remain awaitable in async code. -
Client monitored items retain accepted filters, discard policies, monitoring modes, and server-revised parameters across partial modifications.
-
Async client monitoring and subscription lifecycle callbacks now run on the client loop and log failures.
-
Monitoring rejects subscriptions owned by another client; triggering links reject foreign, uninitialized, or deleted items before sending requests.
-
Servernow raisesValueErrorfor incomplete or empty certificate/key pairs and forsecureOnly=Truewithout credentials. -
Encrypted servers preserve the constructor's
applicationUriin configuration and discovery responses. -
deleteNode([])returns[]without a deletion request on both client and server. -
Client.deleteReference()now preserves the namespace URI and server index ofExpandedNodeIdtargets. -
Client.addReference()anddeleteReference()service failures now raiseStatusCodeErrorinstead ofValueError, preserving the status code. -
Browsing attempts to release outstanding continuation points on failure or cancellation, including tokens returned during client cancellation.
-
Client.call()service failures now raiseStatusCodeErrorwith the original status available in.code. -
Remote typed Method calls now raise
StatusCodeErrorfor failed method results, matching local calls and the documented behavior. -
Server.read()now matches client read options, including raw DataValues and timestamp selection (SOURCE by default); explicit attributes useattr=. -
Read service and value-only batch failures consistently raise
StatusCodeError, preserving status codes and identifying failed batch entries. -
Server-local monitored items report their actual target, mode, filter, and revised settings; ID-only handles explicitly report unavailable metadata.
-
Unsupported local
modify(),setMonitoringMode(), andsetTriggering()calls raiseNotImplementedErrorwithout changing the item. -
Server.write()with aDataValuenow honors the requested attribute and rejects unsupported combinations without overwriting Value. -
Awaiting server node creation from another event loop now returns a usable, fully configured handle and preserves creation errors.
-
Fixed crashes when awaiting
Server.browse()with typed nodes; async calls now consistently requireawaitfor both Node and NodeId targets. -
Synchronous server startup and asynchronous context entry wait for listening sockets and raise bind failures. Asynchronous callers of
start()can awaitwaitReady()before connecting clients. -
Servers can restart after shutdown with active or pending TCP connections.
-
Namespace publication can be retried after a failure without recreating completed nodes or rerunning their initializers.
-
Role equality is consistent with hashing; name-only roles remain usable in permission APIs but are distinct from resolved roles.
-
Failed subscription and monitored-item deletions preserve retry handles; native deletion clears client handles, and subscription modifications retain accepted settings.
-
Server-local monitored-item handles become invalid after numeric deletion or server cleanup; foreign handles and out-of-range numeric IDs are rejected before deletion.
-
Repeated value encoding and decoding no longer leak datatype references, field names, or partially converted values.
-
Range reads retain error statuses in raw DataValues and raise on invalid or out-of-bounds value-only reads.
-
historyReadfollows server-issued pages and releases unused continuation points on limits, failure, or cancellation. -
Writes through
node(value)now raiseStatusCodeErrorwhen the server rejects them. -
Node introspection no longer blocks its own event loop during interactive completion.
-
Client and server callback cycles are collected, including Python plugins and pending requests.
-
Cancelled client requests no longer raise errors when their responses arrive.
-
Namespace conversion preserves native values during callbacks and repeated datatype lookups.
-
Fixed Python 3.11 reference-count corruption during value conversion, DateTime comparisons, and timer callbacks.
-
DateTime comparisons with unrelated types now follow Python comparison semantics.
-
Empty union values no longer crash namespace conversion.
-
Deleting optional DataValue or DiagnosticInfo fields clears them safely; deleting required native properties raises
AttributeError. -
Client.readnow honorstimestampsToReturn. -
Newly created subscriptions report the publishing interval, lifetime, and keepalive count revised by the server.
-
Fixed memory leaks during binary/JSON decoding,
DataValue.valueaccess, and structure formatting. -
Non-type codec datatype arguments, oversized DateTime strings, invalid Guid byte lengths, and invalid string inputs are now rejected safely.
-
Async method, read, and write callbacks run on the server event loop and may suspend; shutdown cancels pending callbacks.
-
Fields declared with an abstract structured DataType accept concrete subtype values.
Breaking Changes¶
-
Commercial wheels without a valid Credential now use ten-minute Script Mode instead of the two-hour evaluation period; commercial use is permitted in Script Mode.
-
Async tasks must await local server creation, node calls, dynamic child lookups, reference mutations, reverse-connect, discovery, and dataset operations, even for immediate results; synchronous SDK callbacks retain their nonblocking behavior.
-
Client credentials no longer enable plaintext password tokens implicitly; configure encryption or explicitly set
allowNonePolicyPassword=True. -
Startup raises for pending history registrations without a configured database or when registration fails, retaining pending entries for retry.
-
Client.getEndpoints(),findServers(), andfindServersOnNetwork()raiseStatusCodeErrorfor service failures instead of returning empty lists; raw discovery services still return full responses. -
Non-Value writes require the attribute's expected datatype on client, server, and callable nodes; use
LocalizedTextfor Description andnumpy.uint8for AccessLevel. Ordinary Value writes retain type inference. -
Client non-Value writes reject DataValue status/timestamp metadata with
BAD_WRITE_NOT_SUPPORTEDinstead of allowing it to be discarded. -
Unknown
client[nodeId]lookups raiseStatusCodeError(BAD_NODE_ID_UNKNOWN)instead ofKeyError, matching server lookup; local disconnected-client checks and malformed responses raiseRuntimeError. -
Client.deleteNode()andServer.deleteNode()return a list of per-target statuses for batch calls instead of one aggregate status; scalar calls return oneStatusCode. -
Rename the server deletion keyword
deleteReferencestodeleteTargetReferences, and awaitdeleteNode()inside async tasks. -
Client.deleteNode()service failures now raiseStatusCodeErrorinstead ofValueError. -
addReference()anddeleteReference()now use(source, reftype, target)anddeleteBidirectional, returnStatusCode, and requireawaitin async tasks; useaddReferenceLegacy()/deleteReferenceLegacy()to retain the old contract. -
Server.browse()now returns a complete list of references, matchingClient.browse(); remove.referencesaccess and movemaxReferences=calls toServer.browsePage()for explicit pagination. -
Client.browse()failures now raiseStatusCodeErrorinstead ofValueError;Server.browseNext()now raisesStatusCodeErrorfor failed page statuses. -
Server.call()now returns(status, *outputs)for method failures, matchingClient.call(); usestatus.check()to retain exception-based handling. -
Server.write()now accepts parallel target/value lists or a mapping; replace broadcast calls withwrite(nodes, [value] * len(nodes))and pass attributes withattr=. -
Server.write()returns one status or an ordered list of statuses and continues batches after individual failures; check results withstatus.check()to retain exception-based handling. -
Client.write()service failures now raiseStatusCodeErrorinstead ofValueError.
Known Issues¶
- Malformed binary union values can crash the underlying SDK decoder; an upstream fix is required.
2.1.0¶
New Features¶
-
Server.createEvent()emits immediately, matching the C SDK, withemitEvent()as an alias. Construct reusable drafts witho6.Event(server, ...)and emit them withtrigger(). -
When
eventTypeis omitted, emission uses the type ofeventInstanceif supplied; otherwise, the source's type definition is browsed for aGeneratesEventreference, and that EventType is used.
server.addReference(
source=o6.NodeId(PumpType),
reftype=ns0.reftypes.GeneratesEvent,
target=o6.NodeId(PumpFaultType),
)
pump = PumpType(parent=server.objectsNode, browseName="Pump1")
server.createEvent(source=pump, message="Cavitation detected") # PumpFaultType
Without an event instance, a type declaring no GeneratesEvent target falls
back to BaseEventType. A type declaring more than one, or a source with no
type definition at all, raises ValueError. Passing eventType= explicitly
selects the type argument. An Event draft resolves it at each trigger().
Field values retain C's precedence: explicit fields, instance properties,
then emission defaults.
ObjectNodeandViewNodefire an event sourced at themselves with<<, without going back to the owningServer:
pump << o6.Event(server, message="Cavitation detected")
pump << {"message": "Cavitation detected", "severity": 400}
pump << eventInstance
pump << {"eventInstance": eventInstance}
An event instance must be an Object of BaseEventType or a subtype on the
same server; emission reads its current fields without modifying the node.
- Variable read and write callbacks may be
async def, matching Method callbacks:
@o6.read
async def _read(self, **kwargs):
return (o6.StatusCode.GOOD, await self.device.readTemperature())
A coroutine that returns without awaiting completes synchronously. One that
awaits leaves the operation pending and completes it when the coroutine
finishes; server shutdown cancels it. This previously raised
TypeError: Variable callbacks cannot be async.
@o6.enumtypesupports declaring more than 255 members. This previously failed registration outright:
This unblocks o6.ns.bacnet, whose BACnetPropertyIdentifier declares 396.
- Server-side historizing is added.
historizing=TrueonaddVariableused to only set theHistorizingattribute; onceserver.config.setHistoryDatabase(...)is configured, it registers the Variable too:
server.config.setHistoryDatabase(capacity=100)
server.addVariable("Level", plant, 0.0, historizing=True)
historizing=o6.History(capacity=, strategy=, interval=) customizes
capacity and sampling strategy per Variable; server.historize(target, ...)
/ unhistorize(target) do the same for a node this server didn't create.
- Server and client application notifications are exposed as handler
registries. Each
server.on<Category>Notification—Lifecycle,SecureChannel,Session,Service,Subscription,MonitoredItem,DiscoveryRegisterServer,DiscoveryServerOnNetworkandAudit— is a list-like registry usable as a decorator, assignable as a whole, and changeable while the server runs:
@server.onSessionNotification
def _audit(notification):
print(notification.type, notification.payload)
The client side offers onLifecycleNotification, onServiceNotification,
and onGlobalNotification, which sees every notification the connection
produces. A handler on either side receives an o6.Notification carrying
type and payload, a read-only str -> Any mapping of that
notification's fields.
-
Server.addSubscribedDataSet(name, metadata, targets)creates a native standalone subscribed DataSet, andremoveSubscribedDataSet(dataSetId)removes it. This defines the dataset without creating or enabling aDataSetReader. -
ServerConfig.maxSubscriptionsandServerConfig.maxSubscriptionsPerSessioncap the number of subscriptions across all sessions and within one session:
Improvements¶
-
Server.createEventMonitoredItemraisesValueErrorwhen the effectiveEventFilterhas no select clauses, instead of letting the server answerBadEventFilterInvalid. -
The server manual gains a tutorial series covering type declaration, method implementations, variables with sources, callbacks, events and timers, access control, security policies, monitoring and history.
- History reads now support continuation points for paging large result sets.
Use
client.serviceHistoryRead()withHistoryReadValueId.continuationPointto resume reading from where the previous batch ended.
Bug Fixes¶
- An OPC UA enumeration is a Python
enum.IntEnum, an OptionSet anenum.IntFlag, chosen by the declaring decorator. An enumeration no longer drops a member valued zero, or one whose value is the sum of two others, from iteration,dir()andrepr:
Members consequently compose as integers: A | B is a plain int rather than
a member, and issubclass(SomeEnum, enum.Flag) is False. OptionSets are
unchanged — in ns0, 48 enumerations change and 19 OptionSets do not.
- An enumeration value outside the declared set decodes instead of raising, so one out-of-specification field no longer fails the read containing it. The value is preserved as sent, including a negative one:
value in SomeTypenow answers the same question on every supported interpreter, for both enumerations and OptionSets — includingStatusCode. On 3.13+, an expression like99 in SomeOptionSetused to answerTruefor every integer; it now discriminates. On 3.11, the same kind of expression used to raiseTypeError; it now answers instead:
-
A notification payload no longer reports a corrupted namespace index for the node it concerns. The conversion borrowed the native namespace index rather than copying it, so a monitored
NodeIdcould surface under the wrong namespace once the native value was released. -
A default
DisplayNamederived from aBrowseNameno longer carries the namespace qualifier:
machine = Machine(server=server, parent=server.objectsNode, browseName="ns=plant;Machine")
machine(attr=o6.AttributeId.DISPLAY_NAME) # "Machine", not "ns=plant;Machine"
An explicitly passed displayName is preserved unchanged.
- Building from source on Windows no longer fails on a backslashed nodeset directory path handed to CMake.
2.0.3¶
New Features¶
@o6.optionsettypeando6.bitmaskdeclare an integer-form OPC UA OptionSet. Members are bit masks, andbase=names the unsigned integer the OptionSet subtypes — it carries the wire width and theHasSubtypeparent, and is mandatory:
@o6.optionsettype(ns="plant", base=o6.Byte)
class AccessLevelType:
CURRENT_READ = o6.bitmask(0x01 << 0, name="CurrentRead")
HISTORY_WRITE = o6.bitmask(0x01 << 3, name="HistoryWrite")
Bit fields declared with @o6.enumtype should move to it; @o6.enumtype now
rejects o6.bitmask members, and @o6.optionsettype rejects o6.enumfield.
o6.optionsetbitdeclares one bit of a structure-form OptionSet — an@o6.datatypesubtyping the ns0OptionSet. Reading a bit is three-valued (NonewhenValidBitssays the bit means nothing); assigning writesValueandValidBitstogether. Generated structure-form OptionSets now carry one accessor per declared bit instead of leaving the two ByteStrings to be hand-masked.
Improvements¶
- The client's limit on concurrent service calls is now configurable through
client.config.maxAsyncServiceCalls(default32,0disables it). Like allclient.configfields, it must be set beforeconnect(). - Reusing send buffer improves async throughput by ~25%
Bug Fixes¶
- Synchronous client calls no longer hang forever when the event loop passed as
Client(loop=...)is not being run; they are driven to completion inline. Callbacks (data change, event, state) are still only delivered while that loop runs. - OptionSet-typed structure fields now surface as their flag class on read-back, in every namespace including ns0.
del instance.memberon a generated structure no longer crashes the interpreter; it raisesAttributeError, since a structure member always has a value on the wire.instance.__dict__andvars(instance)now answer with a dictionary instead of raising, so debuggers and generic introspection work on structure instances.import o6.ns.<x>.datatypesno longer executes the module body twice.Argument.dataTyperesolved to the wrong namespace in several regenerated packages; it now points at the specification the argument's namespace actually intends:
| namespace | was | is |
|---|---|---|
additive_manufacturing, cutting_tool |
ns=dexpi;i=3006, ns=dexpi;i=3013 |
ns=isa95_jobcontrol_v2;i=3006, ns=isa95_jobcontrol_v2;i=3013 |
glass_flat_v2 |
ns=aml;i=3006, ns=aml;i=3013 |
ns=isa95_jobcontrol_v2;i=3006, ns=isa95_jobcontrol_v2;i=3013 |
machine_tool, shotblasting, surface_technology_plasma, woodworking |
ns=bacnet;i=3006, ns=bacnet;i=3013 |
ns=isa95_jobcontrol_v2;i=3006, ns=isa95_jobcontrol_v2;i=3013 |
machinery_jobs |
ns=amb;i=3006, ns=amb;i=3013 |
ns=isa95_jobcontrol_v2;i=3006, ns=isa95_jobcontrol_v2;i=3013 |
wire_harness |
ns=amb;i=3008, ns=amb;i=3010 |
ns=isa95_jobcontrol_v2;i=3008, ns=isa95_jobcontrol_v2;i=3010 |
gms |
ns=amb;i=3005, ns=amb;i=3008 |
ns=machinery_result;i=3005, ns=machinery_result;i=3008 |
| - Integer-form OptionSet member values are now masks, not bit positions. Applies | ||
to every integer-form OptionSet, including AccessLevelType, |
||
AttributeWriteMask and PermissionType. Ordinary @o6.enumtype |
||
| enumerations are unaffected. |
If a value relied on the previous bit position, drop the extra shift:
# before — double-shifted because members were bit positions
value = 1 << int(my_flag) | 1 << int(my_other_flag)
# after — members are masks
value = my_flag | my_other_flag
- The wire format of five struct fields is now correct against conformant equipment. Sizes are in bytes, measured against the same NodeSet on each release:
| field | declared base | v2.0.2 | now |
|---|---|---|---|
safety.RequestSPDUDataType.inFlags |
Byte | 4 | 1 |
safety.ResponseSPDUDataType.outFlags |
Byte | 4 | 1 |
fx_ac.AggregatedHealthDataType.aggregatedDeviceHealth |
UInt16 | 4 | 2 |
fx_cm.ConnectionDiagnosticsDataType.lastActivity |
UInt16 | 4 | 2 |
machinery_jobs.OutputInformationDataType.outputInfo |
Byte | 4 | 1 |
o6.AccessLevel,o6.WriteMaskando6.Permissionare retired. They aliased generated NS0 OptionSet DataTypes; the generated types are now the only spelling.
| before | after |
|---|---|
o6.AccessLevel |
o6.ns.ns0.datatypes.AccessLevelType |
o6.WriteMask |
o6.ns.ns0.datatypes.AttributeWriteMask |
o6.Permission |
o6.ns.ns0.datatypes.PermissionType |
2.0.2¶
Improvements¶
- New documentation site at https://docs.o6-automation.com/o6-python/, with a restructured manual, client and server tutorials, a full API reference, and performance benchmarks.
- The PyPI project page now renders the package documentation and links to the docs site.
Bug Fixes¶
@o6.enumtype(isAbstract=True)no longer crashes on Python 3.11 (the abstract-enum path used a functional-API call shape that 3.12'senum.IntFlagaccepts but 3.11 rejects).
Breaking Changes¶
- Generated type names starting with a digit are spelled out instead of
_-prefixed:_3DVectorbecomesThreeDVector,_3DFrameTypebecomesThreeDFrameType, and so on for all_3D*types inns0and the companion specs. This matches the OPC UA type dictionary and open62541. Enum members are unaffected and keep their_16_BITspelling.
2.0.1¶
Distribution¶
- Public
o6wheels contain the full Client and Server API. - Without an issued Credential, the public wheel runs in the existing two-hour
evaluation mode. Its process-wide timer starts when
o6is imported; a valid Credential removes the time limit. Expiry terminates the process with a failure exit status; POSIX expiry is an immediate signal-safe hard exit. - An unreadable, malformed, incorrectly signed, not-yet-valid, or expired Credential prints the reason and falls back to evaluation mode instead of failing import. Fallback warnings remain visible when routine startup output is suppressed, as do the Trial Mode and expiry notices.
- Commercial builds use
O6PYTHON_LICENSE_FILEwhen set; otherwise they checko6python_license.jsonin the current working directory. AGPL builds do not use Credentials or evaluation mode. A missing configured path warns; a missing default file proceeds directly to the Trial Mode message. - Credential Feature Scopes independently control
client,server, andpubsub; PubSub requires Server. Compiled symbols remain importable, while unauthorized construction or PubSub operations raisePermissionError. PubSub-disabled Servers omit the native PubSub manager, information-model methods, and transports. - Standard GIL-enabled CPython 3.11–3.14 is supported on Linux and macOS
x86_64/ARM64 and Windows AMD64/ARM64. - Linux wheels require glibc 2.28 or newer (
manylinux_2_28). - macOS wheels require macOS 15 Sequoia or newer.
- Windows AMD64 supports Windows 10 Enterprise LTSC 2021 and Windows Server 2022 or newer; Windows ARM64 supports Windows 11 or newer.
- Supported NumPy versions are
>=2.0,<3; the native extension targets the NumPy 2.0 C API and is tested with minimum and current NumPy 2.x releases.
API organization¶
- Added explicit public exports for
o6and its public modules. - Moved subscription classes to the canonical
o6.subscriptionmodule and callback protocols and contexts too6.server; the previous paths have been removed. - Made declaration, decorator, reference, datatype-registration, and node backend implementation paths private without changing the supported root authoring helpers.
- Standardized public methods, properties, parameters, and model members on
lowerCamelCase (
nodeId,browseName,addVariable,encodeJson). Types remain PascalCase and decorators remain lowercase compounds. Previous public spellings have been removed rather than retained as compatibility aliases. - Grouped companion-spec symbols under each namespace's
datatypes,objtypes,vartypes,reftypes, andinstancesmodules instead of flattening them onto the namespace object. - Standardized datatype-discovery result keys on lowerCamelCase (
typeName,typeId,binaryEncodingId,typeKind,structureType,membersSize).
Breaking Changes¶
-
o6.ns.<ns>.datatypes.<X>()now instantiates the concrete datatype.returns o6.Int32()numpy.int32(0)o6.nsx.ns0.BaseDataType.Structure.Argument()o6.ArgumentTo obtain the NodeId, use
o6.NodeId(o6.ns.<ns>.datatypes.<X>). Abstract datatypes (e.g.BaseDataType,Number,Integer) will throw when tried to instantiate. -
struct members caml vs. snake case.
In order to be PEP8 compliant previous versions converted member names of UA Structs and DataTypes to snake case naming convention. For better clarity, we are dropping this conversion and replacing these member names with their official names from the UA Namespace 0 and companion specs. In order to adhere closer to PEP8 we allow a single exception to the UA naming convention: the first character may be lower case for class members of python classes, that represent UA DataTypes and Structs.
-
enum members are consequently converted to capitalized snake case
-
dir()on a node lists instance children in lowerCamelCaseBrowsing a node now surfaces its Object, Variable, Method and View children under the lowerCamelCase name derived from their BrowseName, so completion offers
client.objects.server.serverStatusinstead ofServerStatus— the same spelling that generated declarations already use for their members. Type children (ObjectType, VariableType, ReferenceType, DataType) keep their PascalCase BrowseName. Dot access remains case-insensitive, soclient.objects.server.ServerStatusstill resolves.
New Features¶
- OPC UA Browser, now built in feature of the
o6.Clientavailable throughclient.browseInteractive - Cleaned up Client API
- removed
client.fully_connected,client.connectedis now only true when there's a secure channel and a session - removed
client.disconnect_secure_channelin favor ofclient.disconnect()parameterscloseSessionanddeleteSubscriptions - added range parameter for
client.readandclient.write, that lets one read into a slice of an array variable with e.g. "1:10" - StatusCode is now a proper Python
IntFlagwith full bitwise support: - added support for browse continuation point, i.e.
client.browsenow guarantees to return the complete list of references - cleand up and simplified history access through the client
- revised the client node-management function parameters and added useful defaults for
parentReference-o6.ns.ns0.hasComponenttypeDefinition-o6.ns.ns0.objtypes.BaseDataVariableType
- added callbacks for subscriptions
onCreated- fires when this subscription was created on the serveronStatusChange- fires when the server reports a status change for this subscription (e.g. keepalive timeout exceeded, session transfer on reconnect), receives the newStatusCodeonDeleted- fires when this subscription was deleted on the server
- added callbacks for monitored item
onCreated- fires when this monitored item was created on the serveronDeleted- fires when this monitored item was deleted on the server
- removed