IDataSource
├── IConnector // For historical data access
└── ILiveConnector // For real-time data streaming
ThinkIQ Connector Interfaces Documentation
Base Interface: IDataSource
Namespace: ThinkIQ.DataManagement
Implemented by:
- IConnector (for historical data access)
- ILiveConnector (for live data streaming)
Description
IDataSource defines the foundational contract for any data source connector within the ThinkIQ ecosystem. It abstracts common functionality like connecting, browsing available tags, and disconnecting from the source system.
This interface is designed to be shared between both live and historical connectors, enabling consistent behavior and unified handling in higher-level systems.
Methods & Properties
bool Connect(IConnectorInfo info)
- Purpose:
Establish a connection to the data source using the provided configuration. - Parameters:
info: An object containing connection parameters such as endpoint URL, authentication, and other protocol-specific data. - Returns:
true if connection was successful; false otherwise.
IDictionary<string, ITag> Browse(bool newTagOnly)
- Purpose:
Discover tags (data points) available in the source. - Parameters:
newTagOnly: If true, return only newly discovered tags since the last call. If false, return all tags in the white list. - Returns:
A dictionary mapping tag names to their corresponding ITag metadata.
void Disconnect()
- Purpose:
Gracefully close the connection to the data source and release any held resources.
bool IsConnected { get; }
- Purpose:
Indicates whether the connector is currently connected to the source system.
IConnector Interface
Namespace: ThinkIQ.DataManagement
Implements: IDataSource
Primary Use Case: Historical data acquisition from a source system.
Description
IConnector defines the core interface between the South Bridge and a data source Adapter (connector). It focuses on retrieving historical data and managing the list of tags to be acquired. Implementing this interface allows connectors to provide historical data via a IHistoryReader.
Methods
void SetAcquiredTags(IList<string> tagNameList, bool useAcquiredTagListAsWhiteList)
- Purpose:
Updates the connector with the list of tags acquired from the cloud via CloudAcquiredTagList.txt. - Parameters:
tagNameList: List of tag names to acquire. If the first value is "*", acquire historical data for all tags.
useAcquiredTagListAsWhiteList: If true, restrict data gathering only to the tags in tagNameList. - Typical Use Case:
Used during system startup or when a configuration file changes.
IHistoryReader CreateReader(IDictionary<string, ITag> tagDict, bool acceptStartBoundValue)
- Purpose:
Instantiates a reader to retrieve historical tag values. - Parameters:
tagDict: Dictionary of tag identifiers and their definitions.
acceptStartBoundValue: Whether the returned data should include the exact value at the start time (if available). - Returns:
An instance of IHistoryReader for historical playback.
ILiveConnector Interface
Namespace: ThinkIQ.DataManagement
Implements: IDataSource
Primary Use Case: Real-time data streaming from a source system.
Description
ILiveConnector is a specialized interface for connectors that support live or streaming data. It allows the South Bridge to subscribe to live updates and forward them to the appropriate storage layer.
Methods
void Initialize(ILiveDataStorer dataStorer)
- Purpose:
Initializes the connector with a storage component that handles incoming live data. - Parameters:
dataStorer: Component responsible for storing incoming real-time values. - Typical Use Case:
Called once during startup before any subscriptions are created.
ILiveSubscriber CreateSubscriber(IDictionary<string, ITag> tagDict, int updateRate = 0, float deadband = 0, bool isDeadbandAbsolute = false)
- Purpose:
Creates a live data subscriber to stream updates for a set of tags. - Parameters:
tagDict: The tag definitions to subscribe to.
updateRate: Minimum interval (in milliseconds) for updates. 0 means “as fast as available.”
deadband: Threshold for detecting significant value changes.
isDeadbandAbsolute: Indicates whether the deadband is absolute (true) or percentage-based (false). - Returns:
An ILiveSubscriber object that represents the active subscription.
Data Flow
Historical Connector
Connect → SetAcquiredTags → CreateReader → IHistoryReader → Data
Live Connector
Connect → Initialize(ILiveDataStorer) → CreateSubscriber → ILiveSubscriber → Pushes Data
Supporting Interfaces & Classes
IConnectorInfo
Describes connection metadata (e.g., endpoint, credentials).
ILiveSubscriber
Represents an active real-time data stream.
IHistoryReader
Provides access to historical data range.
ITag
Describes a single tag with name, type, and attributes.
LiveDataStorer
Consumes and stores incoming live values.
Factories
IConnectorFactory
Used to dynamically instantiate historical connectors.
ILiveConnectorFactory
Used to dynamically instantiate live connectors.
ThinkIQ.Utils
The ThinkIQ.Utils project provides general-purpose helper functions, file watchers, configuration readers, and utility classes that support the broader ThinkIQ connector infrastructure.
File/Class |
Description |
ConfigFileChangeWatcher.cs |
Monitors config files for changes and raises events accordingly |
ConfigFileInfo.cs |
Represents metadata or path info for a config file |
Crypto.cs / Fernet.cs |
Cryptography utilities, possibly Fernet-based encryption/decryption |
DirectoryWatcher.cs |
Monitors directories for file additions or changes |
Extensions.cs |
Extension methods to simplify common operations |
FilePath.cs |
Helpers for file path validation, construction, or manipulation |
GateWayConfigFileInfo.cs |
Specialized config file info for Gateway components |
Initializable.cs |
Interface for components requiring Initialize() method |
InitializableFactory.cs |
Factory to instantiate and initialize components |
InitiateDownload.cs |
Manages or triggers download routines (probably for configs or assets) |
JsonHelper.cs |
Read/write JSON objects, wrapping System.Text.Json or Newtonsoft.Json |
NameUtils.cs |
Utility functions for string-based name handling or formatting |
SoftwareComponent.cs |
Describes a software module or component (likely for metadata or logging) |
TempDirPath.cs |
Creates/manages paths to temporary working directories |
TextFileHelper.cs |
Simplified file IO helpers for .txt files
|
Interfaces
Interface |
Purpose |
IInitializable |
For any class that supports explicit initialization logic |
IInitializableFactory |
Abstracts creation and setup of initializable components |
Common Use Cases
- Detect config changes and auto-reload (ConfigFileChangeWatcher)
- Store runtime info for diagnostics (SoftwareComponent)
- Secure local configuration (Fernet, Crypto)
- Load tag or connector configs (TextFileHelper, JsonHelper)
- Standardize naming and paths across projects (FilePath, TempDirPath)
ThinkIQ.Logging
The ThinkIQ.Logging project centralizes application logging using Serilog, with support for structured logging, dynamic log level control, and configurable sinks (console, file). It provides:
- Global logging setup (Setup)
- Logging service provider (LoggingService)
- Throttled error reporting (ErrorHandler)
Components
Setup.cs
Initializes logging during app startup.
- Reads logsettings.json
- Creates rolling log files in Logs/
- Registers ILogger with IServiceCollection
- Supports live-reload of log level via IChangeToken
- Applies fallback logger if config is missing
Key Method: Setup.Initialize()
Related File: logsettings.json
LoggingService.cs
Provides a static access point for DI container-based logging.
public static volatile IServiceProvider Provider;
- Lazily initialized via Setup.Initialize()
- Used internally by ErrorHandler to get typed loggers
ErrorHandler.cs
Singleton error logging utility that prevents duplicate logs for repeated errors within a cooldown window.
public double MinutesBetweenSameErrorLog { get; set; }
Behavior:
- Stores message timestamps in a dictionary
- If the same error occurs again within the cooldown window (default 15 min), it will be ignored
- Supports overloads:
- Handle(Exception ex, string message, LogLevel level)
- Handle(string message, LogLevel level)
Usage Example:
ErrorHandler.Instance.Handle(ex, "Database connection failed", LogLevel.Critical);
Configuration Example (logsettings.json)
{
"Serilog": {
"MinimumLevel": {
"Default": "Information"
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "Logs/ThinkIQ-Log.txt",
"rollingInterval": "Day"
}
}
]
}
}
Usage Tips
- Place logsettings.json in the same directory as the app .exe
- Call Setup.Initialize() at the start of Main()
- Use ErrorHandler for persistent systems that may retry frequently (e.g., OPC clients, background services)