John's Vademecum

Try to learn something about everything, and everything about something -Thomas Huxley “Darwin's bulldog” (1824-1895)

User Tools

Site Tools


public:watches:watchcheck

This is an old revision of the document!


Watchcheck Python code

I wrote a small python2 application to keep track of a watch/clock's daily rate error. It's a console-only mimic of an Android app that I use on my phone to track my watch timekeeping.

I wrote it mainly as a thought-experiment rather than as a fully functional piece of code.

You put the application in a directory specific to the watch and execute it from that directory. the data from each measurement is stored in a json file in the same directory.

watchcheck.py
#! /usr/bin/env python
 
## a text-terminal version of the WatchCheck app
## to track error, daily error rate of timepieces.
# auto update?
#
import time
import datetime
import json
 
 
 
 
def write_file(text):
    filename = "logfile.txt"
    f = open(filename, 'a+')
    timenow = time.strftime("%d/%m/%Y %H:%M:%S", time.gmtime(time.time()))
    log = " ".join((timenow, text, "\r\n"))
    f.write(log)
    f.close()
 
 
 
 
def get_delta():
 
    print time.strftime("Current Time = %H:%M")
 
    h = time.strftime("%H")
    w = raw_input("Watch time %s:" % (h))
    print w
 
    date = time.strftime("%Y/%m/%d")
    s = date + " " + h +":"+ w +":00"
 
    raw_input("Press enter when seconds = 0 ")
 
    watchtime = time.mktime(datetime.datetime.strptime(s, "%Y/%m/%d %H:%M:%S").timetuple())
    record_time = time.strftime("%Y/%m/%d %H:%M:%S")
    timenow = time.time()
    delta = watchtime - timenow
 
    return record_time,delta
 
 
def watch_stat():
 
    try:
        saved_error = open('error_list.json')
        error_list = json.load(saved_error)
    except:
        error_list = []
 
    if len(error_list) > 1:
        first_record = error_list[0]
        latest_record = error_list[-1]
        previous_record = error_list[-2]
 
        first_time = first_record[0]
 
        first_delta = first_record[1]
 
        latest_time = latest_record[0] 
        latest_delta = latest_record[1]
 
        previous_time = previous_record[0]
        previous_delta = previous_record[1]
 
        FMT = '%Y/%m/%d %H:%M:%S'
 
        t_latest = datetime.datetime.strptime(latest_time, FMT)
        t_previous = datetime.datetime.strptime(previous_time, FMT)
        t_first = datetime.datetime.strptime(first_time, FMT)
 
        tdelta = t_latest - t_previous
        full_delta = t_latest - t_first
 
        elapsed_time = tdelta.total_seconds()
 
        full_time = full_delta.total_seconds()
 
        print "First record time ", first_time
        print "First record delta ", first_delta
        print ""
 
        print "Previous record time ", previous_time
        print "Previous record delta ", previous_delta
        print ""
 
        print "Latest record time " , latest_time
        print "Latest record delta ", latest_delta
        print ""
 
        print "Overall elapsed time ", full_delta
        print "Latest elapsed time ", tdelta
        print ""
 
        # Current Error rate
        time_error = latest_delta - previous_delta
        error_rate = time_error / elapsed_time
        daily_rate = error_rate * (60*60*24)
        ppm_daily = error_rate * 1000000
 
        # Overall Error rate
        total_error = latest_delta - first_delta
        average_error_rate = total_error / full_time
 
        average_rate = average_error_rate * (60*60*24)
        ppm_overall = average_error_rate * 1000000
 
 
        print "Latest delta change ", time_error
 
        print "Latest elapsed time %d seconds " % (elapsed_time)
 
        print ""
        print "Daily PPM : %0.3f" % ppm_daily
        print "Daily rate error: %0.1f s/d " % (daily_rate)
 
        print ""
        print "Total Time %d seconds" % (full_time)
        print "Total error ", total_error
        print "Total PPM : %0.3f" % ppm_overall
        print "Total rate error: %0.1f s/d" % (average_rate)
        print ""
        print "========================================================"
        print " Delta : %+0.1f s | Rate : %+0.1f s/d | Average : %+0.1f s/d" % (latest_delta, daily_rate, average_rate)
        print "========================================================"
        print ""
        text = "\t%+0.1f\t\t%+0.1f\t\t%+0.1f" % (latest_delta, daily_rate, average_rate)
        write_file(text)
    else:
        print "No rate yet"
 
 
def new_record():
 
    try:
        saved_error = open('error_list.json')
        error_list = json.load(saved_error)
    except:
        error_list = []
 
    s,delta = get_delta()
 
    print ""
    print "%s \n\nDelta %0.1f seconds" % (s, delta)
    last_data=[s,delta]
    error_list.append(last_data)
    #print error_list
 
    with open('error_list.json', 'wb') as outfile:
        json.dump(error_list, outfile)
 
    return
 
def delete_last():
    try:
        saved_error = open('error_list.json')
        error_list = json.load(saved_error)
    except:
        error_list = []
    error_list.pop()
 
    with open('error_list.json', 'wb') as outfile:
        json.dump(error_list, outfile)
 
    return
 
 
def menu():
    print "Wire2waves WatchCheck....."
    print "=========================\n"
    print "N : New Record\nD : Delete Last\nS : Stats\nQ : Quit\n"
    choice = raw_input("Command > : ").upper()
    if choice == "N":
        print "New"
        new_record()
        watch_stat()
        menu()
    elif choice == "S":
        print "Stat"
        watch_stat()
        menu()
    elif choice == "D":
        delete_last()
        watch_stat()
        menu()
    elif choice == "Q":
        return
    else:
        print "?"
        menu()
 
 
menu()

