(Working Title Note: The name "Corona" is used here as per initial discussion, but a different name might be preferable for a formal standard due to potential external associations.)
This repository contains draft specifications for "Corona", a proposed standard for defining Operational Technology (OT) network and application performance metrics in a protocol-agnostic manner. The goal is to provide clear, reusable semantic definitions for common performance indicators found in industrial control systems and building automation.
This standard aims to:
- Define metrics like traffic counters, latency, error rates, and utilization using semantic web technologies (RDFS).
- Provide validation rules and constraints for data conforming to these metric definitions using SHACL.
- Facilitate interoperability and consistent interpretation of performance data across different OT protocols and platforms.
- Demonstrate seamless integration with existing standards, specifically the BACnet RDF representation proposed in ASHRAE Standard 135-2024 Addendum ct[cite: 1].
- Integrate with network topology models for contextualizing metrics.
This standard is designed to work in conjunction with other related efforts:
- corona-network-standard: Defines the RDFS/SHACL model for representing network topology (Nodes, Interfaces, Links, Subnets, VLANs).
corona-standard
metrics use theobservedFrom
property to link to specificnet:HWNetEntity
instances (likenet:Node
ornet:Iface
) defined in this network model, providing context for where the metrics were observed. - corona-pcap-processor: An example implementation that processes PCAP network capture files (specifically focusing on BACnet traffic), extracts relevant performance data, and generates RDF metrics conforming to the
corona-standard
definitions and Pydantic models.
This repository (conceptually) contains the following components:
-
data/corona-ontology.ttl
:- RDFS definitions for Corona metric classes (e.g.,
NetworkInterfaceMetric
,ApplicationMetric
) and properties (e.g.,bytesReceived
,readCommandLatency
,requestSuccessPercentage
). - Provides the core semantic meaning for each metric.
- References classes from
corona-network-standard
(e.g.,net:HWNetEntity
as the range forcorona:observedFrom
).
- RDFS definitions for Corona metric classes (e.g.,
-
data/corona-shapes.ttl
:- SHACL Node Shapes (e.g.,
NetworkInterfaceShape
,ApplicationMetricShape
) defining constraints for RDF data graphs reporting Corona metrics. - Specifies rules like data types (
xsd:unsignedLong
,xsd:float
), cardinality (min/max count), and value ranges. - Validates links to network entities (e.g., ensuring
corona:observedFrom
points to a validnet:HWNetEntity
).
- SHACL Node Shapes (e.g.,
-
src/models.py
:- Pydantic models mirroring the RDFS/SHACL definitions, providing a Pythonic way to create and validate metric data.
- Includes methods (
to_ttl
,to_prometheus
,to_haystack_json
) for serializing metric instances into various output formats.
-
examples/
:- Illustrative RDF examples demonstrating how systems (e.g., BACnet) can report metrics using the Corona standard definitions.
-
README.md
:- This file.
-
observedFrom
:- Description: Specifies the observer node in the network where these metrics were collected or calculated. This is the monitoring point (capture device, analyzer, or network tap) rather than the device about which the metrics were observed.
- Domain:
PerformanceMetric
- Range:
rdfs:Resource
-
description
:- Description: Provides a detailed description of this metric instance, including context about how it was collected or calculated.
- Domain:
PerformanceMetric
- Range:
xsd:string
-
metric-identifier
:- Description: A unique identifier for this specific metric instance to distinguish it from other similar metric instances in the same system.
- Domain:
PerformanceMetric
- Range:
xsd:string
-
metric-name
:- Description: A human-readable name for this metric instance that can be used for display purposes.
- Domain:
PerformanceMetric
- Range:
xsd:string
-
readPropertyRequests
:- Description: Total number of
ReadProperty
requests sent. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Total number of
-
readPropertyResponses
:- Description: Total number of
ReadProperty
responses received. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Total number of
-
totalProperties
:- Description: Total number of properties available in the BACnet object.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
whoIsRequestsSent
:- Description: Total number of
Who-Is
requests sent. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Total number of
-
globalWhoIsRequestsSent
:- Description: Number of global
Who-Is
requests sent. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Number of global
-
directedWhoIsRequestsSent
:- Description: Number of directed
Who-Is
requests sent. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Number of directed
-
globalWhoHasRequestsSent
:- Description: Number of global
WhoHas
requests sent. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Number of global
-
directedWhoHasRequestsSent
:- Description: Number of directed
WhoHas
requests sent. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Number of directed
-
iAmResponsesSent
:- Description: Total number of
I-am
responses sent. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Total number of
-
iAmResponsesReceived
:- Description: Total number of
I-am
responses received. - Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Description: Total number of
-
globalBroadcastMessageCount
:- Description: Total number of global broadcast messages sent or received.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
totalBacnetMessagesSent
:- Description: Total number of BACnet messages sent by this device.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
totalBroadcastsSent
:- Description: Total number of broadcast messages (any type) sent by this device.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
unconfirmedCOVNotificationsSent
:- Description: Total number of unconfirmed COV notifications sent.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
confirmedCOVNotificationsSent
:- Description: Total number of confirmed COV notifications sent.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
unconfirmedCOVNotificationsReceived
:- Description: Total number of unconfirmed COV notifications received.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
confirmedCOVNotificationsReceived
:- Description: Total number of confirmed COV notifications received.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
messagesRouted
:- Description: Total number of messages routed by this device acting as a router.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
messagesForwarded
:- Description: Total number of messages forwarded by this device acting as a BBMD.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
routedMessagesSent
:- Description: Total number of messages routed and sent to other networks.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
routedMessagesReceived
:- Description: Total number of messages received that were routed from other networks.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
-
routedVia
:- Description: Identifies the router or gateway device through which this message was routed.
- Domain:
ApplicationMetric
- Range:
rdfs:Resource
-
routedDevicesSeen
:- Description: Number of unique devices on other networks that have been seen through routing.
- Domain:
ApplicationMetric
- Range:
xsd:unsignedLong
- Defining Metrics: Use the URIs defined in
corona-ontology.ttl
(e.g.,corona:bytesReceived
) as stable identifiers when referring to these specific metrics in documentation, APIs, or data models. - Validating Data: Use the SHACL shapes in
corona-shapes.ttl
with a SHACL-compliant validation tool to check if RDF data correctly represents Corona metrics according to the defined constraints. - BACnet Integration: The examples show how RDF data generated from BACnet systems (following Addendum ct [cite: 1]) can incorporate Corona metric reporting. Systems can either:
- Directly use
corona:
properties for metrics. - Map existing or vendor-specific BACnet properties to
corona:
properties usingrdfs:subPropertyOf
orowl:sameAs
(if OWL is used). - Ensure generated RDF instances are declared with appropriate
corona:
classes (e.g.,corona:NetworkInterfaceMetric
) to be targeted by the SHACL shapes.
- Directly use
The Corona standard supports multiple output formats to facilitate integration with different systems and tools:
The primary representation format using RDF semantic web technologies:
- Uses subject-predicate-object triples
- Organizes metrics with namespaces:
corona:
andbacnet:
- Links devices and interfaces with relationship predicates
- Example:
ex:addr_10.21.52.5 corona:globalWhoIsRequestsSent "8"^^xsd:unsignedLong
- Row-based representation with metadata in header
- Column-based representation with type information
- One row per (entity, metric) combination
- Example:
{"metric":"globalWhoIsRequestsSent", "val":8, "entity":"@addr_10.21.52.5"}
- Compact representation of the JSON format
- Brief headers and row-based data
- Uses
@id
refs and marker syntax - Example:
@addr_10.21.52.5 ... metric:"globalWhoIsRequestsSent" val:8
Text-based format following OpenTelemetry conventions:
- Metric name + labels pattern
- Type and help metadata as comments
- Counter metrics with
_total
suffix - Example:
bacnet_global_whois_requests_total{device_id="",address="10.21.52.5"} 8
Metrics maintain consistent semantic meaning across formats with format-specific naming conventions:
TTL (Corona) | Prometheus | Haystack (JSON/Zinc) |
---|---|---|
corona:globalWhoIsRequestsSent | bacnet_global_whois_requests_total | metric:"globalWhoIsRequestsSent" |
corona:packetsReceived | bacnet_packets_total | metric:"packetsReceived" |
corona:totalBacnetMessagesSent | bacnet_messages_sent_total | metric:"totalBacnetMessagesSent" |
corona:messagesRouted | bacnet_messages_routed_total | metric:"messagesRouted" |
When translating between formats, the following principles are maintained:
- Semantic equivalence: Same metrics with different syntax
- Namespace mapping: Corona/bacnet → bacnet_ prefix (Prometheus)
- Structure transformation: Resource-centric (TTL) to row-based (Haystack)
- Data type alignment: XSD types (TTL) → native JSON types → text (Prometheus)
DRAFT / PROPOSAL: The specifications contained herein are conceptual drafts and do not represent an official standard. They are intended for discussion, experimentation, and refinement.
This is currently a conceptual exploration. Feedback, suggestions for improvement, additional metric definitions, and use cases are welcome. Please open an issue in the repository tracker (if applicable) for discussion.