Skip to main content

Streaming Telemetry Transport Protocol API

Project description

Python STTP (IEEE 2664) Implementation

Streaming Telemetry Transport Protocol

CodeQL docs Release

The Streaming Telemetry Transport Protocol (STTP) is optimized for the demands of transporting high volume streaming data. The protocol allows for the transmission of any information that can be represented longitudinally, e.g., time-series data.

STTP is an officially approved IEEE standard (2664), see: https://standards.ieee.org/ieee/2664/7397/

Example Usage

from sttp.subscriber import Subscriber
from time import time
from threading import Thread

def main():
    subscriber = Subscriber()

    try:
        # Start new data read at each connection
        subscriber.connectionestablished_receiver = (
            lambda: Thread(target=read_data, args=(subscriber,)).start())

        subscriber.subscribe("FILTER TOP 20 ActiveMeasurements WHERE True")
        subscriber.connect("localhost:7175")

        # Exit when enter key is pressed
        input()
    finally:
        subscriber.dispose()


def read_data(subscriber: Subscriber):
    subscriber.default_connectionestablished_receiver()
    reader = subscriber.read_measurements()
    lastmessage = 0.0

    while subscriber.connected:
        measurement, success = reader.next_measurement()

        if not success:
            break

        if time() - lastmessage < 5.0:
            continue
        elif lastmessage == 0.0:
            subscriber.statusmessage("Receiving measurements...")
            lastmessage = time()
            continue

        message = [
            f"{subscriber.total_measurementsreceived:,}",
            " measurements received so far. Current measurement:\n    ",
            str(measurement)
        ]

        subscriber.statusmessage("".join(message))
        lastmessage = time()

Example Output:

Connection to 127.0.0.1:7175 established.
Received 10,742 bytes of metadata in 0.045 seconds. Decompressing...
Decompressed 89,963 bytes of metadata in 0.004 seconds. Parsing...
Parsed 179 metadata records in 0.215 seconds
    Discovered:
        1 DeviceDetail records
        172 MeasurementDetail records
        5 PhasorDetail records
        1 SchemaVersion records
Metadata schema version: 14
Received success code in response to server command: Subscribe
Client subscribed as compact with 20 signals.
Receiving measurements...
1,470 measurements received so far. Current measurement:
    28bbb1fc-3434-48d3-87a8-bf5024c089d5 @ 19:43:53.600 = 516.545 (Normal)
2,970 measurements received so far. Current measurement:
    ed6def67-54c4-4e74-af95-c95fa6915fbc @ 19:43:58.600 = 218.070 (Normal)
4,460 measurements received so far. Current measurement:
    7aaf0a8f-3a4f-4c43-ab43-ed9d1e64a255 @ 19:44:03.633 = -0.230 (Normal)
5,930 measurements received so far. Current measurement:
    7aaf0a8f-3a4f-4c43-ab43-ed9d1e64a255 @ 19:44:08.633 = 8228.000 (Normal)

Connection to 127.0.0.1:7175 terminated.

Publisher Example

from sttp.publisher import Publisher
from sttp.transport.measurement import Measurement
from sttp.data.dataset import DataSet
from sttp.ticks import Ticks
from threading import Timer
import numpy as np
import os

def main():
    publisher = Publisher()
    
    try:
        # Start publisher on port 7165
        publisher.start(7165)
        
        # Load and define metadata
        metadata_path = os.path.join(os.path.dirname(__file__), "Metadata.xml")
        dataset, err = DataSet.from_xml(open(metadata_path).read())
        
        if err is not None:
            print(f"ERROR: Failed to load metadata: {err}")
            return
        
        publisher.define_metadata(dataset)
        
        # Get measurements to publish (exclude statistics)
        measurements_to_publish = publisher.filter_metadata("SignalAcronym <> 'STAT'")
        
        # Publish measurements every 33ms (30 Hz)
        def publish_data():
            timestamp = Ticks.utcnow()
            measurements = []
            
            for metadata in measurements_to_publish:
                measurement = Measurement()
                measurement.signalid = metadata.signalid
                measurement.timestamp = timestamp
                
                # Generate realistic values based on signal type
                if metadata.signalacronym == "FREQ":
                    measurement.value = np.float64(60.0 + (np.random.random() - 0.5) * 0.02)
                else:
                    measurement.value = np.float64(np.random.random())
                
                measurements.append(measurement)
            
            publisher.publish_measurements(measurements)
            
            # Schedule next publication
            Timer(0.033, publish_data).start()
        
        # Start publishing
        publish_data()
        
        # Wait for user input to stop
        input("Press Enter to stop publishing...\n")
        
    finally:
        publisher.stop()

if __name__ == "__main__":
    main()

Examples

https://github.com/sttp/pyapi/tree/main/examples

Support

For discussion and support, join our discussions channel or open an issue on GitHub.

Links

Lock

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sttpapi-0.7.4.tar.gz (152.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sttpapi-0.7.4-py3-none-any.whl (190.6 kB view details)

Uploaded Python 3

File details

Details for the file sttpapi-0.7.4.tar.gz.

File metadata

  • Download URL: sttpapi-0.7.4.tar.gz
  • Upload date:
  • Size: 152.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.10

File hashes

Hashes for sttpapi-0.7.4.tar.gz
Algorithm Hash digest
SHA256 9403fb8c557d17c7393d7ded4ede998f41c8286c6b5047b2bac621690870ef8e
MD5 1efbe23e7e3fa4cd7a8a3b2de81f84b3
BLAKE2b-256 810cb21bd1df8ed5369ea2d016de2a7577f6135e9d4c3ced004b4c1c8a752880

See more details on using hashes here.

File details

Details for the file sttpapi-0.7.4-py3-none-any.whl.

File metadata

  • Download URL: sttpapi-0.7.4-py3-none-any.whl
  • Upload date:
  • Size: 190.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.10

File hashes

Hashes for sttpapi-0.7.4-py3-none-any.whl
Algorithm Hash digest
SHA256 dda9c97339782664bf83ae1cd59eec3663f860e25ade9eede454bde9998bc2ad
MD5 285ed0f93bd80ae2ee6e6a0c825e8c7e
BLAKE2b-256 6998ce6c1e76a876ed22b93cd6c667b8752304483f1e725361492e0e6e223331

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page