Passed
Push — master ( 8ba94e...b74312 )
by Olivier
04:13 queued 01:55
created

client_to_uanet_alarm_conditions.main()   A

Complexity

Conditions 2

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 17
nop 0
dl 0
loc 31
rs 9.55
c 0
b 0
f 0
1
import asyncio
2
import logging
3
from asyncua import Client, ua
4
from asyncua.common.events import Event, get_filter_from_event_type
5
6
logging.basicConfig(level=logging.INFO)
7
_logger = logging.getLogger(__name__)
8
9
class SubHandler:
10
11
    def __init__(self):
12
        self.currentConditions = {}
13
     
14
    """
15
    Subscription Handler. To receive events from server for a subscription
16
    data_change and event methods are called directly from receiving thread.
17
    Do not do expensive, slow or network operatsion there. Create another
18
    thread if you need to do such a thing
19
    """
20
    def event_notification(self, event):                        
21
        _logger.info("New event received: %r", event)           
22
        # To avoid special event for ConditionRefresh 'Condition refresh started for subscription X.' 
23
        if (event.NodeId):             
24
            conditionId = event.NodeId.to_string()
25
            conditionKeys = self.currentConditions.keys()
26
            # A alarm/condition appears with Retain=True and disappears with Retain=False            
27
            if event.Retain and not conditionId in conditionKeys:                          
28
                self.currentConditions[conditionId] = event
29
            if not event.Retain and conditionId in conditionKeys:
30
                del self.currentConditions[conditionId]                
31
            _logger.info("Current alarms/conditions: %r", conditionKeys)                
32
33
34
async def main():
35
    # OPCFoundation/UA-.NETStandard-Samples Quickstart AlarmConditionServer
36
    url = "opc.tcp://localhost:62544/Quickstarts/AlarmConditionServer"
37
    async with Client(url=url) as client:
38
        alarmConditionType = await client.nodes.root.get_child(["0:Types", "0:EventTypes", "0:BaseEventType", "0:ConditionType", 
39
                                                                "0:AcknowledgeableConditionType", "0:AlarmConditionType"])  
40
41
        conditionType = await client.nodes.root.get_child(["0:Types", "0:EventTypes", "0:BaseEventType", "0:ConditionType"])
42
         
43
        # Create Operand for necessary field ConditionId
44
        # Hint: The ConditionId is not a property of the event, but it's NodeId.
45
        #       ConditionId is named "NodeId" in event field list.
46
        conditionIdOperand = ua.SimpleAttributeOperand()
47
        conditionIdOperand.TypeDefinitionId = ua.NodeId(ua.ObjectIds.ConditionType)    
48
        conditionIdOperand.AttributeId = ua.AttributeIds.NodeId 
49
50
        # Add ConditionId to select filter
51
        evfilter = await get_filter_from_event_type([alarmConditionType])        
52
        evfilter.SelectClauses.append(conditionIdOperand)
53
               
54
        # Create subscription for AlarmConditionType
55
        msclt = SubHandler()
56
        sub = await client.create_subscription(0, msclt)      
57
        handle = await sub.subscribe_events(client.nodes.server, alarmConditionType, evfilter)          
58
59
        # Call ConditionRefresh to get the current conditions with retain = true
60
        # Should also be called after reconnects
61
        await conditionType.call_method("0:ConditionRefresh", ua.Variant(sub.subscription_id, ua.VariantType.UInt32))     
62
63
        await asyncio.sleep(30)  
64
        await sub.unsubscribe(handle)
65
66
if __name__ == "__main__":
67
    asyncio.run(main())
68