Running it for the first time, with no previous records stored, looks like this:

Wire2waves WatchCheck.....
=========================

N : New Record
D : Delete Last
S : Stats
Q : Quit

Command > : n
New
Current Time = 10:18
Watch time 10:19
19
Press enter when seconds = 0

2022/05/04 10:19:30

Delta -30.2 seconds

and the first time-delta is stored in the error_list.json file like this:

[["2022/05/04 10:19:30", -30.179980039596558]]

Running it again, after only 10 minutes looks like this:

Command > : n
New
Current Time = 10:30
Watch time 10:30
30
Press enter when seconds = 0

2022/05/04 10:30:30

Delta -30.2 seconds
First record time  2022/05/04 10:19:30
First record delta  -30.1799800396

Previous record time  2022/05/04 10:19:30
Previous record delta  -30.1799800396

Latest record time  2022/05/04 10:30:30
Latest record delta  -30.1998269558

Overall elapsed time  0:11:00
Latest elapsed time  0:11:00

Latest delta change  -0.0198469161987
Latest elapsed time 660 seconds

Daily PPM : -30.071
Daily rate error: -2.6 s/d

Total Time 660 seconds
Total error  -0.0198469161987
Total PPM : -30.071
Total rate error: -2.6 s/d

========================================================
 Delta : -30.2 s | Rate : -2.6 s/d | Average : -2.6 s/d
========================================================

The error_list.json file now looks like:

[["2022/05/04 10:19:30", -30.179980039596558], ["2022/05/04 10:30:30", -30.199826955795288]]

There's also a small utility called watchstat.py that reads the error_list.json file to calculate and display the data

watchstat.py
#! /usr/bin/env python
 
## a text-terminal version of the WatchCheck app
## to track error, daily error rate of timepieces.
 
#
import time
import datetime
import json
 
 
 
def watch_stat():
 
    try:
        saved_error = open('error_list.json')
        error_list = json.load(saved_error)
    except:
        error_list = []
 
 
 
 
    if len(error_list) > 1:
        first_record = error_list[0]
        latest_record = error_list[-1]
        previous_record = error_list[-2]
 
        first_time = first_record[0]
 
        first_delta = first_record[1]
 
        latest_time = latest_record[0] 
        latest_delta = latest_record[1]
 
        previous_time = previous_record[0]
        previous_delta = previous_record[1]
 
        FMT = '%Y/%m/%d %H:%M:%S'
 
        t_latest = datetime.datetime.strptime(latest_time, FMT)
        t_previous = datetime.datetime.strptime(previous_time, FMT)
        t_first = datetime.datetime.strptime(first_time, FMT)
 
        tdelta = t_latest - t_previous
        full_delta = t_latest - t_first
 
        elapsed_time = tdelta.total_seconds()
 
        full_time = full_delta.total_seconds()
 
        print "First record time ", first_time
        print "First record delta ", first_delta
        print ""
 
        print "Previous record time ", previous_time
        print "Previous record delta ", previous_delta
        print ""
 
        print "Latest record time " , latest_time
        print "Latest record delta ", latest_delta
        print ""
 
        print "Overall elapsed time ", full_delta
        print "Latest elapsed time ", tdelta
        print ""
 
        # Current Error rate
        time_error = latest_delta - previous_delta
        error_rate = time_error / elapsed_time
        daily_rate = error_rate * (60*60*24)
        ppm_daily = error_rate * 1000000
 
        # Overall Error rate
        total_error = latest_delta - first_delta
        average_error_rate = total_error / full_time
 
        average_rate = average_error_rate * (60*60*24)
        ppm_overall = average_error_rate * 1000000
 
 
        print "Latest delta change ", time_error
 
        print "Latest elapsed time %d seconds " % (elapsed_time)
 
        print ""
        print "Daily PPM : %0.3f" % ppm_daily
        print "Daily rate error: %0.1f s/d " % (daily_rate)
 
        print ""
        print "Total Time %d seconds" % (full_time)
        print "Total error ", total_error
        print "Total PPM : %0.3f" % ppm_overall
        print "Total rate error: %0.1f s/d" % (average_rate)
        print ""
        print "========================================================"
        print " Delta : %0.1f s | Rate : %0.1f s/d | Average : %0.1f s/d" % (latest_delta, daily_rate, average_rate)
        print "========================================================"
        print ""
    else:
        print "No rate yet"
 
 
watch_stat()

Running watchstat.py on the newly updated error_list.json

gm4slv@laptop:~/watchcheck_damasko $ python watchstat.py
First record time  2022/05/04 10:19:30
First record delta  -30.1799800396

Previous record time  2022/05/04 10:19:30
Previous record delta  -30.1799800396

Latest record time  2022/05/04 10:30:30
Latest record delta  -30.1998269558

Overall elapsed time  0:11:00
Latest elapsed time  0:11:00

Latest delta change  -0.0198469161987
Latest elapsed time 660 seconds

Daily PPM : -30.071
Daily rate error: -2.6 s/d

Total Time 660 seconds
Total error  -0.0198469161987
Total PPM : -30.071
Total rate error: -2.6 s/d

========================================================
 Delta : -30.2 s | Rate : -2.6 s/d | Average : -2.6 s/d
========================================================

watchcheck.py also creates a log file on each run.

04/05/2022 09:30:30     -30.2           -2.6            -2.6

The fields are “date time”, current error, error in seconds per day since last record, average error in seconds per day since the start.

This mimics the behaviour of the Android Watchcheck app

John Pumford-Green Wed May 4 09:09:09 2022

Page Updated : 06/03/25 06:49 GMT

public/watches/watchcheck.1651657497.txt.gz · Last modified: 06/03/25 06:49 GMT (external edit)