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
Built Distribution
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4fe01833bd0dd3748050b5a4109d0e807b66f4464433189676a5304d8a925c5b |
|
MD5 | 75e1dc9175b1d698e80dae9d32df3604 |
|
BLAKE2b-256 | e5ca91a818299976d3af37ed09a06a90d85e7723eff8cf6f5a55d9dd8df06bcf |
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9776708c5a22e8d6953eefca0965eec99bee71d0e501e80b19262eb344e8efa2 |
|
MD5 | 8baba17047389feeda4ff48b556331a8 |
|
BLAKE2b-256 | 37753651d7df0650781827104adbe3625aef5e3205c7ec20c09d5816b17f8a33 |