Created
December 15, 2010 20:05
-
-
Save acspike/742520 to your computer and use it in GitHub Desktop.
Time Sync Protocol for Lathem Clocks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
DATA: 0#112233456677Z,CR (16 chars) | |
'0' is address byte | |
'#' is command code for Routine Time Update | |
where '11' is hex MS,LS of Seconds of Minute (1-59) | |
where '22' is hex MS,LS of Minutes of Hr (0-59) | |
where '33' is hex MS,LS of Hour of Day (0-23) | |
where '4' is hex Day of Week (Sun - 0 etc.) | |
where '5' is hex Month of Year (1-12) | |
where '66' is hex MS,LS of Day of Month (1-31) | |
where '77' is hex MS,LS of Year offset form 1984 (0-127) | |
where 'Z' is the 1's complement of the mod-64 sum of all | |
characters in the string except the CR and the checksum | |
''' | |
from datetime import datetime | |
def lathem_checksum(s): | |
sum = 0 | |
for x in s: | |
sum += ord(x) | |
return chr((sum & 63) ^ 255) | |
def to_lathem_time_string(dt): | |
#In python week begins on Monday=0 | |
#Lathem expects Sunday=0 | |
weekday = (dt.weekday() + 1) % 7 | |
#Lathem base year is 1984 | |
year = dt.year - 1984 | |
format = '0#%0.2X%0.2X%0.2X%0.1X%0.1X%0.2X%0.2X' | |
buffer = format % (dt.second, dt.minute, dt.hour, weekday, dt.month, dt.day, year) | |
return buffer+lathem_checksum(buffer)+'\x0d' | |
def from_lathem_time_string(s): | |
second = int(s[2:4],16) | |
minute = int(s[4:6],16) | |
hour = int(s[6:8],16) | |
month = int(s[9],16) | |
day = int(s[10:12],16) | |
year = 1984 + int(s[12:14],16) | |
return datetime(year, month, day, hour, minute, second, 0) | |
if __name__ == '__main__': | |
import sys | |
now = datetime.today() | |
if 'write' in sys.argv: | |
import serial | |
p = serial.Serial(port='COM6') | |
p.write(to_lathem_time_string(now)) | |
p.close() | |
elif 'read' in sys.argv: | |
import serial | |
p = serial.Serial(port='COM6', timeout=30) | |
try: | |
while True: | |
x = p.read(16) | |
if x: | |
print repr(x), from_lathem_time_string(x) | |
finally: | |
p.close() | |
else: | |
print now, repr(to_lathem_time_string(now)), from_lathem_time_string(lathem_time_string(now)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment