Skip to main content

Pure Python NTP shared memory library.

Project description

Overview

A pure Python interface to the NTP shared memory segment with no external dependencies.

The only platform-dependent part of this library is the SHM_CREAT constant, which seems to always be the octal value of 01000 (Linux and BSDs). Technically the size of time_t is also platform-dependent, but it's 2021 and this should be 64 bit everywhere.

Prerequisites

Python: 3.7+

OSs: Posix-compliant with the System V shared memory interface.

This uses ctypes for direct access to memory and shared memory routines. This will dynamically load the system's C library to access shmget() and shmat() functions.

Usage

NTP Shared Memory

The NtpShm class wraps up access to the NTP shared memory segments. See the NTP documentation for information on the contents of this memory and how to safely access it.

Example use:

from ntp_shm import NtpShm

seg = NtpShm(segment=0)

# Access copies of the memory segment (ShmTime) through read()/write()
shm_time = seg.read()
shm_time.count += 1
shm_time.clock_time_sec = 42
# ...
seg.write(shm_time)

# Dynamic, direct access (by ref) through .ref
shm_time = seg.ref  # Or just use seg.ref directly
shm_time.count += 1
shm_time.clock_time_sec = 42
# ...

The ShmTime object is a ctypes structure with a few extra properties for convenience, and with fields renamed slightly to be more pythonic. The convenience properties can be used to set or get the clock or receive times using datetime objects or integer time in nanoseconds.

>>> shm_time = seg.ref
>>> seg.ref.receive_dt
datetime.datetime(2021, 9, 6, 13, 45, 3, 495830, tzinfo=datetime.timezone.utc)
>>> seg.ref.receive_dt
datetime.datetime(2021, 9, 6, 13, 45, 4, 440210, tzinfo=datetime.timezone.utc)
>>> shm_time.clock_ns
1630935919000000000

Keep in mind that the datetime representation is only accurate to the microsecond.

Important: Direct access to the shared memory segment suffers from race conditions. Since the time values are split up across multiple fields, these may be modified in between field reads leading to consumers reading corrupted values.

The NTP documentation (above) specifies two different methods of updating and reading from the shared memory segment to avoid this issue. Writing via mode 1 is implemented in the ShmTime.update() method. This can be used to update the clock and receive times:

from ntp_shm import util, NtpShm

seg = NtpShm()

clock_time_ns = some_function_that_gives_integer_nanoseconds()
receive_time_ns = util.datetime_to_ns(datetime.datetime.now())

seg.update(clock_time_ns, receive_time_ns)

Since Python lacks memory barriers or cache synchronization controls, its still not 100% guaranteed that the update() method will be issue free.

NTP Bridge

Included is a utility command: ntp-shm bridge. This acts as a very basic NMEA0183 bridge to NTP shared memory. It reads lines from a file input, looking for and parsing valid GPRMC NMEA sentences. Valid times, after a small holdoff to allow for stabilization, are passed to the NTP shared memory segment.

The NMEA sentences must come from a file-like device, such as a character device or pipe (stdin). For GPSs connected to a serial tty device, use stty to configure the device for direct access. Alternatively, use one of many applications to handle the serial interface and pipe the output to ntp-shm bridge.

Example tty setup for raw access (on FreeBSD).

stty -f /dev/ttyu1.init raw 9600

Test the tty configuration using cat /dev/ttyu1. The output should be smooth, without extra blank lines or non-printable characters.

To bridge the NMEA data on ttyu1 to segment 0:

ntp-shm bridge -p /dev/ttyu1 -s 0

To create a persistent process, consider using daemon (FreeBSD) or daemonize (Linux) and your system's service manager.

Installation

From pypi:

pip install ntp-shm

From your local checkout:

pip install [--user] .

or

python setup.py install [--user]

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

ntp-shm-2.0.2.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

ntp_shm-2.0.2-py3-none-any.whl (11.0 kB view details)

Uploaded Python 3

File details

Details for the file ntp-shm-2.0.2.tar.gz.

File metadata

  • Download URL: ntp-shm-2.0.2.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.6

File hashes

Hashes for ntp-shm-2.0.2.tar.gz
Algorithm Hash digest
SHA256 74c9344d058bfd36cedd5ae0fb8033c4926e0a8c55c722cf82491c08c19e6d75
MD5 d83f0e9b7d21070a74497418b576f5c5
BLAKE2b-256 84a42117cb5d4a17caea67cde98e2f1899eb2070716f4a6aa2ad1d470de94d5f

See more details on using hashes here.

File details

Details for the file ntp_shm-2.0.2-py3-none-any.whl.

File metadata

  • Download URL: ntp_shm-2.0.2-py3-none-any.whl
  • Upload date:
  • Size: 11.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.6

File hashes

Hashes for ntp_shm-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b18657abf946f41d71527d5200af3c9d7c6ee2a3b4c18437041f2df2ca585b91
MD5 b3afeaeddf7f8727296011857118c296
BLAKE2b-256 4225c86941823d3ce6b3222050f8b2d5a7aefee3dbfb67a67484ad6f6081cac4

See more details on using hashes here.

Supported by

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