graph TD
A[Start Application<br>File: main.py<br>Function: main] --> B{Validate Operation Mode<br>File: main.py<br>Class: OperationMode}
B -->|Valid: ACTIVE or LOG_ONLY| C[Initialize Resources<br>File: main.py<br>Function: manage_resources]
B -->|Valid: CONFIG| D[Log Config Mode and Exit<br>File: main.py]
B -->|Invalid| E[Log Error and Exit<br>File: main.py]
C --> F[Create OpcUaManager<br>File: opcua_client.py<br>Class: OpcUaManager]
C --> G[Create OutputTStore<br>File: output_tstore.py<br>Class: OutputTStore]
F --> H[Set OpcUaManager in AppState<br>File: state.py<br>Class: AppState]
F --> I[Start OPC UA Client Task<br>File: opcua_client.py<br>Function: start_client]
G --> J[Start TStore Send Data Loop<br>File: output_tstore.py<br>Function: send_data_loop]
I --> K{Check Server Availability<br>File: opcua_client.py<br>Function: check_server_availability}
K -->|Success| L{Connect to OPC UA Server<br>File: opcua_client.py<br>Function: ensure_connected}
K -->|Failure| M{Retry Connection<br>connection_errors_count++}
M -->|Max Retries Exceeded<br>connection_retry_count| N[Log Error and Exit<br>File: opcua_client.py]
M -->|Retry| K
L -->|Success| O[State: CONNECTED<br>connection_success_count++<br>File: opcua_client.py]
L -->|Failure| M
O --> P[Validate Nodes<br>File: opcua_client.py<br>Function: monitor_values]
P --> Q{Check for Enumeration Nodes<br>File: opcua_client.py<br>Class: OpcUaEnumerationsManager}
Q -->|Is Enumeration| R[Process Enum and Cache<br>File: opcua_client.py<br>Function: process_node_as_enum]
Q -->|Not Enumeration| S[Subscribe to Nodes<br>File: opcua_client.py<br>Function: monitor_values]
R --> S
S -->|Success| T[State: Monitoring<br>consecutive_errors = 0<br>File: opcua_client.py]
S -->|Failure| U{Retry Subscription<br>consecutive_errors++<br>File: opcua_client.py}
U -->|force_reconnect=True or<br>consecutive_errors >= reconnect_error_threshold| K
U -->|Retry<br>read_retry_count| S
T --> V[Receive Data Changes<br>File: opcua_client.py<br>Class: SubscriptionHandler]
V -->|LOG_ONLY| W[Log Data<br>File: opcua_client.py<br>Function: datachange_notification]
V -->|ACTIVE| X[Enqueue Data to TStore<br>File: opcua_client.py<br>Function: datachange_notification]
X --> J
V -->|Connection Lost| Y[force_reconnect=True<br>consecutive_errors++<br>File: opcua_client.py]
Y --> K
subgraph Configuration Updates
Z[Detect Config Update<br>File: main.py<br>Function: wait_for_config_update]
Z -->|Config Changed| AA[Restart Resources<br>File: main.py<br>Function: manage_resources]
AA --> C
end
-
Start Application:
- The app starts by running
main.py, which initializes logging and validates the operation mode (OPERATION_MODE) fromsettings.
- The app starts by running
-
Validate Operation Mode:
- Checks if the operation mode is valid (
ACTIVE,LOG_ONLY, orCONFIG). - If invalid, logs an error and exits.
- If
CONFIG, logs configuration details and exits. - If
ACTIVEorLOG_ONLY, proceeds to initialize resources.
- Checks if the operation mode is valid (
-
Initialize Resources:
- Creates an
OutputTStoreinstance for data storage. - Creates an
OpcUaManagerinstance with the OPC UA configuration fromopcua_config.yaml. - Starts two background tasks:
- OPC UA client task (
opcua_manager.start_client) to connect and monitor nodes. - TStore send data loop (
output_tstore.send_data_loop) to process enqueued data.
- OPC UA client task (
- Creates an
-
Connect to OPC UA Server:
- Attempts to connect to the OPC UA server (endpoint from
opcua_config.yaml). - Tracks connection state with
stateflag (Disconnected→Connected). - Increments
connection_success_counton success orconnection_errors_counton failure. - If connection fails, retries up to
connection_retriestimes with exponential backoff. - If all retries fail, logs an error and exits.
- Attempts to connect to the OPC UA server (endpoint from
-
Monitor Nodes:
- Retrieves monitored items from
opcua_config.yaml(e.g., node IDs likens=1;i=1450). - Validates each node by reading its display name.
- Creates a subscription with specified parameters (
publishing_interval,queue_size, etc.). - Subscribes to each valid node, checking if it’s an enumeration node (using
OpcUaEnumerationsManager). - Tracks subscription state with
consecutive_errorscounter andforce_reconnectflag.
- Retrieves monitored items from
-
Handle Data Changes:
- Receives data change notifications via
SubscriptionHandler. - If
LOG_ONLYmode, logs the data (value, timestamp, tags). - If
ACTIVEmode, enqueues data toOutputTStorefor storage. - Processes timestamps based on
timestamp_source(gather, server, or source).
- Receives data change notifications via
-
Handle Connection Issues:
- If a connection error occurs (e.g.,
ConnectionErroror bad status code), incrementsconsecutive_errors. - If
consecutive_errorsreachesreconnect_error_thresholdor specific OPC UA errors occur (e.g.,BadSessionIDInvalid), setsforce_reconnect=True. - Triggers reconnection by returning to the connection step.
- If a connection error occurs (e.g.,
-
Shutdown:
- On interruption (e.g., KeyboardInterrupt) or error, cancels background tasks (
opcua_task,tstore_task). - Disconnects the OPC UA client and logs shutdown completion.
- On interruption (e.g., KeyboardInterrupt) or error, cancels background tasks (
-
Boolean Flags:
force_reconnect: Set toTruewhen a session is invalid orconsecutive_errorsexceeds the threshold, triggering a reconnection attempt.state: Tracks connection status (DisconnectedorConnected), updated during connection attempts and disconnections.
-
Counters:
connection_success_count: Increments on successful connections.connection_errors_count: Increments on failed connection attempts.consecutive_errors: Tracks sequential subscription failures, reset to 0 on success, and triggers reconnection if it reachesreconnect_error_threshold.data_points_count: Tracks the number of data points processed (not fully utilized in the provided code but present for monitoring).
-
Retries:
- Connection retries (
connection_retries): Attempts to connect to the OPC UA server with exponential backoff. - Subscription retries (
read_retry_count): Attempts to subscribe to nodes, with a delay (read_retry_timeout) between tries.
- Connection retries (