{ "info": { "author": "Markus Juenemann", "author_email": "markus@juenemann.net", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Operating System :: Unix", "Programming Language :: C", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries", "Topic :: System :: Networking :: Time Synchronization" ], "description": "python-ntpdshm\n**************\n\nOverview\n========\n\n*python-ntpdshm* provides a Python interface to *ntpd's* shared memory `driver 28`_. A single\nclass ``NtpdShm`` exposes the fields of the shared memory structure as attributes that can be read and written.\nIn addition there are properties to set the clock and receive timestamps from float values. There is also a convenience ``update()`` function for setting the time related fields in a single step.\n\n*python-ntpdshm* is implemented using Swig_.\n\n.. _Swig: http://www.swig.org/Doc1.3/Python.html\n\n*python-ntpdshm* works with the following Python versions.\n\n* Python 2.6\n* Python 2.7\n* Python 3.3\n* Python 3.4\n* Python 3.5\n* PyPy (but not PyPy3!)\n\nExample\n=======\n\n.. code-block:: python\n\n import ntpdshm\n \n ntpd_shm = ntpdshm.NtpdShm(unit=0)\n\nThe members of the C struct can be accessed by their original names. These have **not**\nbeen converted into PEP-8 compliant names.\n\n.. code-block:: python\n \n print ntpd_shm.mode\n print ntpd_shm.clockTimeStampSec\n print ntpd_shm.clockTimeStampUSec\n print ntpd_shm.clockTimeStampNSec # only ntpd 4.2.7p303 or later, probably random value otherwise\n print ntpd_shm.receiveTimeStampSec\n print ntpd_shm.receiveTimeStampUSec\n print ntpd_shm.receiveTimeStampNSec # only ntpd 4.2.7p303 or later, probably random value otherwise\n print ntpd_shm.leap\n print ntpd_shm.precision\n print ntpd_shm.valid\n\nIn addition there are two pseudo properties that combine the second and microsecond attributes into \n\"float\" timestamps. These don't support nanosecond precision as (as far as I know) it is not possible\nto detect whether *ntpd* does support nanosecond resolution.\n\n.. code-block:: python\n\n print ntpd_shm.clockTimeStamp # clockTimeStampSec.clockTimeStampUSec\n print ntpd_shm.receiveTimeStamp # receiveTimeStampSec.receiveTimeStampUSec\n\nThe process to feed *ntpd* an external reference time is shown below.\n\n.. code-block:: python\n\n import time\n \n clock_time = get_clock_time() # `get_clock_time` must be implemented somewhere else and\n # return a float.\n recev_time = time.time()\n ntpd_shm.valid = 0 # don't use Python boolean\n ntpd_shm.clockTimeStamp = clock_time \n ntpd_shm.receiveTimeStamp = recv_time \n ntpd_shm.precision = -5 # 2^-5 = 0.03125 seconds in this case\n ntpd_shm.count += 1\n ntpd_shm.valid = 1\n \nAs this is somewhat cumbersome, there is a convenience method ``update()`` that achieves the same in \na single line. It requires the ``clock_time`` as mandatory argument and accepts several optional\narguments.\n\n.. code-block:: python\n\n ntpd_shm.update(clock_time, recv_time=recv_time, precision=-5)\n \n # Or simply, if no other fields are to be changed. The receive timestamp is set\n # automatically.\n ntpd_shm.update(clock_time)\n\n.. _`driver 28`: http://doc.ntp.org/4.2.8/drivers/driver28.html\n\n\nApplications\n============\n\n\"Off by one second\" reference time\n----------------------------------\n\nA just for fun example of using *python-ntpdshm* is to implement an \"off by one second\" reference time source for *ntpd*. While this example makes no sense at all for practical purposes it provides a useful template for how it all fits together.\n\nFirst we write the code for the reference clock.\n\n.. code-block:: python\n\n import time\n import ntpdshm\n \n def get_clock_time():\n return time.time() - 1.0 # always be exactly one second behind.\n \n def main():\n ntpd_shm = ntpdshm.NtpdShm(unit=2)\n ntpd_shm.mode = 0 # set mode\n ntpd_shm.precision = -6 # set precision once\n ntpd_shm.leap = 0 # how would we know about leap seconds?\n \n while True:\n clock_time = get_clock_time()\n ntpd_shm.update(clock_time)\n time.sleep(1.0)\n \n if __name__ == '__main__':\n main()\n \nThen add the shared memory reference clock to ``ntp.conf``:: \n\n # ntp.conf\n ...\n server 127.127.28.2 noselect # unit=2, never select this reference\n fudge 127.127.28.2 refid PYTH stratum 10\n\nRestart *ntpd* and monitor the output of ``ntpq -pn``. The offset should be exactly -1000 msec:\n\n.. code-block:: console\n\n $ ntpq -pn\n remote refid st t when poll reach delay offset jitter\n ==============================================================================\n ...\n 127.127.28.2 .PYTH. 10 l 9 16 377 0.000 -1000.0 0.017\n\n\n\n\nHistory\n=======\n\n0.1.0 (15-Dec-2015)\n---------------------\n\n* Initial version", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/mjuenema/python-ntpdshm", "keywords": "ntp,shared memory", "license": "BSD License", "maintainer": "", "maintainer_email": "", "name": "ntpdshm", "package_url": "https://pypi.org/project/ntpdshm/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/ntpdshm/", "project_urls": { "Homepage": "https://github.com/mjuenema/python-ntpdshm" }, "release_url": "https://pypi.org/project/ntpdshm/0.2.1/", "requires_dist": null, "requires_python": "", "summary": "Python interface to NTP Shared Memory", "version": "0.2.1" }, "last_serial": 2456008, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "82c09ff0dd55da02633d2c78efd3d566", "sha256": "0521f789ecc1ca76e8d3a4ae219636cdcbab8bf4fca4d179babb3137071a77e1" }, "downloads": -1, "filename": "ntpdshm-0.1.0.tar.gz", "has_sig": false, "md5_digest": "82c09ff0dd55da02633d2c78efd3d566", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39028, "upload_time": "2015-12-15T03:40:53", "url": "https://files.pythonhosted.org/packages/8b/d6/d7b898f0cd3c5b05b96f8a9939c3603c2d063d6f32743680ed6bd9e2da74/ntpdshm-0.1.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "77ee5b84039bad2a406e1686e999a9f6", "sha256": "b8c51773ea03789a1697e124b01a43ca4e0e77f2bacdd6858bccfb0b174309e2" }, "downloads": -1, "filename": "ntpdshm-0.2.1.tar.gz", "has_sig": false, "md5_digest": "77ee5b84039bad2a406e1686e999a9f6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42268, "upload_time": "2016-11-12T01:15:23", "url": "https://files.pythonhosted.org/packages/41/b3/eca2a32f63252b5fb95898200a99fb4af1a5fc6559ebbd35e35bd29e2bf6/ntpdshm-0.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "77ee5b84039bad2a406e1686e999a9f6", "sha256": "b8c51773ea03789a1697e124b01a43ca4e0e77f2bacdd6858bccfb0b174309e2" }, "downloads": -1, "filename": "ntpdshm-0.2.1.tar.gz", "has_sig": false, "md5_digest": "77ee5b84039bad2a406e1686e999a9f6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42268, "upload_time": "2016-11-12T01:15:23", "url": "https://files.pythonhosted.org/packages/41/b3/eca2a32f63252b5fb95898200a99fb4af1a5fc6559ebbd35e35bd29e2bf6/ntpdshm-0.2.1.tar.gz" } ] }