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.5+

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-1.4.0.tar.gz (11.0 kB view details)

Uploaded Source

Built Distribution

ntp_shm-1.4.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: ntp-shm-1.4.0.tar.gz
  • Upload date:
  • Size: 11.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.9.4

File hashes

Hashes for ntp-shm-1.4.0.tar.gz
Algorithm Hash digest
SHA256 4fe01833bd0dd3748050b5a4109d0e807b66f4464433189676a5304d8a925c5b
MD5 75e1dc9175b1d698e80dae9d32df3604
BLAKE2b-256 e5ca91a818299976d3af37ed09a06a90d85e7723eff8cf6f5a55d9dd8df06bcf

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ntp_shm-1.4.0-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.9.4

File hashes

Hashes for ntp_shm-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9776708c5a22e8d6953eefca0965eec99bee71d0e501e80b19262eb344e8efa2
MD5 8baba17047389feeda4ff48b556331a8
BLAKE2b-256 37753651d7df0650781827104adbe3625aef5e3205c7ec20c09d5816b17f8a33

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